From 606f420d215f30ec7102ffebc60e799ba29574fb Mon Sep 17 00:00:00 2001 From: kakiba <97882386+kotto5@users.noreply.github.com> Date: Tue, 30 Jan 2024 12:29:01 +0900 Subject: [PATCH] [backend] implement to check online status api (#230) --- backend/src/chat/chat.controller.ts | 7 ++++ backend/src/chat/chat.service.ts | 2 + backend/test/chat-gateway.e2e-spec.ts | 57 ++++++++++++++++++++++++--- backend/test/utils/app.ts | 5 +++ 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/backend/src/chat/chat.controller.ts b/backend/src/chat/chat.controller.ts index b1c6be92..36a8ef3b 100644 --- a/backend/src/chat/chat.controller.ts +++ b/backend/src/chat/chat.controller.ts @@ -25,4 +25,11 @@ export class ChatController { ) { return this.chatService.findConversation(userId, user); } + + @Get(':userId/online') + @UseGuards(JwtAuthGuard) + @ApiBearerAuth() + isUserOnline(@Param('userId', ParseIntPipe) userId: number) { + return this.chatService.isOnline(userId); + } } diff --git a/backend/src/chat/chat.service.ts b/backend/src/chat/chat.service.ts index 56b8dcd2..2e81979b 100644 --- a/backend/src/chat/chat.service.ts +++ b/backend/src/chat/chat.service.ts @@ -211,4 +211,6 @@ export class ChatService { }, }); } + + isOnline = (userId: number) => ({ isOnline: this.clients.has(userId) }); } diff --git a/backend/test/chat-gateway.e2e-spec.ts b/backend/test/chat-gateway.e2e-spec.ts index a8ddc4f6..5266a1bf 100644 --- a/backend/test/chat-gateway.e2e-spec.ts +++ b/backend/test/chat-gateway.e2e-spec.ts @@ -4,7 +4,7 @@ import { Socket, io } from 'socket.io-client'; import { AppModule } from 'src/app.module'; import { MessageEntity } from 'src/chat/entities/message.entity'; import { constants } from './constants'; -import { TestApp } from './utils/app'; +import { TestApp, UserEntityWithAccessToken } from './utils/app'; async function createNestApp(): Promise { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -32,6 +32,10 @@ describe('ChatGateway and ChatController (e2e)', () => { bannedUser1, mutedUser1; const waitTime = 500; + type UserAndSocket = { + user: UserEntityWithAccessToken; + ws: Socket; + }; beforeAll(async () => { //app = await initializeApp(); @@ -1050,10 +1054,6 @@ describe('ChatGateway and ChatController (e2e)', () => { // TODO }); describe('invite pong game', () => { - type UserAndSocket = { - user: any; - ws: Socket; - }; let userAndSockets: UserAndSocket[]; beforeAll(() => { @@ -1064,6 +1064,7 @@ describe('ChatGateway and ChatController (e2e)', () => { extraHeaders: { cookie: 'token=' + user.accessToken }, }), })); + return userAndSockets.map((s) => connect(s.ws)); }); afterAll(() => { userAndSockets.map((userAndSocket) => { @@ -1425,4 +1426,50 @@ describe('ChatGateway and ChatController (e2e)', () => { }); }); }); + describe('online status', () => { + let userAndSockets: UserAndSocket[]; + beforeAll(async () => { + ws1.close(); + ws2.close(); + ws3.close(); + ws4.close(); + ws5.close(); + ws6.close(); + ws7.close(); + const users = [user1, user2]; + userAndSockets = await users.map((user) => { + return { + user, + ws: io('ws://localhost:3000/chat', { + extraHeaders: { cookie: 'token=' + user.accessToken }, + }), + }; + }); + userAndSockets[1].ws.close(); + await connect(userAndSockets[0].ws); + return new Promise((resolve) => setTimeout(resolve, waitTime)); + }); + afterAll(() => { + userAndSockets.map((userAndSocket) => { + userAndSocket.ws.close(); + }); + }); + + it('connected user should be online', async () => { + const u = userAndSockets[0]; + const res = await app.isOnline(u.user.id, u.user.accessToken).expect(200); + const body = res.body; + expect(body.isOnline).toEqual(true); + }); + it('disconnected user should be offline', async () => { + const u = userAndSockets[1]; + const res = await app.isOnline(u.user.id, u.user.accessToken).expect(200); + const body = res.body; + expect(body.isOnline).toEqual(false); + }); + it('check online status with invalid access token should be unauthorized', async () => { + const u = userAndSockets[0]; + await app.isOnline(u.user.id, '').expect(401); + }); + }); }); diff --git a/backend/test/utils/app.ts b/backend/test/utils/app.ts index 2d6015a5..b4a7c0a9 100644 --- a/backend/test/utils/app.ts +++ b/backend/test/utils/app.ts @@ -305,6 +305,11 @@ export class TestApp { user.accessToken = res2.body.accessToken; return user; }; + + isOnline = (userId: number, accessToken: string) => + request(this.app.getHttpServer()) + .get(`/chat/${userId}/online`) + .set('Authorization', `Bearer ${accessToken}`); } export type UserEntityWithAccessToken = UserEntity & { accessToken: string };