Port property assessor helpers to TypeScript
This commit is contained in:
82
skills/property-assessor/tests/public-records.test.ts
Normal file
82
skills/property-assessor/tests/public-records.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
import { resolvePublicRecords } from "../src/public-records.js";
|
||||
|
||||
const geocoderPayload = {
|
||||
result: {
|
||||
addressMatches: [
|
||||
{
|
||||
matchedAddress: "4141 WHITELEY DR, CORPUS CHRISTI, TX, 78418",
|
||||
coordinates: { x: -97.30174, y: 27.613668 },
|
||||
geographies: {
|
||||
States: [{ NAME: "Texas", STUSAB: "TX", STATE: "48" }],
|
||||
Counties: [{ NAME: "Nueces County", COUNTY: "355", GEOID: "48355" }],
|
||||
"2020 Census Blocks": [{ GEOID: "483550031013005" }]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const countyIndexHtml = `
|
||||
<ul>
|
||||
<li><a href="nueces.php">178 Nueces</a></li>
|
||||
</ul>
|
||||
`;
|
||||
|
||||
const countyPageHtml = `
|
||||
<div class="medium-6 small-12 columns">
|
||||
<h3>Appraisal District</h3>
|
||||
<p class="file-info">Last Updated: 08/13/2025</p>
|
||||
<h4>Chief Appraiser: Debra Morin, Interim</h4>
|
||||
<p>
|
||||
<strong>Phone:</strong> <a href="tel:361-881-9978">361-881-9978</a><br />
|
||||
<strong>Email:</strong> <a href="mailto:info@nuecescad.net">info@nuecescad.net</a><br />
|
||||
<strong>Website:</strong> <a href="http://www.ncadistrict.com/">www.ncadistrict.com</a>
|
||||
</p>
|
||||
<h4>Mailing Address</h4>
|
||||
<p>201 N. Chaparral St.<br />Corpus Christi, TX 78401-2503</p>
|
||||
</div>
|
||||
<div class="medium-6 small-12 columns">
|
||||
<h3>Tax Assessor/Collector</h3>
|
||||
<p class="file-info">Last Updated: 02/18/2025</p>
|
||||
<h4>Tax Assessor-Collector: Kevin Kieschnick</h4>
|
||||
<p>
|
||||
<strong>Phone:</strong> <a href="tel:361-888-0307">361-888-0307</a><br />
|
||||
<strong>Email:</strong> <a href="mailto:nueces.tax@nuecesco.com">nueces.tax@nuecesco.com</a><br />
|
||||
<strong>Website:</strong> <a href="http://www.nuecesco.com">www.nuecesco.com</a>
|
||||
</p>
|
||||
<h4>Street Address</h4>
|
||||
<p>901 Leopard St., Room 301<br />Corpus Christi, Texas 78401-3602</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const fakeFetchText = async (url: string): Promise<string> => {
|
||||
if (url.includes("geocoding.geo.census.gov")) {
|
||||
return JSON.stringify(geocoderPayload);
|
||||
}
|
||||
if (url.endsWith("/county-directory/")) {
|
||||
return countyIndexHtml;
|
||||
}
|
||||
if (url.endsWith("/county-directory/nueces.php")) {
|
||||
return countyPageHtml;
|
||||
}
|
||||
throw new Error(`Unexpected URL: ${url}`);
|
||||
};
|
||||
|
||||
test("resolvePublicRecords uses Census and Texas county directory", async () => {
|
||||
const payload = await resolvePublicRecords("4141 Whiteley Dr, Corpus Christi, TX 78418", {
|
||||
parcelId: "14069438",
|
||||
listingGeoId: "233290",
|
||||
listingSourceUrl: "https://www.zillow.com/homedetails/example",
|
||||
fetchText: fakeFetchText
|
||||
});
|
||||
|
||||
assert.equal(payload.county.name, "Nueces County");
|
||||
assert.equal(payload.state.code, "TX");
|
||||
assert.equal(payload.appraisalDistrict?.Website, "http://www.ncadistrict.com/");
|
||||
assert.equal(payload.taxAssessorCollector?.Email, "nueces.tax@nuecesco.com");
|
||||
assert.equal(payload.sourceIdentifierHints.parcelId, "14069438");
|
||||
assert.match(payload.lookupRecommendations.join(" "), /listing geo IDs as regional hints only/i);
|
||||
});
|
||||
69
skills/property-assessor/tests/report-pdf.test.ts
Normal file
69
skills/property-assessor/tests/report-pdf.test.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
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
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user