130 lines
4.0 KiB
TypeScript
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");
|
|
}
|
|
});
|
|
});
|