diff --git a/src/modules/auth/auth.controller.spec.ts b/src/modules/auth/auth.controller.spec.ts index 152b6274..587861a0 100644 --- a/src/modules/auth/auth.controller.spec.ts +++ b/src/modules/auth/auth.controller.spec.ts @@ -8,13 +8,18 @@ import { AuthController } from './auth.controller' import { AuthService } from './auth.service' import { SecretData } from './dtos' -import { formattedProfileMock } from '@common/mocks' +import { formattedProfileMock, profileMock, userMock } from '@common/mocks' +import { ProfilesRepository, ProfilesService } from '@modules/profiles' +import { UsersRepository } from '@modules/users' describe('AuthController', () => { const redirectUrl = 'http://test.com' let authController: AuthController let authService: AuthService + let profilesRepository: ProfilesRepository + let profilesService: ProfilesService + let usersRepository: UsersRepository beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ @@ -33,11 +38,32 @@ describe('AuthController', () => { get: vi.fn().mockReturnValue(redirectUrl), }, }, + { + provide: ProfilesService, + useValue: { + create: vi.fn(), + }, + }, + { + provide: ProfilesRepository, + useValue: { + findProfileById: vi.fn(), + }, + }, + { + provide: UsersRepository, + useValue: { + createUser: vi.fn(), + }, + }, ], }).compile() authController = module.get(AuthController) authService = module.get(AuthService) + profilesRepository = module.get(ProfilesRepository) + profilesService = module.get(ProfilesService) + usersRepository = module.get(UsersRepository) }) test('should be defined', () => { @@ -51,23 +77,83 @@ describe('AuthController', () => { expect(statusCode).toEqual(HttpStatus.PERMANENT_REDIRECT) }) - test('callback should return valid redirect path', async () => { + describe('callback', () => { + const code = 'code' const tokenResponse = { accessToken: '123', refreshToken: '456', expiresIn: 3600, } + const { accessToken, refreshToken } = tokenResponse - vi.spyOn(authService, 'token').mockReturnValue(of(tokenResponse)) + test('callback should return valid redirect path', async () => { + const tokenSpy = vi + .spyOn(authService, 'token') + .mockReturnValue(of(tokenResponse)) + const profileSpy = vi + .spyOn(authService, 'profile') + .mockReturnValue(of(formattedProfileMock)) + + expect(await authController.callback(code)).toEqual({ + url: `${redirectUrl}/api/authorize?${new URLSearchParams({ + accessToken, + refreshToken, + })}`, + statusCode: HttpStatus.PERMANENT_REDIRECT, + }) + expect(tokenSpy).toHaveBeenCalledWith({ code }) + expect(profileSpy).toHaveBeenCalledWith(accessToken) + }) - const { accessToken, refreshToken } = tokenResponse + test('should find profile by id', async () => { + vi.spyOn(authService, 'token').mockReturnValue(of(tokenResponse)) + vi.spyOn(authService, 'profile').mockReturnValue(of(formattedProfileMock)) + + const findProfileByIdSpy = vi + .spyOn(profilesRepository, 'findProfileById') + .mockResolvedValue(profileMock) + const createSpy = vi.spyOn(profilesService, 'create') + const createUserSpy = vi.spyOn(usersRepository, 'createUser') + + expect(await authController.callback(code)).toEqual({ + url: `${redirectUrl}/api/authorize?${new URLSearchParams({ + accessToken, + refreshToken, + })}`, + statusCode: HttpStatus.PERMANENT_REDIRECT, + }) + + expect(findProfileByIdSpy).toHaveBeenCalledWith(formattedProfileMock.id) + expect(createSpy).not.toHaveBeenCalled() + expect(createUserSpy).not.toHaveBeenCalled() + }) - expect(await authController.callback('code')).toEqual({ - url: `${redirectUrl}/api/authorize?${new URLSearchParams({ - accessToken, + test('should create profile and user', async () => { + vi.spyOn(authService, 'token').mockReturnValue(of(tokenResponse)) + vi.spyOn(authService, 'profile').mockReturnValue(of(formattedProfileMock)) + + const findProfileByIdSpy = vi.spyOn(profilesRepository, 'findProfileById') + const createSpy = vi + .spyOn(profilesService, 'create') + .mockResolvedValue(profileMock) + const createUserSpy = vi + .spyOn(usersRepository, 'createUser') + .mockResolvedValue(userMock) + + expect(await authController.callback(code)).toEqual({ + url: `${redirectUrl}/api/authorize?${new URLSearchParams({ + accessToken, + refreshToken, + })}`, + statusCode: HttpStatus.PERMANENT_REDIRECT, + }) + + expect(findProfileByIdSpy).toHaveBeenCalledWith(formattedProfileMock.id) + expect(createSpy).toHaveBeenCalledWith(formattedProfileMock) + expect(createUserSpy).toHaveBeenCalledWith({ + profile: profileMock, refreshToken, - })}`, - statusCode: HttpStatus.PERMANENT_REDIRECT, + }) }) }) diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index 323bace0..b1681cd1 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -11,6 +11,8 @@ import { ProfileDto, SecretData } from './dtos' import { Environment } from '@config/environment' import { AuthenticationType } from '@modules/auth/enums' +import { UsersRepository } from '@modules/users' +import { ProfilesRepository, ProfilesService } from '@modules/profiles' const { SPOTIFY_CALLBACK_URL, @@ -24,7 +26,10 @@ const { export class AuthController { constructor( private readonly authService: AuthService, - private readonly configService: ConfigService + private readonly configService: ConfigService, + private readonly profilesService: ProfilesService, + private readonly profilesRepository: ProfilesRepository, + private readonly usersRepository: UsersRepository ) {} @Get('login') @@ -52,7 +57,22 @@ export class AuthController { this.authService.token({ code }) ) - console.log(await firstValueFrom(this.authService.profile(accessToken))) + const spotifyProfile = await firstValueFrom( + this.authService.profile(accessToken) + ) + + const foundProfile = await this.profilesRepository.findProfileById( + spotifyProfile.id + ) + + if (!foundProfile) { + const profile = await this.profilesService.create(spotifyProfile) + + await this.usersRepository.createUser({ + profile, + refreshToken, + }) + } return { url: `${this.configService.get( diff --git a/src/modules/auth/auth.module.ts b/src/modules/auth/auth.module.ts index 1e08c5c8..5e4e4425 100644 --- a/src/modules/auth/auth.module.ts +++ b/src/modules/auth/auth.module.ts @@ -7,6 +7,8 @@ import { AuthService } from './auth.service' import { AuthController } from './auth.controller' import { Environment } from '@config/environment' +import { UsersModule } from '@modules/users' +import { ProfilesModule } from '@modules/profiles' @Module({ imports: [ @@ -31,6 +33,8 @@ import { Environment } from '@config/environment' }, inject: [ConfigService], }), + ProfilesModule, + UsersModule, ], providers: [AuthService], controllers: [AuthController],