import assert from "node:assert/strict"; import { sanitizeFontfileForFilter } from "../lib/fonts"; import { buildDrawtextFilter, clampOffset, drawtextXy, overlayXy, requiresCustomWatermarkEntitlement, sanitizeDrawtext, normalizeWatermarkSettings, } from "../lib/watermark"; function testSanitize() { const s = sanitizeDrawtext("Hi:there'100%[x]"); assert.ok(s.includes("\\:"), "colon escaped as \\\\:"); assert.ok(s.includes("\\'"), "quote escaped"); assert.equal(sanitizeDrawtext("a".repeat(200)).length, 80); assert.equal(sanitizeDrawtext("ok\nline").includes("\n"), false); } function testPositions() { assert.deepEqual(overlayXy("bottom-right", 20, 20), { x: "W-w-20", y: "H-h-20" }); assert.deepEqual(overlayXy("top-left", 10, 5), { x: "10", y: "5" }); assert.deepEqual(drawtextXy("center", 0, 0), { x: "(w-text_w)/2+0", y: "(h-th)/2+0", }); } function testEntitlements() { assert.equal( requiresCustomWatermarkEntitlement( normalizeWatermarkSettings({ mode: "default" }, true), ), false, ); assert.equal( requiresCustomWatermarkEntitlement( normalizeWatermarkSettings({ mode: "text", text: "Brand" }, true), ), true, ); assert.equal( requiresCustomWatermarkEntitlement( normalizeWatermarkSettings({ mode: "default", position: "top-left" }, true), ), true, ); assert.equal( requiresCustomWatermarkEntitlement( normalizeWatermarkSettings({ mode: "default", fontKey: "inter" }, true), ), true, ); assert.equal(clampOffset(999), 200); assert.equal(clampOffset(-5), 0); } function testDrawtextFontfile() { const withFont = buildDrawtextFilter({ text: "Brand", fontSize: 24, position: "bottom-right", offsetX: 20, offsetY: 20, fontfileEscaped: sanitizeFontfileForFilter("C:\\fonts\\My Font.ttf"), }); assert.ok(withFont.includes("fontfile="), "fontfile present"); assert.ok(withFont.includes("C\\:/fonts/My Font.ttf") || withFont.includes("C\\:/fonts/My\\ Font.ttf") || withFont.includes("fontfile='"), "escaped path"); assert.ok(!withFont.includes("C:\\fonts"), "backslashes normalized"); const injection = sanitizeFontfileForFilter("/tmp/evil':drawtext=text='x"); assert.ok(injection.includes("\\'"), "quote escaped in font path"); const noFont = buildDrawtextFilter({ text: "Hi", fontSize: 18, position: "top-left", offsetX: 0, offsetY: 0, }); assert.equal(noFont.includes("fontfile"), false); } testSanitize(); testPositions(); testEntitlements(); testDrawtextFontfile(); console.log("watermark.test.ts: ok");