Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

33 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3import { archivedAssetKey, serveArchivedAsset } from "./asset-archive.ts";
4
5test("archive keys cannot read releases, source maps or private objects", () => {
6 assert.equal(archivedAssetKey("/assets/app-old12345.css"), "web-assets/assets/app-old12345.css");
7 for (const path of ["/downloads/runner", "/assets/../secret.js", "/assets/a.js.map", "/assets/%2e%2e/secret.js", "/assets/nested/a.js"]) assert.equal(archivedAssetKey(path), null);
8});
9
10test("a stylesheet removed from the new build stays available with its MIME type", async () => {
11 const bucket = { get: async (key: string) => {
12 assert.equal(key, "web-assets/assets/app-old12345.css");
13 return { body: "body{color:red}", size: 15, httpEtag: '"old"', writeHttpMetadata: (headers: Headers) => headers.set("content-type", "text/css") };
14 } } as unknown as R2Bucket;
15 const url = "https://g1t.sh/assets/app-old12345.css";
16 const response = await serveArchivedAsset(new Request(url), bucket);
17 assert.equal(response.status, 200);
18 assert.equal(response.headers.get("content-type"), "text/css");
19 assert.match(response.headers.get("cache-control")!, /immutable/);
20 assert.equal(await response.text(), "body{color:red}");
21 assert.equal(await (await serveArchivedAsset(new Request(url, { method: "HEAD" }), bucket)).text(), "");
22 assert.equal((await serveArchivedAsset(new Request(url, { headers: { "if-none-match": '"old"' } }), bucket)).status, 304);
23});
24
25test("missing or unavailable assets never become HTML or cacheable errors", async () => {
26 const url = "https://g1t.sh/assets/missing-12345678.js";
27 const missing = await serveArchivedAsset(new Request(url), { get: async () => null } as unknown as R2Bucket);
28 assert.equal(missing.status, 404);
29 assert.equal(missing.headers.get("cache-control"), "no-store");
30 const down = await serveArchivedAsset(new Request(url), undefined);
31 assert.equal(down.status, 503);
32 assert.equal(down.headers.get("cache-control"), "no-store");
33});