1- import { Suspense } from 'react ' ;
1+ import { HttpResponse } from 'msw ' ;
22
3- import { render , screen , act , fireEvent } from '@/test-utils/rtl' ;
3+ import { render , screen , userEvent } from '@/test-utils/rtl' ;
44
55import { type ListWorkflowsResponse } from '@/route-handlers/list-workflows/list-workflows.types' ;
6- import * as requestModule from '@/utils/request' ;
76
7+ import type { Props as MSWMocksHandlersProps } from '../../../../test-utils/msw-mock-handlers/msw-mock-handlers.types' ;
88import { mockDomainWorkflowsQueryParamsValues } from '../../__fixtures__/domain-workflows-query-params' ;
99import { type Props as EndMessageProps } from '../../domain-workflows-table-end-message/domain-workflows-table-end-message.types' ;
1010import DomainWorkflowsTable from '../domain-workflows-table' ;
1111
12+ jest . mock ( '@/components/error-panel/error-panel' , ( ) =>
13+ jest . fn ( ( { message } : { message : string } ) => < div > { message } </ div > )
14+ ) ;
15+
16+ jest . mock ( '../helpers/get-workflows-error-panel-props' , ( ) =>
17+ jest . fn ( ) . mockImplementation ( ( { error } ) => ( {
18+ message : error ? 'Error loading workflows' : 'No workflows found' ,
19+ } ) )
20+ ) ;
21+
1222jest . mock (
1323 '../../domain-workflows-table-end-message/domain-workflows-table-end-message' ,
1424 ( ) =>
@@ -20,19 +30,19 @@ jest.mock(
2030) ;
2131
2232jest . mock ( 'query-string' , ( ) => ( {
23- stringifyUrl : jest . fn ( ( ) => 'mock-stringified-api-url' ) ,
33+ stringifyUrl : jest . fn (
34+ ( ) => '/api/domains/mock-domain/mock-cluster/workflows'
35+ ) ,
2436} ) ) ;
2537
26- jest . mock ( '@/utils/request' ) ;
27-
2838const mockSetQueryParams = jest . fn ( ) ;
2939jest . mock ( '@/hooks/use-page-query-params/use-page-query-params' , ( ) =>
3040 jest . fn ( ( ) => [ mockDomainWorkflowsQueryParamsValues , mockSetQueryParams ] )
3141) ;
3242
3343describe ( DomainWorkflowsTable . name , ( ) => {
3444 it ( 'renders workflows without error' , async ( ) => {
35- await setup ( { } ) ;
45+ const { user } = setup ( { } ) ;
3646
3747 expect ( await screen . findByText ( 'Mock end message: OK' ) ) . toBeInTheDocument ( ) ;
3848 Array ( 10 ) . forEach ( ( _ , index ) => {
@@ -41,9 +51,7 @@ describe(DomainWorkflowsTable.name, () => {
4151 ) . toBeInTheDocument ( ) ;
4252 } ) ;
4353
44- act ( ( ) => {
45- fireEvent . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
46- } ) ;
54+ await user . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
4755
4856 expect ( await screen . findByText ( 'Mock end message: OK' ) ) . toBeInTheDocument ( ) ;
4957 Array ( 10 ) . forEach ( ( _ , index ) => {
@@ -53,23 +61,22 @@ describe(DomainWorkflowsTable.name, () => {
5361 } ) ;
5462 } ) ;
5563
56- it ( 'does not render if the initial call fails' , async ( ) => {
57- let renderErrorMessage ;
58- try {
59- await act ( async ( ) => {
60- await setup ( { errorCase : 'initial-fetch-error' } ) ;
61- } ) ;
62- } catch ( error ) {
63- if ( error instanceof Error ) {
64- renderErrorMessage = error . message ;
65- }
66- }
67-
68- expect ( renderErrorMessage ) . toEqual ( 'Request failed' ) ;
64+ it ( 'renders error panel if the initial call fails' , async ( ) => {
65+ setup ( { errorCase : 'initial-fetch-error' } ) ;
66+
67+ expect (
68+ await screen . findByText ( 'Error loading workflows' )
69+ ) . toBeInTheDocument ( ) ;
70+ } ) ;
71+
72+ it ( 'renders error panel if no workflows are found' , async ( ) => {
73+ setup ( { errorCase : 'no-workflows' } ) ;
74+
75+ expect ( await screen . findByText ( 'No workflows found' ) ) . toBeInTheDocument ( ) ;
6976 } ) ;
7077
7178 it ( 'renders workflows and allows the user to try again if there is an error' , async ( ) => {
72- await setup ( { errorCase : 'subsequent-fetch-error' } ) ;
79+ const { user } = setup ( { errorCase : 'subsequent-fetch-error' } ) ;
7380
7481 expect ( await screen . findByText ( 'Mock end message: OK' ) ) . toBeInTheDocument ( ) ;
7582 Array ( 10 ) . forEach ( ( _ , index ) => {
@@ -78,17 +85,13 @@ describe(DomainWorkflowsTable.name, () => {
7885 ) . toBeInTheDocument ( ) ;
7986 } ) ;
8087
81- act ( ( ) => {
82- fireEvent . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
83- } ) ;
88+ await user . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
8489
8590 expect (
8691 await screen . findByText ( 'Mock end message: Error' )
8792 ) . toBeInTheDocument ( ) ;
8893
89- act ( ( ) => {
90- fireEvent . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
91- } ) ;
94+ await user . click ( screen . getByTestId ( 'mock-end-message' ) ) ;
9295
9396 expect ( await screen . findByText ( 'Mock end message: OK' ) ) . toBeInTheDocument ( ) ;
9497 Array ( 10 ) . forEach ( ( _ , index ) => {
@@ -99,41 +102,57 @@ describe(DomainWorkflowsTable.name, () => {
99102 } ) ;
100103} ) ;
101104
102- async function setup ( {
105+ function setup ( {
103106 errorCase,
104107} : {
105- errorCase ?: 'initial-fetch-error' | 'subsequent-fetch-error' ;
108+ errorCase ?: 'initial-fetch-error' | 'subsequent-fetch-error' | 'no-workflows' ;
106109} ) {
107- // TODO: @adhitya .mamallan - This is not type-safe, explore using a library such as nock or msw
108- const requestMock = jest . spyOn ( requestModule , 'default' ) as jest . Mock ;
109110 const pages = generateWorkflowPages ( 2 ) ;
111+ let currentEventIndex = 0 ;
112+ const user = userEvent . setup ( ) ;
113+
114+ render ( < DomainWorkflowsTable domain = "mock-domain" cluster = "mock-cluster" /> , {
115+ endpointsMocks : [
116+ {
117+ path : '/api/domains/:domain/:cluster/workflows' ,
118+ httpMethod : 'GET' ,
119+ mockOnce : false ,
120+ httpResolver : async ( ) => {
121+ const index = currentEventIndex ;
122+ currentEventIndex ++ ;
123+
124+ switch ( errorCase ) {
125+ case 'no-workflows' :
126+ return HttpResponse . json ( { workflows : [ ] , nextPage : undefined } ) ;
127+ case 'initial-fetch-error' :
128+ return HttpResponse . json (
129+ { message : 'Request failed' } ,
130+ { status : 500 }
131+ ) ;
132+ case 'subsequent-fetch-error' :
133+ if ( index === 0 ) {
134+ return HttpResponse . json ( pages [ 0 ] ) ;
135+ } else if ( index === 1 ) {
136+ return HttpResponse . json (
137+ { message : 'Request failed' } ,
138+ { status : 500 }
139+ ) ;
140+ } else {
141+ return HttpResponse . json ( pages [ 1 ] ) ;
142+ }
143+ default :
144+ if ( index === 0 ) {
145+ return HttpResponse . json ( pages [ 0 ] ) ;
146+ } else {
147+ return HttpResponse . json ( pages [ 1 ] ) ;
148+ }
149+ }
150+ } ,
151+ } ,
152+ ] as MSWMocksHandlersProps [ 'endpointsMocks' ] ,
153+ } ) ;
110154
111- if ( errorCase === 'subsequent-fetch-error' ) {
112- requestMock
113- . mockResolvedValueOnce ( {
114- json : ( ) => Promise . resolve ( pages [ 0 ] ) ,
115- } )
116- . mockRejectedValueOnce ( new Error ( 'Request failed' ) )
117- . mockResolvedValueOnce ( {
118- json : ( ) => Promise . resolve ( pages [ 1 ] ) ,
119- } ) ;
120- } else if ( errorCase === 'initial-fetch-error' ) {
121- requestMock . mockRejectedValueOnce ( new Error ( 'Request failed' ) ) ;
122- } else {
123- requestMock
124- . mockResolvedValueOnce ( {
125- json : ( ) => Promise . resolve ( pages [ 0 ] ) ,
126- } )
127- . mockResolvedValueOnce ( {
128- json : ( ) => Promise . resolve ( pages [ 1 ] ) ,
129- } ) ;
130- }
131-
132- render (
133- < Suspense >
134- < DomainWorkflowsTable domain = "mock-domain" cluster = "mock-cluster" />
135- </ Suspense >
136- ) ;
155+ return { user } ;
137156}
138157
139158// TODO @adhitya .mamallan - Explore using fakerjs.dev for cases like this
0 commit comments