11import "../../../../tests/ui/dom" ;
22
33import { afterEach , beforeEach , describe , expect , mock , spyOn , test } from "bun:test" ;
4- import { cleanup , render , within } from "@testing-library/react" ;
4+ import { cleanup , fireEvent , render , within } from "@testing-library/react" ;
55import type { ReactNode } from "react" ;
66import { installDom } from "../../../../tests/ui/dom" ;
77import type * as ReactDndModuleType from "react-dnd" ;
@@ -17,9 +17,12 @@ import type * as RuntimeStatusStoreModuleType from "@/browser/stores/RuntimeStat
1717import type * as WorkspaceStoreModule from "@/browser/stores/WorkspaceStore" ;
1818import * as TooltipModule from "../Tooltip/Tooltip" ;
1919import * as WorkspaceStatusIndicatorModule from "../WorkspaceStatusIndicator/WorkspaceStatusIndicator" ;
20+ import { parseRightSidebarLayoutState } from "@/browser/utils/rightSidebarLayout" ;
21+ import { getRightSidebarLayoutKey } from "@/common/constants/storage" ;
2022import type { AgentRowRenderMeta } from "@/browser/utils/ui/workspaceFiltering" ;
2123import type { StreamAbortReasonSnapshot } from "@/common/types/stream" ;
2224import type { FrontendWorkspaceMetadata } from "@/common/types/workspace" ;
25+ import type { WorkspaceSelection } from "./AgentListItem" ;
2326import type { AgentListItem as AgentListItemComponent } from "./AgentListItem" ;
2427
2528let AgentListItem ! : typeof AgentListItemComponent ;
@@ -225,6 +228,7 @@ function renderWorkspaceItem(
225228 subAgentConnectorLayout ?: "default" | "task-group-member" ;
226229 completedChildrenExpanded ?: boolean ;
227230 onToggleCompletedChildren ?: ( workspaceId : string ) => void ;
231+ onSelectWorkspace ?: ( selection : WorkspaceSelection ) => void ;
228232 } = { }
229233) {
230234 const metadata = options . metadata ?? createMetadata ( ) ;
@@ -240,7 +244,7 @@ function renderWorkspaceItem(
240244 subAgentConnectorLayout = { options . subAgentConnectorLayout }
241245 completedChildrenExpanded = { options . completedChildrenExpanded }
242246 onToggleCompletedChildren = { options . onToggleCompletedChildren }
243- onSelectWorkspace = { ( ) => undefined }
247+ onSelectWorkspace = { options . onSelectWorkspace ?? ( ( ) => undefined ) }
244248 onForkWorkspace = { ( ) => Promise . resolve ( ) }
245249 onArchiveWorkspace = { ( ) => Promise . resolve ( ) }
246250 onCancelCreation = { ( ) => Promise . resolve ( ) }
@@ -311,6 +315,47 @@ describe("AgentListItem", () => {
311315 expect ( pill . getAttribute ( "aria-label" ) ) . toBe ( "Goal budget limited, $5.25 of $5.00 spent" ) ;
312316 } ) ;
313317
318+ test ( "goal pill selects the workspace and persists the Goal tab before navigation" , ( ) => {
319+ mockWorkspaceHeartbeatsEnabled = true ;
320+ mockWorkspaceSidebarState = createWorkspaceSidebarState ( {
321+ goal : {
322+ goalId : "22222222-2222-4222-8222-222222222222" ,
323+ status : "active" ,
324+ objective : "Open the goal tab" ,
325+ budgetCents : 100_000 ,
326+ costCents : 5_294 ,
327+ turnsUsed : 2 ,
328+ turnCap : null ,
329+ startedAtMs : Date . now ( ) ,
330+ } ,
331+ } ) ;
332+ const onSelectWorkspace = mock ( ( _ : WorkspaceSelection ) => undefined ) ;
333+
334+ const { row, metadata } = renderWorkspaceItem ( { onSelectWorkspace } ) ;
335+ const pill = within ( row ) . getByTestId ( `workspace-goal-pill-${ TEST_WORKSPACE_ID } ` ) ;
336+
337+ fireEvent . click ( pill ) ;
338+
339+ expect ( onSelectWorkspace ) . toHaveBeenCalledWith ( {
340+ projectPath : metadata . projectPath ,
341+ projectName : metadata . projectName ,
342+ namedWorkspacePath : metadata . namedWorkspacePath ,
343+ workspaceId : metadata . id ,
344+ } ) ;
345+ const persistedLayout = window . localStorage . getItem ( getRightSidebarLayoutKey ( metadata . id ) ) ;
346+ if ( persistedLayout === null ) {
347+ throw new Error ( "expected target workspace right sidebar layout to be persisted" ) ;
348+ }
349+ const rawLayout : unknown = JSON . parse ( persistedLayout ) ;
350+ const layout = parseRightSidebarLayoutState ( rawLayout , "costs" ) ;
351+ expect ( layout . root . type ) . toBe ( "tabset" ) ;
352+ if ( layout . root . type !== "tabset" ) {
353+ throw new Error ( "expected default right sidebar layout to be a tabset" ) ;
354+ }
355+ expect ( layout . root . activeTab ) . toBe ( "goal" ) ;
356+ expect ( layout . root . tabs ) . toContain ( "goal" ) ;
357+ } ) ;
358+
314359 test ( "renders a heartbeat icon directly in the leading slot for seen rows when the heartbeat experiment is enabled" , ( ) => {
315360 mockWorkspaceHeartbeatsEnabled = true ;
316361
0 commit comments