116 lines
4.2 KiB
TypeScript
116 lines
4.2 KiB
TypeScript
import { applyCvTheme, getCvPageCount, getCvPageMetrics, getCvPreviewFitZoom, getVisibleCvThemes, moveItem, normalizeCvLanguage, wrapSelection } from "./cvBuilder";
|
|
|
|
describe("moveItem", () => {
|
|
test("moves an item forward", () => {
|
|
expect(moveItem(["a", "b", "c"], 0, 2)).toEqual(["b", "c", "a"]);
|
|
});
|
|
test("moves an item backward", () => {
|
|
expect(moveItem(["a", "b", "c"], 2, 0)).toEqual(["c", "a", "b"]);
|
|
});
|
|
test("no-op for equal or out-of-range indices", () => {
|
|
const a = ["a", "b"];
|
|
expect(moveItem(a, 1, 1)).toBe(a);
|
|
expect(moveItem(a, 5, 0)).toBe(a);
|
|
expect(moveItem(a, 0, -1)).toBe(a);
|
|
});
|
|
test("does not mutate the input", () => {
|
|
const a = ["a", "b", "c"];
|
|
moveItem(a, 0, 2);
|
|
expect(a).toEqual(["a", "b", "c"]);
|
|
});
|
|
});
|
|
|
|
describe("wrapSelection", () => {
|
|
test("wraps a selection and keeps the selection over the inner text", () => {
|
|
const r = wrapSelection("hello world", 6, 11, "**", "**");
|
|
expect(r.text).toBe("hello **world**");
|
|
expect(r.text.slice(r.selStart, r.selEnd)).toBe("world");
|
|
});
|
|
test("inserts a placeholder when nothing is selected", () => {
|
|
const r = wrapSelection("", 0, 0, "**", "**", "bold text");
|
|
expect(r.text).toBe("**bold text**");
|
|
expect(r.text.slice(r.selStart, r.selEnd)).toBe("bold text");
|
|
});
|
|
test("wraps a link with a url suffix", () => {
|
|
const r = wrapSelection("see docs", 4, 8, "[", "](https://)");
|
|
expect(r.text).toBe("see [docs](https://)");
|
|
expect(r.text.slice(r.selStart, r.selEnd)).toBe("docs");
|
|
});
|
|
});
|
|
|
|
describe("CV page measurement", () => {
|
|
test("uses the selected physical page size", () => {
|
|
expect(getCvPageMetrics("a4")).toMatchObject({ widthMm: 210, heightMm: 297 });
|
|
expect(getCvPageMetrics("letter")).toMatchObject({ widthMm: 215.9, heightMm: 279.4 });
|
|
});
|
|
|
|
test("rounds layout pixels without hiding partial pages", () => {
|
|
const { heightPx } = getCvPageMetrics("a4");
|
|
expect(getCvPageCount(Math.ceil(heightPx), heightPx)).toBe(1);
|
|
expect(getCvPageCount(heightPx + 20, heightPx)).toBe(2);
|
|
expect(getCvPageCount(heightPx * 2 + 20, heightPx)).toBe(3);
|
|
});
|
|
});
|
|
|
|
describe("CV language compatibility", () => {
|
|
test("maps legacy Norwegian values to the supported Bokmål locale", () => {
|
|
expect(normalizeCvLanguage("no")).toBe("nb-NO");
|
|
expect(normalizeCvLanguage("nb")).toBe("nb-NO");
|
|
expect(normalizeCvLanguage("nb-NO")).toBe("nb-NO");
|
|
expect(normalizeCvLanguage("en")).toBe("en");
|
|
});
|
|
|
|
test("fits the physical page to the available preview width", () => {
|
|
expect(getCvPreviewFitZoom(500, 800)).toBeCloseTo(0.595);
|
|
expect(getCvPreviewFitZoom(1200, 800)).toBe(1);
|
|
expect(getCvPreviewFitZoom(120, 800, 24, 0.2)).toBe(0.2);
|
|
});
|
|
});
|
|
|
|
describe("CV template selection", () => {
|
|
test("restores the selected template visual defaults without discarding user content", () => {
|
|
const settings = {
|
|
themeId: "minimal",
|
|
layout: "single" as const,
|
|
headerStyle: "plain" as const,
|
|
headingStyle: "plain" as const,
|
|
sidebarWidthMm: 70,
|
|
sidebarSections: ["skills"],
|
|
accentColor: "#123456",
|
|
headingFont: "Georgia, 'Times New Roman', serif",
|
|
pageMarginMm: 9,
|
|
skillsStyle: "text" as const,
|
|
showPhoto: false,
|
|
showPageNumbers: false,
|
|
showIcons: true,
|
|
sections: [{ key: "experience", title: "Career" }],
|
|
overrides: {},
|
|
customSections: [],
|
|
};
|
|
|
|
expect(applyCvTheme(settings, "technical")).toMatchObject({
|
|
themeId: "technical",
|
|
layout: null,
|
|
headerStyle: null,
|
|
headingStyle: null,
|
|
sidebarWidthMm: null,
|
|
sidebarSections: null,
|
|
accentColor: null,
|
|
headingFont: null,
|
|
pageMarginMm: null,
|
|
skillsStyle: null,
|
|
sections: [{ key: "experience", title: "Career" }],
|
|
});
|
|
});
|
|
|
|
test("shows ATS templates first and keeps an active non-ATS template visible", () => {
|
|
const themes = [
|
|
{ id: "creative", atsFriendly: false },
|
|
{ id: "classic", atsFriendly: true },
|
|
{ id: "minimal", atsFriendly: true },
|
|
] as never[];
|
|
expect(getVisibleCvThemes(themes, true, "creative").map((theme) => theme.id)).toEqual(["classic", "minimal", "creative"]);
|
|
expect(getVisibleCvThemes(themes, true).map((theme) => theme.id)).toEqual(["classic", "minimal"]);
|
|
});
|
|
});
|