import { describe, expect, it } from "vitest";
import { createDavFixture, davRequest } from "@tests/worker/helpers/dav";
import { fetchWorker } from "@tests/worker/helpers/http";
import { withEnvBinding } from "@tests/worker/helpers/env";
import { name } from "./files-helpers";
describe("WebDAV file limits", () => {
it("rejects over-limit XML request bodies", async () => {
const fixture = await createDavFixture();
const body = `${"x".repeat(
1_049_000,
)}`;
const response = await fetchWorker(
davRequest(fixture, "/files/", {
method: "PROPFIND",
headers: { depth: "0", "content-type": "application/xml" },
body,
}),
);
expect(response.status).toBe(400);
await expect(response.text()).resolves.toContain("XML body exceeds");
});
it("bounds Depth infinity PROPFIND by the configured maximum nodes", async () => {
const fixture = await createDavFixture();
const directory = name("depth-bound");
expect(await fetchWorker(davRequest(fixture, `/files/${directory}/`, { method: "MKCOL" }))).toMatchObject({
status: 201,
});
expect(
await fetchWorker(davRequest(fixture, `/files/${directory}/a.txt`, { method: "PUT", body: "a" })),
).toHaveProperty("status", 201);
expect(
await fetchWorker(davRequest(fixture, `/files/${directory}/b.txt`, { method: "PUT", body: "b" })),
).toHaveProperty("status", 201);
await withEnvBinding("MAX_DAV_DEPTH_INFINITY_NODES", "2", async () => {
const response = await fetchWorker(
davRequest(fixture, "/files/", {
method: "PROPFIND",
headers: { depth: "infinity", "content-type": "application/xml" },
body: ``,
}),
);
expect(response.status).toBe(403);
await expect(response.text()).resolves.toContain("configured maximum");
});
});
it("fails recursive DELETE, COPY, and MOVE before mutation when the subtree exceeds the configured node limit", async () => {
const fixture = await createDavFixture();
const directory = name("recursive-bound");
expect(await fetchWorker(davRequest(fixture, `/files/${directory}/`, { method: "MKCOL" }))).toHaveProperty(
"status",
201,
);
expect(
await fetchWorker(davRequest(fixture, `/files/${directory}/a.txt`, { method: "PUT", body: "a" })),
).toHaveProperty("status", 201);
expect(
await fetchWorker(davRequest(fixture, `/files/${directory}/b.txt`, { method: "PUT", body: "b" })),
).toHaveProperty("status", 201);
await withEnvBinding("MAX_DAV_DEPTH_INFINITY_NODES", "2", async () => {
const deleted = await fetchWorker(davRequest(fixture, `/files/${directory}/`, { method: "DELETE" }));
expect(deleted.status).toBe(403);
expect(await fetchWorker(davRequest(fixture, `/files/${directory}/a.txt`))).toHaveProperty("status", 200);
const copied = await fetchWorker(
davRequest(fixture, `/files/${directory}/`, {
method: "COPY",
headers: { destination: `https://${fixture.hostLabel}.dav.example.com/files/${directory}-copy/` },
}),
);
expect(copied.status).toBe(403);
expect(await fetchWorker(davRequest(fixture, `/files/${directory}-copy/a.txt`))).toHaveProperty("status", 404);
const moved = await fetchWorker(
davRequest(fixture, `/files/${directory}/`, {
method: "MOVE",
headers: { destination: `https://${fixture.hostLabel}.dav.example.com/files/${directory}-moved/` },
}),
);
expect(moved.status).toBe(403);
expect(await fetchWorker(davRequest(fixture, `/files/${directory}/a.txt`))).toHaveProperty("status", 200);
expect(await fetchWorker(davRequest(fixture, `/files/${directory}-moved/a.txt`))).toHaveProperty("status", 404);
});
});
});