const { jwtDecode } = require('jwt-decode'); const { getHealth, getUser, getVersion } = require('./controller'); const { getDbVersion, healthCheck } = require('../data/dataLayer'); jest.mock('jwt-decode', () => ({ jwtDecode: jest.fn() })); jest.mock('../data/dataLayer', () => ({ healthCheck: jest.fn(), getDbVersion: jest.fn() })); let mockRes; beforeEach(() => { mockRes = { status: jest.fn().mockReturnThis(), json: jest.fn() }; console.log = jest.fn(); }); afterEach(() => { jest.restoreAllMocks(); }); describe('Controller', () => { describe('getHealth', () => { it('responds with 200 and message on success', async () => { healthCheck.mockImplementation(async () => { return { healthy: true, message: "test health check" }; }); await getHealth(null, mockRes); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ status: 200, message: "test health check" }); }); it('responds with 500 and message on failure', async () => { healthCheck.mockImplementation(async () => { return { healthy: false, message: "database issues" }; }); await getHealth(null, mockRes); expect(mockRes.status).toHaveBeenCalledWith(500); expect(mockRes.json).toHaveBeenCalledWith({ status: 500, message: "database issues" }); }); it('responds with 500 and generic message on falsy result', async () => { healthCheck.mockResolvedValue(undefined); await getHealth(null, mockRes); expect(mockRes.status).toHaveBeenCalledWith(500); expect(mockRes.json).toHaveBeenCalledWith({ status: 500, message: "Internal Server Error" }); }); }); describe('getUser', () => { it ('responds with 200 and decoded token from request header: Authorization', async () => { jwtDecode.mockReturnValue({ token: "decoded-auth" }); const mockReq = { headersDistinct: { Authorization: [ "test-auth" ] } }; await getUser(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ token: "decoded-auth" }); }); it ('responds with 200 and decoded token from request header: authorization', async () => { jwtDecode.mockReturnValue({ token: "decoded-auth" }); const mockReq = { headersDistinct: { authorization: [ "test-auth" ] } }; await getUser(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ token: "decoded-auth" }); }); it ('responds with 200 and generic message if no auth header found', async () => { const mockReq = {}; await getUser(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ result: "no authorization header found" }); }); it ('responds with 400 and error message if decode fails', async () => { jwtDecode.mockImplementation(() => { throw new Error("failed to decode"); }); const mockReq = { headersDistinct: { Authorization: [ "test-auth" ] } }; await getUser(mockReq, mockRes); expect(mockRes.status).toHaveBeenCalledWith(400); expect(mockRes.json.mock.calls[0][0].error).toContain("failed to decode"); }); }); describe('getVersion', () => { it('responds with 200 and versions', async () => { getDbVersion.mockResolvedValue("1.2.3"); await getVersion(null, mockRes); expect(mockRes.status).toHaveBeenCalledWith(200); expect(mockRes.json).toHaveBeenCalledWith({ apiVersion: "0.0.1", dbVersion: "1.2.3" }); }); }); });