feat(web): open project surfaces in browser targets — #204

This commit is contained in:
2026-08-15 01:16:23 +02:00
parent 7fea538d0d
commit 0d543fb298
8 changed files with 513 additions and 132 deletions

View File

@ -0,0 +1,64 @@
import { describe, expect, it, vi } from "vitest";
import {
buildWebSurfaceWindowUrl,
openWebSurfaceInBrowser,
parseWebSurfaceWindowParams,
} from "./webSurfaceNavigation";
describe("web surface navigation (#204)", () => {
it("builds and parses a detached web surface URL", () => {
const url = buildWebSurfaceWindowUrl({
baseHref: "https://idea.local/workspace?old=1#ignored",
panel: "tickets",
projectId: "p-1",
projectRoot: "/srv/demo project",
projectName: "Demo",
focusSprintId: "s-1",
});
expect(url).toBe(
"https://idea.local/workspace?webPanel=tickets&projectId=p-1&projectRoot=%2Fsrv%2Fdemo+project&projectName=Demo&focusSprintId=s-1",
);
expect(parseWebSurfaceWindowParams(new URL(url).search)).toEqual({
panel: "tickets",
projectId: "p-1",
projectRoot: "/srv/demo project",
projectName: "Demo",
focusSprintId: "s-1",
});
});
it("rejects non-openable or incomplete detached surface URLs", () => {
expect(parseWebSurfaceWindowParams("?webPanel=projects&projectId=p&projectRoot=/x&projectName=X")).toBeNull();
expect(parseWebSurfaceWindowParams("?webPanel=tickets&projectId=p&projectRoot=/x")).toBeNull();
});
it("falls back from browser window to tab when the popup is blocked", () => {
const open = vi
.fn((..._args: Parameters<Window["open"]>): ReturnType<Window["open"]> => null)
.mockReturnValueOnce(null)
.mockReturnValueOnce({ closed: false } as Window);
const outcome = openWebSurfaceInBrowser(
{
baseHref: "https://idea.local/",
panel: "git",
projectId: "p-1",
projectRoot: "/srv/demo",
projectName: "Demo",
},
"window",
open,
);
expect(outcome.result).toBe("tab");
expect(open).toHaveBeenNthCalledWith(
1,
outcome.url,
"idea-web-git",
"popup,width=1280,height=900,noopener,noreferrer",
);
expect(open).toHaveBeenNthCalledWith(2, outcome.url, "_blank", "noopener,noreferrer");
});
});