Add folder game, file browser UI, and automated tests.
Introduces a localStorage-backed messy-desktop challenge with sub-steps, drag-and-drop and Places/Back navigation, IBM Plex Mono, and a /api/health endpoint. Adds Vitest coverage for the API and level logic plus Playwright smoke tests. Made-with: Cursor
This commit is contained in:
11
tests/api/health-route.test.ts
Normal file
11
tests/api/health-route.test.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { GET } from "~/app/api/health/route";
|
||||
|
||||
describe("GET /api/health", () => {
|
||||
it("returns 200 and status ok", async () => {
|
||||
const res = await GET();
|
||||
expect(res.status).toBe(200);
|
||||
await expect(res.json()).resolves.toEqual({ status: "ok" });
|
||||
});
|
||||
});
|
||||
21
tests/api/post-hello.test.ts
Normal file
21
tests/api/post-hello.test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("~/server/auth", () => ({
|
||||
auth: vi.fn(async () => null),
|
||||
}));
|
||||
|
||||
vi.mock("~/server/db", () => ({
|
||||
db: {},
|
||||
}));
|
||||
|
||||
import { createCaller } from "~/server/api/root";
|
||||
import { createTRPCContext } from "~/server/api/trpc";
|
||||
|
||||
describe("tRPC post.hello", () => {
|
||||
it("returns a greeting for the given text", async () => {
|
||||
const ctx = await createTRPCContext({ headers: new Headers() });
|
||||
const caller = createCaller(ctx);
|
||||
const out = await caller.post.hello({ text: "Tester" });
|
||||
expect(out.greeting).toBe("Hello Tester");
|
||||
});
|
||||
});
|
||||
52
tests/unit/levels.test.ts
Normal file
52
tests/unit/levels.test.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
buildInitialFs,
|
||||
isFsLevelComplete,
|
||||
isQuizComplete,
|
||||
isSubComplete,
|
||||
QUIZ_CORRECT_ID,
|
||||
} from "~/lib/folder-game/levels";
|
||||
|
||||
describe("isFsLevelComplete", () => {
|
||||
it("level 0 completes when Games and Documents were opened", () => {
|
||||
const fs = buildInitialFs(0);
|
||||
expect(isFsLevelComplete(0, fs)).toBe(false);
|
||||
expect(
|
||||
isFsLevelComplete(0, {
|
||||
...fs,
|
||||
visitedFolderIds: ["fld-games", "fld-docs"],
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("level 1 completes when files are sorted", () => {
|
||||
const fs = buildInitialFs(1);
|
||||
const nodes = fs.nodes.map((n) => {
|
||||
if (n.id === "file-cat") return { ...n, parentId: "fld-pics" };
|
||||
if (n.id === "file-hw") return { ...n, parentId: "fld-school" };
|
||||
return n;
|
||||
});
|
||||
expect(isFsLevelComplete(1, { ...fs, nodes })).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isSubComplete", () => {
|
||||
it("level 0 sub 0 requires Games", () => {
|
||||
const fs = buildInitialFs(0);
|
||||
expect(isSubComplete(0, 0, fs)).toBe(false);
|
||||
expect(
|
||||
isSubComplete(0, 0, {
|
||||
...fs,
|
||||
visitedFolderIds: ["fld-games"],
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isQuizComplete", () => {
|
||||
it("accepts Documents choice", () => {
|
||||
expect(isQuizComplete(QUIZ_CORRECT_ID)).toBe(true);
|
||||
expect(isQuizComplete("opt-dl")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user