Uploaded signatures/stamps aren't always transparent PNGs, so an opaque stamp overlapping the signature/name would cover them. Extract the signatory-block geometry into a tested helper (signatoryLayout): the signature is centred over the name and the stamp sits to its RIGHT with a 10px gap — never overlapping. - lib/po-export-layout.ts (signatoryLayout) + unit test - export route uses it instead of inline overlap math Verified in a real export: signature 175-328px (centred), stamp 338-405px (10px gap, no overlap), stamp drawn behind the signature. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
39 lines
1.9 KiB
TypeScript
39 lines
1.9 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { signatoryLayout } from "@/lib/po-export-layout";
|
|
|
|
const BLOCK = 503; // px width of the A-D signatory block
|
|
|
|
describe("signatoryLayout", () => {
|
|
it("centres the signature in the block", () => {
|
|
const { sigLeft } = signatoryLayout({ blockPx: BLOCK, sig: { width: 153, height: 44 }, stamp: null });
|
|
expect(sigLeft).not.toBeNull();
|
|
expect(sigLeft! + 153 / 2).toBeCloseTo(BLOCK / 2, 0); // centre ≈ block centre
|
|
});
|
|
|
|
it("places the stamp to the RIGHT of the signature with no overlap", () => {
|
|
const sig = { width: 153, height: 44 };
|
|
const stamp = { width: 67, height: 66 };
|
|
const { sigLeft, stampLeft } = signatoryLayout({ blockPx: BLOCK, sig, stamp, gap: 10 });
|
|
expect(stampLeft! ).toBeGreaterThanOrEqual(sigLeft! + sig.width); // starts at/after signature ends
|
|
expect(stampLeft! + stamp.width).toBeLessThanOrEqual(BLOCK); // stays inside the block
|
|
});
|
|
|
|
it("never overlaps even with the widest signature + stamp", () => {
|
|
const sig = { width: 165, height: 44 }; // scaleToBox caps
|
|
const stamp = { width: 80, height: 66 }; // scaleToBox caps
|
|
const { sigLeft, stampLeft } = signatoryLayout({ blockPx: BLOCK, sig, stamp });
|
|
expect(stampLeft!).toBeGreaterThanOrEqual(sigLeft! + sig.width);
|
|
expect(stampLeft! + stamp.width).toBeLessThanOrEqual(BLOCK);
|
|
});
|
|
|
|
it("right-aligns the stamp when there is no signature", () => {
|
|
const { sigLeft, stampLeft } = signatoryLayout({ blockPx: BLOCK, sig: null, stamp: { width: 67, height: 66 } });
|
|
expect(sigLeft).toBeNull();
|
|
expect(stampLeft! + 67).toBeLessThanOrEqual(BLOCK);
|
|
expect(stampLeft!).toBeGreaterThan(BLOCK / 2); // on the right side
|
|
});
|
|
|
|
it("returns nulls when there are no images", () => {
|
|
expect(signatoryLayout({ blockPx: BLOCK, sig: null, stamp: null })).toEqual({ sigLeft: null, stampLeft: null });
|
|
});
|
|
});
|