mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 17:38:12 +00:00
100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
import { ContractViewModelBuilder, ContractSignatureView } from "./contract-view-model.builder";
|
|
|
|
/**
|
|
* The EDR side of a contract is sealed with the ONE global company stamp, read
|
|
* live at render time; the client side keeps whatever stamp the customer
|
|
* uploaded. These specs pin that asymmetry — the standing rule is that
|
|
* centralizing the EDR seal must not touch customer stamps.
|
|
*/
|
|
describe("ContractViewModelBuilder.attachProviderStamp", () => {
|
|
const STAMP = "data:image/png;base64,RURS";
|
|
|
|
const build = (stampImageUrl: string | null = STAMP) => {
|
|
const getStampImageUrl = jest.fn().mockResolvedValue(stampImageUrl);
|
|
const builder = Object.create(
|
|
ContractViewModelBuilder.prototype,
|
|
) as ContractViewModelBuilder;
|
|
Object.assign(builder, { stampSettings: { getStampImageUrl } });
|
|
return { builder, getStampImageUrl };
|
|
};
|
|
|
|
const sig = (role: "STAFF" | "CUSTOMER", extra: Partial<ContractSignatureView> = {}) =>
|
|
({
|
|
role,
|
|
signerDisplayName: `${role} signer`,
|
|
signedAt: "1 January 2026",
|
|
signatureImageUrl: "https://minio.local/sig.png",
|
|
...extra,
|
|
}) as ContractSignatureView;
|
|
|
|
it("stamps the EDR side with the global stamp", async () => {
|
|
const { builder } = build();
|
|
const signatures = [sig("STAFF")];
|
|
|
|
await builder.attachProviderStamp(signatures);
|
|
|
|
expect(signatures[0]!.stampImageUrl).toBe(STAMP);
|
|
});
|
|
|
|
it("leaves the customer side untouched", async () => {
|
|
const { builder } = build();
|
|
const customerStamp = "data:image/png;base64,Q1VTVA==";
|
|
const signatures = [
|
|
sig("CUSTOMER", { stampImageUrl: customerStamp }),
|
|
sig("STAFF"),
|
|
];
|
|
|
|
await builder.attachProviderStamp(signatures);
|
|
|
|
expect(signatures[0]!.stampImageUrl).toBe(customerStamp);
|
|
expect(signatures[1]!.stampImageUrl).toBe(STAMP);
|
|
});
|
|
|
|
it("does not read the stamp at all when EDR has not signed yet", async () => {
|
|
const { builder, getStampImageUrl } = build();
|
|
const signatures = [sig("CUSTOMER")];
|
|
|
|
await builder.attachProviderStamp(signatures);
|
|
|
|
expect(getStampImageUrl).not.toHaveBeenCalled();
|
|
expect(signatures[0]!.stampImageUrl).toBeUndefined();
|
|
});
|
|
|
|
it("renders unstamped rather than failing when no stamp is configured", async () => {
|
|
const { builder } = build(null);
|
|
const signatures = [sig("STAFF")];
|
|
|
|
await expect(builder.attachProviderStamp(signatures)).resolves.toBeUndefined();
|
|
expect(signatures[0]!.stampImageUrl).toBeNull();
|
|
});
|
|
|
|
it("reads the stamp once for every EDR signature row", async () => {
|
|
const { builder, getStampImageUrl } = build();
|
|
const signatures = [sig("STAFF"), sig("STAFF")];
|
|
|
|
await builder.attachProviderStamp(signatures);
|
|
|
|
expect(getStampImageUrl).toHaveBeenCalledTimes(1);
|
|
expect(signatures.map((s) => s.stampImageUrl)).toEqual([STAMP, STAMP]);
|
|
});
|
|
|
|
it("is applied by loadSignatures, so the HTML view and the PDF agree", async () => {
|
|
const { builder } = build();
|
|
Object.assign(builder, {
|
|
bookingsRepository: {
|
|
findContractSignatures: jest.fn().mockResolvedValue([
|
|
{ signerRole: "STAFF", signerDisplayName: "EDR", signedAt: new Date() },
|
|
]),
|
|
},
|
|
});
|
|
|
|
const views = await (
|
|
builder as unknown as {
|
|
loadSignatures(id: string): Promise<ContractSignatureView[]>;
|
|
}
|
|
).loadSignatures("b-1");
|
|
|
|
expect(views[0]!.stampImageUrl).toBe(STAMP);
|
|
});
|
|
});
|