mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-08 11:37:25 +00:00
151 lines
4.3 KiB
TypeScript
151 lines
4.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { createPibiRequests, PIBI_ORDERED_TEXT_PROP } from "./createPibiRequests";
|
|
import type { RunCreatePibiTx, SyncMeasuresField, StampPushedAt } from "./createPibiRequests";
|
|
|
|
function makeDeps(overrides?: {
|
|
txResult?: { insertedRowIds: bigint[]; allMeasureNames: string[] };
|
|
txError?: Error;
|
|
syncResult?: { ok: true } | { ok: false; error: string };
|
|
stampError?: Error;
|
|
}) {
|
|
const txResult = overrides?.txResult ?? {
|
|
insertedRowIds: [1n, 2n],
|
|
allMeasureNames: ["CWI", "Loft insulation"],
|
|
};
|
|
|
|
const runCreateTx: RunCreatePibiTx = vi.fn(async () => {
|
|
if (overrides?.txError) throw overrides.txError;
|
|
return txResult;
|
|
});
|
|
|
|
const syncMeasuresField: SyncMeasuresField = vi.fn(async () => {
|
|
return overrides?.syncResult ?? ({ ok: true } as const);
|
|
});
|
|
|
|
const stampPushedAt: StampPushedAt = vi.fn(async () => {
|
|
if (overrides?.stampError) throw overrides.stampError;
|
|
});
|
|
|
|
return { runCreateTx, syncMeasuresField, stampPushedAt };
|
|
}
|
|
|
|
describe("createPibiRequests — happy path", () => {
|
|
it("inserts rows, syncs all deal measures to HubSpot, stamps pushed_at", async () => {
|
|
const orderedAt = new Date("2026-05-06T10:00:00Z");
|
|
const deps = makeDeps({
|
|
txResult: { insertedRowIds: [10n, 11n], allMeasureNames: ["CWI", "Loft insulation"] },
|
|
});
|
|
|
|
const result = await createPibiRequests({
|
|
dealId: "deal-1",
|
|
portfolioId: 42n,
|
|
measureNames: ["CWI", "Loft insulation"],
|
|
orderedAt,
|
|
userId: 5n,
|
|
deps,
|
|
});
|
|
|
|
expect(result).toMatchObject({
|
|
ok: true,
|
|
insertedRowIds: [10n, 11n],
|
|
hubspotSync: "ok",
|
|
});
|
|
|
|
expect(deps.runCreateTx).toHaveBeenCalledWith({
|
|
dealId: "deal-1",
|
|
portfolioId: 42n,
|
|
measureNames: ["CWI", "Loft insulation"],
|
|
orderedAt,
|
|
userId: 5n,
|
|
});
|
|
|
|
expect(deps.syncMeasuresField).toHaveBeenCalledWith({
|
|
hubspotDealId: "deal-1",
|
|
propName: PIBI_ORDERED_TEXT_PROP,
|
|
measureNames: ["CWI", "Loft insulation"],
|
|
});
|
|
|
|
expect(deps.stampPushedAt).toHaveBeenCalledWith([10n, 11n]);
|
|
});
|
|
|
|
it("uses now() when orderedAt is omitted", async () => {
|
|
const before = new Date();
|
|
const deps = makeDeps();
|
|
|
|
await createPibiRequests({
|
|
dealId: "deal-2",
|
|
portfolioId: 1n,
|
|
measureNames: ["ASHP"],
|
|
userId: 1n,
|
|
deps,
|
|
});
|
|
|
|
const callArg = (deps.runCreateTx as ReturnType<typeof vi.fn>).mock.calls[0][0] as {
|
|
orderedAt: Date;
|
|
};
|
|
expect(callArg.orderedAt.getTime()).toBeGreaterThanOrEqual(before.getTime());
|
|
});
|
|
});
|
|
|
|
describe("createPibiRequests — validation", () => {
|
|
it("returns ok=false immediately when measureNames is empty", async () => {
|
|
const deps = makeDeps();
|
|
|
|
const result = await createPibiRequests({
|
|
dealId: "deal-3",
|
|
portfolioId: 1n,
|
|
measureNames: [],
|
|
userId: 1n,
|
|
deps,
|
|
});
|
|
|
|
expect(result).toEqual({ ok: false, error: "measureNames must not be empty" });
|
|
expect(deps.runCreateTx).not.toHaveBeenCalled();
|
|
expect(deps.syncMeasuresField).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("createPibiRequests — DB failure", () => {
|
|
it("returns ok=false, skips HubSpot when tx throws", async () => {
|
|
const deps = makeDeps({ txError: new Error("insert failed") });
|
|
|
|
const result = await createPibiRequests({
|
|
dealId: "deal-x",
|
|
portfolioId: 1n,
|
|
measureNames: ["EWI"],
|
|
userId: 1n,
|
|
deps,
|
|
});
|
|
|
|
expect(result).toEqual({ ok: false, error: "insert failed" });
|
|
expect(deps.syncMeasuresField).not.toHaveBeenCalled();
|
|
expect(deps.stampPushedAt).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("createPibiRequests — HubSpot failure", () => {
|
|
it("returns ok=true with hubspotSync=failed, does NOT stamp pushed_at", async () => {
|
|
const deps = makeDeps({
|
|
txResult: { insertedRowIds: [20n], allMeasureNames: ["Solar PV"] },
|
|
syncResult: { ok: false, error: "hubspot 503" },
|
|
});
|
|
|
|
const result = await createPibiRequests({
|
|
dealId: "deal-h",
|
|
portfolioId: 1n,
|
|
measureNames: ["Solar PV"],
|
|
userId: 2n,
|
|
deps,
|
|
});
|
|
|
|
expect(result).toMatchObject({
|
|
ok: true,
|
|
insertedRowIds: [20n],
|
|
hubspotSync: "failed",
|
|
hubspotError: "hubspot 503",
|
|
});
|
|
|
|
expect(deps.runCreateTx).toHaveBeenCalledTimes(1);
|
|
expect(deps.stampPushedAt).not.toHaveBeenCalled();
|
|
});
|
|
});
|