@@ -5,18 +5,20 @@ import {
55} from 'sentry-fixture/automations' ;
66import { ActionHandlerFixture } from 'sentry-fixture/workflowEngine' ;
77
8- import { render , screen , userEvent } from 'sentry-test/reactTestingLibrary' ;
8+ import {
9+ render ,
10+ renderGlobalModal ,
11+ screen ,
12+ userEvent ,
13+ } from 'sentry-test/reactTestingLibrary' ;
914
10- import { openModal } from 'sentry/actionCreators/modal' ;
1115import type { Action } from 'sentry/types/workflowEngine/actions' ;
1216import { ActionGroup , ActionType } from 'sentry/types/workflowEngine/actions' ;
1317import type { Automation } from 'sentry/types/workflowEngine/automations' ;
1418import { ActionNodeContext } from 'sentry/views/automations/components/actionNodes' ;
1519import { TicketActionSettingsButton } from 'sentry/views/automations/components/actions/ticketActionSettingsButton' ;
1620import { AutomationFormProvider } from 'sentry/views/automations/components/forms/context' ;
1721
18- jest . mock ( 'sentry/actionCreators/modal' ) ;
19-
2022function renderComponent ( {
2123 action,
2224 automation,
@@ -29,6 +31,8 @@ function renderComponent({
2931 handlerGroup : ActionGroup . TICKET_CREATION ,
3032 } ) ;
3133
34+ renderGlobalModal ( ) ;
35+
3236 render (
3337 < AutomationFormProvider automation = { automation } >
3438 < ActionNodeContext . Provider
@@ -45,19 +49,28 @@ function renderComponent({
4549 ) ;
4650}
4751
48- async function getModalInstance ( ) {
49- await userEvent . click ( screen . getByRole ( 'button' , { name : 'Action Settings' } ) ) ;
50- const renderer = ( openModal as jest . Mock ) . mock . calls [ 0 ] [ 0 ] ;
51- const modalElement = renderer ( { closeModal : jest . fn ( ) } ) ;
52- return modalElement . props . instance ;
52+ /**
53+ * Mock the integration config API to return string fields for the given field
54+ * names. When the modal opens, instance values for these fields will be set as
55+ * the form input defaults, so we can assert on them.
56+ */
57+ function mockIntegrationConfig ( integrationId : string , fieldNames : string [ ] = [ ] ) {
58+ return MockApiClient . addMockResponse ( {
59+ url : `/organizations/org-slug/integrations/${ integrationId } /` ,
60+ body : {
61+ createIssueConfig : fieldNames . map ( name => ( {
62+ name,
63+ label : name ,
64+ type : 'string' ,
65+ } ) ) ,
66+ } ,
67+ } ) ;
5368}
5469
5570describe ( 'TicketActionSettingsButton' , ( ) => {
56- beforeEach ( ( ) => {
57- ( openModal as jest . Mock ) . mockClear ( ) ;
58- } ) ;
59-
6071 it ( 'uses additional_fields and dynamic_form_fields from ticketAction.data' , async ( ) => {
72+ mockIntegrationConfig ( 'int-1' , [ 'project' , 'issuetype' ] ) ;
73+
6174 const action = ActionFixture ( {
6275 id : '42' ,
6376 type : ActionType . JIRA ,
@@ -70,18 +83,16 @@ describe('TicketActionSettingsButton', () => {
7083
7184 renderComponent ( { action} ) ;
7285
73- const instance = await getModalInstance ( ) ;
74- expect ( instance ) . toEqual (
75- expect . objectContaining ( {
76- project : '10000' ,
77- issuetype : '10001' ,
78- integration : 'int-1' ,
79- dynamic_form_fields : [ { name : 'priority' , label : 'Priority' , type : 'select' } ] ,
80- } )
81- ) ;
86+ await userEvent . click ( screen . getByRole ( 'button' , { name : 'Action Settings' } ) ) ;
87+
88+ // Modal opens and form fields render with instance values as defaults
89+ expect ( await screen . findByRole ( 'textbox' , { name : 'project' } ) ) . toHaveValue ( '10000' ) ;
90+ expect ( screen . getByRole ( 'textbox' , { name : 'issuetype' } ) ) . toHaveValue ( '10001' ) ;
8291 } ) ;
8392
8493 it ( 'falls back to savedActionData with camelCase keys from API response' , async ( ) => {
94+ mockIntegrationConfig ( 'int-1' , [ 'project' , 'reporter' ] ) ;
95+
8596 const action = ActionFixture ( {
8697 id : '42' ,
8798 type : ActionType . JIRA ,
@@ -107,18 +118,15 @@ describe('TicketActionSettingsButton', () => {
107118
108119 renderComponent ( { action, automation} ) ;
109120
110- const instance = await getModalInstance ( ) ;
111- expect ( instance ) . toEqual (
112- expect . objectContaining ( {
113- project : 'CAMEL' ,
114- reporter : 'me' ,
115- integration : 'int-1' ,
116- dynamic_form_fields : [ { name : 'camelField' , label : 'Camel' , type : 'text' } ] ,
117- } )
118- ) ;
121+ await userEvent . click ( screen . getByRole ( 'button' , { name : 'Action Settings' } ) ) ;
122+
123+ expect ( await screen . findByRole ( 'textbox' , { name : 'project' } ) ) . toHaveValue ( 'CAMEL' ) ;
124+ expect ( screen . getByRole ( 'textbox' , { name : 'reporter' } ) ) . toHaveValue ( 'me' ) ;
119125 } ) ;
120126
121127 it ( 'falls back to savedActionData with snake_case keys from frontend write' , async ( ) => {
128+ mockIntegrationConfig ( 'int-1' , [ 'project' , 'reporter' ] ) ;
129+
122130 const action = ActionFixture ( {
123131 id : '42' ,
124132 type : ActionType . JIRA ,
@@ -144,18 +152,15 @@ describe('TicketActionSettingsButton', () => {
144152
145153 renderComponent ( { action, automation} ) ;
146154
147- const instance = await getModalInstance ( ) ;
148- expect ( instance ) . toEqual (
149- expect . objectContaining ( {
150- project : 'SNAKE' ,
151- reporter : 'them' ,
152- integration : 'int-1' ,
153- dynamic_form_fields : [ { name : 'snakeField' , label : 'Snake' , type : 'text' } ] ,
154- } )
155- ) ;
155+ await userEvent . click ( screen . getByRole ( 'button' , { name : 'Action Settings' } ) ) ;
156+
157+ expect ( await screen . findByRole ( 'textbox' , { name : 'project' } ) ) . toHaveValue ( 'SNAKE' ) ;
158+ expect ( screen . getByRole ( 'textbox' , { name : 'reporter' } ) ) . toHaveValue ( 'them' ) ;
156159 } ) ;
157160
158161 it ( 'uses savedActionData dynamic_form_fields when ticketAction has empty array' , async ( ) => {
162+ mockIntegrationConfig ( 'int-1' , [ 'project' ] ) ;
163+
159164 const action = ActionFixture ( {
160165 id : '42' ,
161166 type : ActionType . JIRA ,
@@ -185,13 +190,8 @@ describe('TicketActionSettingsButton', () => {
185190
186191 renderComponent ( { action, automation} ) ;
187192
188- const instance = await getModalInstance ( ) ;
189- expect ( instance ) . toEqual (
190- expect . objectContaining ( {
191- project : 'DIRECT' ,
192- integration : 'int-1' ,
193- dynamic_form_fields : [ { name : 'fromSaved' , label : 'From Saved' , type : 'select' } ] ,
194- } )
195- ) ;
193+ await userEvent . click ( screen . getByRole ( 'button' , { name : 'Action Settings' } ) ) ;
194+
195+ expect ( await screen . findByRole ( 'textbox' , { name : 'project' } ) ) . toHaveValue ( 'DIRECT' ) ;
196196 } ) ;
197197} ) ;
0 commit comments