From 0a3026085d47f701b8297f52a8e11610eb2d1e3a Mon Sep 17 00:00:00 2001 From: Mac Payton Date: Sat, 6 Dec 2025 11:52:52 -0600 Subject: [PATCH] updated tests --- test/api-endpoints/availability.test.ts | 39 +++++++++++++++++++++++-- test/api-endpoints/meetings.test.ts | 6 ++-- test/library-functions.test.ts | 9 +++++- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/test/api-endpoints/availability.test.ts b/test/api-endpoints/availability.test.ts index 8a164da..3949651 100644 --- a/test/api-endpoints/availability.test.ts +++ b/test/api-endpoints/availability.test.ts @@ -14,13 +14,18 @@ import type { APIContext } from "astro"; import { beforeEach, describe, expect, it, vi } from "vitest"; +import { hashPassword } from "#/src/lib/server_helpers.ts"; -vi.mock("drizzle-orm", () => { +// Mock `drizzle-orm`'s `eq` function +vi.mock("drizzle-orm", async (importOriginal) => { + const actual = await importOriginal(); return { + ...actual, eq: (left: unknown, right: unknown) => ({ left, right }), }; }); + vi.mock("nanoid", () => { return { nanoid: () => "fixed-nanoid", @@ -79,16 +84,21 @@ vi.mock("drizzle-orm/d1", async () => { // Import the mocked module statically (vi.mock is hoisted so this is our mock) import * as mockD1 from "drizzle-orm/d1"; +//import { hash } from "node:crypto"; function makeApiContext(opts: { params?: Record; jsonBody?: unknown; url?: string; + meetingIdForCookie?: string; + authCookieValue?: string; }) { const { params = {}, jsonBody = undefined, url = "https://example.test/", + meetingIdForCookie = params.meetingId ?? "test-meeting-id", + authCookieValue = "test-cookie", } = opts; const request = { @@ -96,6 +106,16 @@ function makeApiContext(opts: { url, } as unknown as Request; + const cookies = { + get: (name: string) => { + const expected = `auth-cookie-for-meeting-${meetingIdForCookie}`; + if (name === expected) { + return { value: authCookieValue }; + } + return undefined; + }, + } as any; + const context = { params, locals: { @@ -104,6 +124,7 @@ function makeApiContext(opts: { }, }, request, + cookies, } as unknown as APIContext; return context; @@ -122,13 +143,23 @@ describe("PUT /api/meetings/[meetingId]/availability/[memberId] (server handler) it("Creates availability for existing member & meeting -> returns 201 and availability body", async () => { // existing member row - const memberRow = { id: "aaaaaaaaaaaaaaaaaaaaa", defaultName: "Sam" }; + const memberRow = { + id: "aaaaaaaaaaaaaaaaaaaaa", + defaultName: "Sam", + hashedPassword: await hashPassword("test-hash" as any), + authCookie: "aaaaaaaaaaaaaaaaaaaaa" as any + }; // existing meeting without this member's availability const meeting = { name: "Weekly", availability: {}, // empty - members: [{ memberId: memberRow.id, name: memberRow.defaultName }], + members: [{ + memberId: memberRow.id, + name: memberRow.defaultName, + hashedPassword: memberRow.hashedPassword, + authCookie: memberRow.authCookie + }], availabilityBounds: { availableDayConstraints: { type: "daysOfWeek", days: ["monday"] }, timeRangeForEachDay: { @@ -165,6 +196,8 @@ describe("PUT /api/meetings/[meetingId]/availability/[memberId] (server handler) params: { meetingId: "m1", memberId: memberRow.id }, jsonBody: newAvailability, url: "https://example.test/api/meetings/m1/availability/aaaaaaaaaaaaaaaaaaaaa", + meetingIdForCookie: "m1", + authCookieValue: memberRow.authCookie, }); const { PUT } = await import( diff --git a/test/api-endpoints/meetings.test.ts b/test/api-endpoints/meetings.test.ts index 270123b..b3bbd25 100644 --- a/test/api-endpoints/meetings.test.ts +++ b/test/api-endpoints/meetings.test.ts @@ -14,9 +14,11 @@ import type { APIContext } from "astro"; import { beforeEach, describe, expect, it, vi } from "vitest"; -// Mock `drizzle-orm`'s `eq` to return a plain object we can inspect in the fake DB. -vi.mock("drizzle-orm", () => { +// Mock `drizzle-orm`'s `eq` function +vi.mock("drizzle-orm", async (importOriginal) => { + const actual = await importOriginal(); return { + ...actual, eq: (left: unknown, right: unknown) => ({ left, right }), }; }); diff --git a/test/library-functions.test.ts b/test/library-functions.test.ts index e8f4701..37eb725 100644 --- a/test/library-functions.test.ts +++ b/test/library-functions.test.ts @@ -16,6 +16,9 @@ import * as usersApi from "../src/lib/api/users"; * - Fallback to JSON parsing when content-type is wrong but body is JSON. * - Throws when content-type unsupported and JSON parse fails. */ + +vi.stubGlobal("window", { location: { origin: "http://localhost" } }); + describe("handleApiResponse", () => { it("returns undefined for 204 No Content", async () => { const res = new Response(null, { @@ -180,6 +183,7 @@ describe("meetings API client", () => { const sampleMeeting = { name: "Team Sync", availability: {}, + members: [], availabilityBounds: { availableDayConstraints: { type: "daysOfWeek", days: ["monday"] }, timeRangeForEachDay: { @@ -206,7 +210,10 @@ describe("meetings API client", () => { const meetingPartial = { name: "x" }; const fakeResponse = new Response(JSON.stringify({ id: "m1" }), { status: 201, - headers: { "content-type": "application/json" }, + headers: { + "content-type": "application/json", + Location: "/api/meeetings/m1", + }, }); globalThis.fetch = vi.fn(async (input: RequestInfo, init?: RequestInit) => {