75 lines
4.2 KiB
TypeScript
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));
|
|
}
|
|
}
|
|
});
|