diff --git a/backend/src/graphql/rooms.ts b/backend/src/graphql/rooms.ts index 109bf1d55..cb511c4eb 100644 --- a/backend/src/graphql/rooms.ts +++ b/backend/src/graphql/rooms.ts @@ -30,3 +30,11 @@ export const roomQuery = () => { } ` } + +export const unreadRoomsQuery = () => { + return gql` + query { + UnreadRooms + } + ` +} diff --git a/backend/src/middleware/permissionsMiddleware.ts b/backend/src/middleware/permissionsMiddleware.ts index c07098a3c..f87f4b079 100644 --- a/backend/src/middleware/permissionsMiddleware.ts +++ b/backend/src/middleware/permissionsMiddleware.ts @@ -408,6 +408,7 @@ export default shield( getInviteCode: isAuthenticated, // and inviteRegistration Room: isAuthenticated, Message: isAuthenticated, + UnreadRooms: isAuthenticated, }, Mutation: { '*': deny, diff --git a/backend/src/schema/resolvers/rooms.spec.ts b/backend/src/schema/resolvers/rooms.spec.ts index 03c3d4456..6a8cb47de 100644 --- a/backend/src/schema/resolvers/rooms.spec.ts +++ b/backend/src/schema/resolvers/rooms.spec.ts @@ -1,7 +1,8 @@ import { createTestClient } from 'apollo-server-testing' import Factory, { cleanDatabase } from '../../db/factories' import { getNeode, getDriver } from '../../db/neo4j' -import { createRoomMutation, roomQuery } from '../../graphql/rooms' +import { createRoomMutation, roomQuery, unreadRoomsQuery } from '../../graphql/rooms' +import { createMessageMutation } from '../../graphql/messages' import createServer from '../../server' const driver = getDriver() @@ -29,11 +30,13 @@ beforeAll(async () => { }) afterAll(async () => { - await cleanDatabase() + // await cleanDatabase() driver.close() }) describe('Room', () => { + let roomId: string + beforeAll(async () => { ;[chattingUser, otherChattingUser, notChattingUser] = await Promise.all([ Factory.build('user', { @@ -68,8 +71,6 @@ describe('Room', () => { }) describe('authenticated', () => { - let roomId: string - beforeAll(async () => { authenticatedUser = await chattingUser.toJson() }) @@ -260,4 +261,115 @@ describe('Room', () => { }) }) }) + + describe('unread rooms query', () => { + describe('unauthenticated', () => { + it('throws authorization error', async () => { + authenticatedUser = null + await expect( + query({ + query: unreadRoomsQuery(), + }), + ).resolves.toMatchObject({ + errors: [{ message: 'Not Authorized!' }], + }) + }) + }) + + describe('authenticated', () => { + let otherRoomId: string + + beforeAll(async () => { + authenticatedUser = await chattingUser.toJson() + const result = await mutate({ + mutation: createRoomMutation(), + variables: { + userId: 'not-chatting-user', + }, + }) + otherRoomId = result.data.CreateRoom.roomId + await mutate({ + mutation: createMessageMutation(), + variables: { + roomId: otherRoomId, + content: 'Message to not chatting user', + }, + }) + await mutate({ + mutation: createMessageMutation(), + variables: { + roomId, + content: '1st message to other chatting user', + }, + }) + await mutate({ + mutation: createMessageMutation(), + variables: { + roomId, + content: '2nd message to other chatting user', + }, + }) + authenticatedUser = await otherChattingUser.toJson() + const result2 = await mutate({ + mutation: createRoomMutation(), + variables: { + userId: 'not-chatting-user', + }, + }) + otherRoomId = result2.data.CreateRoom.roomId + await mutate({ + mutation: createMessageMutation(), + variables: { + roomId: otherRoomId, + content: 'Other message to not chatting user', + }, + }) + }) + + describe('as chatting user', () => { + it('has 0 unread rooms', async () => { + authenticatedUser = await chattingUser.toJson() + await expect( + query({ + query: unreadRoomsQuery(), + }), + ).resolves.toMatchObject({ + data: { + UnreadRooms: 0, + }, + }) + }) + }) + + describe('as other chatting user', () => { + it('has 1 unread rooms', async () => { + authenticatedUser = await otherChattingUser.toJson() + await expect( + query({ + query: unreadRoomsQuery(), + }), + ).resolves.toMatchObject({ + data: { + UnreadRooms: 1, + }, + }) + }) + }) + + describe('as not chatting user', () => { + it('has 2 unread rooms', async () => { + authenticatedUser = await notChattingUser.toJson() + await expect( + query({ + query: unreadRoomsQuery(), + }), + ).resolves.toMatchObject({ + data: { + UnreadRooms: 2, + }, + }) + }) + }) + }) + }) }) diff --git a/backend/src/schema/resolvers/rooms.ts b/backend/src/schema/resolvers/rooms.ts index 3eda1440c..084a75eb0 100644 --- a/backend/src/schema/resolvers/rooms.ts +++ b/backend/src/schema/resolvers/rooms.ts @@ -33,11 +33,11 @@ export default { const readTxResultPromise = session.readTransaction(async (transaction) => { const unreadRoomsCypher = ` MATCH (:User { id: $currentUserId })-[:CHATS_IN]->(room:Room)<-[:INSIDE]-(message:Message)<-[:CREATED]-(user:User) - WHERE NOT message.seen AND NOT user.id = $currentUserId - RETURN toString(COUNT(room)) AS count + WHERE NOT user.id = $currentUserId AND NOT message.seen + RETURN toString(COUNT(DISTINCT room)) AS count ` const unreadRoomsTxResponse = await transaction.run(unreadRoomsCypher, { currentUserId }) - return unreadRoomsTxResponse.records.map((record) => record.get('count')) + return unreadRoomsTxResponse.records.map((record) => record.get('count'))[0] }) try { const count = await readTxResultPromise