import { describe, expect, it } from "vitest"; import { appTabDestinationKey, appTabRoute, normalizeAppTabLocation, sameAppTabDestination } from "./app-tab-location"; describe("application tab destinations", () => { it("matches equivalent query ordering without dropping destination details", () => { expect(sameAppTabDestination("/projects/p/?view=v&objective=o", "/projects/p?objective=o&view=v")).toBe(true); }); it.each([ ["/pull-requests?pr=a", "/pull-requests?pr=b"], ["/pull-requests", "/pull-requests?pr=a"], ["/pull-requests?run=a", "/pull-requests"], ["/projects/p?issue=a", "/projects/p"], ["/projects/p?setup=numo", "/projects/p"], ["/all?view=a", "/all?view=b"], ["/projects/p?family=a", "/projects/p?objective=a"], ["/projects/p/pages/a#one", "/projects/p/pages/a#two"], ["/projects/p/pages/a", "/projects/p/pages/a#one"], ["/settings?section=profile", "/settings"], ["/home?view=a&view=b", "/home?view=a"], ["/login", "/login"], ])("keeps distinct or unsupported destinations separate: %s and %s", (left, right) => { expect(sameAppTabDestination(left, right)).toBe(false); }); it.each(["/login", "/signup", "/share/token", "/f/token", "/p/token", "/connect/github", "/projects/p/pages-print/a", "//example.com", "/\\example.com", "/home\n", "/projects/p/unknown", "/home/extra", "/projects/%2f%2fevil"])("rejects unsupported destination %s", (href) => { expect(normalizeAppTabLocation(href)).toBeNull(); }); it("keeps repeatable selections and removes one-use commands", () => { expect(normalizeAppTabLocation("/routines?routine=a&new=1&setup=git&compose=1&billing=success")).toBe("/routines?routine=a"); expect(normalizeAppTabLocation("/projects/p?view=b&family=parent&issue=child")).toBe("/projects/p?family=parent&view=b"); expect(normalizeAppTabLocation("/projects/p/pages/a?entry=b#heading")).toBe("/projects/p/pages/a?entry=b#heading"); expect(normalizeAppTabLocation("/settings?tab=security§ion=account-security#hint")).toBe("/settings?tab=security"); }); it("moves restored statistics tabs to the profile that now holds them", () => { expect(normalizeAppTabLocation("/statistics")).toBe("/settings"); expect(normalizeAppTabLocation("/statistics/")).toBe("/settings"); }); it("rejects the retired Numo routes (the FAB has no URL)", () => { expect(normalizeAppTabLocation("/agents?run=a")).toBeNull(); expect(normalizeAppTabLocation("/numo?conversation=a")).toBeNull(); }); it("canonicalizes ordering and resolves project sections", () => { expect(normalizeAppTabLocation("/all/?view=b&tab=a")).toBe("/all?tab=a&view=b"); expect(appTabRoute("/projects/p?view=b")).toEqual({ section: "tickets", projectId: "p", objectiveId: null, familyId: null, view: "b", pageId: null, prId: null, routineId: null, adminTab: null }); expect(appTabRoute("/projects/p/pages/a")).toEqual({ section: "pages", projectId: "p", objectiveId: null, familyId: null, view: null, pageId: "a", prId: null, routineId: null, adminTab: null }); }); it("exposes the objective param so tabs can name an objective's tickets", () => { expect(appTabRoute("/projects/p?objective=o")).toEqual({ section: "tickets", projectId: "p", objectiveId: "o", familyId: null, view: null, pageId: null, prId: null, routineId: null, adminTab: null }); }); it("names the objective selected on the Objectives page, and only there", () => { expect(appTabRoute("/projects/p/objectives?open=o").objectiveId).toBe("o"); expect(appTabRoute("/projects/p/objectives").objectiveId).toBeNull(); expect(appTabRoute("/projects/p/feedback?open=o").objectiveId).toBeNull(); }); it("exposes the family param so tabs can name a family board", () => { expect(appTabRoute("/projects/p?family=parent")).toEqual({ section: "tickets", projectId: "p", objectiveId: null, familyId: "parent", view: null, pageId: null, prId: null, routineId: null, adminTab: null }); }); it("exposes the selection params a tab's title may mirror", () => { expect(appTabRoute("/pull-requests?pr=og")).toEqual({ section: "pull-requests", projectId: null, objectiveId: null, familyId: null, view: null, pageId: null, prId: "og", routineId: null, adminTab: null }); expect(appTabRoute("/routines?routine=rt")).toEqual({ section: "routines", projectId: null, objectiveId: null, familyId: null, view: null, pageId: null, prId: null, routineId: "rt", adminTab: null }); }); it("exposes the admin dashboard tab, and only on the admin dashboard", () => { expect(appTabRoute("/admin?tab=instance").adminTab).toBe("instance"); expect(appTabRoute("/admin").adminTab).toBeNull(); expect(appTabRoute("/settings?tab=profile").adminTab).toBeNull(); }); it("exposes the cycle sentinel so tabs can name the cycle board", () => { expect(appTabRoute("/all?view=cycle").view).toBe("cycle"); expect(appTabRoute("/all?view=cycle").projectId).toBeNull(); }); }); describe("destination keys", () => { const project = "9e3d0c35-c1d7-4d2a-983d-8190638cc887"; const page = "6ea5bcf7-5a2a-4c5e-803d-cb64e52d9db9"; it("treat a full id, its short code and a keyed project segment as one destination", () => { const key = appTabDestinationKey(`/projects/${project}?view=${page}`); expect(appTabDestinationKey("/projects/aur-9e3d0c35?view=6ea5bcf7")).toBe(key); expect(appTabDestinationKey("/projects/9e3d0c35?view=6ea5bcf7")).toBe(key); expect(appTabDestinationKey(`/projects/${project}/pages/${page}`)).toBe(appTabDestinationKey("/projects/aur-9e3d0c35/pages/6ea5bcf7")); }); it("keep different destinations apart", () => { expect(appTabDestinationKey("/projects/aur-9e3d0c35")).not.toBe(appTabDestinationKey("/projects/aur-9e3d0c35/triage")); expect(appTabDestinationKey("/projects/aur-9e3d0c35")).not.toBe(appTabDestinationKey("/projects/aur-ff02a987")); expect(appTabDestinationKey("/settings?tab=profile")).not.toBe(appTabDestinationKey("/settings?tab=security")); expect(appTabDestinationKey("not a path")).toBeNull(); }); });