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.

36 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"])
8 assert.equal(archivedAssetKey(path), null);
9});
10
11test("a stylesheet removed from the new build stays available with its MIME type", async () => {
12 const bucket = {
13 get: async (key: string) => {
14 assert.equal(key, "web-assets/assets/app-old12345.css");
15 return { body: "body{color:red}", size: 15, httpEtag: '"old"', writeHttpMetadata: (headers: Headers) => headers.set("content-type", "text/css") };
16 },
17 } as unknown as R2Bucket;
18 const url = "https://g1t.sh/assets/app-old12345.css";
19 const response = await serveArchivedAsset(new Request(url), bucket);
20 assert.equal(response.status, 200);
21 assert.equal(response.headers.get("content-type"), "text/css");
22 assert.match(response.headers.get("cache-control")!, /immutable/);
23 assert.equal(await response.text(), "body{color:red}");
24 assert.equal(await (await serveArchivedAsset(new Request(url, { method: "HEAD" }), bucket)).text(), "");
25 assert.equal((await serveArchivedAsset(new Request(url, { headers: { "if-none-match": '"old"' } }), bucket)).status, 304);
26});
27
28test("missing or unavailable assets never become HTML or cacheable errors", async () => {
29 const url = "https://g1t.sh/assets/missing-12345678.js";
30 const missing = await serveArchivedAsset(new Request(url), { get: async () => null } as unknown as R2Bucket);
31 assert.equal(missing.status, 404);
32 assert.equal(missing.headers.get("cache-control"), "no-store");
33 const down = await serveArchivedAsset(new Request(url), undefined);
34 assert.equal(down.status, 503);
35 assert.equal(down.headers.get("cache-control"), "no-store");
36});