test(13-01): add failing aiCoordsToPagePdfSpace unit tests

- Add ai-coords.test.ts with 3 test cases covering US Letter (612x792 pts)
- Tests import from lib/ai/field-placement which does not exist yet (RED phase)
- Cases: text field near top, checkbox near bottom-right, client-sig at center
This commit is contained in:
Chandler Copeland
2026-03-21 16:59:11 -06:00
parent df4676c23c
commit f7d74c0523

View File

@@ -0,0 +1,91 @@
/**
* Unit tests for aiCoordsToPagePdfSpace — AI top-left percentage coordinates to PDF bottom-left points.
*
* AI models return positions with top-left origin (0,0 = top-left corner of page).
* PDF user space uses bottom-left origin (0,0 = bottom-left corner of page).
* The conversion must flip the Y axis and multiply percentages by page dimensions.
*
* US Letter: 612 × 792 pts at 72 DPI.
*/
import { aiCoordsToPagePdfSpace } from '../../../lib/ai/field-placement';
const US_LETTER_W = 612; // pts
const US_LETTER_H = 792; // pts
describe('aiCoordsToPagePdfSpace — AI top-left percentage to PDF bottom-left points', () => {
test('text field near top of page', () => {
// xPct=10, yPct=5, widthPct=30, heightPct=5
// x = 612 * 0.10 = 61.2
// fieldH = 792 * 0.05 = 39.6
// screenY = 792 * 0.05 = 39.6
// y = 792 - 39.6 - 39.6 = 712.8
const result = aiCoordsToPagePdfSpace(
{
page: 1,
fieldType: 'text',
xPct: 10,
yPct: 5,
widthPct: 30,
heightPct: 5,
prefillValue: '',
},
US_LETTER_W,
US_LETTER_H,
);
expect(result.x).toBeCloseTo(61.2, 1);
expect(result.y).toBeCloseTo(712.8, 1);
expect(result.width).toBeCloseTo(183.6, 1);
expect(result.height).toBeCloseTo(39.6, 1);
});
test('checkbox near bottom-right', () => {
// xPct=90, yPct=95, widthPct=3, heightPct=3
// x = 612 * 0.90 = 550.8
// fieldH = 792 * 0.03 = 23.76
// screenY = 792 * 0.95 = 752.4
// y = 792 - 752.4 - 23.76 = 15.84
const result = aiCoordsToPagePdfSpace(
{
page: 1,
fieldType: 'checkbox',
xPct: 90,
yPct: 95,
widthPct: 3,
heightPct: 3,
prefillValue: '',
},
US_LETTER_W,
US_LETTER_H,
);
expect(result.x).toBeCloseTo(550.8, 1);
expect(result.y).toBeCloseTo(15.84, 1);
expect(result.width).toBeCloseTo(18.36, 1);
expect(result.height).toBeCloseTo(23.76, 1);
});
test('client-signature field at exact center', () => {
// xPct=50, yPct=50, widthPct=20, heightPct=5
// x = 612 * 0.50 = 306
// fieldH = 792 * 0.05 = 39.6
// screenY = 792 * 0.50 = 396
// y = 792 - 396 - 39.6 = 356.4
const result = aiCoordsToPagePdfSpace(
{
page: 1,
fieldType: 'client-signature',
xPct: 50,
yPct: 50,
widthPct: 20,
heightPct: 5,
prefillValue: '',
},
US_LETTER_W,
US_LETTER_H,
);
expect(result.x).toBeCloseTo(306, 1);
expect(result.y).toBeCloseTo(356.4, 1);
expect(result.width).toBeCloseTo(122.4, 1);
expect(result.height).toBeCloseTo(39.6, 1);
});
});