diff --git a/nestjs-BE/server/src/auth/auth.controller.spec.ts b/nestjs-BE/server/src/auth/auth.controller.spec.ts index 387bd383..87e0c788 100644 --- a/nestjs-BE/server/src/auth/auth.controller.spec.ts +++ b/nestjs-BE/server/src/auth/auth.controller.spec.ts @@ -1,15 +1,11 @@ import { HttpStatus, NotFoundException } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { Test, TestingModule } from '@nestjs/testing'; -import { User } from '@prisma/client'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; -import { UsersService } from '../users/users.service'; -import { ProfilesService } from '../profiles/profiles.service'; describe('AuthController', () => { let controller: AuthController; - let usersService: UsersService; let authService: AuthService; beforeEach(async () => { @@ -20,47 +16,26 @@ describe('AuthController', () => { { provide: AuthService, useValue: { - getKakaoAccount: jest.fn(), - login: jest.fn(), + kakaoLogin: jest.fn(), renewAccessToken: jest.fn(), logout: jest.fn(), }, }, - { - provide: UsersService, - useValue: { - findUserByEmailAndProvider: jest.fn(), - getOrCreateUser: jest.fn(), - }, - }, - { - provide: ProfilesService, - useValue: { - getOrCreateProfile: jest.fn(), - }, - }, ], }).compile(); controller = module.get(AuthController); authService = module.get(AuthService); - usersService = module.get(UsersService); }); it('kakaoLogin', async () => { const requestMock = { kakaoUserId: 0 }; - const kakaoUserAccountMock = { email: 'kakao email' }; const tokenMock = { refresh_token: 'refresh token', access_token: 'access token', }; - jest - .spyOn(authService, 'getKakaoAccount') - .mockResolvedValue(kakaoUserAccountMock); - jest.spyOn(usersService, 'getOrCreateUser').mockResolvedValue({ - uuid: 'user uuid', - } as User); - jest.spyOn(authService, 'login').mockResolvedValue(tokenMock); + + jest.spyOn(authService, 'kakaoLogin').mockResolvedValue(tokenMock); const response = controller.kakaoLogin(requestMock); @@ -73,7 +48,10 @@ describe('AuthController', () => { it('kakaoLogin kakao login fail', async () => { const requestMock = { kakaoUserId: 0 }; - jest.spyOn(authService, 'getKakaoAccount').mockResolvedValue(null); + + jest + .spyOn(authService, 'kakaoLogin') + .mockRejectedValue(new NotFoundException()); const response = controller.kakaoLogin(requestMock); diff --git a/nestjs-BE/server/src/auth/auth.controller.ts b/nestjs-BE/server/src/auth/auth.controller.ts index fd2a6a83..3ad894d7 100644 --- a/nestjs-BE/server/src/auth/auth.controller.ts +++ b/nestjs-BE/server/src/auth/auth.controller.ts @@ -1,28 +1,14 @@ -import { - Controller, - Post, - Body, - NotFoundException, - HttpStatus, -} from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; +import { Controller, Post, Body, HttpStatus } from '@nestjs/common'; import { ApiTags, ApiResponse, ApiOperation } from '@nestjs/swagger'; import { AuthService } from './auth.service'; import { Public } from './decorators/public.decorator'; import { KakaoUserDto } from './dto/kakao-user.dto'; import { RefreshTokenDto } from './dto/refresh-token.dto'; -import { UsersService } from '../users/users.service'; -import { ProfilesService } from '../profiles/profiles.service'; @Controller('auth') @ApiTags('auth') export class AuthController { - constructor( - private authService: AuthService, - private usersService: UsersService, - private profilesService: ProfilesService, - private configService: ConfigService, - ) {} + constructor(private authService: AuthService) {} @Post('kakao-oauth') @Public() @@ -36,19 +22,9 @@ export class AuthController { description: 'Not Found.', }) async kakaoLogin(@Body() kakaoUserDto: KakaoUserDto) { - const kakaoUserAccount = await this.authService.getKakaoAccount( + const tokenData = await this.authService.kakaoLogin( kakaoUserDto.kakaoUserId, ); - if (!kakaoUserAccount) throw new NotFoundException(); - const userData = { email: kakaoUserAccount.email }; - const user = await this.usersService.getOrCreateUser(userData); - const profileData = { - userUuid: user.uuid, - image: this.configService.get('BASE_IMAGE_URL'), - nickname: '익명의 사용자', - }; - await this.profilesService.getOrCreateProfile(profileData); - const tokenData = await this.authService.login(user.uuid); return { statusCode: HttpStatus.OK, message: 'OK', data: tokenData }; } diff --git a/nestjs-BE/server/src/auth/auth.service.spec.ts b/nestjs-BE/server/src/auth/auth.service.spec.ts index 8c037972..28444947 100644 --- a/nestjs-BE/server/src/auth/auth.service.spec.ts +++ b/nestjs-BE/server/src/auth/auth.service.spec.ts @@ -1,9 +1,12 @@ import { Test, TestingModule } from '@nestjs/testing'; import { JwtModule, JwtService } from '@nestjs/jwt'; import { ConfigModule } from '@nestjs/config'; +import { NotFoundException } from '@nestjs/common'; import { RefreshToken } from '@prisma/client'; import { AuthService } from './auth.service'; import { RefreshTokensService } from '../refresh-tokens/refresh-tokens.service'; +import { UsersService } from '../users/users.service'; +import { ProfilesService } from '../profiles/profiles.service'; const fetchSpy = jest.spyOn(global, 'fetch'); @@ -11,6 +14,7 @@ describe('AuthService', () => { let service: AuthService; let jwtService: JwtService; let refreshTokensService: RefreshTokensService; + let usersService: UsersService; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -24,6 +28,14 @@ describe('AuthService', () => { findRefreshToken: jest.fn(), }, }, + { + provide: UsersService, + useValue: { getOrCreateUser: jest.fn() }, + }, + { + provide: ProfilesService, + useValue: { getOrCreateProfile: jest.fn() }, + }, ], }) .overrideProvider(JwtService) @@ -34,12 +46,41 @@ describe('AuthService', () => { jwtService = module.get(JwtService); refreshTokensService = module.get(RefreshTokensService); + usersService = module.get(UsersService); }); afterEach(() => { fetchSpy.mockRestore(); }); + describe('kakaoLogin', () => { + const kakaoUserId = 0; + const kakaoUser = { email: 'test@email.com' }; + const user = { uuid: 'user uuid' }; + const tokens = { + access_token: 'access token', + refresh_token: 'refresh token', + }; + + it('kakao user exist', async () => { + jest.spyOn(service, 'getKakaoAccount').mockResolvedValue(kakaoUser); + jest.spyOn(service, 'login').mockResolvedValue(tokens); + (usersService.getOrCreateUser as jest.Mock).mockResolvedValue(user); + + const tokenData = service.kakaoLogin(kakaoUserId); + + await expect(tokenData).resolves.toEqual(tokens); + }); + + it('kakao user not exist', async () => { + jest.spyOn(service, 'getKakaoAccount').mockResolvedValue(null); + + const tokenData = service.kakaoLogin(kakaoUserId); + + await expect(tokenData).rejects.toThrow(NotFoundException); + }); + }); + it('login success', async () => { jest.spyOn(jwtService, 'signAsync').mockResolvedValue('access token'); jest.spyOn(refreshTokensService, 'createRefreshToken').mockResolvedValue({ diff --git a/nestjs-BE/server/src/auth/auth.service.ts b/nestjs-BE/server/src/auth/auth.service.ts index 758dc6b4..08326e4b 100644 --- a/nestjs-BE/server/src/auth/auth.service.ts +++ b/nestjs-BE/server/src/auth/auth.service.ts @@ -1,8 +1,14 @@ -import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { + Injectable, + NotFoundException, + UnauthorizedException, +} from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import { stringify } from 'qs'; import { RefreshTokensService } from '../refresh-tokens/refresh-tokens.service'; +import { UsersService } from '../users/users.service'; +import { ProfilesService } from '../profiles/profiles.service'; @Injectable() export class AuthService { @@ -10,8 +16,25 @@ export class AuthService { private jwtService: JwtService, private configService: ConfigService, private refreshTokensService: RefreshTokensService, + private usersService: UsersService, + private profilesService: ProfilesService, ) {} + async kakaoLogin(kakaoUserId: number) { + const kakaoUserAccount = await this.getKakaoAccount(kakaoUserId); + if (!kakaoUserAccount) throw new NotFoundException(); + const userData = { email: kakaoUserAccount.email }; + const user = await this.usersService.getOrCreateUser(userData); + const profileData = { + userUuid: user.uuid, + image: this.configService.get('BASE_IMAGE_URL'), + nickname: '익명의 사용자', + }; + await this.profilesService.getOrCreateProfile(profileData); + const tokenData = await this.login(user.uuid); + return tokenData; + } + async getKakaoAccount(kakaoUserId: number) { const url = `https://kapi.kakao.com/v2/user/me`; const queryParams = { target_id_type: 'user_id', target_id: kakaoUserId };