'use strict'; /** * Integration tests – billing controller (controllers/billing.js) */ const { connectDB, disconnectDB, clearCollection } = require('./jest.setup'); const { mockApplicator, mockReq, mockRes } = require('./mock_data'); let Customer; beforeAll(async () => { await connectDB(); Customer = require('../../model/customer'); }); afterAll(async () => { await disconnectDB(); }); const billingCtl = require('../../controllers/billing'); describe('billing controller – getCustUsage_post', () => { let applicator; beforeAll(async () => { applicator = await Customer.create(mockApplicator()); }); afterAll(async () => { await Customer.deleteMany({ _id: applicator._id }); }); const makeReq = (bodyOverrides = {}) => mockReq({ uid: applicator._id, puid: applicator._id, body: { from: '2024-01-01', to: '2024-12-31', tz: 'America/Chicago', ...bodyOverrides, }, }); it('throws AppParamError when body is null', async () => { const req = mockReq({ body: null }); const res = mockRes(); await expect(billingCtl.getCustUsage_post(req, res)).rejects.toThrow(); }); it('throws AppParamError when from date is missing', async () => { const req = makeReq({ from: undefined }); const res = mockRes(); await expect(billingCtl.getCustUsage_post(req, res)).rejects.toThrow(); }); it('throws AppParamError when to date is missing', async () => { const req = makeReq({ to: undefined }); const res = mockRes(); await expect(billingCtl.getCustUsage_post(req, res)).rejects.toThrow(); }); it('throws AppParamError when from is an invalid date string', async () => { const req = makeReq({ from: 'not-a-date' }); const res = mockRes(); await expect(billingCtl.getCustUsage_post(req, res)).rejects.toThrow(); }); it('returns an empty array when no customers have jobs in the date range', async () => { const req = makeReq(); const res = mockRes(); await billingCtl.getCustUsage_post(req, res); expect(res.json).toHaveBeenCalled(); expect(Array.isArray(res._data)).toBe(true); // No active customers have any jobs in the test DB for this date range expect(res._data.length).toBe(0); }); it('accepts ISO datetime strings for from/to', async () => { const req = makeReq({ from: '2024-01-01T00:00:00.000Z', to: '2024-12-31T23:59:59.999Z', }); const res = mockRes(); await billingCtl.getCustUsage_post(req, res); expect(res.json).toHaveBeenCalled(); expect(Array.isArray(res._data)).toBe(true); }); it('billable filter is accepted without error', async () => { const req = makeReq({ billable: true }); const res = mockRes(); await billingCtl.getCustUsage_post(req, res); expect(res.json).toHaveBeenCalled(); expect(Array.isArray(res._data)).toBe(true); }); });