1- import React from 'react' ;
1+ import React , { Suspense } from 'react' ;
22
3- import { render , screen , act , fireEvent } from '@/test-utils/rtl' ;
3+ import { HttpResponse } from 'msw' ;
4+
5+ import { render , screen , userEvent } from '@/test-utils/rtl' ;
6+
7+ import ErrorBoundary from '@/components/error-boundary/error-boundary' ;
8+ import { type GetConfigResponse } from '@/route-handlers/get-config/get-config.types' ;
49
5- import domainPageTabsConfig from '../../config/domain-page-tabs.config' ;
610import DomainPageTabs from '../domain-page-tabs' ;
711
812const mockPushFn = jest . fn ( ) ;
@@ -36,40 +40,63 @@ jest.mock('../../config/domain-page-tabs.config', () => ({
3640 title : 'Workflows' ,
3741 artwork : ( ) => < div data-testid = "workflows-artwork" /> ,
3842 } ,
39- 'page-2' : {
40- title : 'Page 2' ,
43+ metadata : {
44+ title : 'Metadata' ,
45+ artwork : ( ) => < div data-testid = "metadata-artwork" /> ,
46+ } ,
47+ failovers : {
48+ title : 'Failovers' ,
49+ artwork : ( ) => < div data-testid = "failovers-artwork" /> ,
50+ } ,
51+ settings : {
52+ title : 'Settings' ,
53+ artwork : ( ) => < div data-testid = "settings-artwork" /> ,
54+ } ,
55+ archival : {
56+ title : 'Archival' ,
57+ artwork : ( ) => < div data-testid = "archival-artwork" /> ,
4158 } ,
4259} ) ) ;
4360
4461jest . mock ( '../../domain-page-help/domain-page-help' , ( ) =>
4562 jest . fn ( ( ) => < button data-testid = "domain-page-help" > Help Button</ button > )
4663) ;
4764
48- describe ( ' DomainPageTabs' , ( ) => {
65+ describe ( DomainPageTabs . name , ( ) => {
4966 afterEach ( ( ) => {
5067 jest . clearAllMocks ( ) ;
5168 } ) ;
5269
53- it ( 'renders tabs titles correctly' , ( ) => {
54- render ( < DomainPageTabs /> ) ;
70+ it ( 'renders tabs titles correctly with failover history disabled' , async ( ) => {
71+ await setup ( { enableFailoverHistory : false } ) ;
5572
56- Object . values ( domainPageTabsConfig ) . forEach ( ( { title } ) => {
57- expect ( screen . getByText ( title ) ) . toBeInTheDocument ( ) ;
58- } ) ;
73+ expect ( screen . getByText ( 'Workflows' ) ) . toBeInTheDocument ( ) ;
74+ expect ( screen . getByText ( 'Metadata' ) ) . toBeInTheDocument ( ) ;
75+ expect ( screen . getByText ( 'Settings' ) ) . toBeInTheDocument ( ) ;
76+ expect ( screen . getByText ( 'Archival' ) ) . toBeInTheDocument ( ) ;
77+ expect ( screen . queryByText ( 'Failovers' ) ) . toBeNull ( ) ;
5978 } ) ;
6079
61- it ( 'reroutes when new tab is clicked' , ( ) => {
62- render ( < DomainPageTabs /> ) ;
80+ it ( 'renders tabs with failover history enabled' , async ( ) => {
81+ await setup ( { enableFailoverHistory : true } ) ;
6382
64- const page2Tab = screen . getByText ( 'Page 2' ) ;
65- act ( ( ) => {
66- fireEvent . click ( page2Tab ) ;
67- } ) ;
83+ expect ( screen . getByText ( 'Workflows' ) ) . toBeInTheDocument ( ) ;
84+ expect ( screen . getByText ( 'Metadata' ) ) . toBeInTheDocument ( ) ;
85+ expect ( screen . getByText ( 'Failovers' ) ) . toBeInTheDocument ( ) ;
86+ expect ( screen . getByText ( 'Settings' ) ) . toBeInTheDocument ( ) ;
87+ expect ( screen . getByText ( 'Archival' ) ) . toBeInTheDocument ( ) ;
88+ } ) ;
6889
69- expect ( mockPushFn ) . toHaveBeenCalledWith ( 'page-2' ) ;
90+ it ( 'reroutes when new tab is clicked' , async ( ) => {
91+ const { user } = await setup ( { enableFailoverHistory : false } ) ;
92+
93+ const metadataTab = await screen . findByText ( 'Metadata' ) ;
94+ await user . click ( metadataTab ) ;
95+
96+ expect ( mockPushFn ) . toHaveBeenCalledWith ( 'metadata' ) ;
7097 } ) ;
7198
72- it ( 'retains query params when new tab is clicked' , ( ) => {
99+ it ( 'retains query params when new tab is clicked' , async ( ) => {
73100 // TODO: this is a bit hacky, see if there is a better way to mock the window search property
74101 const originalWindow = window ;
75102 window = Object . create ( window ) ;
@@ -81,41 +108,95 @@ describe('DomainPageTabs', () => {
81108 writable : true ,
82109 } ) ;
83110
84- render ( < DomainPageTabs /> ) ;
111+ const { user } = await setup ( { enableFailoverHistory : false } ) ;
85112
86- const page2Tab = screen . getByText ( 'Page 2' ) ;
87- act ( ( ) => {
88- fireEvent . click ( page2Tab ) ;
89- } ) ;
113+ const metadataTab = await screen . findByText ( 'Metadata' ) ;
114+ await user . click ( metadataTab ) ;
90115
91116 expect ( mockPushFn ) . toHaveBeenCalledWith (
92- 'page-2 ?queryParam1=one&queryParam2=two'
117+ 'metadata ?queryParam1=one&queryParam2=two'
93118 ) ;
94119
95120 window = originalWindow ;
96121 } ) ;
97122
98- it ( 'renders tabs artworks correctly' , ( ) => {
99- render ( < DomainPageTabs /> ) ;
123+ it ( 'renders tabs artworks correctly' , async ( ) => {
124+ await setup ( { enableFailoverHistory : false } ) ;
100125
101- Object . entries ( domainPageTabsConfig ) . forEach ( ( [ key , { artwork } ] ) => {
102- if ( typeof artwork !== 'undefined' )
103- expect ( screen . getByTestId ( `${ key } -artwork` ) ) . toBeInTheDocument ( ) ;
104- else
105- expect ( screen . queryByTestId ( `${ key } -artwork` ) ) . not . toBeInTheDocument ( ) ;
106- } ) ;
126+ expect ( screen . getByTestId ( 'workflows-artwork' ) ) . toBeInTheDocument ( ) ;
127+ expect ( screen . getByTestId ( 'metadata-artwork' ) ) . toBeInTheDocument ( ) ;
128+ expect ( screen . getByTestId ( 'settings-artwork' ) ) . toBeInTheDocument ( ) ;
129+ expect ( screen . getByTestId ( 'archival-artwork' ) ) . toBeInTheDocument ( ) ;
130+ expect ( screen . queryByTestId ( 'failovers-artwork' ) ) . toBeNull ( ) ;
107131 } ) ;
108132
109- it ( 'renders the help button as endEnhancer' , ( ) => {
110- render ( < DomainPageTabs /> ) ;
133+ it ( 'handles errors gracefully' , async ( ) => {
134+ await setup ( { error : true } ) ;
135+
136+ expect (
137+ await screen . findByText ( 'Error: Failed to fetch config' )
138+ ) . toBeInTheDocument ( ) ;
139+ } ) ;
140+
141+ it ( 'renders the help button as endEnhancer' , async ( ) => {
142+ await setup ( { } ) ;
111143
112144 expect ( screen . getByTestId ( 'domain-page-help' ) ) . toBeInTheDocument ( ) ;
113145 expect ( screen . getByText ( 'Help Button' ) ) . toBeInTheDocument ( ) ;
114146 } ) ;
115147
116- it ( 'renders the start workflow button' , ( ) => {
117- render ( < DomainPageTabs /> ) ;
148+ it ( 'renders the start workflow button' , async ( ) => {
149+ await setup ( { } ) ;
118150
119151 expect ( screen . getByTestId ( 'start-workflow-button' ) ) . toBeInTheDocument ( ) ;
120152 } ) ;
121153} ) ;
154+
155+ async function setup ( {
156+ error,
157+ enableFailoverHistory,
158+ } : {
159+ error ?: boolean ;
160+ enableFailoverHistory ?: boolean ;
161+ } ) {
162+ const user = userEvent . setup ( ) ;
163+
164+ render (
165+ < ErrorBoundary
166+ fallbackRender = { ( { error } ) => < div > Error: { error . message } </ div > }
167+ >
168+ < Suspense fallback = { < div > Loading...</ div > } >
169+ < DomainPageTabs />
170+ </ Suspense >
171+ </ ErrorBoundary > ,
172+ {
173+ endpointsMocks : [
174+ {
175+ path : '/api/config' ,
176+ httpMethod : 'GET' ,
177+ mockOnce : false ,
178+ httpResolver : async ( ) => {
179+ if ( error ) {
180+ return HttpResponse . json (
181+ { message : 'Failed to fetch config' } ,
182+ { status : 500 }
183+ ) ;
184+ } else {
185+ return HttpResponse . json (
186+ ( enableFailoverHistory ??
187+ false ) satisfies GetConfigResponse < 'FAILOVER_HISTORY_ENABLED' >
188+ ) ;
189+ }
190+ } ,
191+ } ,
192+ ] ,
193+ }
194+ ) ;
195+
196+ if ( ! error ) {
197+ // Wait for the first tab to load
198+ await screen . findByText ( 'Workflows' ) ;
199+ }
200+
201+ return { user } ;
202+ }
0 commit comments