import assert from "node:assert/strict"; import {readFile} from "node:fs/promises"; import {fileURLToPath} from "node:url"; import {resolve,dirname} from "node:path"; import {parseCatalog,dollars,gigabytes} from "../src/pricing/catalog.js"; const valid = {prices:[{interval:"monthly",currency:"usd",unitAmount:900,regularUnitAmount:1500,promotion:"early_bird"}],limits:{freeRecordingLimit:5,freeMaxRecordingBytes:1e9,plusMaxRecordingBytes:1e10,storageLimitBytes:null}}; const parsed = parseCatalog(valid); assert.equal(dollars(parsed.amount), "$9"); assert.equal(dollars(parsed.regular), "$15"); assert.equal(gigabytes(parsed.cloudBytes), "10 GB"); assert.equal(parseCatalog({...valid,prices:[{...valid.prices[0],promotion:undefined}]}).regular,null); for (const unitAmount of [0,-900,9.5,"900",NaN]) assert.throws(()=>parseCatalog({...valid,prices:[{...valid.prices[0],unitAmount}]})); assert.throws(()=>parseCatalog({...valid,prices:[{...valid.prices[0],currency:"eur"}]})); assert.throws(()=>parseCatalog({...valid,limits:{...valid.limits,plusMaxRecordingBytes:1}})); assert.throws(()=>parseCatalog(null)); const root=resolve(dirname(fileURLToPath(import.meta.url)),".."); const html=await readFile(resolve(root,"dist/pricing/index.html"),"utf8"); assert.match(html, /Pricing \| Recordly<\/title>/); assert.match(html, /<a href="\/pricing">Pricing<\/a>/); assert.match(html, /id="free-plan"/); assert.match(html, /id="cloud-plan"/); assert.doesNotMatch(html, /id="get-cloud"|href="#get-cloud"|Your plan lives in Recordly/); assert.match(html, /href="\/billing">Billing & refunds/); assert.doesNotMatch(html, /<a href="\/billing">Pricing/); const blog=await readFile(resolve(root,"dist/blog/index.html"),"utf8"); assert.match(blog, /<a href="\/pricing">Pricing<\/a>/); assert.match(blog, /No posts yet/); console.log("Passed: validated prices/limits, safe rejection of invalid catalogs, pricing route, separate policy link, and empty blog preserved.");