11import { HttpResponse } from 'msw' ;
22
3- import { render , screen , userEvent } from '@/test-utils/rtl' ;
3+ import { render , screen , userEvent , waitFor } from '@/test-utils/rtl' ;
44
55import { 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' ;
87import { mockWorkflowDetailsParams } from '@/views/workflow-page/__fixtures__/workflow-details-params' ;
98
109import { mockWorkflowActionsConfig } from '../../__fixtures__/workflow-actions-config' ;
@@ -21,6 +20,8 @@ jest.mock('baseui/snackbar', () => ({
2120 } ) ,
2221} ) ) ;
2322
23+ const mockResetAction = mockWorkflowActionsConfig [ 2 ] ;
24+
2425describe ( WorkflowActionsModalContent . name , ( ) => {
2526 beforeEach ( ( ) => {
2627 jest . clearAllMocks ( ) ;
@@ -41,11 +42,11 @@ describe(WorkflowActionsModalContent.name, () => {
4142 expect ( docsLink ) . toHaveAttribute ( 'href' , 'https://mock.docs.link' ) ;
4243 } ) ;
4344
44- it ( 'calls onCloseModal when the Go Back button is clicked' , async ( ) => {
45+ it ( 'calls onCloseModal when the Cancel button is clicked' , async ( ) => {
4546 const { user, mockOnClose } = setup ( { } ) ;
4647
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 ) ;
4950
5051 expect ( mockOnClose ) . toHaveBeenCalled ( ) ;
5152 } ) ;
@@ -58,11 +59,13 @@ describe(WorkflowActionsModalContent.name, () => {
5859 } ) ;
5960 await user . click ( cancelButton ) ;
6061
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+ } ) ;
6669 expect ( mockOnClose ) . toHaveBeenCalled ( ) ;
6770 } ) ;
6871
@@ -74,9 +77,9 @@ describe(WorkflowActionsModalContent.name, () => {
7477 } ) ;
7578 await user . click ( cancelButton ) ;
7679
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+ } ) ;
8083 expect ( mockOnClose ) . not . toHaveBeenCalled ( ) ;
8184 } ) ;
8285
@@ -93,19 +96,74 @@ describe(WorkflowActionsModalContent.name, () => {
9396 expect ( screen . getByText ( 'First line of array text' ) ) . toBeInTheDocument ( ) ;
9497 expect ( screen . getByText ( 'Second line of array text' ) ) . toBeInTheDocument ( ) ;
9598 } ) ;
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+ } ) ;
96151} ) ;
97152
98153function setup ( {
99154 error,
100155 actionConfig,
101156} : {
102157 error ?: boolean ;
103- actionConfig ?: WorkflowAction <
104- CancelWorkflowResponse | TerminateWorkflowResponse | RestartWorkflowResponse
105- > ;
158+ actionConfig ?: WorkflowAction < any , any , any > ;
106159} ) {
107160 const user = userEvent . setup ( ) ;
108161 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+ } ) ;
109167
110168 render (
111169 < WorkflowActionsModalContent
@@ -116,22 +174,38 @@ function setup({
116174 {
117175 endpointsMocks : [
118176 {
119- path : '/api/domains/:domain/:cluster/workflows/:workflowId/:runId/cancel ' ,
177+ path : '/api/domains/:domain/:cluster/workflows/:workflowId/:runId/:action ' ,
120178 httpMethod : 'POST' ,
121179 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+
123186 if ( error ) {
124187 return HttpResponse . json (
125188 { message : 'Failed to cancel workflow' } ,
126189 { status : 500 }
127190 ) ;
128191 }
192+
193+ if ( request . url . endsWith ( '/reset' ) ) {
194+ return HttpResponse . json ( {
195+ runId : 'new-run-id' ,
196+ } satisfies ResetWorkflowResponse ) ;
197+ }
129198 return HttpResponse . json ( { } satisfies CancelWorkflowResponse ) ;
130199 } ,
131200 } ,
132201 ] ,
133202 }
134203 ) ;
135204
136- return { user, mockOnClose } ;
205+ return {
206+ user,
207+ mockOnClose,
208+ getLatestRequestBody : ( ) => latestRequestBody ,
209+ waitForRequest : ( ) => requestPromise ,
210+ } ;
137211}
0 commit comments