Puts webhook key on the template object in WFJTEdit

Also adds aria-label to Label Select Options to improve test matchers
 Improves the name of the template payload in WFJTAdd and WFJTEdit
 Updates tests including a failing snapshot DeleteConfirmationModal
 test that was failing in devel
This commit is contained in:
Alex Corey
2020-04-13 14:39:52 -04:00
parent 27e6c2d47d
commit 440691387b
13 changed files with 38 additions and 53 deletions

View File

@@ -288,8 +288,6 @@ describe('<ProjectForm />', () => {
}); });
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0); await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
console.log(wrapper.debug());
const scmTypeSelect = wrapper.find( const scmTypeSelect = wrapper.find(
'FormGroup[label="Source Control Credential Type"] FormSelect' 'FormGroup[label="Source Control Credential Type"] FormSelect'
); );

View File

@@ -35,7 +35,7 @@ const mockJobTemplate = {
limit: '', limit: '',
name: 'Foo', name: 'Foo',
playbook: 'Baz', playbook: 'Baz',
project: { id: 3, summary_fields: { organization: { id: 1 } } }, project: 3,
scm_branch: '', scm_branch: '',
skip_tags: '', skip_tags: '',
summary_fields: { summary_fields: {

View File

@@ -32,7 +32,6 @@ class WorkflowJobTemplate extends Component {
contentError: null, contentError: null,
hasContentLoading: true, hasContentLoading: true,
template: null, template: null,
webhook_key: null,
isNotifAdmin: false, isNotifAdmin: false,
}; };
this.createSchedule = this.createSchedule.bind(this); this.createSchedule = this.createSchedule.bind(this);
@@ -59,11 +58,9 @@ class WorkflowJobTemplate extends Component {
this.setState({ contentError: null }); this.setState({ contentError: null });
try { try {
const { data } = await WorkflowJobTemplatesAPI.readDetail(id); const { data } = await WorkflowJobTemplatesAPI.readDetail(id);
let webhookKey;
if (data?.related?.webhook_key) { if (data?.related?.webhook_key) {
const { webhookKey = await WorkflowJobTemplatesAPI.readWebhookKey(id);
data: { webhook_key },
} = await WorkflowJobTemplatesAPI.readWebhookKey(id);
this.setState({ webhook_key });
} }
if (data?.summary_fields?.webhook_credential) { if (data?.summary_fields?.webhook_credential) {
const { const {
@@ -83,7 +80,7 @@ class WorkflowJobTemplate extends Component {
}); });
setBreadcrumb(data); setBreadcrumb(data);
this.setState({ this.setState({
template: data, template: { ...data, webhook_key: webhookKey.data.webhook_key },
isNotifAdmin: notifAdminRes.data.results.length > 0, isNotifAdmin: notifAdminRes.data.results.length > 0,
}); });
} catch (err) { } catch (err) {
@@ -114,7 +111,6 @@ class WorkflowJobTemplate extends Component {
contentError, contentError,
hasContentLoading, hasContentLoading,
template, template,
webhook_key,
isNotifAdmin, isNotifAdmin,
} = this.state; } = this.state;
@@ -211,10 +207,7 @@ class WorkflowJobTemplate extends Component {
key="wfjt-details" key="wfjt-details"
path="/templates/workflow_job_template/:id/details" path="/templates/workflow_job_template/:id/details"
> >
<WorkflowJobTemplateDetail <WorkflowJobTemplateDetail template={template} />
template={template}
webhook_key={webhook_key}
/>
</Route> </Route>
)} )}
{template && ( {template && (
@@ -239,10 +232,7 @@ class WorkflowJobTemplate extends Component {
key="wfjt-edit" key="wfjt-edit"
path="/templates/workflow_job_template/:id/edit" path="/templates/workflow_job_template/:id/edit"
> >
<WorkflowJobTemplateEdit <WorkflowJobTemplateEdit template={template} />
template={template}
webhook_key={webhook_key}
/>
</Route> </Route>
)} )}
{template && ( {template && (

View File

@@ -17,18 +17,18 @@ function WorkflowJobTemplateAdd() {
inventory, inventory,
organization, organization,
webhook_credential, webhook_credential,
webhookKey, webhook_key,
...remainingValues ...templatePayload
} = values; } = values;
remainingValues.inventory = inventory?.id; templatePayload.inventory = inventory?.id;
remainingValues.organization = organization?.id; templatePayload.organization = organization?.id;
remainingValues.webhook_credential = webhook_credential?.id; templatePayload.webhook_credential = webhook_credential?.id;
const organizationId = const organizationId =
organization?.id || inventory?.summary_fields?.organization.id || null; organization?.id || inventory?.summary_fields?.organization.id;
try { try {
const { const {
data: { id }, data: { id },
} = await WorkflowJobTemplatesAPI.create(remainingValues); } = await WorkflowJobTemplatesAPI.create(templatePayload);
await Promise.all(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) {

View File

@@ -85,8 +85,7 @@ describe('<WorkflowJobTemplateAdd/>', () => {
act(() => { act(() => {
wrapper wrapper
.find('SelectOption') .find('SelectOption')
.find('button') .find('button[aria-label="Label 3"]')
.at(2)
.prop('onClick')(); .prop('onClick')();
}); });

View File

@@ -25,7 +25,7 @@ import LaunchButton from '@components/LaunchButton';
import Sparkline from '@components/Sparkline'; import Sparkline from '@components/Sparkline';
import { toTitleCase } from '@util/strings'; import { toTitleCase } from '@util/strings';
function WorkflowJobTemplateDetail({ template, i18n, webhook_key }) { function WorkflowJobTemplateDetail({ template, i18n }) {
const { const {
id, id,
ask_inventory_on_launch, ask_inventory_on_launch,
@@ -38,6 +38,7 @@ function WorkflowJobTemplateDetail({ template, i18n, webhook_key }) {
summary_fields, summary_fields,
related, related,
webhook_credential, webhook_credential,
webhook_key,
} = template; } = template;
const urlOrigin = window.location.origin; const urlOrigin = window.location.origin;

View File

@@ -39,6 +39,7 @@ describe('<WorkflowJobTemplateDetail/>', () => {
user_capabilities: { edit: true, delete: true }, user_capabilities: { edit: true, delete: true },
}, },
webhook_service: 'Github', webhook_service: 'Github',
webhook_key: 'Foo webhook key',
}; };
beforeEach(async () => { beforeEach(async () => {
@@ -52,7 +53,6 @@ describe('<WorkflowJobTemplateDetail/>', () => {
component={() => ( component={() => (
<WorkflowJobTemplateDetail <WorkflowJobTemplateDetail
template={template} template={template}
webhook_key="Foo webhook key"
hasContentLoading={false} hasContentLoading={false}
onSetContentLoading={() => {}} onSetContentLoading={() => {}}
/> />

View File

@@ -6,7 +6,7 @@ import { getAddedAndRemoved } from '@util/lists';
import { WorkflowJobTemplatesAPI, OrganizationsAPI } from '@api'; import { WorkflowJobTemplatesAPI, OrganizationsAPI } from '@api';
import { WorkflowJobTemplateForm } from '../shared'; import { WorkflowJobTemplateForm } from '../shared';
function WorkflowJobTemplateEdit({ template, webhook_key }) { function WorkflowJobTemplateEdit({ template }) {
const history = useHistory(); const history = useHistory();
const [formSubmitError, setFormSubmitError] = useState(null); const [formSubmitError, setFormSubmitError] = useState(null);
@@ -16,12 +16,12 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
inventory, inventory,
organization, organization,
webhook_credential, webhook_credential,
webhookKey, webhook_key,
...remainingValues ...templatePayload
} = values; } = values;
remainingValues.inventory = inventory?.id; templatePayload.inventory = inventory?.id;
remainingValues.organization = organization?.id; templatePayload.organization = organization?.id;
remainingValues.webhook_credential = webhook_credential?.id || null; templatePayload.webhook_credential = webhook_credential?.id || null;
const formOrgId = const formOrgId =
organization?.id || inventory?.summary_fields?.organization.id || null; organization?.id || inventory?.summary_fields?.organization.id || null;
@@ -29,7 +29,7 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
await Promise.all( await Promise.all(
await submitLabels(labels, formOrgId, template.organization) await submitLabels(labels, formOrgId, template.organization)
); );
await WorkflowJobTemplatesAPI.update(template.id, remainingValues); await WorkflowJobTemplatesAPI.update(template.id, templatePayload);
history.push(`/templates/workflow_job_template/${template.id}/details`); history.push(`/templates/workflow_job_template/${template.id}/details`);
} catch (err) { } catch (err) {
setFormSubmitError(err); setFormSubmitError(err);
@@ -73,7 +73,6 @@ function WorkflowJobTemplateEdit({ template, webhook_key }) {
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
handleCancel={handleCancel} handleCancel={handleCancel}
template={template} template={template}
webhookKey={webhook_key}
submitError={formSubmitError} submitError={formSubmitError}
/> />
</CardBody> </CardBody>

View File

@@ -100,8 +100,7 @@ describe('<WorkflowJobTemplateEdit/>', () => {
act(() => { act(() => {
wrapper wrapper
.find('SelectOption') .find('SelectOption')
.find('button') .find('button[aria-label="Label 3"]')
.at(2)
.prop('onClick')(); .prop('onClick')();
}); });
@@ -110,8 +109,7 @@ describe('<WorkflowJobTemplateEdit/>', () => {
act(() => act(() =>
wrapper wrapper
.find('SelectOption') .find('SelectOption')
.find('button') .find('button[aria-label="Label 1"]')
.at(0)
.prop('onClick')() .prop('onClick')()
); );

View File

@@ -14,7 +14,7 @@ describe('<JobTemplateForm />', () => {
description: 'Bar', description: 'Bar',
job_type: 'run', job_type: 'run',
inventory: 2, inventory: 2,
project: { id: 3, summary_fields: { organization: { id: 1 } } }, project: 3,
playbook: 'Baz', playbook: 'Baz',
type: 'job_template', type: 'job_template',
scm_branch: 'Foo', scm_branch: 'Foo',

View File

@@ -47,7 +47,7 @@ function LabelSelect({ value, placeholder, onChange, onError }) {
const renderOptions = opts => { const renderOptions = opts => {
return opts.map(option => ( return opts.map(option => (
<SelectOption key={option.id} value={option}> <SelectOption key={option.id} aria-label={option.name} value={option}>
{option.name} {option.name}
</SelectOption> </SelectOption>
)); ));

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { useRouteMatch, useParams, withRouter } from 'react-router-dom'; import { useRouteMatch, useParams } from 'react-router-dom';
import PropTypes, { shape } from 'prop-types'; import PropTypes, { shape } from 'prop-types';
@@ -67,7 +67,7 @@ function WorkflowJobTemplateForm({
] = useField('webhook_service'); ] = useField('webhook_service');
const [webhookKeyField, webhookKeyMeta, webhookKeyHelpers] = useField( const [webhookKeyField, webhookKeyMeta, webhookKeyHelpers] = useField(
'webhookKey' 'webhook_key'
); );
const [hasWebhooks, setHasWebhooks] = useState( const [hasWebhooks, setHasWebhooks] = useState(
@@ -339,7 +339,7 @@ function WorkflowJobTemplateForm({
fieldId="wfjt-webhook-key" fieldId="wfjt-webhook-key"
type="text" type="text"
id="wfjt-webhook-key" id="wfjt-webhook-key"
name="webhookKey" name="webhook_key"
label={i18n._(t`Webhook Key`)} label={i18n._(t`Webhook Key`)}
> >
<FieldTooltip <FieldTooltip
@@ -397,7 +397,7 @@ WorkflowJobTemplateForm.defaultProps = {
}; };
const FormikApp = withFormik({ const FormikApp = withFormik({
mapPropsToValues({ template = {}, webhookKey }) { mapPropsToValues({ template = {} }) {
return { return {
name: template.name || '', name: template.name || '',
description: template.description || '', description: template.description || '',
@@ -417,7 +417,7 @@ const FormikApp = withFormik({
webhook_url: template?.related?.webhook_receiver webhook_url: template?.related?.webhook_receiver
? `${urlOrigin}${template.related.webhook_receiver}` ? `${urlOrigin}${template.related.webhook_receiver}`
: '', : '',
webhookKey: webhookKey || null, webhook_key: template.webhook_key || '',
}; };
}, },
handleSubmit: async (values, { props, setErrors }) => { handleSubmit: async (values, { props, setErrors }) => {
@@ -430,4 +430,4 @@ const FormikApp = withFormik({
})(WorkflowJobTemplateForm); })(WorkflowJobTemplateForm);
export { WorkflowJobTemplateForm as _WorkflowJobTemplateForm }; export { WorkflowJobTemplateForm as _WorkflowJobTemplateForm };
export default withI18n()(withRouter(FormikApp)); export default withI18n()(FormikApp);

View File

@@ -40,6 +40,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
related: { related: {
webhook_receiver: '/api/v2/workflow_job_templates/57/gitlab/', webhook_receiver: '/api/v2/workflow_job_templates/57/gitlab/',
}, },
webhook_key: 'sdfghjklmnbvcdsew435678iokjhgfd',
}; };
beforeEach(async () => { beforeEach(async () => {
@@ -74,7 +75,6 @@ describe('<WorkflowJobTemplateForm/>', () => {
template={mockTemplate} template={mockTemplate}
handleCancel={handleCancel} handleCancel={handleCancel}
handleSubmit={handleSubmit} handleSubmit={handleSubmit}
webhookKey="sdfghjklmnbvcdsew435678iokjhgfd"
/> />
)} )}
/>, />,
@@ -172,7 +172,7 @@ 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="Enable Webhooks"]').invoke('onChange')( wrapper.find('Checkbox[aria-label="Enable Webhook"]').invoke('onChange')(
true, true,
{ {
currentTarget: { value: true, type: 'change', checked: true }, currentTarget: { value: true, type: 'change', checked: true },
@@ -181,7 +181,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
}); });
wrapper.update(); wrapper.update();
expect( expect(
wrapper.find('Checkbox[aria-label="Enable Webhooks"]').prop('isChecked') wrapper.find('Checkbox[aria-label="Enable Webhook"]').prop('isChecked')
).toBe(true); ).toBe(true);
expect( expect(
@@ -192,7 +192,7 @@ describe('<WorkflowJobTemplateForm/>', () => {
).toBe('sdfghjklmnbvcdsew435678iokjhgfd'); ).toBe('sdfghjklmnbvcdsew435678iokjhgfd');
await act(() => await act(() =>
wrapper wrapper
.find('FormGroup[name="webhookKey"]') .find('FormGroup[name="webhook_key"]')
.find('Button[variant="tertiary"]') .find('Button[variant="tertiary"]')
.prop('onClick')() .prop('onClick')()
); );