@@ -30,6 +30,16 @@ vi.mock('@/hooks/useWebRTC', () => ({
3030 useWebRTC : ( ) => mockUseWebRTC ,
3131} ) ) ;
3232
33+ vi . mock ( '@/components/chat/ChatPanel' , ( ) => ( {
34+ ChatPanel : ( { sessionId } : { sessionId : string } ) => (
35+ < div data-testid = "chat-panel" > Chat for { sessionId } </ div >
36+ ) ,
37+ } ) ) ;
38+
39+ vi . mock ( '@/components/session/SessionSettingsPanel' , ( ) => ( {
40+ SessionSettingsPanel : ( ) => < div data-testid = "session-settings-panel" > Settings Panel</ div > ,
41+ } ) ) ;
42+
3343// Create a stable promise that resolves immediately
3444function createResolvedParams ( id : string ) {
3545 return Promise . resolve ( { id } ) ;
@@ -348,4 +358,122 @@ describe('SessionViewerPage', () => {
348358 expect ( screen . queryByText ( 'Left User' ) ) . not . toBeInTheDocument ( ) ;
349359 } ) ;
350360 } ) ;
361+
362+ describe ( 'Sidebar panel toggling' , ( ) => {
363+ const mockSessionData = {
364+ id : 'session-123' ,
365+ join_code : 'ABC123' ,
366+ status : 'active' ,
367+ settings : { quality : 'medium' , allowControl : false , maxParticipants : 5 } ,
368+ created_at : '2024-01-01T00:00:00Z' ,
369+ session_participants : [
370+ {
371+ id : 'p-1' ,
372+ display_name : 'Host User' ,
373+ role : 'host' ,
374+ control_state : 'granted' ,
375+ joined_at : '2024-01-01T00:00:00Z' ,
376+ } ,
377+ ] ,
378+ } ;
379+
380+ beforeEach ( ( ) => {
381+ vi . mocked ( global . fetch ) . mockResolvedValue ( {
382+ ok : true ,
383+ json : ( ) => Promise . resolve ( { data : mockSessionData } ) ,
384+ } as Response ) ;
385+ } ) ;
386+
387+ it ( 'shows participants panel by default' , async ( ) => {
388+ const params = createResolvedParams ( 'session-123' ) ;
389+
390+ await act ( async ( ) => {
391+ renderWithSuspense ( < SessionViewerPage params = { params } /> ) ;
392+ } ) ;
393+
394+ await waitFor ( ( ) => {
395+ expect ( screen . getByText ( 'Participants (1)' ) ) . toBeInTheDocument ( ) ;
396+ } ) ;
397+ expect ( screen . queryByTestId ( 'chat-panel' ) ) . not . toBeInTheDocument ( ) ;
398+ expect ( screen . queryByTestId ( 'session-settings-panel' ) ) . not . toBeInTheDocument ( ) ;
399+ } ) ;
400+
401+ it ( 'switches to chat panel when Chat button is clicked' , async ( ) => {
402+ const params = createResolvedParams ( 'session-123' ) ;
403+
404+ await act ( async ( ) => {
405+ renderWithSuspense ( < SessionViewerPage params = { params } /> ) ;
406+ } ) ;
407+
408+ await waitFor ( ( ) => {
409+ expect ( screen . getByRole ( 'button' , { name : / C h a t / } ) ) . toBeInTheDocument ( ) ;
410+ } ) ;
411+
412+ fireEvent . click ( screen . getByRole ( 'button' , { name : / C h a t / } ) ) ;
413+
414+ expect ( screen . getByTestId ( 'chat-panel' ) ) . toBeInTheDocument ( ) ;
415+ expect ( screen . queryByText ( 'Participants (1)' ) ) . not . toBeInTheDocument ( ) ;
416+ } ) ;
417+
418+ it ( 'switches to settings panel when Settings button is clicked' , async ( ) => {
419+ const params = createResolvedParams ( 'session-123' ) ;
420+
421+ await act ( async ( ) => {
422+ renderWithSuspense ( < SessionViewerPage params = { params } /> ) ;
423+ } ) ;
424+
425+ await waitFor ( ( ) => {
426+ expect ( screen . getByRole ( 'button' , { name : / S e t t i n g s / } ) ) . toBeInTheDocument ( ) ;
427+ } ) ;
428+
429+ fireEvent . click ( screen . getByRole ( 'button' , { name : / S e t t i n g s / } ) ) ;
430+
431+ expect ( screen . getByTestId ( 'session-settings-panel' ) ) . toBeInTheDocument ( ) ;
432+ expect ( screen . queryByText ( 'Participants (1)' ) ) . not . toBeInTheDocument ( ) ;
433+ } ) ;
434+
435+ it ( 'closes sidebar when active panel button is clicked again' , async ( ) => {
436+ const params = createResolvedParams ( 'session-123' ) ;
437+
438+ await act ( async ( ) => {
439+ renderWithSuspense ( < SessionViewerPage params = { params } /> ) ;
440+ } ) ;
441+
442+ await waitFor ( ( ) => {
443+ expect ( screen . getByText ( 'Participants (1)' ) ) . toBeInTheDocument ( ) ;
444+ } ) ;
445+
446+ // Click Participants button to toggle off
447+ fireEvent . click ( screen . getByRole ( 'button' , { name : / P a r t i c i p a n t s / } ) ) ;
448+
449+ expect ( screen . queryByText ( 'Participants (1)' ) ) . not . toBeInTheDocument ( ) ;
450+ expect ( screen . queryByTestId ( 'chat-panel' ) ) . not . toBeInTheDocument ( ) ;
451+ } ) ;
452+
453+ it ( 'switches between panels without closing sidebar' , async ( ) => {
454+ const params = createResolvedParams ( 'session-123' ) ;
455+
456+ await act ( async ( ) => {
457+ renderWithSuspense ( < SessionViewerPage params = { params } /> ) ;
458+ } ) ;
459+
460+ await waitFor ( ( ) => {
461+ expect ( screen . getByText ( 'Participants (1)' ) ) . toBeInTheDocument ( ) ;
462+ } ) ;
463+
464+ // Switch to chat
465+ fireEvent . click ( screen . getByRole ( 'button' , { name : / C h a t / } ) ) ;
466+ expect ( screen . getByTestId ( 'chat-panel' ) ) . toBeInTheDocument ( ) ;
467+
468+ // Switch to settings
469+ fireEvent . click ( screen . getByRole ( 'button' , { name : / S e t t i n g s / } ) ) ;
470+ expect ( screen . getByTestId ( 'session-settings-panel' ) ) . toBeInTheDocument ( ) ;
471+ expect ( screen . queryByTestId ( 'chat-panel' ) ) . not . toBeInTheDocument ( ) ;
472+
473+ // Switch back to participants
474+ fireEvent . click ( screen . getByRole ( 'button' , { name : / P a r t i c i p a n t s / } ) ) ;
475+ expect ( screen . getByText ( 'Participants (1)' ) ) . toBeInTheDocument ( ) ;
476+ expect ( screen . queryByTestId ( 'session-settings-panel' ) ) . not . toBeInTheDocument ( ) ;
477+ } ) ;
478+ } ) ;
351479} ) ;
0 commit comments