Allow seeding a missing repo from a reference

Following a link to a repo we don't have only led to the explorer, but
the reason it's missing is usually that we haven't seeded it yet.
A deep link that can't be opened now says so instead of doing nothing.
This commit is contained in:
Rūdolfs Ošiņš
2026-10-06 11:16:14 +02:00
parent e010517b79
commit e793ed5f01
12 changed files with 367 additions and 95 deletions
+63 -1
View File
@@ -1,13 +1,18 @@
import type { Page } from "@playwright/test";
import type { RadiclePeer } from "@tests/support/peerManager.js";
import { createProject } from "@tests/support/collaboration.js";
import {
createCollaborators,
createProject,
} from "@tests/support/collaboration.js";
import {
expect,
reload,
test,
useBackend,
waitForCommand,
} from "@tests/support/fixtures.js";
import { createRepo } from "@tests/support/repo.js";
async function openIssue(page: Page, peer: RadiclePeer) {
const project = await createProject(peer);
@@ -236,3 +241,60 @@ test("every reference type renders and links where it should", async ({
await link(`${repo}/issues?status=all`).click();
await expect(page).toHaveURL(/\/issues\?status=all$/);
});
test("a repo that isn't here can be seeded from its chip", async ({
page,
peerManager,
}) => {
const { bob, eve } = await createCollaborators(peerManager);
const { rid: garden } = await createRepo(eve, { name: "garden" });
await bob.startHttpd();
await useBackend(page, bob);
await openIssue(page, bob);
await commentBox(page).fill(`[garden](${garden})`);
await comment(page);
await reload(page);
const chip = rendered(page).last().locator("a.mention.unresolved");
await expect(chip).toContainText("garden");
await chip.click({ button: "right" });
await waitForCommand(page, "seed", () =>
page.getByRole("menuitem", { name: "Seed repository" }).click(),
);
await expect(
page.getByRole("navigation").getByRole("link", { name: /garden/ }),
).toBeVisible({ timeout: 20_000 });
});
test("a link to a repo that isn't here can be seeded without an explorer page", async ({
page,
peerManager,
}) => {
const { bob, eve } = await createCollaborators(peerManager);
const { rid: garden } = await createRepo(eve, { name: "garden" });
await bob.startHttpd();
await useBackend(page, bob);
await openIssue(page, bob);
await commentBox(page).fill(
`[garden tree](${garden}/tree/${"f".repeat(40)})`,
);
await comment(page);
await reload(page);
await rendered(page)
.last()
.locator("a", { hasText: "garden tree" })
.click({ button: "right" });
await expect(page.getByRole("menuitem")).toHaveText([
"Copy rad: URI",
"Seed repository",
]);
await waitForCommand(page, "seed", () =>
page.getByRole("menuitem", { name: "Seed repository" }).click(),
);
await expect(
page.getByRole("navigation").getByRole("link", { name: /garden/ }),
).toBeVisible({ timeout: 20_000 });
});
+19 -3
View File
@@ -23,7 +23,14 @@ function target(link: string, local = true) {
}
describe("parseDeepLink", () => {
test.each([rid, `rad:///${repo}`, ` ${rid}\n`])("accepts %j", link => {
test.each([
rid,
`rad:///${repo}`,
` ${rid}\n`,
`rad:///${rid}`,
`rad://${rid}`,
`rad:${rid}`,
])("accepts %j", link => {
expect(parseDeepLink(link)).toEqual({ type: "uri", uri: { repo } });
});
@@ -59,13 +66,22 @@ describe("deepLinkTarget", () => {
expect(target(link)).toEqual({ type: "route", route });
});
test("opens the explorer when the repo is not here", () => {
test("offers to seed a repo that is not here", () => {
expect(target(`${rid}/cob/xyz.radicle.issue/${oid}`, false)).toEqual({
type: "external",
type: "missing",
rid,
url: `${explorer}/issues/${oid}`,
});
});
test("offers to seed a repo that is not here when nothing has a page", () => {
expect(target(`${rid}/tree/${oid}`, false)).toEqual({
type: "missing",
rid,
url: undefined,
});
});
test("opens the explorer for a page the app lacks", () => {
expect(target(`${rid}/cob/dev.radicle.artifact/${oid}`)).toEqual({
type: "external",