feat(test): add tests for invitation service

This commit is contained in:
Phan An 2024-02-25 16:38:55 +07:00
parent cfd4a37171
commit 727370446f
5 changed files with 67 additions and 7 deletions

View file

@ -10,7 +10,7 @@ export interface UpdateCurrentProfileData {
new_password?: string
}
interface CompositeToken {
export interface CompositeToken {
'audio-token': string
'token': string
}

View file

@ -29,11 +29,11 @@ new class extends UnitTestCase {
it('downloads a playlist', () => {
const mock = this.mock(downloadService, 'trigger')
const playlist = factory<Playlist>('playlist', { id: 42 })
const playlist = factory<Playlist>('playlist')
downloadService.fromPlaylist(playlist)
expect(mock).toHaveBeenCalledWith('playlist/42')
expect(mock).toHaveBeenCalledWith(`playlist/${playlist.id}`)
})
it.each<[Song[], boolean]>([[[], false], [factory<Song>('song', 5), true]])(

View file

@ -0,0 +1,57 @@
import { expect, it } from 'vitest'
import UnitTestCase from '@/__tests__/UnitTestCase'
import factory from '@/__tests__/factory'
import { authService, http } from '@/services'
import { userStore } from '@/stores'
import { invitationService } from './invitationService'
new class extends UnitTestCase {
protected test () {
it('accepts an invitation', async () => {
const postMock = this.mock(http, 'post').mockResolvedValue({
'audio-token': 'my-audio-token',
token: 'my-token',
})
const setAudioTokenMock = this.mock(authService, 'setAudioToken')
const setApiTokenMock = this.mock(authService, 'setApiToken')
await invitationService.accept('invite-token', 'foo', 'bar')
expect(postMock).toHaveBeenCalledWith('invitations/accept', {
token: 'invite-token',
name: 'foo',
password: 'bar',
})
expect(setAudioTokenMock).toHaveBeenCalledWith('my-audio-token')
expect(setApiTokenMock).toHaveBeenCalledWith('my-token')
})
it('invites users', async () => {
const prospects = factory.states('prospect')<User>('user', 2)
const addMock = this.mock(userStore, 'add')
const postMock = this.mock(http, 'post').mockResolvedValue(prospects)
await invitationService.invite([prospects[0].email, prospects[1].email], false)
expect(postMock).toHaveBeenCalledWith('invitations', {
emails: [prospects[0].email, prospects[1].email],
is_admin: false,
})
expect(addMock).toHaveBeenCalledWith(prospects)
})
it('revokes an invitation', async () => {
const user = factory.states('prospect')<User>('user')
const removeMock = this.mock(userStore, 'remove')
const deleteMock = this.mock(http, 'delete')
await invitationService.revoke(user)
expect(deleteMock).toHaveBeenCalledWith('invitations', { email: user.email })
expect(removeMock).toHaveBeenCalledWith(user)
})
}
}

View file

@ -1,16 +1,19 @@
import { http } from '@/services'
import { authService, CompositeToken, http } from '@/services'
import { userStore } from '@/stores'
export const invitationService = {
getUserProspect: async (token: string) => await http.get<User>(`invitations?token=${token}`),
async accept (token: string, name: string, password: string) {
await http.post<User>('invitations/accept', { token, name, password })
const compositeToken = await http.post<CompositeToken>('invitations/accept', { token, name, password })
authService.setAudioToken(compositeToken['audio-token'])
authService.setApiToken(compositeToken.token)
},
invite: async (emails: string[], isAdmin: boolean) => {
const users = await http.post<User[]>('invitations', { emails, is_admin: isAdmin })
users.forEach(user => userStore.add(user))
userStore.add(users)
},
revoke: async (user: User) => {

View file

@ -58,7 +58,7 @@ export const userStore = {
return this.byId(user.id)
},
add (user: User) {
add (user: User | User[]) {
this.state.users.push(...this.syncWithVault(user))
},