agmission/Development/server/tests/integration/invoice.integration.test.js
Devin Major 6ff07c9d74
All checks were successful
Server Tests / Mocha – Unit & Utility Tests (push) Successful in 1m13s
Server Tests / Jest – Integration Tests (push) Successful in 1m43s
additional integration tests
2026-05-08 14:51:04 -04:00

221 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
/**
* Integration tests Invoice controller (controllers/invoice.js)
*
* We focus on the read path (getInvoices_get) which does not require the full
* complex invoice-creation pipeline (jobs, clients, Stripe, etc.).
* A seeded Invoice document is created directly via the model for query tests.
*/
const { connectDB, disconnectDB, clearCollection } = require('./jest.setup');
const { mockApplicator, mockClient, mockReq, mockRes, newId } = require('./mock_data');
let Invoice, Customer, Client;
beforeAll(async () => {
await connectDB();
Invoice = require('../../model/invoice');
Customer = require('../../model/customer');
Client = require('../../model/client');
});
afterAll(async () => {
await disconnectDB();
});
const invoiceCtl = require('../../controllers/invoice');
describe('Invoice controller data methods', () => {
let applicator, client;
function makeInvoiceDoc(puid, clientId) {
return {
code: `INV-${Date.now()}`,
companyName: 'Test Applicator Co.',
address: '123 Main St',
currency: 'USD',
dueDate: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000),
openDate: new Date(),
status: 'open',
paymentTerm: 30,
byPuid: puid,
clients: [
{
billTo: clientId,
code: `INV-${Date.now()}-1`,
split: '100',
subTotal: '100.00',
},
],
jobs: [],
};
}
beforeAll(async () => {
await clearCollection(Invoice);
applicator = await Customer.create(mockApplicator());
client = await Client.create(mockClient(applicator._id));
});
afterAll(async () => {
await clearCollection(Invoice);
await Client.deleteMany({ _id: client._id });
await Customer.deleteMany({ _id: applicator._id });
});
const makeReq = (extra = {}) =>
mockReq({
uid: applicator._id,
puid: applicator._id,
ut: '1',
userInfo: {
puid: applicator._id,
kind: '1',
premium: 0,
membership: null,
markedDelete: false,
},
...extra,
});
// -------------------------------------------------------------------------
describe('getInvoices_get', () => {
beforeAll(async () => {
await Invoice.create(makeInvoiceDoc(applicator._id, client._id));
});
it('returns invoices for the applicator', async () => {
const req = makeReq({ query: {} });
const res = mockRes();
await invoiceCtl.getInvoices_get(req, res);
expect(res.json).toHaveBeenCalled();
expect(Array.isArray(res._data)).toBe(true);
expect(res._data.length).toBeGreaterThan(0);
});
it('returns empty array when no invoices match filter', async () => {
const filters = JSON.stringify({ code: { value: 'NONEXISTENT_CODE_12345', valueOperator: 'contains' } });
const req = makeReq({ query: { filters } });
const res = mockRes();
await invoiceCtl.getInvoices_get(req, res);
expect(res.json).toHaveBeenCalled();
expect(res._data.length).toBe(0);
});
it('throws AppParamError when applicator puid is invalid', async () => {
const req = mockReq({
uid: newId(),
puid: 'invalid-puid',
ut: '1',
userInfo: {
puid: 'invalid-puid',
kind: '1',
premium: 0,
membership: null,
markedDelete: false,
},
});
const res = mockRes();
await expect(invoiceCtl.getInvoices_get(req, res)).rejects.toThrow();
});
});
// -------------------------------------------------------------------------
describe('getInvoiceById_get', () => {
let invoiceId, InvoiceSetting;
beforeAll(async () => {
InvoiceSetting = require('../../model/invoice_settings');
// Seed a default invoice issuer setting (required by getInvoiceById_get)
await InvoiceSetting.findOneAndUpdate(
{ userId: null, byPuid: applicator._id },
{ $setOnInsert: { userId: null, byPuid: applicator._id, companyName: 'Test Co.', paymentTerm: 30 } },
{ upsert: true, new: true }
);
const doc = await Invoice.create(makeInvoiceDoc(applicator._id, client._id));
invoiceId = String(doc._id);
});
it('returns invoice detail with issuer info', async () => {
const req = makeReq({ params: { id: invoiceId } });
const res = mockRes();
await invoiceCtl.getInvoiceById_get(req, res);
expect(res.json).toHaveBeenCalled();
expect(res._data).toBeTruthy();
});
it('throws when invoice is not found', async () => {
const req = makeReq({ params: { id: String(newId()) } });
const res = mockRes();
await expect(invoiceCtl.getInvoiceById_get(req, res)).rejects.toThrow();
});
});
// -------------------------------------------------------------------------
describe('getPrintInformation_get', () => {
let invoiceId, InvoiceSetting;
beforeAll(async () => {
InvoiceSetting = require('../../model/invoice_settings');
await InvoiceSetting.findOneAndUpdate(
{ userId: null, byPuid: applicator._id },
{ $setOnInsert: { userId: null, byPuid: applicator._id, companyName: 'Test Co.', paymentTerm: 30 } },
{ upsert: true, new: true }
);
const doc = await Invoice.create(makeInvoiceDoc(applicator._id, client._id));
invoiceId = String(doc._id);
});
it('throws when invoiceId is missing', async () => {
const req = makeReq({
query: { clientId: String(client._id) },
});
const res = mockRes();
await expect(invoiceCtl.getPrintInformation_get(req, res)).rejects.toThrow();
});
it('throws when invoice is not found for the given client', async () => {
const req = makeReq({
query: { invoiceId: String(newId()), clientId: String(client._id) },
});
const res = mockRes();
await expect(invoiceCtl.getPrintInformation_get(req, res)).rejects.toThrow();
});
it('returns print information for a valid invoice and client', async () => {
const req = makeReq({
query: { invoiceId, clientId: String(client._id) },
});
const res = mockRes();
await invoiceCtl.getPrintInformation_get(req, res);
expect(res.json).toHaveBeenCalled();
expect(res._data).toBeTruthy();
});
});
// -------------------------------------------------------------------------
describe('exportInvoices_get', () => {
it('throws when exportType is missing', async () => {
const req = makeReq({ query: { invoiceIds: [String(newId())] } });
const res = mockRes();
await expect(invoiceCtl.exportInvoices_get(req, res)).rejects.toThrow();
});
it('throws when invoiceIds is empty', async () => {
const req = makeReq({ query: { exportType: 'csv', invoiceIds: [] } });
const res = mockRes();
await expect(invoiceCtl.exportInvoices_get(req, res)).rejects.toThrow();
});
});
});