a0b407e92d
CI / Architecture Guardrails (push) Successful in 19m4s
CI / Assistant Split Regression (push) Successful in 20m21s
CI / Lint (push) Successful in 21m52s
CI / Typecheck (push) Successful in 22m37s
CI / Unit Tests (push) Successful in 7m48s
CI / Build (push) Successful in 5m16s
CI / Fresh-Linux Docker Deploy (push) Failing after 12m42s
CI / E2E Tests (push) Failing after 35m15s
CI / Release Images (push) Has been skipped
Unit Tests flaked on QNAP: skillMatrixParser ExcelJS workbook builds exceeded the 5s default per-test timeout (runtime ~8.6s for the suite). Bumped to 30s. Docker Deploy smoke tests failed because `npm install` in the repo root tried to resolve sibling workspace:* deps (pnpm protocol, not npm-supported). Install @playwright/test into /tmp/pw-install instead and symlink the package dirs into apps/web/node_modules so the CJS require() in playwright.ci.config.ts resolves it by walking up from apps/web/.
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { matchRoleName, parseSkillMatrixWorkbook } from "./skillMatrixParser.js";
|
|
|
|
async function createWorkbookBuffer(
|
|
sheets: Array<{ name: string; rows: unknown[][] }>,
|
|
): Promise<ArrayBuffer> {
|
|
const ExcelJS = await import("exceljs");
|
|
const workbook = new ExcelJS.Workbook();
|
|
|
|
for (const sheet of sheets) {
|
|
const worksheet = workbook.addWorksheet(sheet.name);
|
|
for (const row of sheet.rows) {
|
|
worksheet.addRow(row);
|
|
}
|
|
}
|
|
|
|
const buffer = await workbook.xlsx.writeBuffer();
|
|
const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
|
}
|
|
|
|
describe("skill matrix parser", () => {
|
|
it("extracts employee info and merges skills by highest proficiency", async () => {
|
|
// ExcelJS dynamic import + workbook writeBuffer is slow on constrained CI runners.
|
|
const workbook = await createWorkbookBuffer([
|
|
{
|
|
name: "Employee Information",
|
|
rows: [
|
|
["item", "property"],
|
|
["Full Name", "Alex Artist"],
|
|
["Area of Expertise", "Compositing"],
|
|
["Years of Experience", "7.4"],
|
|
["Portfolio URL", "https://portfolio.example/alex"],
|
|
],
|
|
},
|
|
{
|
|
name: "Software Skills",
|
|
rows: [
|
|
["category", "item", "property", "main skillset"],
|
|
["Software", "Nuke", "2", "1"],
|
|
["Software", "Photoshop", "0", ""],
|
|
],
|
|
},
|
|
{
|
|
name: "Technical Skillset",
|
|
rows: [
|
|
["category", "item", "property", "main skillset"],
|
|
["Pipeline", "Nuke", "4", ""],
|
|
["Pipeline", "Python", "3", "2"],
|
|
],
|
|
},
|
|
]);
|
|
|
|
await expect(parseSkillMatrixWorkbook(workbook)).resolves.toEqual({
|
|
employeeInfo: {
|
|
displayName: "Alex Artist",
|
|
areaOfExpertise: "Compositing",
|
|
yearsOfExperience: 7,
|
|
portfolioUrl: "https://portfolio.example/alex",
|
|
},
|
|
skills: expect.arrayContaining([
|
|
{
|
|
skill: "Nuke",
|
|
category: "Pipeline",
|
|
proficiency: 5,
|
|
},
|
|
{
|
|
skill: "Python",
|
|
category: "Pipeline",
|
|
proficiency: 4,
|
|
isMainSkill: true,
|
|
},
|
|
]),
|
|
});
|
|
}, 30000);
|
|
|
|
it("rejects duplicate headers in skill sheets", async () => {
|
|
const workbook = await createWorkbookBuffer([
|
|
{
|
|
name: "Employee Information",
|
|
rows: [
|
|
["item", "property"],
|
|
["Full Name", "Alex Artist"],
|
|
],
|
|
},
|
|
{
|
|
name: "Software Skills",
|
|
rows: [
|
|
["item", "item", "property"],
|
|
["Nuke", "Duplicate", "2"],
|
|
],
|
|
},
|
|
{
|
|
name: "Technical Skillset",
|
|
rows: [["category", "item", "property"]],
|
|
},
|
|
]);
|
|
|
|
await expect(parseSkillMatrixWorkbook(workbook)).rejects.toThrow('duplicate header "item"');
|
|
}, 30000);
|
|
|
|
it("matches role names by exact and partial matches", () => {
|
|
expect(matchRoleName("Compositing", ["Producer", "Compositing"])).toBe("Compositing");
|
|
expect(matchRoleName("Senior Producer", ["Producer", "Lighting"])).toBe("Producer");
|
|
expect(matchRoleName("Rigging", ["Producer", "Lighting"])).toBeNull();
|
|
});
|
|
});
|