Files
optima/api/tests/unit/controllers/CompanyController.fetchConfigurations.test.ts
2026-04-07 23:56:31 +00:00

130 lines
4.0 KiB
TypeScript

import { beforeEach, describe, expect, mock, test } from "bun:test";
import { buildMockCompany } from "../../setup";
const getMock: any = mock(() => Promise.resolve({ data: [] as any[] }));
mock.module("../../../src/constants", () => ({
prisma: new Proxy(
{},
{
get() {
return mock(() => Promise.resolve([]));
},
},
),
connectWiseApi: {
get: getMock,
post: mock(() => Promise.resolve({ data: {} })),
put: mock(() => Promise.resolve({ data: {} })),
patch: mock(() => Promise.resolve({ data: {} })),
delete: mock(() => Promise.resolve({ data: {} })),
},
}));
function buildConfig(id: number) {
return {
id,
name: `Config ${id}`,
activeFlag: true,
serialNumber: `SN-${id}`,
type: { id: 9, name: "Firewall" },
notes: "test notes",
status: { id: 2, name: "Active" },
questions: [
{
questionId: 11,
question: "Hostname",
answer: `host-${id}`,
fieldType: "Text",
},
],
_info: { lastUpdated: "2026-03-31T00:00:00Z" },
};
}
describe("CompanyController.fetchConfigurations", () => {
beforeEach(() => {
getMock.mockReset();
});
test("fetches and transforms company configurations from ConnectWise", async () => {
const { CompanyController } = await import(
"../../../src/controllers/CompanyController"
);
getMock.mockImplementation(() => Promise.resolve({ data: [buildConfig(1)] }));
const controller = new CompanyController(buildMockCompany({ id: 123 }) as any);
const result = await controller.fetchConfigurations();
expect(getMock).toHaveBeenCalledTimes(1);
const requestUrl = String((getMock.mock.calls[0] as any[])?.[0] ?? "");
expect(requestUrl).toContain(
"/company/configurations?page=1&pageSize=1000&conditions=company%2Fid%3D123",
);
expect(result).toHaveLength(1);
const first = result[0] as any;
expect(first.id).toBe(1);
expect(first.name).toBe("Config 1");
expect(first.active).toBe(true);
expect(first.serialNumber).toBe("SN-1");
expect(first.type?.id).toBe(9);
expect(first.status?.name).toBe("Active");
expect(first.questions?.[0]?.question).toBe("Hostname");
});
test("paginates when page is full", async () => {
const { CompanyController } = await import(
"../../../src/controllers/CompanyController"
);
const firstPage = Array.from({ length: 1000 }, (_, i) => buildConfig(i + 1));
const secondPage = [buildConfig(1001)];
getMock
.mockImplementationOnce(() => Promise.resolve({ data: firstPage }))
.mockImplementationOnce(() => Promise.resolve({ data: secondPage }));
const controller = new CompanyController(buildMockCompany({ id: 456 }) as any);
const result = await controller.fetchConfigurations();
expect(getMock).toHaveBeenCalledTimes(2);
const firstUrl = String((getMock.mock.calls[0] as any[])?.[0] ?? "");
const secondUrl = String((getMock.mock.calls[1] as any[])?.[0] ?? "");
expect(firstUrl).toContain("page=1");
expect(secondUrl).toContain("page=2");
expect(result).toHaveLength(1001);
});
test("throws GenericError when CW request fails", async () => {
const { CompanyController } = await import(
"../../../src/controllers/CompanyController"
);
const err: any = new Error("Unauthorized");
err.isAxiosError = true;
err.response = {
status: 401,
data: { message: "Unauthorized" },
statusText: "Unauthorized",
};
getMock.mockImplementation(() => Promise.reject(err));
const controller = new CompanyController(buildMockCompany({ id: 321 }) as any);
try {
await controller.fetchConfigurations();
expect(true).toBe(false);
} catch (error: any) {
expect(error.name).toBe("ConnectWiseFetchFailed");
expect(error.status).toBe(401);
expect(error.message).toBe(
"Failed to fetch company configurations from ConnectWise",
);
expect(error.cause).toBe("Unauthorized");
}
});
});