70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { ReportValidationError, renderReportPdf } from "../src/report-pdf.js";
|
|
|
|
const samplePayload = {
|
|
recipientEmails: ["buyer@example.com"],
|
|
reportTitle: "Property Assessment Report",
|
|
subjectProperty: {
|
|
address: "4141 Whiteley Dr, Corpus Christi, TX 78418",
|
|
listingPrice: 149900,
|
|
propertyType: "Townhouse",
|
|
beds: 2,
|
|
baths: 2,
|
|
squareFeet: 900,
|
|
yearBuilt: 1978
|
|
},
|
|
verdict: {
|
|
decision: "only below x",
|
|
fairValueRange: "$132,000 - $138,000",
|
|
offerGuidance:
|
|
"Only attractive below ask after HOA, insurance, and medium make-ready assumptions are priced in."
|
|
},
|
|
snapshot: ["2 bed / 2 bath coastal townhouse in Flour Bluff."],
|
|
whatILike: ["Compact layout with usable bedroom count for the size."],
|
|
whatIDontLike: ["Thin margin at the current ask."],
|
|
compView: ["Need same-building or local comp confirmation."],
|
|
carryView: ["Underwrite taxes, HOA, wind/flood exposure, and maintenance together."],
|
|
risksAndDiligence: ["Confirm reserve strength and special assessment history."],
|
|
photoReview: {
|
|
status: "completed",
|
|
source: "Zillow",
|
|
attempts: ["Zillow all-photo extractor returned the full 29-photo set."],
|
|
summary: "Interior reads dated-to-average rather than turnkey."
|
|
},
|
|
publicRecords: {
|
|
jurisdiction: "Nueces Appraisal District",
|
|
assessedTotalValue: 141000,
|
|
links: [{ label: "Nueces CAD", url: "http://www.ncadistrict.com/" }]
|
|
},
|
|
sourceLinks: [
|
|
{ label: "Zillow Listing", url: "https://www.zillow.com/homedetails/example" }
|
|
]
|
|
};
|
|
|
|
test("renderReportPdf writes a non-empty PDF", async () => {
|
|
const outputPath = path.join(os.tmpdir(), `property-assessor-${Date.now()}.pdf`);
|
|
await renderReportPdf(samplePayload, outputPath);
|
|
const stat = await fs.promises.stat(outputPath);
|
|
assert.ok(stat.size > 1000);
|
|
});
|
|
|
|
test("renderReportPdf requires recipient email", async () => {
|
|
const outputPath = path.join(os.tmpdir(), `property-assessor-missing-email-${Date.now()}.pdf`);
|
|
await assert.rejects(
|
|
() =>
|
|
renderReportPdf(
|
|
{
|
|
...samplePayload,
|
|
recipientEmails: []
|
|
},
|
|
outputPath
|
|
),
|
|
ReportValidationError
|
|
);
|
|
});
|