Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/nestjs/swagger-7.1.17
Browse files Browse the repository at this point in the history
  • Loading branch information
Mnigos authored Dec 18, 2023
2 parents 1066222 + 0ca2509 commit 536587e
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 273 deletions.
5 changes: 0 additions & 5 deletions src/common/utils/catch-spotify-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@ export const SPOTIFY_DEFAULT_ERROR_MESSAGE =
'Something went wrong with fetching data from spotify API:'

export const catchSpotifyError = (response: SpotifyResponseError) => {
console.log(response.data.error)

const { data, status } = response

if ('error_description' in data) {
console.log('ee')
if (data.error === 'invalid_grant')
throw new UnauthorizedException('Invalid token')

Expand All @@ -35,8 +32,6 @@ export const catchSpotifyError = (response: SpotifyResponseError) => {
)
}

console.log(status)

if (status === 401) throw new UnauthorizedException(data.error.message)

throw new BadGatewayException(
Expand Down
25 changes: 10 additions & 15 deletions src/modules/auth/auth.controller.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { HttpStatus } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { Test, TestingModule } from '@nestjs/testing'
import { firstValueFrom, of } from 'rxjs'

import { AuthController } from './auth.controller'
import { AuthService } from './auth.service'
Expand Down Expand Up @@ -82,10 +81,10 @@ describe('AuthController', () => {
test('callback should return valid redirect path', async () => {
const tokenSpy = vi
.spyOn(authService, 'token')
.mockReturnValue(of(tokenResponse))
.mockResolvedValue(tokenResponse)
const profileSpy = vi
.spyOn(authService, 'profile')
.mockReturnValue(of(profileMock))
.mockResolvedValue(profileMock)

expect(await authController.callback(code)).toEqual({
url: `${redirectUrl}/api/authorize?${new URLSearchParams({
Expand All @@ -99,8 +98,8 @@ describe('AuthController', () => {
})

test('should find profile by id', async () => {
vi.spyOn(authService, 'token').mockReturnValue(of(tokenResponse))
vi.spyOn(authService, 'profile').mockReturnValue(of(profileMock))
vi.spyOn(authService, 'token').mockResolvedValue(tokenResponse)
vi.spyOn(authService, 'profile').mockResolvedValue(profileMock)

const findUserByProfileId = vi
.spyOn(usersRepository, 'findOneByProfileId')
Expand All @@ -122,8 +121,8 @@ describe('AuthController', () => {
})

test('should create profile and user', async () => {
vi.spyOn(authService, 'token').mockReturnValue(of(tokenResponse))
vi.spyOn(authService, 'profile').mockReturnValue(of(profileMock))
vi.spyOn(authService, 'token').mockResolvedValue(tokenResponse)
vi.spyOn(authService, 'profile').mockResolvedValue(profileMock)

const findUserByProfileId = vi.spyOn(
usersRepository,
Expand Down Expand Up @@ -159,18 +158,14 @@ describe('AuthController', () => {
expiresIn: 3600,
}

vi.spyOn(authService, 'token').mockReturnValue(of(secretData))
vi.spyOn(authService, 'token').mockResolvedValue(secretData)

expect(await firstValueFrom(authController.refresh('123'))).toEqual(
secretData
)
expect(await authController.refresh('123')).toEqual(secretData)
})

test('should return profile', async () => {
vi.spyOn(authService, 'profile').mockReturnValue(of(profileMock))
vi.spyOn(authService, 'profile').mockResolvedValue(profileMock)

expect(await firstValueFrom(authController.profile('123'))).toEqual(
profileMock
)
expect(await authController.profile('123')).toEqual(profileMock)
})
})
10 changes: 2 additions & 8 deletions src/modules/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
forwardRef,
} from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { firstValueFrom } from 'rxjs'
import {
ApiExcludeEndpoint,
ApiOkResponse,
Expand Down Expand Up @@ -70,13 +69,8 @@ export class AuthController {
async callback(
@Query('code') code: string
): Promise<RedirectResponse | undefined> {
const { accessToken, refreshToken } = await firstValueFrom(
this.authService.token({ code })
)

const spotifyProfile = await firstValueFrom(
this.authService.profile(accessToken)
)
const { accessToken, refreshToken } = await this.authService.token({ code })
const spotifyProfile = await this.authService.profile(accessToken)

const foundUser = await this.usersRepository.findOneByProfileId(
spotifyProfile.id
Expand Down
20 changes: 8 additions & 12 deletions src/modules/auth/auth.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ConfigService } from '@nestjs/config'
import { JwtService } from '@nestjs/jwt'
import { Test, TestingModule } from '@nestjs/testing'
import { Profile } from 'passport-spotify'
import { firstValueFrom, of } from 'rxjs'
import { of } from 'rxjs'

import { AuthService } from './auth.service'

Expand Down Expand Up @@ -93,14 +93,13 @@ describe('AuthService', () => {
httpService.post = vi
.fn()
.mockImplementation((_url, parameters: URLSearchParams) => {
if (parameters.get('grant_type') === 'refresh_token') {
if (parameters.get('grant_type') === 'refresh_token')
return of(response)
}
})

expect(
await firstValueFrom(authService.token({ refreshToken: 'refresh' }))
).toEqual(expectedResponse)
expect(await authService.token({ refreshToken: 'refresh' })).toEqual(
expectedResponse
)
})

test('should authorize and get tokens', async () => {
Expand All @@ -123,12 +122,11 @@ describe('AuthService', () => {
httpService.post = vi
.fn()
.mockImplementation((_url, parameters: URLSearchParams) => {
if (parameters.get('grant_type') === 'authorization_code') {
if (parameters.get('grant_type') === 'authorization_code')
return of(response)
}
})

expect(await firstValueFrom(authService.token({ code: 'code' }))).toEqual(
expect(await authService.token({ code: 'code' })).toEqual(
expectedResponse
)
})
Expand All @@ -141,8 +139,6 @@ describe('AuthService', () => {

httpService.get = vi.fn().mockReturnValue(of(response))

expect(await firstValueFrom(authService.profile('token'))).toEqual(
profileMock
)
expect(await authService.profile('token')).toEqual(profileMock)
})
})
60 changes: 32 additions & 28 deletions src/modules/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { JwtService } from '@nestjs/jwt'
import { Profile as PassportSpotifyProfile } from 'passport-spotify'
import { Observable, map, catchError } from 'rxjs'
import { map, catchError, firstValueFrom } from 'rxjs'

import { SecretData } from './dtos'
import { TokenOptions } from './types'
Expand All @@ -30,7 +30,7 @@ export class AuthService {
return this.jwtService.sign(payload)
}

token({ refreshToken, code }: TokenOptions): Observable<SecretData> {
token({ refreshToken, code }: TokenOptions): Promise<SecretData> {
const url = `${this.configService.get(
Environment.SPOTIFY_ACCOUNTS_URL
)}/api/token`
Expand All @@ -47,39 +47,43 @@ export class AuthService {
const bufferedCredentials = Buffer.from(
`${cliendId}:${clientSecret}`
).toString('base64')
const parameters = new URLSearchParams()
const params = new URLSearchParams()

if (refreshToken) {
parameters.append('refresh_token', refreshToken)
parameters.append('grant_type', 'refresh_token')
params.append('refresh_token', refreshToken)
params.append('grant_type', 'refresh_token')
}
if (code) {
parameters.append('code', code)
parameters.append('grant_type', 'authorization_code')
callbackUrl && parameters.append('redirect_uri', callbackUrl)
params.append('code', code)
params.append('grant_type', 'authorization_code')
callbackUrl && params.append('redirect_uri', callbackUrl)
}

return this.httpService
.post<SpotifyToken>(url, parameters, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${bufferedCredentials}`,
},
})
.pipe(
map(response => response.data),
map(adaptSecretData),
catchError(catchSpotifyError)
)
return firstValueFrom(
this.httpService
.post<SpotifyToken>(url, params, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
Authorization: `Basic ${bufferedCredentials}`,
},
})
.pipe(
map(response => response.data),
map(adaptSecretData),
catchError(catchSpotifyError)
)
)
}

profile(accessToken: string): Observable<Profile> {
return this.httpService
.get<SpotifyProfile>('/me', applyAuthorizationHeader(accessToken))
.pipe(
map(response => response.data),
map(adaptProfile),
catchError(catchSpotifyError)
)
profile(accessToken: string): Promise<Profile> {
return firstValueFrom(
this.httpService
.get<SpotifyProfile>('/me', applyAuthorizationHeader(accessToken))
.pipe(
map(response => response.data),
map(adaptProfile),
catchError(catchSpotifyError)
)
)
}
}
59 changes: 20 additions & 39 deletions src/modules/player/player.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpService } from '@nestjs/axios'
import { TestingModule, Test } from '@nestjs/testing'
import { of, firstValueFrom, throwError, catchError } from 'rxjs'
import { of, throwError } from 'rxjs'
import { ForbiddenException } from '@nestjs/common'

import { PlayerService } from './player.service'
Expand All @@ -12,7 +12,6 @@ import {
spotifyPlaybackStateMock,
axiosResponseMockFactory,
} from '@common/mocks'
import { SpotifyResponseError } from '@common/utils'

const forbiddenExceptionObserver = throwError(() => ({
data: {
Expand Down Expand Up @@ -59,9 +58,7 @@ describe('PlayerService', () => {
)
)

expect(
await firstValueFrom(playerService.availableDevices('awd'))
).toEqual(devicesMock)
expect(await playerService.availableDevices('awd')).toEqual(devicesMock)
})

test('should throw Forbidden expception because no device is currently playing', async () => {
Expand All @@ -73,13 +70,9 @@ describe('PlayerService', () => {
)
)

expect(
await firstValueFrom(
playerService
.availableDevices('awd')
.pipe(catchError((error: SpotifyResponseError) => [error]))
)
).toBeInstanceOf(ForbiddenException)
await expect(playerService.availableDevices('awd')).rejects.toThrowError(
ForbiddenException
)
})
})

Expand All @@ -89,63 +82,51 @@ describe('PlayerService', () => {
of(axiosResponseMockFactory(spotifyPlaybackStateMock))
)

expect(
await firstValueFrom(playerService.currentPlaybackState('awd'))
).toEqual(playbackStateMock)
expect(await playerService.currentPlaybackState('awd')).toEqual(
playbackStateMock
)
})

test.skip('should throw Forbidden expception because No device is currently playing', async () => {
vi.spyOn(httpService, 'get').mockReturnValue(
of(axiosResponseMockFactory(''))
of(axiosResponseMockFactory(forbiddenExceptionObserver))
)

expect(
await firstValueFrom(
playerService
.currentPlaybackState('awd')
.pipe(catchError((error: SpotifyResponseError) => [error]))
)
).toBeInstanceOf(ForbiddenException)
await expect(
playerService.currentPlaybackState('awd')
).rejects.toThrowError(ForbiddenException)
})
})

describe('pausePlayer', () => {
test('should pause player', async () => {
expect(await firstValueFrom(playerService.pausePlayer('awd'))).toEqual({
expect(await playerService.pausePlayer('awd')).toEqual({
success: true,
})
})

test('should throw Forbidden expception because no device is currently playing', async () => {
vi.spyOn(httpService, 'put').mockReturnValue(forbiddenExceptionObserver)

expect(
await firstValueFrom(
playerService
.pausePlayer('awd')
.pipe(catchError((error: SpotifyResponseError) => [error]))
)
).toBeInstanceOf(ForbiddenException)
await expect(playerService.pausePlayer('awd')).rejects.toThrowError(
ForbiddenException
)
})
})

describe('resumePlayer', () => {
test('should resume player', async () => {
expect(await firstValueFrom(playerService.resumePlayer('awd'))).toEqual({
expect(await playerService.resumePlayer('awd')).toEqual({
success: true,
})
})

test('should throw Forbidden expception because no device is currently playing', async () => {
vi.spyOn(httpService, 'put').mockReturnValue(forbiddenExceptionObserver)

expect(
await firstValueFrom(
playerService
.resumePlayer('awd')
.pipe(catchError((error: SpotifyResponseError) => [error]))
)
).toBeInstanceOf(ForbiddenException)
await expect(playerService.resumePlayer('awd')).rejects.toThrowError(
ForbiddenException
)
})
})
})
Loading

0 comments on commit 536587e

Please sign in to comment.