pelagia-portal/App/tests/unit/po-export-layout.test.ts
Hardik 65a9335de1
All checks were successful
PR checks / checks (pull_request) Successful in 35s
PR checks / integration (pull_request) Successful in 26s
fix(po): keep the export stamp clear of the signature (no overlap)
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>
2026-06-21 15:35:09 +05:30

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 });
});
});