/* @jest-environment node */ import last from 'lodash/last'; import { Request, Response } from 'jest-express'; import User, { createMock, createInstanceMock } from '../../../models/user'; import { createApiKey, removeApiKey } from '../../user.controller/apiKey'; jest.mock('../../../models/user'); describe('user.controller', () => { let UserMock; let UserInstanceMock; beforeEach(() => { UserMock = createMock(); UserInstanceMock = createInstanceMock(); }); afterEach(() => { UserMock.restore(); UserInstanceMock.restore(); }); describe('createApiKey', () => { it('returns an error if user doesn\'t exist', () => { const request = { user: { id: '1234' } }; const response = new Response(); UserMock .expects('findById') .withArgs('1234') .yields(null, null); createApiKey(request, response); expect(response.status).toHaveBeenCalledWith(404); expect(response.json).toHaveBeenCalledWith({ error: 'User not found' }); }); it('returns an error if label not provided', () => { const request = { user: { id: '1234' }, body: {} }; const response = new Response(); UserMock .expects('findById') .withArgs('1234') .yields(null, new User()); createApiKey(request, response); expect(response.status).toHaveBeenCalledWith(400); expect(response.json).toHaveBeenCalledWith({ error: 'Expected field \'label\' was not present in request body' }); }); it('returns generated API key to the user', (done) => { const request = new Request(); request.setBody({ label: 'my key' }); request.user = { id: '1234' }; const response = new Response(); const user = new User(); UserMock .expects('findById') .withArgs('1234') .yields(null, user); UserInstanceMock.expects('save') .yields(); function expectations() { const lastKey = last(user.apiKeys); expect(lastKey.label).toBe('my key'); expect(typeof lastKey.hashedKey).toBe('string'); const responseData = response.json.mock.calls[0][0]; expect(responseData.apiKeys.length).toBe(1); expect(responseData.apiKeys[0]).toMatchObject({ label: 'my key', token: lastKey.hashedKey, lastUsedAt: undefined, createdAt: undefined }); done(); } const promise = createApiKey(request, response); promise.then(expectations, expectations).catch(expectations); }); }); describe('removeApiKey', () => { it('returns an error if user doesn\'t exist', () => { const request = { user: { id: '1234' } }; const response = new Response(); UserMock .expects('findById') .withArgs('1234') .yields(null, null); removeApiKey(request, response); expect(response.status).toHaveBeenCalledWith(404); expect(response.json).toHaveBeenCalledWith({ error: 'User not found' }); }); it('returns an error if specified key doesn\'t exist', () => { const request = { user: { id: '1234' }, params: { keyId: 'not-a-real-key' } }; const response = new Response(); const user = new User(); UserMock .expects('findById') .withArgs('1234') .yields(null, user); removeApiKey(request, response); expect(response.status).toHaveBeenCalledWith(404); expect(response.json).toHaveBeenCalledWith({ error: 'Key does not exist for user' }); }); it('removes key if it exists', () => { const user = new User(); user.apiKeys.push({ label: 'first key' }); // id 0 user.apiKeys.push({ label: 'second key' }); // id 1 const firstKeyId = user.apiKeys[0]._id.toString(); const secondKeyId = user.apiKeys[1]._id.toString(); const request = { user: { id: '1234' }, params: { keyId: firstKeyId } }; const response = new Response(); UserMock .expects('findById') .withArgs('1234') .yields(null, user); UserInstanceMock .expects('save') .yields(); removeApiKey(request, response); expect(response.status).toHaveBeenCalledWith(200); const responseData = response.json.mock.calls[0][0]; expect(responseData.apiKeys.length).toBe(1); expect(responseData.apiKeys[0]).toMatchObject({ id: secondKeyId, label: 'second key', lastUsedAt: undefined, createdAt: undefined }); }); }); });