import { describe, expect, it } from "vitest"; import { parseIfHeader, positiveEtags, positiveLockTokens } from "@/worker/dav/if-header"; import { ifHeaderMatches } from "@/worker/dav/locks"; import type { FileLockRow } from "@/worker/db/file-dav-do/schema"; function activeLock(input: { token?: string; rootPath: string; depth?: "0" | "infinity" }): FileLockRow { return { token: input.token ?? "opaquelocktoken:abc", rootNodeId: "node-1", rootPath: input.rootPath, ownerXml: '', principalSubjectId: "subject-1", scope: "exclusive", depth: input.depth ?? "0", createdAtMs: 1, expiresAtMs: 2, }; } describe("WebDAV If header parser", () => { it("parses untagged lock tokens and entity tags", () => { const parsed = parseIfHeader('( ["etag-1"])'); expect(parsed.ok).toBe(true); if (!parsed.ok) return; expect(positiveLockTokens(parsed.header)).toEqual(["opaquelocktoken:abc"]); expect(positiveEtags(parsed.header)).toEqual(['"etag-1"']); }); it("parses tagged lists and Not conditions without treating prefixes as text hacks", () => { const parsed = parseIfHeader(" (Not ) ()"); expect(parsed.ok).toBe(true); if (!parsed.ok) return; expect(parsed.header.lists[0]?.resourceHref).toBe("/files/a.txt"); expect(parsed.header.lists[0]?.conditions[0]).toMatchObject({ not: true, kind: "lock-token" }); expect(positiveLockTokens(parsed.header)).toEqual(["opaquelocktoken:def"]); }); it("matches absolute tagged lock roots against descendant writes", () => { const parsed = parseIfHeader(" ()"); expect(parsed.ok).toBe(true); if (!parsed.ok) return; expect( ifHeaderMatches({ header: parsed.header, targetHref: "/files/locked/child.txt", targetEtag: null, locks: [activeLock({ rootPath: "/files/locked/", depth: "infinity" })], }), ).toBe(true); }); it("honors Not conditions for entity tags", () => { const parsed = parseIfHeader('(Not ["other-etag"])'); expect(parsed.ok).toBe(true); if (!parsed.ok) return; expect( ifHeaderMatches({ header: parsed.header, targetHref: "/files/a.txt", targetEtag: '"etag-1"', locks: [], }), ).toBe(true); }); });