Skip to content
69 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { FIRST_PARTY_EXTENSIONS, type ExtensionManifest, checkManifest, dataDisclosure, extensionFrameUrl, parseListing, versionOfTag } from "./marketplace.ts";
5import { isScope } from "./scopes.ts";
6
7const published: ExtensionManifest = {
8 ...FIRST_PARTY_EXTENSIONS[0]!,
9 id: "standup",
10 status: "available",
11 source: { repo: "flagon-io/standup", tag: "v1.2.0" },
12 version: "1.2.0",
13};
14
15test("g1t's own extensions are listed as coming, with manifests publishing would accept", () => {
16 const ids = new Set<string>();
17 for (const extension of FIRST_PARTY_EXTENSIONS) {
18 assert.ok(!ids.has(extension.id), extension.id);
19 ids.add(extension.id);
20 assert.equal(extension.status, "soon", `${extension.id} isn't published yet`);
21 assert.equal(extension.source, null);
22 assert.equal(extension.pricing, null);
23 assert.equal(extension.publisher.tier, "official");
24 const checked = checkManifest(extension, isScope);
25 assert.ok(checked.ok, `${extension.id}: ${checked.ok ? "" : checked.message}`);
26 }
27});
28
29test("publishing checks a manifest strictly", () => {
30 assert.ok(checkManifest(published, isScope).ok);
31 const refused = (changes: Partial<ExtensionManifest> | Record<string, unknown>, why: RegExp) => {
32 const checked = checkManifest({ ...published, ...changes }, isScope);
33 assert.equal(checked.ok, false, JSON.stringify(changes));
34 if (!checked.ok) assert.match(checked.message, why);
35 };
36 refused({ id: "Bad Id" }, /id/);
37 refused({ scopes: ["everything:admin"] }, /scope/);
38 refused({ source: null }, /source/);
39 refused({ domains: ["not a host"] }, /domains/);
40 refused({ runtime: "connected", domains: [] }, /declares the domains/);
41 refused({ publisher: { name: "anyone", tier: "community" } }, /Community extensions run on their publisher's servers/);
42 refused({ pricing: { monthly: 5 } }, /free/);
43 refused({ permissions: [] }, /permissions/);
44 refused({ ui: { entry: "index.html" } }, /ui.entry/);
45 // A community extension that runs on its own servers, declaring them, is fine.
46 assert.ok(checkManifest({ ...published, runtime: "connected", publisher: { name: "anyone", tier: "community" }, domains: ["api.example.com"] }, isScope).ok);
47});
48
49test("the install screen says where data goes", () => {
50 assert.equal(dataDisclosure({ domains: [] }), "Its data stays in g1t.");
51 assert.equal(dataDisclosure({ domains: ["api.acme.dev", "eu.acme.dev"] }), "Data leaves g1t to api.acme.dev, eu.acme.dev.");
52});
53
54test("an extension's page loads from the user-content origin, by version", () => {
55 assert.equal(extensionFrameUrl(published, "https://g1tusercontent.com/"), "https://g1tusercontent.com/x/standup/1.2.0/index.html");
56 assert.equal(extensionFrameUrl({ ...published, ui: null }, "https://g1tusercontent.com"), null);
57 assert.equal(extensionFrameUrl(FIRST_PARTY_EXTENSIONS[0]!, "https://g1tusercontent.com"), null, "nothing published, nothing to load");
58});
59
60test("a tag publishes a version", () => {
61 assert.equal(versionOfTag("v1.4.0"), "1.4.0");
62 assert.equal(versionOfTag("2.0.0-beta.1"), "2.0.0-beta.1");
63 assert.equal(versionOfTag("latest"), null);
64});
65
66test("listings are referenced by kind and id", () => {
67 assert.deepEqual(parseListing("extension:on-call"), { kind: "extension", id: "on-call" });
68 assert.equal(parseListing("app:on-call"), null);
69});