243 lines
8.6 KiB
TypeScript
243 lines
8.6 KiB
TypeScript
import { describe, test, expect, mock, beforeEach } from "bun:test";
|
|
import { buildMockCWActivity } from "../setup";
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Stable mock factory (same pattern as generatedQuotesManager.test.ts)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
function createStablePrismaMock(
|
|
overrides: Record<string, Record<string, any>> = {},
|
|
) {
|
|
return new Proxy(
|
|
{},
|
|
{
|
|
get(_target, model: string) {
|
|
if (model === "$connect" || model === "$disconnect")
|
|
return mock(() => Promise.resolve());
|
|
if (overrides[model]) return overrides[model];
|
|
return new Proxy({}, { get: () => mock(() => Promise.resolve(null)) });
|
|
},
|
|
},
|
|
);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Tests
|
|
// ---------------------------------------------------------------------------
|
|
|
|
describe("activities manager", () => {
|
|
beforeEach(() => {
|
|
mock.restore();
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// fetchItem
|
|
// -------------------------------------------------------------------
|
|
describe("fetchItem()", () => {
|
|
test("returns an ActivityController on success", async () => {
|
|
const cwData = buildMockCWActivity();
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
fetch: mock(() => Promise.resolve(cwData)),
|
|
fetchByCompany: mock(() => Promise.resolve([])),
|
|
fetchByOpportunity: mock(() => Promise.resolve([])),
|
|
delete: mock(() => Promise.resolve()),
|
|
countItems: mock(() => Promise.resolve(0)),
|
|
update: mock(() => Promise.resolve(cwData)),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
post: mock(() => Promise.resolve({ data: {} })),
|
|
patch: mock(() => Promise.resolve({ data: {} })),
|
|
delete: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
const result = await activities.fetchItem(5001);
|
|
expect(result).toBeDefined();
|
|
expect(result.cwActivityId).toBe(5001);
|
|
});
|
|
|
|
test("throws GenericError on failure", async () => {
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
fetch: mock(() => Promise.reject(new Error("CW API down"))),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
try {
|
|
await activities.fetchItem(9999);
|
|
expect(true).toBe(false);
|
|
} catch (e: any) {
|
|
expect(e.name).toBe("FetchActivityError");
|
|
expect(e.status).toBeDefined();
|
|
}
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// fetchPages
|
|
// -------------------------------------------------------------------
|
|
describe("fetchPages()", () => {
|
|
test("returns array of ActivityControllers", async () => {
|
|
const cwData = [buildMockCWActivity(), buildMockCWActivity({ id: 5002 })];
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: cwData })),
|
|
post: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
const result = await activities.fetchPages(1, 10);
|
|
expect(result).toBeArrayOfSize(2);
|
|
});
|
|
|
|
test("clamps page to minimum 1", async () => {
|
|
const getMock = mock(() => Promise.resolve({ data: [] }));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: { get: getMock },
|
|
}));
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
await activities.fetchPages(-5, 10);
|
|
const url = getMock.mock.calls[0]?.[0] as string;
|
|
expect(url).toContain("page=1");
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// fetchByCompany
|
|
// -------------------------------------------------------------------
|
|
describe("fetchByCompany()", () => {
|
|
test("returns ActivityControllers for a company", async () => {
|
|
const items = [buildMockCWActivity()];
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
fetchByCompany: mock(() => Promise.resolve(items)),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
const result = await activities.fetchByCompany(123);
|
|
expect(result).toBeArrayOfSize(1);
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// fetchByOpportunity
|
|
// -------------------------------------------------------------------
|
|
describe("fetchByOpportunity()", () => {
|
|
test("returns ActivityControllers for an opportunity", async () => {
|
|
const items = [buildMockCWActivity()];
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
fetchByOpportunity: mock(() => Promise.resolve(items)),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
const result = await activities.fetchByOpportunity(1001);
|
|
expect(result).toBeArrayOfSize(1);
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// delete
|
|
// -------------------------------------------------------------------
|
|
describe("delete()", () => {
|
|
test("delegates to activityCw.delete", async () => {
|
|
const deleteMock = mock(() => Promise.resolve());
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: { delete: deleteMock },
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
await activities.delete(5001);
|
|
expect(deleteMock).toHaveBeenCalledWith(5001);
|
|
});
|
|
|
|
test("throws GenericError on failure", async () => {
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
delete: mock(() => Promise.reject(new Error("fail"))),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
try {
|
|
await activities.delete(9999);
|
|
expect(true).toBe(false);
|
|
} catch (e: any) {
|
|
expect(e.name).toBe("DeleteActivityError");
|
|
}
|
|
});
|
|
});
|
|
|
|
// -------------------------------------------------------------------
|
|
// count
|
|
// -------------------------------------------------------------------
|
|
describe("count()", () => {
|
|
test("returns count from activityCw", async () => {
|
|
mock.module("../../src/modules/cw-utils/activities/activities", () => ({
|
|
activityCw: {
|
|
countItems: mock(() => Promise.resolve(42)),
|
|
},
|
|
}));
|
|
mock.module("../../src/constants", () => ({
|
|
prisma: createStablePrismaMock(),
|
|
connectWiseApi: {
|
|
get: mock(() => Promise.resolve({ data: {} })),
|
|
},
|
|
}));
|
|
|
|
const { activities } = await import("../../src/managers/activities");
|
|
const result = await activities.count();
|
|
expect(result).toBe(42);
|
|
});
|
|
});
|
|
});
|