Initial addition of the Arcade study feature. Add connections as the first working game.
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m4s
All checks were successful
Automated Container Build / build-and-push (push) Successful in 1m4s
This commit is contained in:
parent
7b90409f2e
commit
611a585757
43 changed files with 5990 additions and 68 deletions
74
src/lib/arcade/connectionsImport.test.ts
Normal file
74
src/lib/arcade/connectionsImport.test.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { ArcadeImportError, parseConnectionsImport, parseConnectionsImportBatch } from "@/lib/arcade/connectionsImport";
|
||||
|
||||
function validPack() {
|
||||
return {
|
||||
schemaVersion: 1,
|
||||
type: "connections",
|
||||
name: "Medication Connections",
|
||||
description: "Four medication groups",
|
||||
settings: { groupCount: 4, itemsPerGroup: 4, allowedMistakes: 4 },
|
||||
content: Array.from({ length: 4 }, (_, groupIndex) => ({
|
||||
category: `Category ${groupIndex + 1}`,
|
||||
items: Array.from({ length: 4 }, (_, itemIndex) => `Item ${groupIndex + 1}-${itemIndex + 1}`),
|
||||
explanation: `Explanation ${groupIndex + 1}`,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
describe("Connections imports", () => {
|
||||
it("normalizes a valid board and creates stable ids", () => {
|
||||
const result = parseConnectionsImport(JSON.stringify(validPack()));
|
||||
expect(result.preview.itemCount).toBe(16);
|
||||
expect(result.preview.itemCount).toBe(16);
|
||||
expect(result.preview.normalized.content[0].id).toBe("group-1");
|
||||
expect(result.preview.normalized.content[0].items[0].id).toBe("group-1-item-1");
|
||||
});
|
||||
|
||||
it("rejects fences and surrounding prose", () => {
|
||||
expect(() => parseConnectionsImport(`\`\`\`json\n${JSON.stringify(validPack())}\n\`\`\``)).toThrow(ArcadeImportError);
|
||||
expect(() => parseConnectionsImport(`Here is the pack: ${JSON.stringify(validPack())}`)).toThrow(ArcadeImportError);
|
||||
});
|
||||
|
||||
it("rejects duplicate tiles case-insensitively", () => {
|
||||
const pack = validPack();
|
||||
pack.content[1].items[0] = " item 1-1 ";
|
||||
expect(() => parseConnectionsImport(JSON.stringify(pack))).toThrow("Every tile must be unique");
|
||||
});
|
||||
|
||||
it("rejects unknown keys", () => {
|
||||
const pack = { ...validPack(), extra: true };
|
||||
expect(() => parseConnectionsImport(JSON.stringify(pack))).toThrow("does not match schema version 1");
|
||||
});
|
||||
|
||||
it("reports long-tile warnings without changing the content", () => {
|
||||
const pack = validPack();
|
||||
pack.content[0].items[0] = "This intentionally long tile contains too many words";
|
||||
const result = parseConnectionsImport(JSON.stringify(pack));
|
||||
expect(result.report.warnings.length).toBeGreaterThan(0);
|
||||
expect(result.preview.normalized.content[0].items[0].text).toBe(pack.content[0].items[0]);
|
||||
});
|
||||
|
||||
it("does not treat a shared generic word as a similar category", () => {
|
||||
const pack = validPack();
|
||||
pack.content[0].category = "ACE Inhibitors";
|
||||
pack.content[1].category = "Proton Pump Inhibitors";
|
||||
const result = parseConnectionsImport(JSON.stringify(pack));
|
||||
expect(result.report.warnings).not.toContain(
|
||||
"Categories “ACE Inhibitors” and “Proton Pump Inhibitors” may be too similar."
|
||||
);
|
||||
});
|
||||
|
||||
it("previews multiple packs from one JSON array", () => {
|
||||
const first = validPack();
|
||||
const second = { ...validPack(), name: "Second board" };
|
||||
const result = parseConnectionsImportBatch(JSON.stringify([first, second]));
|
||||
expect(result.count).toBe(2);
|
||||
expect(result.packs.map((pack) => pack.name)).toEqual(["Medication Connections", "Second board"]);
|
||||
});
|
||||
|
||||
it("limits batch imports to ten packs", () => {
|
||||
const batch = Array.from({ length: 11 }, () => validPack());
|
||||
expect(() => parseConnectionsImportBatch(JSON.stringify(batch))).toThrow("between 1 and 10");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue