/* @jest-environment node */ import last from 'lodash/last'; import { createApiKey, removeApiKey } from '../../user.controller/apiKey'; jest.mock('../../../models/user'); /* Create a mock object representing an express Response */ const createResponseMock = function createResponseMock(done) { const json = jest.fn(() => { if (done) { done(); } }); const status = jest.fn(() => ({ json })); return { status, json }; }; /* Create a mock of the mongoose User model */ const createUserMock = function createUserMock() { const apiKeys = []; let nextId = 0; apiKeys.push = ({ label, hashedKey }) => { const id = nextId; nextId += 1; const publicFields = { id, label }; const allFields = { ...publicFields, hashedKey }; Object.defineProperty(allFields, 'toObject', { value: () => publicFields, enumerable: false }); return Array.prototype.push.call(apiKeys, allFields); }; apiKeys.pull = ({ _id }) => { const index = apiKeys.findIndex(({ id }) => id === _id); return apiKeys.splice(index, 1); }; return { apiKeys, save: jest.fn(callback => callback()) }; }; const User = require('../../../models/user').default; describe('user.controller', () => { beforeEach(() => { User.__setFindById(null, null); }); describe('createApiKey', () => { it('returns an error if user doesn\'t exist', () => { const request = { user: { id: '1234' } }; const response = createResponseMock(); createApiKey(request, response); expect(User.findById.mock.calls[0][0]).toBe('1234'); expect(response.status).toHaveBeenCalledWith(404); expect(response.json).toHaveBeenCalledWith({ error: 'User not found' }); }); it('returns an error if label not provided', () => { User.__setFindById(undefined, createUserMock()); const request = { user: { id: '1234' }, body: {} }; const response = createResponseMock(); 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) => { let response; const request = { user: { id: '1234' }, body: { label: 'my key' } }; const user = createUserMock(); const checkExpecations = () => { const lastKey = last(user.apiKeys); expect(lastKey.label).toBe('my key'); expect(typeof lastKey.hashedKey).toBe('string'); expect(response.json).toHaveBeenCalledWith({ apiKeys: [ { id: 0, label: 'my key', token: lastKey.hashedKey } ] }); done(); }; response = createResponseMock(checkExpecations); User.__setFindById(undefined, user); createApiKey(request, response); }); }); describe('removeApiKey', () => { it('returns an error if user doesn\'t exist', () => { const request = { user: { id: '1234' } }; const response = createResponseMock(); removeApiKey(request, response); expect(User.findById.mock.calls[0][0]).toBe('1234'); 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 = createResponseMock(); const user = createUserMock(); User.__setFindById(undefined, user); removeApiKey(request, response); expect(response.status).toHaveBeenCalledWith(404); expect(response.json).toHaveBeenCalledWith({ error: 'Key does not exist for user' }); }); it.skip('removes key if it exists', () => { const request = { user: { id: '1234' }, params: { keyId: 0 } }; const response = createResponseMock(); const user = createUserMock(); user.apiKeys.push({ label: 'first key' }); // id 0 user.apiKeys.push({ label: 'second key' }); // id 1 User.__setFindById(undefined, user); removeApiKey(request, response); expect(response.status).toHaveBeenCalledWith(200); expect(response.json).toHaveBeenCalledWith({ apiKeys: [ { id: 1, label: 'second key' } ] }); }); }); });