import { expect } from "vitest"; import { createDavFixture, davRequest } from "@tests/worker/helpers/dav"; import { fetchWorker } from "@tests/worker/helpers/http"; type DavFixture = Awaited>; export function uid(): string { return `${crypto.randomUUID()}@example.test`; } export function event(input: { uid: string; summary: string; start?: string; end?: string; rrule?: string; categories?: string[]; }): string { return [ "BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//dab//tests//EN", "BEGIN:VEVENT", `UID:${input.uid}`, "DTSTAMP:20260101T000000Z", `SUMMARY:${input.summary}`, `DTSTART:${input.start ?? "20260521T120000Z"}`, `DTEND:${input.end ?? "20260521T130000Z"}`, input.categories ? `CATEGORIES:${input.categories.join(",")}` : null, input.rrule ? `RRULE:${input.rrule}` : null, "END:VEVENT", "END:VCALENDAR", "", ] .filter((line): line is string => line !== null) .join("\r\n"); } export function propfindBody(props: string): string { return `${props}`; } export function mkcolCalendarBody(displayName: string, timezoneIcal?: string): string { return [ '', '', "", `${displayName}`, timezoneIcal ? `${timezoneIcal}` : null, "", ] .filter((line): line is string => line !== null) .join(""); } export function reportBody(name: string, body: string): string { return name === "sync-collection" ? `${body}` : `${body}`; } export function syncCollectionBody(prevToken: string, props = ""): string { return reportBody( "sync-collection", `${prevToken}1${props}`, ); } export async function syncToken(fixture: DavFixture): Promise { const response = await fetchWorker( davRequest(fixture, "/calendars/default/", { method: "REPORT", headers: { "content-type": "application/xml" }, body: syncCollectionBody(""), }), ); expect(response.status).toBe(207); const token = /([^<]+)<\/D:sync-token>/.exec(await response.text())?.[1]; if (!token) throw new Error("Missing sync-token in baseline sync-collection response"); return token; } export async function propfindSyncToken(fixture: DavFixture, href = "/calendars/default/") { const response = await fetchWorker( davRequest(fixture, href, { method: "PROPFIND", headers: { depth: "0", "content-type": "application/xml" }, body: propfindBody(""), }), ); expect(response.status).toBe(207); const token = /([^<]+)<\/D:sync-token>/.exec(await response.text())?.[1]; if (!token) throw new Error("Missing sync-token in PROPFIND response"); return token; }