// ABOUTME: Tests for the database setup script that creates PocketBase collections. // ABOUTME: Verifies collection definitions and setup logic without hitting real PocketBase. import { describe, expect, it, vi } from "vitest"; import { DAILY_LOGS_COLLECTION, getExistingCollectionNames, getMissingCollections, PERIOD_LOGS_COLLECTION, } from "./setup-db"; describe("PERIOD_LOGS_COLLECTION", () => { it("has correct name", () => { expect(PERIOD_LOGS_COLLECTION.name).toBe("period_logs"); }); it("has required fields", () => { const fieldNames = PERIOD_LOGS_COLLECTION.fields.map((f) => f.name); expect(fieldNames).toContain("user"); expect(fieldNames).toContain("startDate"); expect(fieldNames).toContain("predictedDate"); }); it("has user field as relation to users", () => { const userField = PERIOD_LOGS_COLLECTION.fields.find( (f) => f.name === "user", ); expect(userField?.type).toBe("relation"); expect(userField?.collectionId).toBe("users"); expect(userField?.maxSelect).toBe(1); expect(userField?.cascadeDelete).toBe(true); }); it("has startDate as required date", () => { const startDateField = PERIOD_LOGS_COLLECTION.fields.find( (f) => f.name === "startDate", ); expect(startDateField?.type).toBe("date"); expect(startDateField?.required).toBe(true); }); it("has predictedDate as optional date", () => { const predictedDateField = PERIOD_LOGS_COLLECTION.fields.find( (f) => f.name === "predictedDate", ); expect(predictedDateField?.type).toBe("date"); expect(predictedDateField?.required).toBe(false); }); }); describe("DAILY_LOGS_COLLECTION", () => { it("has correct name", () => { expect(DAILY_LOGS_COLLECTION.name).toBe("dailyLogs"); }); it("has all required fields", () => { const fieldNames = DAILY_LOGS_COLLECTION.fields.map((f) => f.name); // Core fields expect(fieldNames).toContain("user"); expect(fieldNames).toContain("date"); expect(fieldNames).toContain("cycleDay"); expect(fieldNames).toContain("phase"); // Garmin biometric fields expect(fieldNames).toContain("bodyBatteryCurrent"); expect(fieldNames).toContain("bodyBatteryYesterdayLow"); expect(fieldNames).toContain("hrvStatus"); expect(fieldNames).toContain("weekIntensityMinutes"); // Decision fields expect(fieldNames).toContain("phaseLimit"); expect(fieldNames).toContain("remainingMinutes"); expect(fieldNames).toContain("trainingDecision"); expect(fieldNames).toContain("decisionReason"); expect(fieldNames).toContain("notificationSentAt"); }); it("has user field as relation to users", () => { const userField = DAILY_LOGS_COLLECTION.fields.find( (f) => f.name === "user", ); expect(userField?.type).toBe("relation"); expect(userField?.collectionId).toBe("users"); expect(userField?.maxSelect).toBe(1); expect(userField?.cascadeDelete).toBe(true); }); it("has trainingDecision as required text", () => { const field = DAILY_LOGS_COLLECTION.fields.find( (f) => f.name === "trainingDecision", ); expect(field?.type).toBe("text"); expect(field?.required).toBe(true); }); }); describe("getExistingCollectionNames", () => { it("extracts collection names from PocketBase response", async () => { const mockPb = { collections: { getFullList: vi .fn() .mockResolvedValue([ { name: "users" }, { name: "period_logs" }, { name: "_superusers" }, ]), }, }; // biome-ignore lint/suspicious/noExplicitAny: test mock const names = await getExistingCollectionNames(mockPb as any); expect(names).toEqual(["users", "period_logs", "_superusers"]); }); it("returns empty array when no collections exist", async () => { const mockPb = { collections: { getFullList: vi.fn().mockResolvedValue([]), }, }; // biome-ignore lint/suspicious/noExplicitAny: test mock const names = await getExistingCollectionNames(mockPb as any); expect(names).toEqual([]); }); }); describe("getMissingCollections", () => { it("returns both collections when none exist", () => { const existing = ["users"]; const missing = getMissingCollections(existing); expect(missing).toHaveLength(2); expect(missing.map((c) => c.name)).toContain("period_logs"); expect(missing.map((c) => c.name)).toContain("dailyLogs"); }); it("returns only dailyLogs when period_logs exists", () => { const existing = ["users", "period_logs"]; const missing = getMissingCollections(existing); expect(missing).toHaveLength(1); expect(missing[0].name).toBe("dailyLogs"); }); it("returns only period_logs when dailyLogs exists", () => { const existing = ["users", "dailyLogs"]; const missing = getMissingCollections(existing); expect(missing).toHaveLength(1); expect(missing[0].name).toBe("period_logs"); }); it("returns empty array when all collections exist", () => { const existing = ["users", "period_logs", "dailyLogs"]; const missing = getMissingCollections(existing); expect(missing).toHaveLength(0); }); });