Adds error handling test to add and edit form. Updates Form component

This commit is contained in:
Alex Corey
2020-03-02 14:48:44 -05:00
parent acfa6d056f
commit b055aad641
12 changed files with 216 additions and 130 deletions

View File

@@ -48,7 +48,7 @@ class WorkflowJobTemplates extends Base {
readScheduleList(id, params) { readScheduleList(id, params) {
return this.http.get(`${this.baseUrl}${id}/schedules/`, { return this.http.get(`${this.baseUrl}${id}/schedules/`, {
params params,
}); });
} }
} }

View File

@@ -100,6 +100,7 @@ function CredentialLookup({
}, },
]} ]}
readOnly={!canDelete} readOnly={!canDelete}
name="credential"
selectItem={item => dispatch({ type: 'SELECT_ITEM', item })} selectItem={item => dispatch({ type: 'SELECT_ITEM', item })}
deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })} deselectItem={item => dispatch({ type: 'DESELECT_ITEM', item })}
/> />

View File

@@ -221,36 +221,34 @@ class Template extends Component {
<JobList defaultParams={{ job__job_template: template.id }} /> <JobList defaultParams={{ job__job_template: template.id }} />
</Route> </Route>
)} )}
{template?.id && ( {template && (
<Route path="/templates/:templateType/:id/completed_jobs"> <Route
<JobList defaultParams={{ job__job_template: template.id }} /> path="/templates/:templateType/:id/schedules"
</Route> render={() => (
)} <ScheduleList loadSchedules={this.loadSchedules} />
{template && ( )}
/>
)}
<Route <Route
path="/templates/:templateType/:id/schedules" key="not-found"
render={() => <ScheduleList loadSchedules={this.loadSchedules} />} path="*"
render={() =>
!hasContentLoading && (
<ContentError isNotFound>
{match.params.id && (
<Link
to={`/templates/${match.params.templateType}/${match.params.id}/details`}
>
{i18n._(`View Template Details`)}
</Link>
)}
</ContentError>
)
}
/> />
)} </Switch>
<Route </Card>
key="not-found" </PageSection>
path="*"
render={() =>
!hasContentLoading && (
<ContentError isNotFound>
{match.params.id && (
<Link
to={`/templates/${match.params.templateType}/${match.params.id}/details`}
>
{i18n._(`View Template Details`)}
</Link>
)}
</ContentError>
)
}
/>
</Switch>
</Card>
); );
} }
} }

View File

@@ -21,7 +21,7 @@ class Templates extends Component {
'/templates': i18n._(t`Templates`), '/templates': i18n._(t`Templates`),
'/templates/job_template/add': i18n._(t`Create New Job Template`), '/templates/job_template/add': i18n._(t`Create New Job Template`),
'/templates/workflow_job_template/add': i18n._( '/templates/workflow_job_template/add': i18n._(
t`Create New Workflow Job Template` t`Create New Workflow Template`
), ),
}, },
}; };
@@ -35,6 +35,9 @@ class Templates extends Component {
const breadcrumbConfig = { const breadcrumbConfig = {
'/templates': i18n._(t`Templates`), '/templates': i18n._(t`Templates`),
'/templates/job_template/add': i18n._(t`Create New Job Template`), '/templates/job_template/add': i18n._(t`Create New Job Template`),
'/templates/workflow_job_template/add': i18n._(
t`Create New Workflow Template`
),
[`/templates/${template.type}/${template.id}`]: `${template.name}`, [`/templates/${template.type}/${template.id}`]: `${template.name}`,
[`/templates/${template.type}/${template.id}/details`]: i18n._( [`/templates/${template.type}/${template.id}/details`]: i18n._(
t`Details` t`Details`

View File

@@ -186,16 +186,6 @@ class WorkflowJobTemplate extends Component {
)} )}
/> />
)} )}
{template?.id && (
<Route path="/templates/workflow_job_template/:id/completed_jobs">
<JobList
defaultParams={{
workflow_job__workflow_job_template: template.id,
}}
/>
</Route>
)}
{template?.id && ( {template?.id && (
<Route path="/templates/workflow_job_template/:id/completed_jobs"> <Route path="/templates/workflow_job_template/:id/completed_jobs">
<JobList <JobList

View File

@@ -17,7 +17,7 @@ function WorkflowJobTemplateAdd() {
const { const {
data: { id }, data: { id },
} = await WorkflowJobTemplatesAPI.create(remainingValues); } = await WorkflowJobTemplatesAPI.create(remainingValues);
await submitLabels(id, labels, organizationId); await Promise.all(await submitLabels(id, labels, organizationId));
history.push(`/templates/workflow_job_template/${id}/details`); history.push(`/templates/workflow_job_template/${id}/details`);
} catch (err) { } catch (err) {
setFormSubmitError(err); setFormSubmitError(err);

View File

@@ -1,43 +1,60 @@
import React from 'react'; import React from 'react';
import { Route } from 'react-router-dom'; import { Route } from 'react-router-dom';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { WorkflowJobTemplatesAPI } from '@api'; import { WorkflowJobTemplatesAPI, OrganizationsAPI, LabelsAPI } from '@api';
import { mountWithContexts } from '@testUtils/enzymeHelpers'; import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import WorkflowJobTemplateAdd from './WorkflowJobTemplateAdd'; import WorkflowJobTemplateAdd from './WorkflowJobTemplateAdd';
jest.mock('@api'); jest.mock('@api/models/WorkflowJobTemplates');
jest.mock('@api/models/Organizations');
jest.mock('@api/models/Labels');
jest.mock('@api/models/Inventories');
describe('<WorkflowJobTemplateAdd/>', () => { describe('<WorkflowJobTemplateAdd/>', () => {
let wrapper; let wrapper;
let history; let history;
beforeEach(async () => { beforeEach(async () => {
WorkflowJobTemplatesAPI.create.mockResolvedValue({ data: { id: 1 } }); WorkflowJobTemplatesAPI.create.mockResolvedValue({ data: { id: 1 } });
OrganizationsAPI.read.mockResolvedValue({ results: [{ id: 1 }] });
LabelsAPI.read.mockResolvedValue({
data: {
results: [
{ name: 'Label 1', id: 1 },
{ name: 'Label 2', id: 2 },
{ name: 'Label 3', id: 3 },
],
},
});
await act(async () => { await act(async () => {
history = createMemoryHistory({ history = createMemoryHistory({
initialEntries: ['/templates/workflow_job_template/add'], initialEntries: ['/templates/workflow_job_template/add'],
}); });
wrapper = mountWithContexts( await act(async () => {
<Route wrapper = await mountWithContexts(
path="/templates/workflow_job_template/add" <Route
component={() => <WorkflowJobTemplateAdd />} path="/templates/workflow_job_template/add"
/>, component={() => <WorkflowJobTemplateAdd />}
{ />,
context: { {
router: { context: {
history, router: {
route: { history,
location: history.location, route: {
location: history.location,
},
}, },
}, },
}, }
} );
); });
}); });
}); });
afterEach(async () => { afterEach(async () => {
wrapper.unmount(); wrapper.unmount();
jest.clearAllMocks();
}); });
test('initially renders successfully', async () => { test('initially renders successfully', async () => {
@@ -67,28 +84,39 @@ describe('<WorkflowJobTemplateAdd/>', () => {
test('throwing error renders FormSubmitError component', async () => { test('throwing error renders FormSubmitError component', async () => {
const error = new Error('oops'); const error = new Error('oops');
WorkflowJobTemplatesAPI.create.mockImplementation(() => WorkflowJobTemplatesAPI.create.mockRejectedValue(error);
Promise.reject(error)
);
await act(async () => { await act(async () => {
await wrapper.find('WorkflowJobTemplateForm').prop('handleSubmit')({ wrapper.find('WorkflowJobTemplateForm').invoke('handleSubmit')({
id: 6, name: 'Foo',
name: 'Alex',
description: 'Apollo and Athena',
inventory: { id: 1, name: 'Inventory 1' },
organization: 2,
scm_branch: 'master',
limit: '5000',
variables: '---',
}); });
}); });
expect(wrapper.find('ContentError').length).toBe(0); expect(WorkflowJobTemplatesAPI.create).toHaveBeenCalled();
expect(wrapper.length).toBe(1);
wrapper.update(); wrapper.update();
expect(WorkflowJobTemplatesAPI.create).toBeCalled();
expect(wrapper.find('ContentError').length).toBe(1);
expect(wrapper.find('WorkflowJobTemplateForm').prop('submitError')).toEqual( expect(wrapper.find('WorkflowJobTemplateForm').prop('submitError')).toEqual(
error error
); );
}); });
test('throwing error prevents navigation away from form', async () => {
OrganizationsAPI.read.mockRejectedValue(
new Error({
response: {
config: {
method: 'get',
},
data: 'An error occurred',
},
})
);
WorkflowJobTemplatesAPI.update.mockResolvedValue();
await act(async () => {
await wrapper.find('Button[aria-label="Save"]').simulate('click');
});
expect(wrapper.find('WorkflowJobTemplateForm').length).toBe(1);
expect(OrganizationsAPI.read).toBeCalled();
expect(history.location.pathname).toBe(
'/templates/workflow_job_template/add'
);
});
}); });

View File

@@ -58,7 +58,7 @@ function WorkflowJobTemplateDetail({ template, i18n, webhook_key }) {
)} )}
{template.webhook_service && ( {template.webhook_service && (
<TextListItem component={TextListItemVariants.li}> <TextListItem component={TextListItemVariants.li}>
{i18n._(t`- Webhooks`)} {i18n._(t`- Enable Webhook`)}
</TextListItem> </TextListItem>
)} )}
</TextList> </TextList>

View File

@@ -13,7 +13,9 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
const handleSubmit = async values => { const handleSubmit = async values => {
const { labels, ...remainingValues } = values; const { labels, ...remainingValues } = values;
try { try {
await submitLabels(labels, values.organization, template.organization); await Promise.all(
await submitLabels(labels, values.organization, template.organization)
);
await WorkflowJobTemplatesAPI.update(template.id, remainingValues); await WorkflowJobTemplatesAPI.update(template.id, remainingValues);
history.push(`/templates/workflow_job_template/${template.id}/details`); history.push(`/templates/workflow_job_template/${template.id}/details`);
} catch (err) { } catch (err) {

View File

@@ -1,13 +1,15 @@
import React from 'react'; import React from 'react';
import { Route } from 'react-router-dom'; import { Route } from 'react-router-dom';
import { act } from 'react-dom/test-utils'; import { act } from 'react-dom/test-utils';
import { WorkflowJobTemplatesAPI, OrganizationsAPI } from '@api'; import { WorkflowJobTemplatesAPI, OrganizationsAPI, LabelsAPI } from '@api';
import { mountWithContexts } from '@testUtils/enzymeHelpers'; import { mountWithContexts } from '@testUtils/enzymeHelpers';
import { createMemoryHistory } from 'history'; import { createMemoryHistory } from 'history';
import WorkflowJobTemplateEdit from './WorkflowJobTemplateEdit'; import WorkflowJobTemplateEdit from './WorkflowJobTemplateEdit';
jest.mock('@api/models/WorkflowJobTemplates'); jest.mock('@api/models/WorkflowJobTemplates');
jest.mock('@api/models/Labels');
jest.mock('@api/models/Organizations'); jest.mock('@api/models/Organizations');
jest.mock('@api/models/Inventories');
const mockTemplate = { const mockTemplate = {
id: 6, id: 6,
@@ -27,8 +29,14 @@ const mockTemplate = {
describe('<WorkflowJobTemplateEdit/>', () => { describe('<WorkflowJobTemplateEdit/>', () => {
let wrapper; let wrapper;
let history; let history;
beforeEach(async () => { beforeEach(async () => {
LabelsAPI.read.mockResolvedValue({
data: {
results: [{ name: 'Label 1', id: 1 }, { name: 'Label 2', id: 2 }],
},
});
OrganizationsAPI.read.mockResolvedValue({ results: [{ id: 1 }] });
await act(async () => { await act(async () => {
history = createMemoryHistory({ history = createMemoryHistory({
initialEntries: ['/templates/workflow_job_template/6/edit'], initialEntries: ['/templates/workflow_job_template/6/edit'],
@@ -93,7 +101,6 @@ describe('<WorkflowJobTemplateEdit/>', () => {
id: 1, id: 1,
}); });
wrapper.update(); wrapper.update();
await expect(WorkflowJobTemplatesAPI.associateLabel).toBeCalledTimes(1); await expect(WorkflowJobTemplatesAPI.associateLabel).toBeCalledTimes(1);
}); });
@@ -108,7 +115,6 @@ describe('<WorkflowJobTemplateEdit/>', () => {
test('throwing error renders FormSubmitError component', async () => { test('throwing error renders FormSubmitError component', async () => {
const error = new Error('oops'); const error = new Error('oops');
OrganizationsAPI.read.mockResolvedValue({ results: [{ id: 1 }] });
WorkflowJobTemplatesAPI.update.mockRejectedValue(error); WorkflowJobTemplatesAPI.update.mockRejectedValue(error);
await act(async () => { await act(async () => {
wrapper.find('Button[aria-label="Save"]').simulate('click'); wrapper.find('Button[aria-label="Save"]').simulate('click');
@@ -120,13 +126,26 @@ describe('<WorkflowJobTemplateEdit/>', () => {
); );
}); });
test('throwing error prevents form submission', () => { test('throwing error prevents form submission', async () => {
OrganizationsAPI.read.mockRejectedValue(new Error('An error occurred')); const templateWithoutOrg = {
WorkflowJobTemplatesAPI.update.mockResolvedValue(); id: 6,
name: 'Foo',
description: 'Foo description',
summary_fields: {
inventory: { id: 1, name: 'Inventory 1' },
labels: {
results: [{ name: 'Label 1', id: 1 }, { name: 'Label 2', id: 2 }],
},
},
scm_branch: 'devel',
limit: '5000',
variables: '---',
};
act(() => { let newWrapper;
wrapper = mountWithContexts( await act(async () => {
<WorkflowJobTemplateEdit template={mockTemplate} />, newWrapper = await mountWithContexts(
<WorkflowJobTemplateEdit template={templateWithoutOrg} />,
{ {
context: { context: {
router: { router: {
@@ -136,9 +155,22 @@ describe('<WorkflowJobTemplateEdit/>', () => {
} }
); );
}); });
wrapper.find('Button[aria-label="Save"]').simulate('click'); OrganizationsAPI.read.mockRejectedValue(
new Error({
response: {
config: {
method: 'get',
},
data: 'An error occurred',
},
})
);
WorkflowJobTemplatesAPI.update.mockResolvedValue();
expect(wrapper.find('WorkflowJobTemplateForm').length).toBe(1); await act(async () => {
await newWrapper.find('Button[aria-label="Save"]').simulate('click');
});
expect(newWrapper.find('WorkflowJobTemplateForm').length).toBe(1);
expect(OrganizationsAPI.read).toBeCalled(); expect(OrganizationsAPI.read).toBeCalled();
expect(WorkflowJobTemplatesAPI.update).not.toBeCalled(); expect(WorkflowJobTemplatesAPI.update).not.toBeCalled();
expect(history.location.pathname).toBe( expect(history.location.pathname).toBe(

View File

@@ -49,12 +49,15 @@ function WorkflowJobTemplateForm({
submitError, submitError,
}) { }) {
const urlOrigin = window.location.origin; const urlOrigin = window.location.origin;
const { id } = useParams(); const { id } = useParams();
const wfjtAddMatch = useRouteMatch('/templates/workflow_job_template/add'); const wfjtAddMatch = useRouteMatch('/templates/workflow_job_template/add');
const [hasContentError, setContentError] = useState(null); const [hasContentError, setContentError] = useState(null);
const [webhook_url, setWebhookUrl] = useState(
template?.related?.webhook_receiver
? `${urlOrigin}${template.related.webhook_receiver}`
: ''
);
const [inventory, setInventory] = useState( const [inventory, setInventory] = useState(
template?.summary_fields?.inventory || null template?.summary_fields?.inventory || null
); );
@@ -141,8 +144,11 @@ function WorkflowJobTemplateForm({
); );
setWebhookCredential(initialWebhookCredential); setWebhookCredential(initialWebhookCredential);
form.setFieldValue('webhook_url', form.initialValues.webhook_url); setWebhookUrl(
template?.related?.webhook_receiver
? `${urlOrigin}${template.related.webhook_receiver}`
: ''
);
form.setFieldValue('webhook_service', form.initialValues.webhook_service); form.setFieldValue('webhook_service', form.initialValues.webhook_service);
setWebHookService(form.initialValues.webhook_service); setWebHookService(form.initialValues.webhook_service);
@@ -151,8 +157,7 @@ function WorkflowJobTemplateForm({
form.setFieldValue('webhook_credential', null); form.setFieldValue('webhook_credential', null);
setWebhookCredential(null); setWebhookCredential(null);
form.setFieldValue( setWebhookUrl(
'webhook_url',
`${urlOrigin}/api/v2/workflow_job_templates/${template.id}/${webhookServiceValue}/` `${urlOrigin}/api/v2/workflow_job_templates/${template.id}/${webhookServiceValue}/`
); );
@@ -171,7 +176,7 @@ function WorkflowJobTemplateForm({
initialWebhookKey = webhookKey; initialWebhookKey = webhookKey;
form.setFieldValue('webhook_credential', null); form.setFieldValue('webhook_credential', null);
form.setFieldValue('webhook_service', ''); form.setFieldValue('webhook_service', '');
form.setFieldValue('webhook_url', ''); setWebhookUrl('');
setWebHookService(''); setWebHookService('');
setWebHookKey(''); setWebHookKey('');
} else { } else {
@@ -203,11 +208,8 @@ function WorkflowJobTemplateForm({
labels: template.summary_fields?.labels?.results || [], labels: template.summary_fields?.labels?.results || [],
extra_vars: template.variables || '---', extra_vars: template.variables || '---',
limit: template.limit || '', limit: template.limit || '',
scmBranch: template.scm_branch || '', scm_branch: template.scm_branch || '',
allow_simultaneous: template.allow_simultaneous || false, allow_simultaneous: template.allow_simultaneous || false,
webhook_url:
template?.related?.webhook_receiver &&
`${urlOrigin}${template?.related?.webhook_receiver}`,
webhook_credential: webhook_credential:
template?.summary_fields?.webhook_credential?.id || null, template?.summary_fields?.webhook_credential?.id || null,
webhook_service: template.webhook_service || '', webhook_service: template.webhook_service || '',
@@ -290,8 +292,8 @@ function WorkflowJobTemplateForm({
tooltip={i18n._( tooltip={i18n._(
t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch.` t`Select a branch for the workflow. This branch is applied to all job template nodes that prompt for a branch.`
)} )}
id="wfjt-scmBranch" id="wfjt-scm_branch"
name="scmBranch" name="scm_branch"
/> />
</FormColumnLayout> </FormColumnLayout>
<FormFullWidthLayout> <FormFullWidthLayout>
@@ -333,17 +335,13 @@ function WorkflowJobTemplateForm({
isInline isInline
label={i18n._(t`Options`)} label={i18n._(t`Options`)}
> >
<Field <Field id="wfjt-webhooks" name="hasWebhooks">
id="wfjt-webhooks"
name="hasWebhooks"
label={i18n._(t`Webhooks`)}
>
{({ form }) => ( {({ form }) => (
<Checkbox <Checkbox
aria-label={i18n._(t`Webhooks`)} aria-label={i18n._(t`Enable Webhook`)}
label={ label={
<span> <span>
{i18n._(t`Webhooks`)} {i18n._(t`Enable Webhook`)}
&nbsp; &nbsp;
<FieldTooltip <FieldTooltip
content={i18n._( content={i18n._(
@@ -408,16 +406,24 @@ function WorkflowJobTemplateForm({
</Field> </Field>
{!wfjtAddMatch && ( {!wfjtAddMatch && (
<> <>
<FormField <FormGroup
type="text" type="text"
fieldId="wfjt-webhookURL"
label={i18n._(t`Webhook URL`)} label={i18n._(t`Webhook URL`)}
id="wfjt-webhook-url" id="wfjt-webhook-url"
name="webhook_url" name="webhook_url"
tooltip={i18n._( >
t`Webhook services can launch jobs with this job template by making a POST request to this URL.` <FieldTooltip
)} content={i18n._(
isReadOnly t`Webhook services can launch jobs with this workflow job template by making a POST request to this URL.`
/> )}
/>
<TextInput
aria-label={i18n._(t`Webhook URL`)}
value={webhook_url}
isReadOnly
/>
</FormGroup>
<Field> <Field>
{({ form }) => ( {({ form }) => (
<FormGroup <FormGroup

View File

@@ -6,13 +6,17 @@ import { sleep } from '@testUtils/testUtils';
import { mountWithContexts } from '@testUtils/enzymeHelpers'; import { mountWithContexts } from '@testUtils/enzymeHelpers';
import WorkflowJobTemplateForm from './WorkflowJobTemplateForm'; import WorkflowJobTemplateForm from './WorkflowJobTemplateForm';
import { WorkflowJobTemplatesAPI } from '@api'; import {
WorkflowJobTemplatesAPI,
LabelsAPI,
OrganizationsAPI,
InventoriesAPI,
} from '@api';
jest.mock('@api/models/WorkflowJobTemplates'); jest.mock('@api/models/WorkflowJobTemplates');
jest.mock('@api/models/Labels');
WorkflowJobTemplatesAPI.updateWebhookKey.mockResolvedValue({ jest.mock('@api/models/Organizations');
data: { webhook_key: 'sdafdghjkl2345678ionbvcxz' }, jest.mock('@api/models/Inventories');
});
describe('<WorkflowJobTemplateForm/>', () => { describe('<WorkflowJobTemplateForm/>', () => {
let wrapper; let wrapper;
@@ -38,12 +42,31 @@ describe('<WorkflowJobTemplateForm/>', () => {
}, },
}; };
beforeEach(() => { beforeEach(async () => {
WorkflowJobTemplatesAPI.updateWebhookKey.mockResolvedValue({
data: { webhook_key: 'sdafdghjkl2345678ionbvcxz' },
});
LabelsAPI.read.mockResolvedValue({
data: {
results: [
{ name: 'Label 1', id: 1 },
{ name: 'Label 2', id: 2 },
{ name: 'Label 3', id: 3 },
],
},
});
OrganizationsAPI.read.mockResolvedValue({
results: [{ id: 1 }, { id: 2 }],
});
InventoriesAPI.read.mockResolvedValue({
results: [{ id: 1, name: 'Foo' }, { id: 2, name: 'Bar' }],
});
history = createMemoryHistory({ history = createMemoryHistory({
initialEntries: ['/templates/workflow_job_template/6/edit'], initialEntries: ['/templates/workflow_job_template/6/edit'],
}); });
act(() => { await act(async () => {
wrapper = mountWithContexts( wrapper = await mountWithContexts(
<Route <Route
path="/templates/workflow_job_template/:id/edit" path="/templates/workflow_job_template/:id/edit"
component={() => ( component={() => (
@@ -86,7 +109,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
'Field[name="organization"]', 'Field[name="organization"]',
'Field[name="inventory"]', 'Field[name="inventory"]',
'FormField[name="limit"]', 'FormField[name="limit"]',
'FormField[name="scmBranch"]', 'FormField[name="scm_branch"]',
'Field[name="labels"]', 'Field[name="labels"]',
'VariablesField', 'VariablesField',
]; ];
@@ -108,8 +131,8 @@ describe('<WorkflowJobTemplateForm/>', () => {
}, },
{ element: 'wfjt-limit', value: { value: 1234567890, name: 'limit' } }, { element: 'wfjt-limit', value: { value: 1234567890, name: 'limit' } },
{ {
element: 'wfjt-scmBranch', element: 'wfjt-scm_branch',
value: { value: 'new branch', name: 'scmBranch' }, value: { value: 'new branch', name: 'scm_branch' },
}, },
]; ];
const changeInputs = async ({ element, value }) => { const changeInputs = async ({ element, value }) => {
@@ -122,7 +145,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
inputsToChange.map(input => changeInputs(input)); inputsToChange.map(input => changeInputs(input));
wrapper.find('LabelSelect').invoke('onChange')([ wrapper.find('LabelSelect').invoke('onChange')([
{ name: 'new label', id: 5 }, { name: 'Label 3', id: 3 },
{ name: 'Label 1', id: 1 }, { name: 'Label 1', id: 1 },
{ name: 'Label 2', id: 2 }, { name: 'Label 2', id: 2 },
]); ]);
@@ -148,13 +171,16 @@ describe('<WorkflowJobTemplateForm/>', () => {
test('webhooks and enable concurrent jobs functions properly', async () => { test('webhooks and enable concurrent jobs functions properly', async () => {
act(() => { act(() => {
wrapper.find('Checkbox[aria-label="Webhooks"]').invoke('onChange')(true, { wrapper.find('Checkbox[aria-label="Enable Webhook"]').invoke('onChange')(
currentTarget: { value: true, type: 'change', checked: true }, true,
}); {
currentTarget: { value: true, type: 'change', checked: true },
}
);
}); });
wrapper.update(); wrapper.update();
expect( expect(
wrapper.find('Checkbox[aria-label="Webhooks"]').prop('isChecked') wrapper.find('Checkbox[aria-label="Enable Webhook"]').prop('isChecked')
).toBe(true); ).toBe(true);
expect( expect(
@@ -171,7 +197,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
); );
expect(WorkflowJobTemplatesAPI.updateWebhookKey).toBeCalledWith('6'); expect(WorkflowJobTemplatesAPI.updateWebhookKey).toBeCalledWith('6');
expect( expect(
wrapper.find('TextInputBase[name="webhook_url"]').prop('value') wrapper.find('TextInputBase[aria-label="Webhook URL"]').prop('value')
).toContain('/api/v2/workflow_job_templates/57/gitlab/'); ).toContain('/api/v2/workflow_job_templates/57/gitlab/');
wrapper.update(); wrapper.update();