@@ -23,6 +23,43 @@ describe('Sidebar ProviderModal', () => {
2323 beforeEach ( ( ) => {
2424 cleanup ( )
2525 mockGatewayAPI = {
26+ listMCPServers : vi . fn ( ) . mockResolvedValue ( {
27+ payload : {
28+ servers : [
29+ {
30+ id : 'stdio-weather' ,
31+ enabled : true ,
32+ trust : false ,
33+ transport : 'stdio' ,
34+ stdio : { command : 'weather' , args : [ ] , env : [ ] } ,
35+ } ,
36+ ] ,
37+ } ,
38+ } ) ,
39+ setMCPServerEnabled : vi . fn ( ) . mockResolvedValue ( undefined ) ,
40+ deleteMCPServer : vi . fn ( ) . mockResolvedValue ( undefined ) ,
41+ upsertMCPServer : vi . fn ( ) . mockResolvedValue ( undefined ) ,
42+ listAvailableSkills : vi . fn ( ) . mockResolvedValue ( {
43+ payload : {
44+ skills : [
45+ {
46+ descriptor : {
47+ id : 'skill-refactor' ,
48+ name : 'Skill Refactor' ,
49+ description : 'Refactor code safely' ,
50+ } ,
51+ active : false ,
52+ } ,
53+ ] ,
54+ } ,
55+ } ) ,
56+ listSessionSkills : vi . fn ( ) . mockResolvedValue ( {
57+ payload : {
58+ skills : [ ] ,
59+ } ,
60+ } ) ,
61+ activateSessionSkill : vi . fn ( ) . mockResolvedValue ( undefined ) ,
62+ deactivateSessionSkill : vi . fn ( ) . mockResolvedValue ( undefined ) ,
2663 listProviders : vi . fn ( ) . mockResolvedValue ( {
2764 payload : {
2865 providers : [
@@ -290,4 +327,53 @@ describe('Sidebar ProviderModal', () => {
290327 expect ( chevronFor ( workspaceTwo ) ) . toHaveClass ( 'expanded' )
291328 } )
292329 } )
330+
331+ it ( 'immediately dispatches collapsed-rail actions' , async ( ) => {
332+ const toggleSidebar = vi . fn ( )
333+ const prepareNewChat = vi . fn ( )
334+ useUIStore . setState ( {
335+ toggleSidebar,
336+ } as any )
337+ useSessionStore . setState ( {
338+ prepareNewChat,
339+ } as any )
340+
341+ const { container } = render ( < Sidebar collapsed /> )
342+ const collapsedButtons = Array . from ( container . querySelectorAll ( '.sidebar-strip-btn' ) )
343+
344+ expect ( collapsedButtons ) . toHaveLength ( 5 )
345+
346+ fireEvent . click ( collapsedButtons [ 0 ] as HTMLButtonElement )
347+ expect ( toggleSidebar ) . toHaveBeenCalledTimes ( 1 )
348+
349+ fireEvent . click ( collapsedButtons [ 1 ] as HTMLButtonElement )
350+ expect ( prepareNewChat ) . toHaveBeenCalledTimes ( 1 )
351+
352+ fireEvent . click ( collapsedButtons [ 2 ] as HTMLButtonElement )
353+ await waitFor ( ( ) => {
354+ expect ( mockGatewayAPI . listMCPServers ) . toHaveBeenCalled ( )
355+ } )
356+
357+ fireEvent . click ( collapsedButtons [ 3 ] as HTMLButtonElement )
358+ await waitFor ( ( ) => {
359+ expect ( mockGatewayAPI . listAvailableSkills ) . toHaveBeenCalled ( )
360+ expect ( screen . getByText ( 'Skill Refactor' ) ) . toBeInTheDocument ( )
361+ } )
362+
363+ fireEvent . click ( collapsedButtons [ 4 ] as HTMLButtonElement )
364+ await waitFor ( ( ) => {
365+ expect ( mockGatewayAPI . listProviders ) . toHaveBeenCalled ( )
366+ expect ( screen . getByText ( 'Gemini' ) ) . toBeInTheDocument ( )
367+ } )
368+ } )
369+
370+ it ( 'keeps the collapsed rail style above neighboring panels' , ( ) => {
371+ const railRule = appCss . match ( / \. s i d e b a r - c o l l a p s e d - w r a p p e r \s * { (?< body > [ ^ } ] * ) } / ) ?. groups ?. body ?? ''
372+ expect ( railRule ) . toContain ( 'position: relative' )
373+ expect ( railRule ) . toContain ( 'z-index: 20' )
374+ expect ( railRule ) . toContain ( 'isolation: isolate' )
375+ expect ( railRule ) . toContain ( 'width: 44px' )
376+ expect ( railRule ) . toContain ( 'min-width: 44px' )
377+ expect ( railRule ) . toContain ( 'flex: 0 0 44px' )
378+ } )
293379} )
0 commit comments