mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-18 19:10:45 +08:00
Open rad: links in the app
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import type { Config } from "@bindings/config/Config";
|
||||
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import {
|
||||
createLinkQueue,
|
||||
deepLinkTarget,
|
||||
parseDeepLink,
|
||||
} from "@app/lib/deepLink";
|
||||
|
||||
const repo = "z3gqcJUoA1n9HaHKufZs5FCSGazv5";
|
||||
const rid = `rad:${repo}`;
|
||||
const oid = "5e4683023476778201ab25c87e1343fbfbe67c89";
|
||||
const nid = "z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi";
|
||||
const config = {
|
||||
publicExplorer: "https://radicle.network/nodes/$host/$rid$path",
|
||||
preferredSeeds: [],
|
||||
} as unknown as Config;
|
||||
const explorer = `https://radicle.network/nodes/rosa.radicle.network/${rid}`;
|
||||
|
||||
function target(link: string, local = true) {
|
||||
return deepLinkTarget(parseDeepLink(link)!, local, config);
|
||||
}
|
||||
|
||||
describe("parseDeepLink", () => {
|
||||
test.each([rid, `rad:///${repo}`, ` ${rid}\n`])("accepts %j", link => {
|
||||
expect(parseDeepLink(link)).toEqual({ type: "uri", uri: { repo } });
|
||||
});
|
||||
|
||||
test.each([
|
||||
`did:key:${nid}`,
|
||||
"https://radicle.network",
|
||||
`web+${rid}`,
|
||||
"rad:bogus",
|
||||
])("rejects %j", link => {
|
||||
expect(parseDeepLink(link)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("deepLinkTarget", () => {
|
||||
test.each([
|
||||
[rid, { resource: "repo.home", rid }],
|
||||
[
|
||||
`${rid}/cob/xyz.radicle.patch/${oid}`,
|
||||
{
|
||||
resource: "repo.patch",
|
||||
rid,
|
||||
patch: oid,
|
||||
status: undefined,
|
||||
reviewId: undefined,
|
||||
},
|
||||
],
|
||||
[`${rid}/commit/${oid}`, { resource: "repo.commit", rid, commit: oid }],
|
||||
[
|
||||
`${rid}/commit/main?path=src/lib.rs#L10`,
|
||||
{ resource: "repo.home", rid, revision: "main", path: "src/lib.rs" },
|
||||
],
|
||||
])("opens %s in-app when the repo is here", (link, route) => {
|
||||
expect(target(link)).toEqual({ type: "route", route });
|
||||
});
|
||||
|
||||
test("opens the explorer when the repo is not here", () => {
|
||||
expect(target(`${rid}/cob/xyz.radicle.issue/${oid}`, false)).toEqual({
|
||||
type: "external",
|
||||
url: `${explorer}/issues/${oid}`,
|
||||
});
|
||||
});
|
||||
|
||||
test("opens the explorer for a page the app lacks", () => {
|
||||
expect(target(`${rid}/cob/dev.radicle.artifact/${oid}`)).toEqual({
|
||||
type: "external",
|
||||
url: `${explorer}/releases/${oid}`,
|
||||
});
|
||||
});
|
||||
|
||||
test("goes nowhere when neither has a page", () => {
|
||||
expect(target(`${rid}/tree/${oid}`)).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("createLinkQueue", () => {
|
||||
function setup(fail?: string) {
|
||||
const opened: string[] = [];
|
||||
let running = 0;
|
||||
let overlapped = false;
|
||||
const queue = createLinkQueue(async link => {
|
||||
running++;
|
||||
overlapped ||= running > 1;
|
||||
await new Promise(resolve => setTimeout(resolve, 1));
|
||||
running--;
|
||||
if (link === fail) throw new Error(link);
|
||||
opened.push(link);
|
||||
});
|
||||
return { queue, opened, overlapped: () => overlapped };
|
||||
}
|
||||
const settle = () => new Promise(resolve => setTimeout(resolve, 20));
|
||||
|
||||
test("holds links until the app is ready", async () => {
|
||||
const { queue, opened } = setup();
|
||||
queue.receive(["a"]);
|
||||
await settle();
|
||||
expect(opened).toEqual([]);
|
||||
|
||||
queue.ready();
|
||||
queue.receive(["b"]);
|
||||
await settle();
|
||||
expect(opened).toEqual(["a", "b"]);
|
||||
});
|
||||
|
||||
test("opens links one at a time, past a failing one", async () => {
|
||||
vi.spyOn(console, "error").mockImplementation(() => undefined);
|
||||
const { queue, opened, overlapped } = setup("b");
|
||||
queue.ready();
|
||||
queue.receive(["a", "b"]);
|
||||
queue.receive(["c"]);
|
||||
await settle();
|
||||
expect(opened).toEqual(["a", "c"]);
|
||||
expect(overlapped()).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user