From af8a14ab556c39b56e8aa6270f4258c0d0fca637 Mon Sep 17 00:00:00 2001 From: Anirudh Oppiliappan Date: Wed, 26 Aug 2026 14:09:23 +0300 Subject: [PATCH] web/lib/components/notifications: fix notif links Signed-off-by: Anirudh Oppiliappan --- .../notifications/notification.test.ts | 43 +++++++++++++++++++ .../components/notifications/notification.ts | 3 ++ 2 files changed, 46 insertions(+) create mode 100644 web/src/lib/components/notifications/notification.test.ts diff --git a/web/src/lib/components/notifications/notification.test.ts b/web/src/lib/components/notifications/notification.test.ts new file mode 100644 index 00000000..0375c984 --- /dev/null +++ b/web/src/lib/components/notifications/notification.test.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from "vitest"; +import { notificationHref } from "./notification"; +import type { NotificationSummary } from "./types"; + +const summary = (overrides: Partial = {}): NotificationSummary => ({ + uri: "at://did:plc:owner/sh.tangled.repo.issue/abc", + type: "issue_created", + read: false, + createdAt: "2026-01-01T00:00:00.000Z", + actor: { did: "did:plc:owner", handle: "alice.test" }, + repo: { ownerHandle: "alice.test", name: "core" }, + subject: { + kind: "issue", + uri: "at://did:plc:owner/sh.tangled.repo.issue/abc", + number: "abc", + title: "a bug" + }, + ...overrides +}); + +describe("notificationHref", () => { + it("links a named repo issue to its owner/repo path", () => { + expect(notificationHref(summary())).toBe( + "/alice.test/core/issues/at://did:plc:owner/sh.tangled.repo.issue/abc" + ); + }); + + it("links a repo-only notification to the owner/repo path", () => { + expect(notificationHref(summary({ subject: undefined }))).toBe("/alice.test/core"); + }); + + it("links a did-addressed repo by its did, without an owner/name guess", () => { + expect( + notificationHref( + summary({ repo: { ownerHandle: "alice.test", name: "did:plc:abc123" } }) + ) + ).toBe("/did:plc:abc123"); + }); + + it("falls back to the actor's page when there is no repo", () => { + expect(notificationHref(summary({ repo: undefined }))).toBe("/alice.test"); + }); +}); diff --git a/web/src/lib/components/notifications/notification.ts b/web/src/lib/components/notifications/notification.ts index 811eff10..95a4d6cc 100644 --- a/web/src/lib/components/notifications/notification.ts +++ b/web/src/lib/components/notifications/notification.ts @@ -124,6 +124,9 @@ export const notificationHref = (notification: NotificationSummary): string => { if (notification.type === "followed") return `/${notification.actor.handle}`; const repo = notification.repo; if (!repo) return `/${notification.actor.handle}`; + // did-addressed repos have no name to route on; the did is their address, and + // issues/pulls under them can't be addressed either + if (repo.name.startsWith("did:")) return `/${repo.name}`; const base = `/${repo.ownerHandle}/${repo.name}`; const subject = notification.subject; if (!subject) return base; -- 2.51.2