Files
jobtrackingapp/job-tracker-ui/src/profileCv.test.ts
T

75 lines
4.2 KiB
TypeScript

import { normalizeStructuredCv, parseStructuredCvJson } from "./profileCv";
const keyedItems = [
["jobs", { id: "job:recorded-Æ_01", title: "Engineer", bullets: ["Recorded delivery"], skills: ["C#"] }],
["education", { id: "education/server:key-02", qualification: "Recorded degree", details: ["Recorded distinction"] }],
["certifications", { id: "certification:key-03", name: "Recorded certification", details: ["Recorded detail"] }],
["projects", { id: "project:key-04", name: "Recorded project", bullets: ["Recorded outcome"], skills: ["SQL"] }],
] as const;
test.each(keyedItems)("preserves the server item ID when normalizing %s", (collection, item) => {
const profile = normalizeStructuredCv({ [collection]: [item] });
expect(profile[collection]).toHaveLength(1);
expect(profile[collection][0]).toMatchObject(item);
expect(parseStructuredCvJson(JSON.stringify(profile))[collection][0]).toMatchObject(item);
});
test("legacy structured items without IDs remain usable and acquire no client-generated IDs", () => {
const legacy = Object.fromEntries(keyedItems.map(([collection, item]) => {
const { id: _id, ...fields } = item;
return [collection, [fields]];
}));
const profile = normalizeStructuredCv(legacy);
const serialized = JSON.parse(JSON.stringify(profile));
for (const [collection] of keyedItems) {
expect(profile[collection]).toHaveLength(1);
expect(serialized[collection][0]).toMatchObject(legacy[collection][0]);
expect(serialized[collection][0]).not.toHaveProperty("id");
}
});
test("legacy parsed sections keep their facts without inventing structured item IDs", () => {
const profile = parseStructuredCvJson(JSON.stringify([
{ name: "Professional Summary", content: "Recorded delivery\nRecorded support", wordCount: 4 },
{ name: "Skills", content: "C#, SQL", wordCount: 2 },
{ name: "Languages", content: "Norwegian: Native", wordCount: 2 },
]));
expect(profile.summary).toEqual(["Recorded delivery", "Recorded support"]);
expect(profile.skills).toEqual(["C#", "SQL"]);
expect(profile.languages).toEqual([{ name: "Norwegian", level: "Native", notes: undefined }]);
for (const [collection] of keyedItems) expect(profile[collection]).toEqual([]);
});
test("API null and missing numeric metadata remain absent rather than becoming zero", () => {
const inputs = [
{ metadata: { profileVersion: null, appliedExtractionRunId: null, fields: { "contact.fullName": { confidence: null, sourcePage: null } } } },
{ metadata: { fields: { "contact.fullName": {} } } },
];
for (const input of inputs) {
for (const profile of [normalizeStructuredCv(input), parseStructuredCvJson(JSON.stringify(input))]) {
expect(profile.metadata.profileVersion).toBeUndefined();
expect(profile.metadata.appliedExtractionRunId).toBeUndefined();
expect(profile.metadata.fields["contact.fullName"].confidence).toBeUndefined();
expect(profile.metadata.fields["contact.fullName"].sourcePage).toBeUndefined();
const serialized = JSON.parse(JSON.stringify(profile));
expect(serialized.metadata).not.toHaveProperty("profileVersion");
expect(serialized.metadata).not.toHaveProperty("appliedExtractionRunId");
expect(serialized.metadata.fields["contact.fullName"]).not.toHaveProperty("confidence");
expect(serialized.metadata.fields["contact.fullName"]).not.toHaveProperty("sourcePage");
}
}
});
test("zero, finite numbers and numeric strings keep the established metadata number conversion", () => {
for (const values of [[0, 0, 0, 0], [5, 3, 0.8, 2], ["6", "4", "0.65", "3"]]) {
const [profileVersion, appliedExtractionRunId, confidence, sourcePage] = values;
const input = { metadata: { profileVersion, appliedExtractionRunId, fields: { "contact.fullName": { confidence, sourcePage } } } };
for (const profile of [normalizeStructuredCv(input), parseStructuredCvJson(JSON.stringify(input))]) {
expect(profile.metadata.profileVersion).toBe(Number(profileVersion));
expect(profile.metadata.appliedExtractionRunId).toBe(Number(appliedExtractionRunId));
expect(profile.metadata.fields["contact.fullName"].confidence).toBe(Number(confidence));
expect(profile.metadata.fields["contact.fullName"].sourcePage).toBe(Number(sourcePage));
}
}
});