Jobber/shared/src/rxresume-schema.test.ts
Shaheer Sarfaraz b94f85b149
Reduce low risk duplication (#79)
* clean up helpers

* shared in it's own top level folder

* workspaces setup

* build fix

* disable workspaces?

* run ci

* rename job-flow to gradcracker

* optional dependencies

* formatting?

* more optional modules

* allow post install runs

* node bump

* remove post install

* add optionals

* add more

* formatting

* comments, but im unsure

* run typescript DIRECTLY

* better build

* camoufox simplification

* lint

* build process doesn't exist

* build fix

* lockfile

* type check everything, build only for client

* rename steps correctly

* import from package!

* fix formatting

* don't fetch twice

* fix concern
2026-02-02 21:30:14 +00:00

244 lines
6.6 KiB
TypeScript

import { createId } from "@paralleldrive/cuid2";
import { describe, expect, it } from "vitest";
import { idSchema, resumeDataSchema, skillSchema } from "./rxresume-schema";
describe("RxResume Schema Validation", () => {
describe("idSchema (CUID2)", () => {
it("should accept valid CUID2 IDs generated by the library", () => {
// Generate real CUID2 IDs using the official library
const validIds = [createId(), createId(), createId()];
validIds.forEach((id) => {
const result = idSchema.safeParse(id);
expect(result.success, `ID "${id}" should be valid`).toBe(true);
});
});
it('should reject invalid IDs like "skill-0"', () => {
const invalidIds = [
"skill-0", // contains hyphen
"skill-1", // contains hyphen
"skill-123", // contains hyphen
"item_1", // contains underscore
"ABC123", // uppercase letters
"", // empty
];
invalidIds.forEach((id) => {
const result = idSchema.safeParse(id);
expect(result.success, `ID "${id}" should be invalid`).toBe(false);
});
});
});
describe("skillSchema", () => {
it("should accept valid skill with CUID2 ID", () => {
const validSkill = {
id: createId(),
visible: true,
name: "JavaScript",
description: "",
level: 3,
keywords: ["ES6", "TypeScript"],
};
const result = skillSchema.safeParse(validSkill);
expect(result.success).toBe(true);
});
it("should reject skill with invalid ID format", () => {
const invalidSkill = {
id: "skill-0", // Invalid CUID2
visible: true,
name: "JavaScript",
description: "",
level: 3,
keywords: ["ES6"],
};
const result = skillSchema.safeParse(invalidSkill);
expect(result.success).toBe(false);
if (!result.success) {
expect(result.error.issues[0].path).toContain("id");
expect(result.error.issues[0].message).toContain("cuid2");
}
});
});
describe("resumeDataSchema", () => {
it("should reject resume with invalid skill IDs", () => {
const resumeWithInvalidIds = {
basics: {
name: "John Doe",
headline: "Developer",
email: "john@example.com",
phone: "",
location: "",
url: { label: "", href: "" },
customFields: [],
picture: {
url: "",
size: 64,
aspectRatio: 1,
borderRadius: 0,
effects: { hidden: false, border: false, grayscale: false },
},
},
sections: {
summary: {
id: "summary",
name: "Summary",
columns: 1,
separateLinks: true,
visible: true,
content: "",
},
skills: {
id: "skills",
name: "Skills",
columns: 1,
separateLinks: true,
visible: true,
items: [
{
id: "skill-0", // Invalid!
visible: true,
name: "JavaScript",
description: "",
level: 1,
keywords: [],
},
],
},
// Minimal required sections
awards: {
id: "awards",
name: "Awards",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
certifications: {
id: "certifications",
name: "Certifications",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
education: {
id: "education",
name: "Education",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
experience: {
id: "experience",
name: "Experience",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
volunteer: {
id: "volunteer",
name: "Volunteer",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
interests: {
id: "interests",
name: "Interests",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
languages: {
id: "languages",
name: "Languages",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
profiles: {
id: "profiles",
name: "Profiles",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
projects: {
id: "projects",
name: "Projects",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
publications: {
id: "publications",
name: "Publications",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
references: {
id: "references",
name: "References",
columns: 1,
separateLinks: true,
visible: true,
items: [],
},
custom: {},
},
metadata: {
template: "rhyhorn",
layout: [[["summary"], ["skills"]]],
css: { value: "", visible: false },
page: {
margin: 18,
format: "a4",
options: { breakLine: true, pageNumbers: true },
},
theme: { background: "#ffffff", text: "#000000", primary: "#dc2626" },
typography: {
font: {
family: "IBM Plex Serif",
subset: "latin",
variants: ["regular"],
size: 14,
},
lineHeight: 1.5,
hideIcons: false,
underlineLinks: true,
},
notes: "",
},
};
const result = resumeDataSchema.safeParse(resumeWithInvalidIds);
expect(result.success).toBe(false);
if (!result.success) {
// Should have error about the skill ID
const idError = result.error.issues.find(
(issue) =>
issue.path.join(".").includes("skills.items") &&
issue.path.includes("id"),
);
expect(idError).toBeDefined();
}
});
});
});