mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-25 17:34:52 +10:00
173 lines
4.4 KiB
TypeScript
173 lines
4.4 KiB
TypeScript
import type { ResumeData } from "@reactive-resume/schema/resume/data";
|
|
import { describe, expect, it } from "vitest";
|
|
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
|
|
import { getSectionStyleRuleContext, resolveStyleRuleSlot } from "./style-rules";
|
|
|
|
const createResumeData = (styleRules: ResumeData["metadata"]["styleRules"]): ResumeData => ({
|
|
...defaultResumeData,
|
|
metadata: {
|
|
...defaultResumeData.metadata,
|
|
styleRules,
|
|
},
|
|
});
|
|
|
|
describe("resolveStyleRuleSlot", () => {
|
|
it("applies global, section-type, and section-id rules in specificity order", () => {
|
|
const data = createResumeData([
|
|
{
|
|
id: "global-heading",
|
|
label: "Global Heading",
|
|
enabled: true,
|
|
target: { scope: "global" },
|
|
slots: { heading: { color: "rgba(0, 0, 0, 1)", fontSize: 12 } },
|
|
},
|
|
{
|
|
id: "experience-heading",
|
|
label: "Experience Heading",
|
|
enabled: true,
|
|
target: { scope: "sectionType", sectionType: "experience" },
|
|
slots: { heading: { color: "rgba(220, 38, 38, 1)" } },
|
|
},
|
|
{
|
|
id: "specific-heading",
|
|
label: "Specific Heading",
|
|
enabled: true,
|
|
target: { scope: "sectionId", sectionId: "experience" },
|
|
slots: { heading: { fontSize: 15 } },
|
|
},
|
|
]);
|
|
|
|
expect(
|
|
resolveStyleRuleSlot(data, {
|
|
sectionId: "experience",
|
|
sectionType: "experience",
|
|
slot: "heading",
|
|
}),
|
|
).toEqual({ color: "#dc2626", fontSize: 15 });
|
|
});
|
|
|
|
it("ignores disabled rules and non-matching deleted section ids", () => {
|
|
const data = createResumeData([
|
|
{
|
|
id: "disabled",
|
|
label: "Disabled",
|
|
enabled: false,
|
|
target: { scope: "global" },
|
|
slots: { section: { backgroundColor: "rgba(0, 0, 0, 1)" } },
|
|
},
|
|
{
|
|
id: "missing",
|
|
label: "Missing",
|
|
enabled: true,
|
|
target: { scope: "sectionId", sectionId: "missing-section" },
|
|
slots: { section: { backgroundColor: "rgba(220, 38, 38, 1)" } },
|
|
},
|
|
]);
|
|
|
|
expect(
|
|
resolveStyleRuleSlot(data, {
|
|
sectionId: "experience",
|
|
sectionType: "experience",
|
|
slot: "section",
|
|
}),
|
|
).toEqual({});
|
|
});
|
|
|
|
it("resolves custom section types for section-type rules", () => {
|
|
const data = createResumeData([
|
|
{
|
|
id: "custom-summary-rich-text",
|
|
label: "Custom Summary Rich Text",
|
|
enabled: true,
|
|
target: { scope: "sectionType", sectionType: "summary" },
|
|
slots: { richParagraph: { color: "rgba(21, 93, 252, 1)" } },
|
|
},
|
|
]);
|
|
const customSection = {
|
|
...defaultResumeData.summary,
|
|
id: "custom-summary",
|
|
type: "summary" as const,
|
|
items: [],
|
|
};
|
|
const customData = { ...data, customSections: [customSection] };
|
|
|
|
expect(getSectionStyleRuleContext(customData, "custom-summary")).toEqual({
|
|
sectionId: "custom-summary",
|
|
sectionType: "summary",
|
|
});
|
|
expect(
|
|
resolveStyleRuleSlot(customData, {
|
|
sectionId: "custom-summary",
|
|
sectionType: "summary",
|
|
slot: "richParagraph",
|
|
}),
|
|
).toEqual({ color: "#155dfc" });
|
|
});
|
|
|
|
it("clamps unsafe spacing values before returning React PDF styles", () => {
|
|
const data = createResumeData([
|
|
{
|
|
id: "spacing",
|
|
label: "Spacing",
|
|
enabled: true,
|
|
target: { scope: "global" },
|
|
slots: { item: { padding: 1000, marginTop: -1000, rowGap: -12, borderWidth: -5 } },
|
|
},
|
|
]);
|
|
|
|
expect(
|
|
resolveStyleRuleSlot(data, {
|
|
sectionId: "skills",
|
|
sectionType: "skills",
|
|
slot: "item",
|
|
}),
|
|
).toEqual({ padding: 72, marginTop: -72, rowGap: -12, borderWidth: 0 });
|
|
});
|
|
|
|
it("resolves visible text, opacity, and border style properties", () => {
|
|
const data = createResumeData([
|
|
{
|
|
id: "rich-link-style",
|
|
label: "Rich Link Style",
|
|
enabled: true,
|
|
target: { scope: "global" },
|
|
slots: {
|
|
richLink: {
|
|
color: "rgba(21, 93, 252, 1)",
|
|
textDecoration: "underline",
|
|
textDecorationColor: "rgba(220, 38, 38, 1)",
|
|
textDecorationStyle: "dashed",
|
|
fontStyle: "italic",
|
|
lineHeight: 9,
|
|
letterSpacing: -100,
|
|
textAlign: "right",
|
|
textTransform: "uppercase",
|
|
opacity: 2,
|
|
borderStyle: "dotted",
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
|
|
expect(
|
|
resolveStyleRuleSlot(data, {
|
|
sectionId: "experience",
|
|
sectionType: "experience",
|
|
slot: "richLink",
|
|
}),
|
|
).toEqual({
|
|
color: "#155dfc",
|
|
textDecoration: "underline",
|
|
textDecorationColor: "#dc2626",
|
|
textDecorationStyle: "dashed",
|
|
fontStyle: "italic",
|
|
lineHeight: 4,
|
|
letterSpacing: -16,
|
|
textAlign: "right",
|
|
textTransform: "uppercase",
|
|
opacity: 1,
|
|
borderStyle: "dotted",
|
|
});
|
|
});
|
|
});
|