mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 08:36:25 +00:00
The JSON-LD and rendered-HTML branches returned structurally different records: the fallback emitted raw DD-MM-YYYY page text as datePosted, free text (including the literal "Loebende") as validThrough, and a hardcoded null addressLocality. Overview dates now convert to ISO, Loebende maps to null, and the locality derives from the workplace address via the same exported extractCity search uses. Review finding F25 (2026-08-19). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
87 lines
3.7 KiB
TypeScript
87 lines
3.7 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { parseJobPostingFromHtml } from "../src/commands/detail";
|
|
|
|
const HTML_WITHOUT_JSON_LD = `<!doctype html>
|
|
<html lang="da">
|
|
<head>
|
|
<title>Journalistisk udvikler søges | jobdanmark</title>
|
|
</head>
|
|
<body>
|
|
<div class="job-list-details">
|
|
<div class="job-details-head row mx-0">
|
|
<div class="company-logo col-auto">
|
|
<img src="/media/jfm-logo.png?width=100" alt="JFM">
|
|
</div>
|
|
<h3 class="title">Journalistisk udvikler søges</h3>
|
|
<a href="/virksomheder/jfm">JFM</a>
|
|
<span>Banegårdspladsen 1, 5000 Odense C</span>
|
|
</div>
|
|
<p>Hvad nu hvis du med få klik kunne undersøge dit lokalområde?</p>
|
|
<ul>
|
|
<li>identificere relevante datasæt og muligheder</li>
|
|
</ul>
|
|
</div>
|
|
<a href="https://jfm.career.emply.com/da/apply/example" class="action primary count-click">Ansøg nu</a>
|
|
<ul class="job-overview list-unstyled">
|
|
<li><strong>Udgivet:</strong> 03-07-2026</li>
|
|
<li><strong>Jobtype:</strong> Fuldtid</li>
|
|
<li><strong>Arbejdssted:</strong> Banegårdspladsen 1, 5000 Odense C</li>
|
|
<li><strong>Ansøgningsfrist:</strong> 02-08-2026 23.59</li>
|
|
</ul>
|
|
</body>
|
|
</html>`;
|
|
|
|
describe("parseJobPostingFromHtml", () => {
|
|
test("falls back to rendered Jobdanmark HTML when JSON-LD is absent", () => {
|
|
const parsed = parseJobPostingFromHtml(
|
|
HTML_WITHOUT_JSON_LD,
|
|
"journalistisk-udvikler",
|
|
"https://jobdanmark.dk/job/journalistisk-udvikler",
|
|
);
|
|
|
|
expect(parsed.title).toBe("Journalistisk udvikler søges");
|
|
// The fallback must emit the same shapes as the JSON-LD branch: contract
|
|
// dates, not the page's raw DD-MM-YYYY text (review finding F25, 2026-08-19).
|
|
expect(parsed.datePosted).toBe("2026-07-03");
|
|
expect(parsed.validThrough).toBe("2026-08-02");
|
|
expect(parsed.employmentType).toEqual(["Fuldtid"]);
|
|
expect(parsed.hiringOrganization.name).toBe("JFM");
|
|
expect(parsed.hiringOrganization.logo).toBe("https://jobdanmark.dk/media/jfm-logo.png?width=100");
|
|
expect(parsed.jobLocation.streetAddress).toBe("Banegårdspladsen 1, 5000 Odense C");
|
|
expect(parsed.jobLocation.addressLocality).toBe("Odense C");
|
|
expect(parsed.description).toContain("identificere relevante datasæt");
|
|
expect(parsed.applyUrl).toBe("https://jfm.career.emply.com/da/apply/example");
|
|
});
|
|
|
|
test("maps a rolling deadline (Løbende) to null in the HTML fallback", () => {
|
|
// "Løbende" is free text meaning rolling/ongoing - jobbank's parser maps
|
|
// its equivalent to null, and a stored "Løbende" deadline would hit every
|
|
// date-arithmetic consumer (review finding F25, 2026-08-19).
|
|
const html = HTML_WITHOUT_JSON_LD.replace(
|
|
"<li><strong>Ansøgningsfrist:</strong> 02-08-2026 23.59</li>",
|
|
"<li><strong>Ansøgningsfrist:</strong> Løbende</li>",
|
|
);
|
|
const parsed = parseJobPostingFromHtml(html, "s", "https://jobdanmark.dk/job/s");
|
|
expect(parsed.validThrough).toBeNull();
|
|
});
|
|
|
|
test("does not reject titles containing '404' mid-phrase", () => {
|
|
const htmlWith404InTitle = HTML_WITHOUT_JSON_LD.replace(
|
|
"<title>Journalistisk udvikler søges | jobdanmark</title>",
|
|
"<title>HTTP 404 Page Designer | jobdanmark</title>",
|
|
).replace(
|
|
'<h3 class="title">Journalistisk udvikler søges</h3>',
|
|
'<h3 class="title">HTTP 404 Page Designer</h3>',
|
|
);
|
|
|
|
const parsed = parseJobPostingFromHtml(
|
|
htmlWith404InTitle,
|
|
"http-404-designer",
|
|
"https://jobdanmark.dk/job/http-404-designer",
|
|
);
|
|
|
|
expect(parsed.title).toBe("HTTP 404 Page Designer");
|
|
expect(parsed.hiringOrganization.name).toBe("JFM");
|
|
});
|
|
});
|