import { describe, expect, it } from "bun:test"; import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { ApiError } from "./api"; import { anchoredChildPaths, AnchoredChildSurface, childCloseAction, childFocusTransition, childHistoryState, childPresentation, rebaseChildHistoryState, } from "./anchored-child-surface"; import { hostedRoute, retryableChannelFailure } from "./hosted"; import { githubLoginHref } from "./hosted-login"; import { prepareDocumentLoad, validatedChildPath } from "./document-loader"; import { Workspace } from "./workspace"; import type { ChannelDetail } from "./api"; const workspaceIds = { heading: { chat: "workspace-chat-heading", decisions: "workspace-decisions-heading", plan: "workspace-plan-heading", }, pane: { chat: "workspace-chat-pane" }, }; function detail( id: string, slug: string, parentChannelId?: string, repositoryId = "R_score", ): ChannelDetail { return { repository: { id: repositoryId, owner: "octo-org", name: "score", fullName: "octo-org/score", private: false, url: "https://github.com/octo-org/score", defaultBranch: "main", permissions: { pull: true, push: true, admin: false }, }, canEdit: true, canManage: true, channel: { descriptionRevision: 0, id, repositoryId, repositoryOwner: "octo-org", repositoryName: "score", ...(parentChannelId ? { parentChannelId } : {}), title: slug, slug, createdBy: "user-one", revision: 0, createdAt: "2026-08-24T00:00:00.000Z", updatedAt: "2026-08-24T00:00:00.000Z", }, }; } describe("hosted routes", () => { it("recognizes canonical document routes and rejects the removed research route", () => { expect(hostedRoute("/")).toEqual({ page: "repositories" }); expect(hostedRoute("/documents/octo-org/score")).toEqual({ page: "repository", owner: "octo-org", repository: "score", }); expect(hostedRoute("/documents/octo-org/score/r%C3%A9sum%C3%A9-%E8%A8%88%E7%94%BB")) .toEqual({ page: "document", owner: "octo-org", repository: "score", slug: "résumé-計画", }); expect(hostedRoute( "/documents/octo-org/score/r%C3%A9sum%C3%A9-%E8%A8%88%E7%94%BB/research/workspace%3A1", )).toEqual({ page: "missing" }); expect(hostedRoute("/repositories/octo-org/score")).toEqual({ page: "repository", owner: "octo-org", repository: "score", }); expect(hostedRoute("/repositories/github%20next/chopin")).toEqual({ page: "repository", owner: "github next", repository: "chopin", }); expect(hostedRoute("/channels/019c1234-1234-4123-8123-123456789abc")).toEqual({ page: "channel", id: "019c1234-1234-4123-8123-123456789abc", }); expect(hostedRoute("/channels/019c1234-1234-5123-8123-123456789abc")).toEqual({ page: "channel", id: "019c1234-1234-5123-8123-123456789abc", }); expect(hostedRoute("/plans/main")).toEqual({ page: "missing" }); expect(hostedRoute("/documents/octo-org/score/plan/extra")) .toEqual({ page: "missing" }); expect(hostedRoute("/documents/octo-org/score/plan/research")) .toEqual({ page: "missing" }); }); it("recognizes a child route before the ordinary document route", () => { expect(hostedRoute( "/documents/octo-org/score/release-plan/children/source%20review", )).toEqual({ page: "child", owner: "octo-org", repository: "score", parentSlug: "release-plan", childSlug: "source review", }); }); it("accepts direct child entry only for its recorded parent and repository", () => { let parent = detail("parent-one", "canonical-parent"); let child = detail("child-one", "canonical-child", parent.channel.id); expect(validatedChildPath(child, parent)).toBe( "/documents/octo-org/score/canonical-parent/children/canonical-child", ); for ( let invalid of [ detail("child-one", "canonical-child"), detail("child-one", "canonical-child", "different-parent"), detail("child-one", "canonical-child", parent.channel.id, "R_other"), ] ) { expect(() => validatedChildPath(invalid, parent)).toThrow(ApiError); try { validatedChildPath(invalid, parent); } catch (error) { expect((error as ApiError).status).toBe(404); } } }); }); describe("anchored child lifecycle", () => { it("restores only the close attempt that reaches its own mounted parent", () => { let opener = { current: null }; let state = childFocusTransition({ generation: 0 }, { type: "begin", opener, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }); let token = { generation: 1, parentId: "parent-one" }; state = childFocusTransition(state, { type: "route", pathname: "/documents/octo-org/score/parent-one", }); state = childFocusTransition(state, { type: "restore", token }); expect(state.attempt).toMatchObject({ generation: 1, parentId: "parent-one", phase: "deferred", }); expect(childFocusTransition(state, { type: "restore", token })).toBe(state); let finished = childFocusTransition(state, { type: "finish", token }); expect(finished).toEqual({ generation: 1, }); expect(childFocusTransition(finished, { type: "restore", token })).toBe(finished); }); it("invalidates a close attempt on reopen, sibling, or different-document navigation", () => { for ( let pathname of [ "/documents/octo-org/score/parent-one/children/child-one", "/documents/octo-org/score/parent-one/children/child-two", "/documents/octo-org/score/parent-two", ] ) { let state = childFocusTransition({ generation: 0 }, { type: "begin", opener: { current: null }, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }); let token = { generation: 1, parentId: "parent-one" }; state = childFocusTransition(state, { type: "route", pathname: "/documents/octo-org/score/parent-one", }); state = childFocusTransition(state, { type: "route", pathname }); state = childFocusTransition(state, { type: "restore", token }); expect(state).toEqual({ generation: 2 }); } }); it("ignores stale completion after a superseding close attempt", () => { let state = childFocusTransition({ generation: 0 }, { type: "begin", opener: { current: null }, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }); let stale = { generation: 1, parentId: "parent-one" }; state = childFocusTransition(state, { type: "begin", opener: { current: null }, parentId: "parent-two", parentPath: "/documents/octo-org/score/parent-two", }); expect(childFocusTransition(state, { type: "restore", token: stale })).toBe(state); expect(state.attempt?.generation).toBe(2); }); it("coalesces repeated close requests until the child route changes", () => { let state = childFocusTransition({ generation: 0 }, { type: "begin", opener: { current: null }, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }); let repeated = childFocusTransition(state, { type: "begin", opener: { current: null }, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }); expect(repeated).toBe(state); repeated = childFocusTransition(repeated, { type: "route", pathname: "/documents/octo-org/score/parent-one/children/child-one", }); expect( childFocusTransition(repeated, { type: "begin", opener: { current: null }, parentId: "parent-one", parentPath: "/documents/octo-org/score/parent-one", }).attempt?.generation, ).toBe(3); }); it("keeps the parent shell visible around separate workspace rooms", () => { let markup = renderToStaticMarkup(createElement(AnchoredChildSurface, { child: createElement("div", { "data-workspace-room": "child-room" }), childLabel: "Source review", onBackdropClick() {}, parent: createElement("div", { "data-workspace-room": "parent-room" }), presentation: "open", })); let closing = renderToStaticMarkup(createElement(AnchoredChildSurface, { child: createElement("div"), childLabel: "Source review", onBackdropClick() {}, parent: createElement("div"), presentation: "closing", })); expect(markup).not.toContain('inert=""'); expect(markup).not.toContain('aria-label="Back to Release plan"'); expect(markup).toContain('class="anchored-child-backdrop"'); expect(markup).toContain('aria-hidden="true"'); expect(markup).not.toContain('