From 6ae0e82032d2b379c2f3e8a9b2f2685481c2c538 Mon Sep 17 00:00:00 2001 From: HeeDragoN1123 Date: Sun, 12 Nov 2023 11:26:08 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[=EC=88=98=EC=A0=95]=20console.log=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20prettier=EA=B0=80=20=EC=9E=98=EB=AA=BB?= =?UTF-8?q?=EB=90=9C=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/auth.controller.ts | 9 ++++----- src/auth/auth.service.ts | 6 ++---- src/chats/chats.gateway.spec.ts | 18 ------------------ src/chats/chats.gateway.ts | 16 +++++++--------- src/chats/models/chattings.model.ts | 12 ------------ src/data/data.module.ts | 2 +- src/data/interface/city.ts | 10 +++++----- src/events/dto/create-event.dto.ts | 2 +- src/events/events.service.ts | 2 +- 9 files changed, 21 insertions(+), 56 deletions(-) delete mode 100644 src/chats/chats.gateway.spec.ts diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index 53ce146..17e9dca 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -93,14 +93,13 @@ export class AuthController { this.authService.OAuthLogin({ req, res }); } //-----------------------구글 로그인-----------------------------// - @Get('/login/google') //restAPI만들기. 엔드포인트는 users/login/google. + @Get('/login/google') @ApiOperation({ summary: '구글 소셜 로그인' }) - @UseGuards(AuthGuard('google')) //인증과정을 거쳐야하기때문에 UseGuards를 써주고 passport인증으로 AuthGuard를 써준다. 이름은 google로 + @UseGuards(AuthGuard('google')) async loginGoogle( - @Req() req: Request & IOAuthUser, - @Res() res: Response //Nest.js가 express를 기반으로 하기때문에 Request는 express에서 import한다. + @Req() req: Request & IOAuthUser, // + @Res() res: Response ) { - //프로필을 받아온 다음, 로그인 처리해야하는 곳(auth.service.ts에서 선언해준다) this.authService.OAuthLogin({ req, res }); } diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index e54a560..e6d58bf 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -18,7 +18,6 @@ export class AuthService { ) {} async login({ email, password, res }: IAuthServiceLogin): Promise<{ - // 리팩토링 시 res 빼도 작동하는지 테스트 accessToken: string; refreshToken: string; userId: number; @@ -76,7 +75,7 @@ export class AuthService { return refreshToken; } - async refreshAccessToken(refreshToken: string): Promise { + refreshAccessToken(refreshToken: string): string { // 리프레시 토큰의 유효성을 검증 const decodedToken = this.jwtService.verify(refreshToken, { secret: process.env.JWT_REFRESH_KEY, @@ -85,7 +84,7 @@ export class AuthService { // 리프레시 토큰이 유효하다면 새로운 액세스 토큰을 발급 const userId = decodedToken.sub; // 추출된 사용자 ID - const newAccessToken = await this.getAccessToken({ + const newAccessToken = this.getAccessToken({ user: { userId }, // 사용자 ID를 전달 }); return newAccessToken; @@ -114,7 +113,6 @@ export class AuthService { // 2-1. 사용자가 삭제되지 않았는지 확인 (deletedAt가 null이어야 함) if (user.deletedAt !== null) { - // res.redirect('http://localhost:5000/'); throw new UnauthorizedException('사용자가 삭제되었습니다.'); } diff --git a/src/chats/chats.gateway.spec.ts b/src/chats/chats.gateway.spec.ts deleted file mode 100644 index a78f880..0000000 --- a/src/chats/chats.gateway.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -// import { Test, TestingModule } from '@nestjs/testing'; -// import { ChatsGateway } from './chats.gateway'; - -// describe('ChatsGateway', () => { -// let gateway: ChatsGateway; - -// beforeEach(async () => { -// const module: TestingModule = await Test.createTestingModule({ -// providers: [ChatsGateway], -// }).compile(); - -// gateway = module.get(ChatsGateway); -// }); - -// it('should be defined', () => { -// expect(gateway).toBeDefined(); -// }); -// }); diff --git a/src/chats/chats.gateway.ts b/src/chats/chats.gateway.ts index 9430702..7dc49e2 100644 --- a/src/chats/chats.gateway.ts +++ b/src/chats/chats.gateway.ts @@ -58,21 +58,20 @@ export class ChatsGateway }); } // WebSocketGateway가 초기화될 때 실행되는 메소드 - // WebSocketGateway가 초기화되면 로그를 출력합니다. afterInit() { this.logger.log('init'); } async handleDisconnect(@ConnectedSocket() socket: Socket) { const user = await this.socketModel.findOne({ socketId: socket.id }); - console.log('연결해제 유저 확인', user); - console.log('연결해제 소켓 아이디', socket.id); + // console.log('연결해제 유저 확인', user); + // console.log('연결해제 소켓 아이디', socket.id); if (user) { socket.broadcast.emit('disconnect_user', user); await user.deleteOne(); // 유저 리스트에서 해당 유저 삭제 this.userList = this.userList.filter((u) => u.userId !== user.userId); // 수정된 부분 - console.log('연결 해제 유저리스트 ', this.userList); + // console.log('연결 해제 유저리스트 ', this.userList); socket.broadcast.emit('userList', this.userList); } this.logger.log( @@ -81,10 +80,11 @@ export class ChatsGateway } // 클라이언트가 연결되면 해당 클라이언트의 ID와 네임스페이스 정보를 로그에 출력 - async handleConnection(@ConnectedSocket() socket: Socket) { + handleConnection(@ConnectedSocket() socket: Socket) { this.logger.log(`connected : ${socket.id} ${socket.nsp.name}`); - // await this.logger.log(`connected : ${socket.id} ${socket.nsp.name}`); } + + //채팅방 접속시 @SubscribeMessage('join_room') async handleJoinRoom( @MessageBody() @@ -129,7 +129,7 @@ export class ChatsGateway socket.emit('chat_history', chatHistory); // 방에 있는 모든 사용자에게 userList 전송 this.server.to(String(payload.roomId)).emit('user_connected', payload); - console.log('유저리스트 콘솔', this.userList); + // console.log('유저리스트 콘솔', this.userList); this.server.to(String(payload.roomId)).emit('userList', this.userList); } } @@ -168,11 +168,9 @@ export class ChatsGateway profileImg: profileImg, }, ]; - // const userList = await this.socketModel.find({ nickname: { $in: [nickname] } }); // MongoDB에 채팅 메시지 저장 await this.chattingModel.create({ userList: userList, - // user: socketObj, nickname: messageData.nickname, profileImg: messageData.profileImg, roomId: messageData.roomId, diff --git a/src/chats/models/chattings.model.ts b/src/chats/models/chattings.model.ts index 8abd4ec..e86b24c 100644 --- a/src/chats/models/chattings.model.ts +++ b/src/chats/models/chattings.model.ts @@ -8,18 +8,6 @@ const options: SchemaOptions = { }; @Schema(options) export class Chatting extends Document { - // @Prop({ - // type: { - // _id: { type: Types.ObjectId, required: true, ref: 'sockets' }, - // id: { type: String }, - // nickname: { type: String, required: true }, - // profileImg: { type: String }, // 추가: 프로필 이미지 - // roomId: { type: Number }, // 추가: 방 ID 또는 방 식별자 - // time: { type: Date }, - // }, - // }) - // @IsNotEmpty() - // userList: SocketModel; @Prop({ ref: 'Event', }) diff --git a/src/data/data.module.ts b/src/data/data.module.ts index 01ded08..176038c 100644 --- a/src/data/data.module.ts +++ b/src/data/data.module.ts @@ -6,6 +6,6 @@ import { DataController } from './data.controller'; @Module({ controllers: [DataController], providers: [DataService], - imports: [PrismaModule] + imports: [PrismaModule], }) export class DataModule {} diff --git a/src/data/interface/city.ts b/src/data/interface/city.ts index bb63259..ff08820 100644 --- a/src/data/interface/city.ts +++ b/src/data/interface/city.ts @@ -2,7 +2,7 @@ export const city = [ { lang: 'ko', items: [ - { doName: '시 / 도'}, + { doName: '시 / 도' }, { doName: '서울특별시' }, { doName: '부산광역시' }, { doName: '대구광역시' }, @@ -25,7 +25,7 @@ export const city = [ { lang: 'jp', items: [ - { doName: "市 / 道"}, + { doName: '市 / 道' }, { doName: 'ソウル特別市' }, { doName: '釜山広域市' }, { doName: '大邱広域市' }, @@ -48,7 +48,7 @@ export const city = [ { lang: 'en', items: [ - { doName: 'City / Province'}, + { doName: 'City / Province' }, { doName: 'Seoul' }, { doName: 'Busan' }, { doName: 'Daegu' }, @@ -71,6 +71,6 @@ export const city = [ ]; export const filter = { - category: ['선택','☕맛집/커피', '🏃‍♂️운동/건강', '🐾애완동물', '📕공부/교육'], - verify: ['선택','🙋‍♀️아무나', '🏡동네만'], + category: ['선택', '☕맛집/커피', '🏃‍♂️운동/건강', '🐾애완동물', '📕공부/교육'], + verify: ['선택', '🙋‍♀️아무나', '🏡동네만'], }; diff --git a/src/events/dto/create-event.dto.ts b/src/events/dto/create-event.dto.ts index 797458f..7efddfd 100644 --- a/src/events/dto/create-event.dto.ts +++ b/src/events/dto/create-event.dto.ts @@ -10,7 +10,7 @@ import { Max, } from 'class-validator'; -export class CreateEventDto { +export class CreateEventDto { @IsString() @IsNotEmpty() @ApiProperty({ diff --git a/src/events/events.service.ts b/src/events/events.service.ts index 861189b..f8ca737 100644 --- a/src/events/events.service.ts +++ b/src/events/events.service.ts @@ -50,7 +50,7 @@ export class EventsService { } else { const events = await this.prisma.event.findMany({ take: 4, - skip: page, + skip: page, where: { isDeleted: false, }, From 7c4823e8ea6abf458d820ce873b0ac8f32efe515 Mon Sep 17 00:00:00 2001 From: kim jong hwa Date: Mon, 13 Nov 2023 10:13:39 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auth/auth.module.ts | 1 - src/data/data.controller.spec.ts | 50 +++++++++++-- src/data/data.service.spec.ts | 25 ++++--- src/events/events.service.spec.ts | 90 ++++++++++++++++++++---- src/searches/searches.controller.spec.ts | 44 ++++++++---- src/searches/searches.service.spec.ts | 66 ++++++++++++++--- 6 files changed, 228 insertions(+), 48 deletions(-) diff --git a/src/auth/auth.module.ts b/src/auth/auth.module.ts index 833d08c..955a7cd 100644 --- a/src/auth/auth.module.ts +++ b/src/auth/auth.module.ts @@ -16,7 +16,6 @@ export const jwtSecret = process.env.JWT_SECRET; imports: [PrismaModule, PassportModule, UsersModule, JwtModule.register({})], controllers: [AuthController], providers: [ - AuthService, AuthService, UsersService, JwtAccessStrategy, diff --git a/src/data/data.controller.spec.ts b/src/data/data.controller.spec.ts index 74839d2..3d2dd71 100644 --- a/src/data/data.controller.spec.ts +++ b/src/data/data.controller.spec.ts @@ -1,20 +1,62 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { DataController } from './data.controller'; import { DataService } from './data.service'; +import { DataController } from './data.controller'; +import { PrismaModule } from 'src/prisma/prisma.module'; -describe('DataController', () => { +describe('CityController', () => { let controller: DataController; + let dataService: DataService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [DataController], providers: [DataService], + imports: [PrismaModule] }).compile(); controller = module.get(DataController); + dataService = module.get(DataService); }); - it('should be defined', () => { - expect(controller).toBeDefined(); + describe('cityData', () => { + it('should return city data for a valid language', async () => { + const mockQuery = { lang: 'en' }; + + const mockCityData = { + lang: 'en', + items: [ + { doName: 'City / Province'}, + { doName: 'Seoul' }, + { doName: 'Busan' }, + { doName: 'Daegu' }, + { doName: 'Incheon' }, + { doName: 'Gwangju' }, + { doName: 'Daejeon' }, + { doName: 'Ulsan' }, + { doName: 'Sejong' }, + { doName: 'Gyeonggi-do' }, + { doName: 'Gangwon-do' }, + { doName: 'Chungcheongbuk-do' }, + { doName: 'Chungcheongnam-do' }, + { doName: 'Jeollabuk-do' }, + { doName: 'Jeollanam-do' }, + { doName: 'Gyeongsangbuk-do' }, + { doName: 'Gyeongsangnam-do' }, + { doName: 'Jeju-do' }, + ], + } + + const result = await controller.cityData(mockQuery); + + expect(result).toEqual(mockCityData); + }); + + it('should return an error message for an invalid language', async () => { + const mockQuery = { lang: 'fr' }; + + const result = await controller.cityData(mockQuery); + + expect(result).toEqual({ message: '[ko, en, jp] 중 하나를 입력하세요' }); + }); }); }); diff --git a/src/data/data.service.spec.ts b/src/data/data.service.spec.ts index a414789..98eab20 100644 --- a/src/data/data.service.spec.ts +++ b/src/data/data.service.spec.ts @@ -1,18 +1,25 @@ -import { Test, TestingModule } from '@nestjs/testing'; import { DataService } from './data.service'; describe('DataService', () => { - let service: DataService; + let dataService; + let mockPrisma; beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [DataService], - }).compile(); - - service = module.get(DataService); + mockPrisma = { + region: { + findMany: jest.fn(), + }, + }; + dataService = new DataService(mockPrisma); }); - it('should be defined', () => { - expect(service).toBeDefined(); + test('guNameData Method', async () => { + const query = { doName: 'exampleDoName' }; + await dataService.guNameData(query); + + expect(mockPrisma.region.findMany).toHaveBeenCalledWith({ + where: { doName: query.doName }, + select: { guName: true }, + }); }); }); diff --git a/src/events/events.service.spec.ts b/src/events/events.service.spec.ts index 5f25bb9..7b35d27 100644 --- a/src/events/events.service.spec.ts +++ b/src/events/events.service.spec.ts @@ -1,20 +1,86 @@ -import { Test, TestingModule } from '@nestjs/testing'; import { EventsService } from './events.service'; -import { PrismaService } from 'src/prisma/prisma.service'; -describe('EventsService', () => { - let prisma: PrismaService - let service: EventsService; +let eventsService; +let mockPrisma; +let mockCacheManager; + +mockPrisma = { + event: { + create: jest.fn(), + findMany: jest.fn(), + findUnique: jest.fn(), + findFirst: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + }, +}; +mockCacheManager = { + get: jest.fn(), + set: jest.fn() +} - beforeAll(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [EventsService], - }).compile(); +mockCacheManager = {}; +eventsService = new EventsService(mockCacheManager, mockPrisma); - service = module.get(EventsService); +describe('EventsService', () => { + beforeEach(async () => { + jest.resetAllMocks(); }); - it('should be defined', () => { - expect(service).toBeDefined(); + test('create Method', async () => { + const mockReturn = 'create Value'; + mockPrisma.event.create.mockReturnValue(mockReturn); + + const createEventDto = { + eventName: '같이 산책하실분', + maxSize: 10, + eventDate: new Date('2023-11-12'), + signupStartDate: new Date('2023-11-10'), + signupEndDate: new Date('2023-11-11'), + location_City: '서울특별시', + location_District: '종로구', + content: '재밌게 놀아요', + category: '산책', + isDeleted: false, + isVerified: '🙋‍♀️아무나', + eventImg: null + }; + + const createEventData = await eventsService.create(createEventDto) + expect(createEventData).toEqual(mockReturn) + expect(mockPrisma.event.creaet).toHaveBeenCalledWith({ + data: createEventDto + }) }); + + test('findAll Method', async ()=> { + const mockReturn = 'findMany Value' + mockPrisma.event.findMany.mockReturnValue(mockReturn) + + const page = 1 + const events = await eventsService.findAll(page) + + expect(events).toBe(mockReturn) + expect(eventsService.mockPrisma.event.findMany).toHaveBeenCalledTimes(1) + }) + + test('findOne Method', async ()=> { + const mockReturn = "findOne Value" + mockPrisma.event.findUnique.mockReturn(mockReturn) + + const result = await eventsService.findOne(1) + expect(result).toEqual(mockReturn) + }) + + test('findOne NotFoundException', async ()=> { + mockPrisma.event.findUnique.mockReturnValue(null) + try { + await eventsService.findOne(12345) + } catch (err) { + expect(eventsService.findOne).toHaveBeenCalledTimes(1); + expect(eventsService.findOne).toHaveBeenCalledWith(12345) + + expect(err.message).toEqual(`12345번 이벤트가 없습니다`) + } + }) }); diff --git a/src/searches/searches.controller.spec.ts b/src/searches/searches.controller.spec.ts index 63a075e..7252bcd 100644 --- a/src/searches/searches.controller.spec.ts +++ b/src/searches/searches.controller.spec.ts @@ -1,20 +1,40 @@ -import { Test, TestingModule } from '@nestjs/testing'; import { SearchesController } from './searches.controller'; -import { SearchesService } from './searches.service'; +import { SearchesDto } from './searches.dto/searches.dto'; describe('SearchesController', () => { - let controller: SearchesController; + let searchesController + let mockSearchesService beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [SearchesController], - providers: [SearchesService], - }).compile(); - - controller = module.get(SearchesController); + mockSearchesService = { + search: jest.fn() + } + searchesController = new SearchesController(mockSearchesService) }); - it('should be defined', () => { - expect(controller).toBeDefined(); - }); + test('search Method', async () =>{ + const sampleEvents = [ + { + eventId: 1, + eventName: "Developer", + content: "안녕하세요", + createdAt: "2023-08-25T03:43:20", + updatedAt: "2023-08-25T03:43:20", + }, + { + eventId: 2, + eventName: "Developer", + content: "안녕하세요", + createdAt: "2023-08-26T03:43:20", + updatedAt: "2023-08-26T03:43:20", + }, + ]; + + mockSearchesService.search.mockReturnValue(sampleEvents) + const searchDto = SearchesDto + + await searchesController.searchBy(1, searchDto) + + expect(mockSearchesService.search).toHaveBeenCalledTimes(1) + }) }); diff --git a/src/searches/searches.service.spec.ts b/src/searches/searches.service.spec.ts index e09bd0e..e81a11c 100644 --- a/src/searches/searches.service.spec.ts +++ b/src/searches/searches.service.spec.ts @@ -1,18 +1,64 @@ -import { Test, TestingModule } from '@nestjs/testing'; import { SearchesService } from './searches.service'; describe('SearchesService', () => { - let service: SearchesService; + let searchesService; + let mockPrisma; - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [SearchesService], - }).compile(); - - service = module.get(SearchesService); + beforeEach(() => { + mockPrisma = { + event: { + findMany: jest.fn(), + }, + }; + searchesService = new SearchesService(mockPrisma); }); - it('should be defined', () => { - expect(service).toBeDefined(); + test('search', async () => { + const page = 1; + const searchesDto = { + keyWord: 'exampleKeyword', + verify: true, + city: 'exampleCity', + guName: 'exampleGuName', + category: 'exampleCategory', + }; + + await searchesService.search(page, searchesDto); + + expect(mockPrisma.event.findMany).toHaveBeenCalledWith({ + take: 4, + skip: page, + where: { + isDeleted: false, + AND: expect.arrayContaining([ + expect.objectContaining({ + OR: expect.arrayContaining([ + expect.objectContaining({ + eventName: { contains: searchesDto.keyWord }, + }), + expect.objectContaining({ + content: { contains: searchesDto.keyWord }, + }), + ]), + }), + expect.objectContaining({ + isVerified: { contains: searchesDto.verify }, + }), + expect.objectContaining({ + location_City: { contains: searchesDto.city }, + }), + expect.objectContaining({ + location_District: { contains: searchesDto.guName }, + }), + expect.objectContaining({ + category: { contains: searchesDto.category }, + }), + ]), + }, + include: expect.any(Object), + orderBy: { + createdAt: 'desc', + }, + }); }); });