-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(code-coverage): bumping code coverage
- Loading branch information
Showing
23 changed files
with
445 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
express-pg-auth0/src/api/auth/routes/register.route.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { registerRoute as route } from './register.route'; | ||
|
||
describe('route', () => { | ||
it('should be defined', () => { | ||
expect(route).toBeDefined(); | ||
}); | ||
|
||
describe('handler', () => { | ||
const authService = { register: jest.fn(() => ({ user: 'user' })) }; | ||
const req = { | ||
auth: { payload: { sub: '1' } }, | ||
|
||
body: { name: 'Name' }, | ||
services: { authService }, | ||
}; | ||
const send = jest.fn(); | ||
const status = jest.fn(() => ({ send })); | ||
const res = { send, status }; | ||
|
||
it('should call AuthService#register', () => { | ||
route.handler(req as never, res as never, jest.fn()); | ||
expect(authService.register).toHaveBeenCalledWith({ name: 'Name' }); | ||
}); | ||
}); | ||
}); |
86 changes: 86 additions & 0 deletions
86
express-pg-auth0/src/api/auth/services/auth.service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { User } from '@api/users'; | ||
import { AuthService } from './auth.service'; | ||
import { Auth0User, Credentials } from '../interfaces'; | ||
|
||
const userCreds: Credentials = { | ||
email: '[email protected]', | ||
password: 'very-secret', | ||
}; | ||
|
||
const registeredUser: User = { | ||
id: '1', | ||
createdAt: Date.now().toString(), | ||
updatedAt: Date.now().toString(), | ||
email: userCreds.email, | ||
password: 'very-secret', | ||
userId: '1', | ||
}; | ||
|
||
const auth0User: Auth0User = { | ||
blocked: false, | ||
created_at: Date.now().toString(), | ||
email: userCreds.email, | ||
email_verified: true, | ||
identities: [], | ||
name: 'userName', | ||
nickname: 'userNickname', | ||
picture: '', | ||
updated_at: Date.now().toString(), | ||
user_id: '1', | ||
user_metadata: {}, | ||
}; | ||
|
||
describe('AuthService', () => { | ||
const logger = { | ||
warn: jest.fn(), | ||
error: jest.fn(), | ||
} as any; | ||
|
||
const auth0Service = { | ||
createUser: jest.fn(), | ||
deleteUser: jest.fn(), | ||
updateUserMetadata: jest.fn(), | ||
} as any; | ||
|
||
const usersRepository = { | ||
insertOne: jest.fn(), | ||
} as any; | ||
|
||
const authService = new AuthService(logger, auth0Service, usersRepository); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('register', () => { | ||
it('when the email is not registered should register the user', async () => { | ||
const createdUser = { ...registeredUser, ...userCreds }; | ||
auth0Service.createUser.mockResolvedValueOnce(auth0User); | ||
usersRepository.insertOne.mockResolvedValueOnce(createdUser); | ||
auth0Service.updateUserMetadata.mockResolvedValueOnce(auth0User as any); | ||
|
||
const user = await authService.register(userCreds); | ||
|
||
expect(auth0Service.updateUserMetadata).toHaveBeenCalledWith(auth0User.user_id, { | ||
id: createdUser.id | ||
}); | ||
|
||
expect(user).toEqual({ | ||
email: userCreds.email, | ||
userId: auth0User.user_id, | ||
}); | ||
}); | ||
|
||
it('throws error when creating a user in the database fails', async () => { | ||
auth0Service.createUser.mockResolvedValueOnce(auth0User); | ||
usersRepository.insertOne.mockRejectedValueOnce({ error: 'error' }); | ||
auth0Service.deleteUser.mockResolvedValueOnce(auth0User as any); | ||
|
||
await expect(authService.register(userCreds)).rejects.toThrow(); | ||
|
||
expect(logger.warn).toHaveBeenCalledWith('Creating a user in the database failed. Proceeding with deleting it in Auth0.'); | ||
expect(auth0Service.deleteUser).toHaveBeenCalledWith(auth0User.user_id); | ||
|
||
}); | ||
}); | ||
}); |
213 changes: 213 additions & 0 deletions
213
express-pg-auth0/src/api/auth/services/auth0.service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
import { AxiosStatic } from 'axios'; | ||
import { Auth0User, Credentials } from '../interfaces'; | ||
import { Auth0Service } from './auth0.service'; | ||
import { Logger } from 'pino'; | ||
import { Environment } from '@utils/environment'; | ||
|
||
const userCreds: Credentials = { | ||
email: '[email protected]', | ||
password: 'very-secret', | ||
}; | ||
|
||
const auth0User: Auth0User = { | ||
blocked: false, | ||
created_at: Date.now().toString(), | ||
email: userCreds.email, | ||
email_verified: true, | ||
identities: [], | ||
name: 'userName', | ||
nickname: 'userNickname', | ||
picture: '', | ||
updated_at: Date.now().toString(), | ||
user_id: '1', | ||
user_metadata: {}, | ||
}; | ||
|
||
describe('Auth0Service', () => { | ||
let auth0Service: Auth0Service; | ||
let axios: AxiosStatic; | ||
let logger: Logger; | ||
let env: Environment; | ||
|
||
beforeAll(() => { | ||
logger = { error: jest.fn() } as any; | ||
axios = { | ||
post: jest.fn(), | ||
patch: jest.fn(), | ||
get: jest.fn(), | ||
delete: jest.fn(), | ||
} as any; | ||
env = {} as any; | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
describe('createUser', () => { | ||
beforeEach(() => { | ||
auth0Service = new Auth0Service(logger, axios, env); | ||
jest | ||
.spyOn(auth0Service, 'getAuth0AccessToken') | ||
.mockResolvedValue('token'); | ||
}); | ||
|
||
it('when the email is not registered should register the user', async () => { | ||
jest | ||
.spyOn(auth0Service, 'searchUsersByEmail') | ||
.mockResolvedValueOnce([] as unknown as Auth0User); | ||
jest | ||
.spyOn(axios, 'post') | ||
.mockResolvedValueOnce(Promise.resolve({ data: auth0User })); | ||
|
||
const user = await auth0Service.createUser( | ||
userCreds.email, | ||
userCreds.password | ||
); | ||
|
||
expect(user).toEqual(auth0User); | ||
}); | ||
|
||
it('throws error when user is already registered', async () => { | ||
jest | ||
.spyOn(auth0Service, 'searchUsersByEmail') | ||
.mockResolvedValueOnce([auth0User] as unknown as Auth0User); | ||
|
||
await expect( | ||
auth0Service.createUser(userCreds.email, userCreds.password) | ||
).rejects.toThrow(new Error('A user with this email already exists.')); | ||
}); | ||
|
||
it('throws error when auth0 request fails', async () => { | ||
jest | ||
.spyOn(auth0Service, 'searchUsersByEmail') | ||
.mockResolvedValueOnce([] as unknown as Auth0User); | ||
jest | ||
.spyOn(axios, 'post') | ||
.mockRejectedValueOnce({ response: { data: {} } }); | ||
|
||
await expect( | ||
auth0Service.createUser(userCreds.email, userCreds.password) | ||
).rejects.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('updateUserMetadata', () => { | ||
beforeEach(() => { | ||
auth0Service = new Auth0Service(logger, axios, env); | ||
jest | ||
.spyOn(auth0Service, 'getAuth0AccessToken') | ||
.mockResolvedValue('token'); | ||
}); | ||
|
||
it('should updateUserMetadata updates metadata', async () => { | ||
const newMetadata = { data: 'new' }; | ||
jest | ||
.spyOn(axios, 'patch') | ||
.mockResolvedValueOnce({ ...auth0User, user_metadata: newMetadata }); | ||
|
||
const user = await auth0Service.updateUserMetadata('1', newMetadata); | ||
|
||
expect(user).toEqual({ ...auth0User, user_metadata: newMetadata }); | ||
}); | ||
}); | ||
|
||
describe('searchUsersByEmail', () => { | ||
beforeEach(() => { | ||
auth0Service = new Auth0Service(logger, axios, env); | ||
jest | ||
.spyOn(auth0Service, 'getAuth0AccessToken') | ||
.mockResolvedValue('token'); | ||
}); | ||
|
||
it('when the user is found', async () => { | ||
jest.spyOn(axios, 'get').mockResolvedValueOnce({ data: auth0User }); | ||
|
||
const user = await auth0Service.searchUsersByEmail(auth0User.email); | ||
|
||
expect(user).toEqual(auth0User); | ||
}); | ||
|
||
it('throws error when user is not found', async () => { | ||
jest | ||
.spyOn(axios, 'get') | ||
.mockRejectedValueOnce({ response: { data: {} } }); | ||
|
||
await expect( | ||
auth0Service.searchUsersByEmail(auth0User.email) | ||
).rejects.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('deleteUser', () => { | ||
beforeEach(() => { | ||
auth0Service = new Auth0Service(logger, axios, env); | ||
jest | ||
.spyOn(auth0Service, 'getAuth0AccessToken') | ||
.mockResolvedValue('token'); | ||
}); | ||
|
||
it('when user is deleted', async () => { | ||
jest.spyOn(axios, 'delete').mockResolvedValueOnce({}); | ||
|
||
const response = await auth0Service.deleteUser(auth0User.user_id); | ||
|
||
expect(response).toEqual({}); | ||
}); | ||
|
||
it('throws error when auth0 request fails', async () => { | ||
jest | ||
.spyOn(axios, 'delete') | ||
.mockRejectedValueOnce({ response: { data: {} } }); | ||
|
||
await expect( | ||
auth0Service.deleteUser(auth0User.user_id) | ||
).rejects.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('getAuth0AccessToken', () => { | ||
beforeEach(() => { | ||
auth0Service = new Auth0Service(logger, axios, env); | ||
}); | ||
|
||
it('when accessToken is set', async () => { | ||
const tokenResponse = { data: { access_token: 'token' } }; | ||
jest.spyOn(axios, 'post').mockResolvedValueOnce(tokenResponse); | ||
|
||
auth0Service.getAuth0AccessToken(); | ||
|
||
// expect(onModuleInit).toHaveBeenCalled(); | ||
}); | ||
|
||
it('throws error accessToken is missing', async () => { | ||
const tokenResponse = { data: {} }; | ||
jest.spyOn(axios, 'post').mockResolvedValueOnce(tokenResponse); | ||
|
||
await expect(auth0Service.getAuth0AccessToken()).rejects.toThrow( | ||
new Error('Access token is missing!') | ||
); | ||
expect(logger.error).toHaveBeenCalledWith( | ||
'Access token is missing in the response data' | ||
); | ||
}); | ||
|
||
it('throws error when axios response is falsy(undefined)', async () => { | ||
jest.spyOn(axios, 'post').mockResolvedValueOnce(undefined); | ||
|
||
await expect(auth0Service.getAuth0AccessToken()).rejects.toThrow( | ||
new Error('Access token is missing!') | ||
); | ||
}); | ||
|
||
it('throws error when auth0 token request fails', async () => { | ||
jest | ||
.spyOn(axios, 'post') | ||
.mockRejectedValueOnce({ response: { data: {} } }); | ||
|
||
await expect(auth0Service.getAuth0AccessToken()).rejects.toThrow( | ||
new Error('Something went wrong!') | ||
); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.