Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209import { afterEach, describe, expect, it, vi } from "vitest";import { spindleUrl, toPipelineSummary } from "#lib/api/spindle.ts";import type * as CiDefs from "#lib/api/lexicons/types/org/tangled/ci/defs.ts";
describe("spindleUrl", () => { afterEach(() => vi.unstubAllEnvs());
it("refuses hosts that name this machine or its network outside dev", () => { vi.stubEnv("DEV", false); for (const host of [ "localhost:6555", "127.0.0.1", "169.254.169.254", "[::1]", "2130706433" ]) { expect(() => spindleUrl(host), host).toThrow(); } });
it("gives bare hosts https and localhost plain http", () => { expect(spindleUrl("spindle.tangled.org")).toBe("https://spindle.tangled.org"); expect(spindleUrl("localhost:6555")).toBe("http://localhost:6555"); });
it("keeps an explicit scheme and drops the trailing slash", () => { expect(spindleUrl("http://spindle.test/")).toBe("http://spindle.test"); });});
const workflow = (over: Partial<CiDefs.WorkflowRun> = {}): CiDefs.WorkflowRun => ({ id: "build", name: "build", status: "success", ...over }) as CiDefs.WorkflowRun;
// event.push and pullRequest are still empty in the lexicons, so triggers are looseconst pipeline = (over: Record<string, unknown>): CiDefs.Pipeline => ({ id: "3lz", commit: "9f2c1ab4d8e7350f6b1c2d9e4a5b6c7d8e9f0a1b", trigger: { $type: "org.tangled.ci.trigger.manual", repo: "did:plc:thisrepo", commit: "9f2c1ab4d8e7350f6b1c2d9e4a5b6c7d8e9f0a1b" }, workflows: [workflow()], ...over }) as unknown as CiDefs.Pipeline;
describe("toPipelineSummary", () => { it("strips the ref prefix off a push trigger", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.push", ref: "refs/heads/master", newSha: "a".repeat(40), oldSha: "b".repeat(40) } }) ); expect(summary.trigger).toEqual({ kind: "push", targetRef: "master" }); });
it("reads a pull request's target and source branches", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.pullRequest", targetBranch: "master", sourceBranch: "fix-timeout", sourceSha: "c".repeat(40) } }) ); expect(summary.trigger).toEqual({ kind: "pull_request", targetRef: "master", sourceLabel: "fix-timeout" }); });
it("links a pull request run to its pull", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.pullRequest", targetBranch: "main", pull: "at://did:plc:thisrepo/org.tangled.track.ticket/3mpull" } }), "did:plc:thisrepo" ); expect(summary.trigger).toEqual({ kind: "pull_request", targetRef: "main", sourceLabel: "", pullPath: "/did:plc:thisrepo/pulls/3mpull" }); });
it("doesn't link a pull that lives in another repo", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.pullRequest", targetBranch: "main", pull: "at://did:plc:someoneelse/org.tangled.track.ticket/3mpull" } }), "did:plc:thisrepo" ); expect(summary.trigger).not.toHaveProperty("pullPath"); });
it("keeps a fork's repo did so the page can upgrade the label", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.pullRequest", targetBranch: "master", sourceBranch: "fix-timeout", sourceSha: "c".repeat(40), sourceRepo: "did:plc:forkowner" } }), "did:plc:thisrepo" ); expect(summary.trigger).toEqual({ kind: "pull_request", targetRef: "master", sourceLabel: "fix-timeout", sourceRepo: "did:plc:forkowner" }); });
it("drops the did when the pull came from the same repo", () => { const summary = toPipelineSummary( pipeline({ trigger: { $type: "org.tangled.event.pullRequest", targetBranch: "master", sourceBranch: "fix-timeout", sourceSha: "c".repeat(40), sourceRepo: "did:plc:thisrepo" } }), "did:plc:thisrepo" ); expect(summary.trigger).toEqual({ kind: "pull_request", targetRef: "master", sourceLabel: "fix-timeout" }); });
it("times a workflow from its own start and finish stamps", () => { const summary = toPipelineSummary( pipeline({ workflows: [ workflow({ startedAt: "2026-08-04T09:00:00.000Z", finishedAt: "2026-08-04T09:01:12.000Z" }), workflow({ name: "test", status: "running", startedAt: "2026-08-04T09:00:00.000Z" }) ] }) ); expect(summary.workflows.map((w) => w.duration)).toEqual([72_000, 0]); });});
describe("createSpindleClient", () => { const load = async () => { vi.resetModules(); vi.doMock("$app/env", () => ({ browser: false, dev: false })); return import("#lib/api/spindle.ts"); };
it("never sends a request to a spindle in the private network", async () => { const { createSpindleClient, queryPipelines } = await load(); const fetch = vi.fn(async () => Response.json({ pipelines: [] })); for (const spindle of ["http://169.254.169.254", "http://10.0.0.5:9000", "localhost:6555"]) await expect( queryPipelines(createSpindleClient(spindle, fetch), { repo: "did:plc:alice" }) ).rejects.toThrow(); expect(fetch).not.toHaveBeenCalled(); });
it("reaches a public spindle without following redirects", async () => { const { createSpindleClient, queryPipelines } = await load(); const fetch = vi.fn(async () => Response.json({ pipelines: [] })); await queryPipelines(createSpindleClient("did:web:spindle.example.com", fetch), { repo: "did:plc:alice" }); expect(fetch).toHaveBeenCalledTimes(1); const [url, init] = fetch.mock.calls[0] as unknown as [URL, RequestInit]; expect(String(url)).toMatch(/^https:\/\/spindle\.example\.com\/xrpc\//); expect(init).toMatchObject({ redirect: "error" }); });});