1
1
import { HttpResponse } from 'msw' ;
2
2
3
- import { render , screen , userEvent } from '@/test-utils/rtl' ;
3
+ import { render , screen , userEvent , waitFor } from '@/test-utils/rtl' ;
4
4
5
5
import { type CancelWorkflowResponse } from '@/route-handlers/cancel-workflow/cancel-workflow.types' ;
6
- import { type RestartWorkflowResponse } from '@/route-handlers/restart-workflow/restart-workflow.types' ;
7
- import { type TerminateWorkflowResponse } from '@/route-handlers/terminate-workflow/terminate-workflow.types' ;
6
+ import { type ResetWorkflowResponse } from '@/route-handlers/reset-workflow/reset-workflow.types' ;
8
7
import { mockWorkflowDetailsParams } from '@/views/workflow-page/__fixtures__/workflow-details-params' ;
9
8
10
9
import { mockWorkflowActionsConfig } from '../../__fixtures__/workflow-actions-config' ;
@@ -21,6 +20,8 @@ jest.mock('baseui/snackbar', () => ({
21
20
} ) ,
22
21
} ) ) ;
23
22
23
+ const mockResetAction = mockWorkflowActionsConfig [ 2 ] ;
24
+
24
25
describe ( WorkflowActionsModalContent . name , ( ) => {
25
26
beforeEach ( ( ) => {
26
27
jest . clearAllMocks ( ) ;
@@ -41,11 +42,11 @@ describe(WorkflowActionsModalContent.name, () => {
41
42
expect ( docsLink ) . toHaveAttribute ( 'href' , 'https://mock.docs.link' ) ;
42
43
} ) ;
43
44
44
- it ( 'calls onCloseModal when the Go Back button is clicked' , async ( ) => {
45
+ it ( 'calls onCloseModal when the Cancel button is clicked' , async ( ) => {
45
46
const { user, mockOnClose } = setup ( { } ) ;
46
47
47
- const goBackButton = await screen . findByText ( 'Go back ' ) ;
48
- await user . click ( goBackButton ) ;
48
+ const cancelButton = await screen . findByText ( 'Cancel ' ) ;
49
+ await user . click ( cancelButton ) ;
49
50
50
51
expect ( mockOnClose ) . toHaveBeenCalled ( ) ;
51
52
} ) ;
@@ -58,11 +59,13 @@ describe(WorkflowActionsModalContent.name, () => {
58
59
} ) ;
59
60
await user . click ( cancelButton ) ;
60
61
61
- expect ( mockEnqueue ) . toHaveBeenCalledWith (
62
- expect . objectContaining ( {
63
- message : 'Mock cancel notification' ,
64
- } )
65
- ) ;
62
+ await waitFor ( ( ) => {
63
+ expect ( mockEnqueue ) . toHaveBeenCalledWith (
64
+ expect . objectContaining ( {
65
+ message : 'Mock cancel notification' ,
66
+ } )
67
+ ) ;
68
+ } ) ;
66
69
expect ( mockOnClose ) . toHaveBeenCalled ( ) ;
67
70
} ) ;
68
71
@@ -74,9 +77,9 @@ describe(WorkflowActionsModalContent.name, () => {
74
77
} ) ;
75
78
await user . click ( cancelButton ) ;
76
79
77
- expect (
78
- await screen . findByText ( 'Failed to cancel workflow' )
79
- ) . toBeInTheDocument ( ) ;
80
+ await waitFor ( ( ) => {
81
+ expect ( screen . getByText ( 'Failed to cancel workflow' ) ) . toBeInTheDocument ( ) ;
82
+ } ) ;
80
83
expect ( mockOnClose ) . not . toHaveBeenCalled ( ) ;
81
84
} ) ;
82
85
@@ -93,19 +96,74 @@ describe(WorkflowActionsModalContent.name, () => {
93
96
expect ( screen . getByText ( 'First line of array text' ) ) . toBeInTheDocument ( ) ;
94
97
expect ( screen . getByText ( 'Second line of array text' ) ) . toBeInTheDocument ( ) ;
95
98
} ) ;
99
+
100
+ describe ( 'form handling' , ( ) => {
101
+ it ( 'renders form when provided in action config' , ( ) => {
102
+ setup ( { actionConfig : mockResetAction } ) ;
103
+
104
+ expect ( screen . getByTestId ( 'mock-form' ) ) . toBeInTheDocument ( ) ;
105
+ expect ( screen . getByTestId ( 'test-input' ) ) . toBeInTheDocument ( ) ;
106
+ } ) ;
107
+
108
+ it ( 'disables submit button when form has validation errors' , async ( ) => {
109
+ const { user } = setup ( { actionConfig : mockResetAction } ) ;
110
+
111
+ const submitButton = screen . getByRole ( 'button' , {
112
+ name : 'Mock reset workflow' ,
113
+ } ) ;
114
+ await user . click ( submitButton ) ;
115
+
116
+ expect ( submitButton ) . toHaveAttribute ( 'disabled' ) ;
117
+ } ) ;
118
+
119
+ it ( 'forms recieves validation error message when field is invalid' , async ( ) => {
120
+ const { user } = setup ( { actionConfig : mockResetAction } ) ;
121
+
122
+ const submitButton = screen . getByRole ( 'button' , {
123
+ name : 'Mock reset workflow' ,
124
+ } ) ;
125
+ await user . click ( submitButton ) ;
126
+
127
+ expect ( screen . getByTestId ( 'test-input' ) ) . toHaveAttribute (
128
+ 'aria-invalid' ,
129
+ 'true'
130
+ ) ;
131
+ } ) ;
132
+
133
+ it ( 'transforms form data before submission' , async ( ) => {
134
+ const { user, getLatestRequestBody, waitForRequest } = setup ( {
135
+ actionConfig : mockResetAction ,
136
+ } ) ;
137
+
138
+ const input = screen . getByTestId ( 'test-input' ) ;
139
+ await user . type ( input , 'test value' ) ;
140
+
141
+ const submitButton = screen . getByRole ( 'button' , {
142
+ name : 'Mock reset workflow' ,
143
+ } ) ;
144
+ await user . click ( submitButton ) ;
145
+
146
+ await waitForRequest ( ) ;
147
+
148
+ expect ( getLatestRequestBody ( ) ) . toEqual ( { transformed : 'test value' } ) ;
149
+ } ) ;
150
+ } ) ;
96
151
} ) ;
97
152
98
153
function setup ( {
99
154
error,
100
155
actionConfig,
101
156
} : {
102
157
error ?: boolean ;
103
- actionConfig ?: WorkflowAction <
104
- CancelWorkflowResponse | TerminateWorkflowResponse | RestartWorkflowResponse
105
- > ;
158
+ actionConfig ?: WorkflowAction < any , any , any > ;
106
159
} ) {
107
160
const user = userEvent . setup ( ) ;
108
161
const mockOnClose = jest . fn ( ) ;
162
+ let latestRequestBody : any = null ;
163
+ let requestPromiseResolve = ( v : unknown ) => v ;
164
+ const requestPromise = new Promise ( ( resolve ) => {
165
+ requestPromiseResolve = resolve ;
166
+ } ) ;
109
167
110
168
render (
111
169
< WorkflowActionsModalContent
@@ -116,22 +174,38 @@ function setup({
116
174
{
117
175
endpointsMocks : [
118
176
{
119
- path : '/api/domains/:domain/:cluster/workflows/:workflowId/:runId/cancel ' ,
177
+ path : '/api/domains/:domain/:cluster/workflows/:workflowId/:runId/:action ' ,
120
178
httpMethod : 'POST' ,
121
179
mockOnce : false ,
122
- httpResolver : ( ) => {
180
+ httpResolver : async ( { request } ) => {
181
+ // Capture the request body
182
+ const text = await request . text ( ) ;
183
+ latestRequestBody = text ? JSON . parse ( text ) : null ;
184
+ requestPromiseResolve ( null ) ;
185
+
123
186
if ( error ) {
124
187
return HttpResponse . json (
125
188
{ message : 'Failed to cancel workflow' } ,
126
189
{ status : 500 }
127
190
) ;
128
191
}
192
+
193
+ if ( request . url . endsWith ( '/reset' ) ) {
194
+ return HttpResponse . json ( {
195
+ runId : 'new-run-id' ,
196
+ } satisfies ResetWorkflowResponse ) ;
197
+ }
129
198
return HttpResponse . json ( { } satisfies CancelWorkflowResponse ) ;
130
199
} ,
131
200
} ,
132
201
] ,
133
202
}
134
203
) ;
135
204
136
- return { user, mockOnClose } ;
205
+ return {
206
+ user,
207
+ mockOnClose,
208
+ getLatestRequestBody : ( ) => latestRequestBody ,
209
+ waitForRequest : ( ) => requestPromise ,
210
+ } ;
137
211
}
0 commit comments