~james/core

core/web/src/lib/api/archive.test.ts -rw-r--r-- 4.2 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 15 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { describe, expect, it } from "vitest";
import {
	archiveUrl,
	defaultArchivePrefix,
	immutableArchiveUrl,
	parseArchiveRequest
} from "#lib/api/archive.ts";

// kit hands the route its rest param decoded
const parse = (target: string, userAgent = "") => {
	const url = new URL(`/${target}`, "https://tangled.test");
	return parseArchiveRequest(
		decodeURIComponent(url.pathname.slice(1)),
		url.searchParams,
		userAgent
	);
};

describe("parseArchiveRequest", () => {
	const windows = "Mozilla/5.0 (Windows NT 10.0; Win64; x64)";
	it.each([
		[
			"a short ref",
			"v1.0.0?format=tar.gz",
			"",
			{ ref: "v1.0.0", format: "tar.gz", prefix: "", guessed: false }
		],
		[
			"a full ref",
			"refs/tags/v1.0.0?prefix=did:plc:boltless",
			"",
			{ ref: "refs/tags/v1.0.0", format: "tar.gz", prefix: "did:plc:boltless", guessed: true }
		],
		[
			"an escaped ref with a format suffix",
			"refs%2Ftags%2Fv1.0.0.tar.gz",
			"",
			{ ref: "refs/tags/v1.0.0", format: "tar.gz", prefix: "", guessed: false }
		],
		[
			"the zip suffix",
			"refs/tags/v1.0.0.zip",
			"",
			{ ref: "refs/tags/v1.0.0", format: "zip", prefix: "", guessed: false }
		],
		[
			"a tag ending in a format suffix",
			"refs/tags/v1.0.0.zip.tar.gz",
			"",
			{ ref: "refs/tags/v1.0.0.zip", format: "tar.gz", prefix: "", guessed: false }
		],
		[
			"an unknown format query over a zip suffix",
			"v1.zip?format=tar.xz",
			"",
			{ ref: "v1", format: "zip", prefix: "", guessed: false }
		],
		[
			"a format query over the suffix",
			"v1.zip?format=tar.gz",
			"",
			{ ref: "v1", format: "tar.gz", prefix: "", guessed: false }
		],
		[
			"zip for a windows user agent",
			"main?format=tar.xz",
			windows,
			{ ref: "main", format: "zip", prefix: "", guessed: true }
		],
		[
			"a percent in the ref itself",
			"refs/tags/a%252Fb",
			"",
			{ ref: "refs/tags/a%2Fb", format: "tar.gz", prefix: "", guessed: true }
		],
		[
			"a prefix wrapped in slashes",
			"main?prefix=/kelp/./reef/",
			"",
			{ ref: "main", format: "tar.gz", prefix: "kelp/reef", guessed: true }
		]
	])("reads %s", (_, path, userAgent, want) => {
		expect(parse(path, userAgent)).toEqual(want);
	});

	it.each([
		["an empty ref", ""],
		["only a suffix", ".tar.gz"],
		["an escaped space", "refs/tags/a%20b"],
		["a ref git would read as an option", "--output=%2Ftmp%2Fevil"],
		["a range", "main..evil"],
		["a prefix escaping the root", "main?prefix=a/../../etc"],
		["a prefix with a backslash", "main?prefix=a%5Cb"],
		["a prefix over 255 bytes", `main?prefix=${"a".repeat(256)}`]
	])("refuses %s", (_, path) => {
		expect(parse(path)).toBeNull();
	});
});

describe("defaultArchivePrefix", () => {
	it.each([
		["squid", "main", "squid-main"],
		["squid", "refs/heads/feat/uni", "squid-feat-uni"],
		["squid", "refs/tags/v1.0.0", "squid-v1.0.0"],
		["squid", "refs/remotes/origin/main", "squid-origin-main"],
		["squid", "refs/notes/x", "squid-notes-x"]
	])("names %s at %s %s", (repo, ref, want) => {
		expect(defaultArchivePrefix(repo, ref)).toBe(want);
	});

	it("cuts a long stem at 255 bytes without splitting a character", () => {
		const prefix = defaultArchivePrefix("squid", "é".repeat(200));
		expect(new TextEncoder().encode(prefix).length).toBe(254);
		expect(prefix.endsWith("é")).toBe(true);
	});
});

describe("archive urls", () => {
	const served = {
		ref: "6f1d3a2b4c5d6e7f8091a2b3c4d5e6f708192a3b",
		format: "zip",
		prefix: "kelp&format=zip#uni"
	} as const;

	it("pins the immutable url to the commit with every parameter spelled out", () => {
		const url = immutableArchiveUrl("https://tangled.test", "did:plc:limpet", served);
		expect(url).toBe(
			"https://tangled.test/did:plc:limpet/archive/6f1d3a2b4c5d6e7f8091a2b3c4d5e6f708192a3b.zip?prefix=kelp%26format%3Dzip%23uni"
		);
		const parsed = new URL(url);
		const ref = decodeURIComponent(parsed.pathname.replace("/did:plc:limpet/archive/", ""));
		expect(parseArchiveRequest(ref, parsed.searchParams, "")).toEqual({
			...served,
			guessed: false
		});
	});

	it("asks bobbin for the same archive", () => {
		const url = new URL(
			archiveUrl("https://bobbin.test", { repo: "did:plc:limpet", ...served })
		);
		expect(url.pathname).toBe("/xrpc/org.tangled.temp.git.getArchive");
		expect(Object.fromEntries(url.searchParams)).toEqual({ repo: "did:plc:limpet", ...served });
	});
});