summaryrefslogtreecommitdiff
path: root/spec/frontend/integrations
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 12:26:25 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 12:26:25 +0000
commita09983ae35713f5a2bbb100981116d31ce99826e (patch)
tree2ee2af7bd104d57086db360a7e6d8c9d5d43667a /spec/frontend/integrations
parent18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff)
downloadgitlab-ce-a09983ae35713f5a2bbb100981116d31ce99826e.tar.gz
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'spec/frontend/integrations')
-rw-r--r--spec/frontend/integrations/edit/components/active_toggle_spec.js18
-rw-r--r--spec/frontend/integrations/edit/components/dynamic_field_spec.js242
-rw-r--r--spec/frontend/integrations/edit/components/integration_form_spec.js94
-rw-r--r--spec/frontend/integrations/edit/components/jira_issues_fields_spec.js96
-rw-r--r--spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js25
-rw-r--r--spec/frontend/integrations/edit/components/trigger_fields_spec.js51
-rw-r--r--spec/frontend/integrations/edit/mock_data.js18
-rw-r--r--spec/frontend/integrations/edit/store/actions_spec.js19
-rw-r--r--spec/frontend/integrations/edit/store/getters_spec.js71
-rw-r--r--spec/frontend/integrations/edit/store/mutations_spec.js19
-rw-r--r--spec/frontend/integrations/edit/store/state_spec.js26
11 files changed, 561 insertions, 118 deletions
diff --git a/spec/frontend/integrations/edit/components/active_toggle_spec.js b/spec/frontend/integrations/edit/components/active_toggle_spec.js
index 5469b45f708..228d8f5fc30 100644
--- a/spec/frontend/integrations/edit/components/active_toggle_spec.js
+++ b/spec/frontend/integrations/edit/components/active_toggle_spec.js
@@ -1,8 +1,10 @@
import { mount } from '@vue/test-utils';
-import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
import { GlToggle } from '@gitlab/ui';
+import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
+
const GL_TOGGLE_ACTIVE_CLASS = 'is-checked';
+const GL_TOGGLE_DISABLED_CLASS = 'is-disabled';
describe('ActiveToggle', () => {
let wrapper;
@@ -11,9 +13,12 @@ describe('ActiveToggle', () => {
initialActivated: true,
};
- const createComponent = props => {
+ const createComponent = (props = {}, isInheriting = false) => {
wrapper = mount(ActiveToggle, {
propsData: { ...defaultProps, ...props },
+ computed: {
+ isInheriting: () => isInheriting,
+ },
});
};
@@ -29,6 +34,15 @@ describe('ActiveToggle', () => {
const findInputInToggle = () => findGlToggle().find('input');
describe('template', () => {
+ describe('is inheriting adminSettings', () => {
+ it('renders GlToggle as disabled', () => {
+ createComponent({}, true);
+
+ expect(findGlToggle().exists()).toBe(true);
+ expect(findButtonInToggle().classes()).toContain(GL_TOGGLE_DISABLED_CLASS);
+ });
+ });
+
describe('initialActivated is false', () => {
it('renders GlToggle as inactive', () => {
createComponent({
diff --git a/spec/frontend/integrations/edit/components/dynamic_field_spec.js b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
index e5710641f81..3a7a0efcab7 100644
--- a/spec/frontend/integrations/edit/components/dynamic_field_spec.js
+++ b/spec/frontend/integrations/edit/components/dynamic_field_spec.js
@@ -14,9 +14,12 @@ describe('DynamicField', () => {
value: '1',
};
- const createComponent = props => {
+ const createComponent = (props, isInheriting = false) => {
wrapper = mount(DynamicField, {
propsData: { ...defaultProps, ...props },
+ computed: {
+ isInheriting: () => isInheriting,
+ },
});
};
@@ -34,108 +37,143 @@ describe('DynamicField', () => {
const findGlFormTextarea = () => wrapper.find(GlFormTextarea);
describe('template', () => {
- describe('dynamic field', () => {
- describe('type is checkbox', () => {
- beforeEach(() => {
- createComponent({
- type: 'checkbox',
+ describe.each([[true, 'disabled', 'readonly'], [false, undefined, undefined]])(
+ 'dynamic field, when isInheriting = `%p`',
+ (isInheriting, disabled, readonly) => {
+ describe('type is checkbox', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ type: 'checkbox',
+ },
+ isInheriting,
+ );
});
- });
- it('renders GlFormCheckbox', () => {
- expect(findGlFormCheckbox().exists()).toBe(true);
- });
+ it(`renders GlFormCheckbox, which ${isInheriting ? 'is' : 'is not'} disabled`, () => {
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ expect(
+ findGlFormCheckbox()
+ .find('[type=checkbox]')
+ .attributes('disabled'),
+ ).toBe(disabled);
+ });
- it('does not render other types of input', () => {
- expect(findGlFormSelect().exists()).toBe(false);
- expect(findGlFormTextarea().exists()).toBe(false);
- expect(findGlFormInput().exists()).toBe(false);
+ it('does not render other types of input', () => {
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
});
- });
- describe('type is select', () => {
- beforeEach(() => {
- createComponent({
- type: 'select',
- choices: [['all', 'All details'], ['standard', 'Standard']],
+ describe('type is select', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ type: 'select',
+ choices: [['all', 'All details'], ['standard', 'Standard']],
+ },
+ isInheriting,
+ );
});
- });
- it('renders findGlFormSelect', () => {
- expect(findGlFormSelect().exists()).toBe(true);
- expect(findGlFormSelect().findAll('option')).toHaveLength(2);
- });
+ it(`renders GlFormSelect, which ${isInheriting ? 'is' : 'is not'} disabled`, () => {
+ expect(findGlFormSelect().exists()).toBe(true);
+ expect(findGlFormSelect().findAll('option')).toHaveLength(2);
+ expect(
+ findGlFormSelect()
+ .find('select')
+ .attributes('disabled'),
+ ).toBe(disabled);
+ });
- it('does not render other types of input', () => {
- expect(findGlFormCheckbox().exists()).toBe(false);
- expect(findGlFormTextarea().exists()).toBe(false);
- expect(findGlFormInput().exists()).toBe(false);
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
});
- });
- describe('type is textarea', () => {
- beforeEach(() => {
- createComponent({
- type: 'textarea',
+ describe('type is textarea', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ type: 'textarea',
+ },
+ isInheriting,
+ );
});
- });
- it('renders findGlFormTextarea', () => {
- expect(findGlFormTextarea().exists()).toBe(true);
- });
+ it(`renders GlFormTextarea, which ${isInheriting ? 'is' : 'is not'} readonly`, () => {
+ expect(findGlFormTextarea().exists()).toBe(true);
+ expect(
+ findGlFormTextarea()
+ .find('textarea')
+ .attributes('readonly'),
+ ).toBe(readonly);
+ });
- it('does not render other types of input', () => {
- expect(findGlFormCheckbox().exists()).toBe(false);
- expect(findGlFormSelect().exists()).toBe(false);
- expect(findGlFormInput().exists()).toBe(false);
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormInput().exists()).toBe(false);
+ });
});
- });
- describe('type is password', () => {
- beforeEach(() => {
- createComponent({
- type: 'password',
+ describe('type is password', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ type: 'password',
+ },
+ isInheriting,
+ );
});
- });
- it('renders GlFormInput', () => {
- expect(findGlFormInput().exists()).toBe(true);
- expect(findGlFormInput().attributes('type')).toBe('password');
- });
+ it(`renders GlFormInput, which ${isInheriting ? 'is' : 'is not'} readonly`, () => {
+ expect(findGlFormInput().exists()).toBe(true);
+ expect(findGlFormInput().attributes('type')).toBe('password');
+ expect(findGlFormInput().attributes('readonly')).toBe(readonly);
+ });
- it('does not render other types of input', () => {
- expect(findGlFormCheckbox().exists()).toBe(false);
- expect(findGlFormSelect().exists()).toBe(false);
- expect(findGlFormTextarea().exists()).toBe(false);
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ });
});
- });
- describe('type is text', () => {
- beforeEach(() => {
- createComponent({
- type: 'text',
- required: true,
+ describe('type is text', () => {
+ beforeEach(() => {
+ createComponent(
+ {
+ type: 'text',
+ required: true,
+ },
+ isInheriting,
+ );
});
- });
- it('renders GlFormInput', () => {
- expect(findGlFormInput().exists()).toBe(true);
- expect(findGlFormInput().attributes()).toMatchObject({
- type: 'text',
- id: 'service_project_url',
- name: 'service[project_url]',
- placeholder: defaultProps.placeholder,
- required: 'required',
+ it(`renders GlFormInput, which ${isInheriting ? 'is' : 'is not'} readonly`, () => {
+ expect(findGlFormInput().exists()).toBe(true);
+ expect(findGlFormInput().attributes()).toMatchObject({
+ type: 'text',
+ id: 'service_project_url',
+ name: 'service[project_url]',
+ placeholder: defaultProps.placeholder,
+ required: 'required',
+ });
+ expect(findGlFormInput().attributes('readonly')).toBe(readonly);
});
- });
- it('does not render other types of input', () => {
- expect(findGlFormCheckbox().exists()).toBe(false);
- expect(findGlFormSelect().exists()).toBe(false);
- expect(findGlFormTextarea().exists()).toBe(false);
+ it('does not render other types of input', () => {
+ expect(findGlFormCheckbox().exists()).toBe(false);
+ expect(findGlFormSelect().exists()).toBe(false);
+ expect(findGlFormTextarea().exists()).toBe(false);
+ });
});
- });
- });
+ },
+ );
describe('help text', () => {
it('renders description with help text', () => {
@@ -147,6 +185,20 @@ describe('DynamicField', () => {
.text(),
).toBe(defaultProps.help);
});
+
+ it('renders description with help text as HTML', () => {
+ const helpHTML = 'The <strong>URL</strong> of the project';
+
+ createComponent({
+ help: helpHTML,
+ });
+
+ expect(
+ findGlFormGroup()
+ .find('small')
+ .html(),
+ ).toContain(helpHTML);
+ });
});
describe('label text', () => {
@@ -175,5 +227,39 @@ describe('DynamicField', () => {
});
});
});
+
+ describe('validations', () => {
+ describe('password field', () => {
+ beforeEach(() => {
+ createComponent({
+ type: 'password',
+ required: true,
+ value: null,
+ });
+
+ wrapper.vm.validated = true;
+ });
+
+ describe('without value', () => {
+ it('requires validation', () => {
+ expect(wrapper.vm.valid).toBe(false);
+ expect(findGlFormGroup().classes('is-invalid')).toBe(true);
+ expect(findGlFormInput().classes('is-invalid')).toBe(true);
+ });
+ });
+
+ describe('with value', () => {
+ beforeEach(() => {
+ wrapper.setProps({ value: 'true' });
+ });
+
+ it('does not require validation', () => {
+ expect(wrapper.vm.valid).toBe(true);
+ expect(findGlFormGroup().classes('is-valid')).toBe(true);
+ expect(findGlFormInput().classes('is-valid')).toBe(true);
+ });
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js
index b598a71cea8..482c6a439f2 100644
--- a/spec/frontend/integrations/edit/components/integration_form_spec.js
+++ b/spec/frontend/integrations/edit/components/integration_form_spec.js
@@ -1,32 +1,32 @@
import { shallowMount } from '@vue/test-utils';
+import { createStore } from '~/integrations/edit/store';
import IntegrationForm from '~/integrations/edit/components/integration_form.vue';
+import OverrideDropdown from '~/integrations/edit/components/override_dropdown.vue';
import ActiveToggle from '~/integrations/edit/components/active_toggle.vue';
import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
+import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
+import { mockIntegrationProps } from 'jest/integrations/edit/mock_data';
describe('IntegrationForm', () => {
let wrapper;
- const defaultProps = {
- activeToggleProps: {
- initialActivated: true,
- },
- showActive: true,
- triggerFieldsProps: {
- initialTriggerCommit: false,
- initialTriggerMergeRequest: false,
- initialEnableComments: false,
- },
- type: '',
- };
-
- const createComponent = props => {
+ const createComponent = (customStateProps = {}, featureFlags = {}, initialState = {}) => {
wrapper = shallowMount(IntegrationForm, {
- propsData: { ...defaultProps, ...props },
+ propsData: {},
+ store: createStore({
+ customState: { ...mockIntegrationProps, ...customStateProps },
+ ...initialState,
+ }),
stubs: {
+ OverrideDropdown,
ActiveToggle,
JiraTriggerFields,
+ TriggerFields,
+ },
+ provide: {
+ glFeatures: featureFlags,
},
});
};
@@ -38,8 +38,10 @@ describe('IntegrationForm', () => {
}
});
+ const findOverrideDropdown = () => wrapper.find(OverrideDropdown);
const findActiveToggle = () => wrapper.find(ActiveToggle);
const findJiraTriggerFields = () => wrapper.find(JiraTriggerFields);
+ const findJiraIssuesFields = () => wrapper.find(JiraIssuesFields);
const findTriggerFields = () => wrapper.find(TriggerFields);
describe('template', () => {
@@ -62,23 +64,41 @@ describe('IntegrationForm', () => {
});
describe('type is "slack"', () => {
- it('does not render JiraTriggerFields', () => {
- createComponent({
- type: 'slack',
- });
+ beforeEach(() => {
+ createComponent({ type: 'slack' });
+ });
+ it('does not render JiraTriggerFields', () => {
expect(findJiraTriggerFields().exists()).toBe(false);
});
+
+ it('does not render JiraIssuesFields', () => {
+ expect(findJiraIssuesFields().exists()).toBe(false);
+ });
});
describe('type is "jira"', () => {
it('renders JiraTriggerFields', () => {
- createComponent({
- type: 'jira',
- });
+ createComponent({ type: 'jira' });
expect(findJiraTriggerFields().exists()).toBe(true);
});
+
+ describe('featureFlag jiraIssuesIntegration is false', () => {
+ it('does not render JiraIssuesFields', () => {
+ createComponent({ type: 'jira' }, { jiraIssuesIntegration: false });
+
+ expect(findJiraIssuesFields().exists()).toBe(false);
+ });
+ });
+
+ describe('featureFlag jiraIssuesIntegration is true', () => {
+ it('renders JiraIssuesFields', () => {
+ createComponent({ type: 'jira' }, { jiraIssuesIntegration: true });
+
+ expect(findJiraIssuesFields().exists()).toBe(true);
+ });
+ });
});
describe('triggerEvents is present', () => {
@@ -116,5 +136,35 @@ describe('IntegrationForm', () => {
});
});
});
+
+ describe('adminState state is null', () => {
+ it('does not render OverrideDropdown', () => {
+ createComponent(
+ {},
+ {},
+ {
+ adminState: null,
+ },
+ );
+
+ expect(findOverrideDropdown().exists()).toBe(false);
+ });
+ });
+
+ describe('adminState state is an object', () => {
+ it('renders OverrideDropdown', () => {
+ createComponent(
+ {},
+ {},
+ {
+ adminState: {
+ ...mockIntegrationProps,
+ },
+ },
+ );
+
+ expect(findOverrideDropdown().exists()).toBe(true);
+ });
+ });
});
});
diff --git a/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
new file mode 100644
index 00000000000..f58825f6297
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/jira_issues_fields_spec.js
@@ -0,0 +1,96 @@
+import { mount } from '@vue/test-utils';
+
+import { GlFormCheckbox, GlFormInput } from '@gitlab/ui';
+
+import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
+
+describe('JiraIssuesFields', () => {
+ let wrapper;
+
+ const defaultProps = {
+ showJiraIssuesIntegration: true,
+ editProjectPath: '/edit',
+ };
+
+ const createComponent = props => {
+ wrapper = mount(JiraIssuesFields, {
+ propsData: { ...defaultProps, ...props },
+ });
+ };
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ wrapper = null;
+ }
+ });
+
+ const findEnableCheckbox = () => wrapper.find(GlFormCheckbox);
+ const findProjectKey = () => wrapper.find(GlFormInput);
+ const expectedBannerText = 'This is a Premium feature';
+
+ describe('template', () => {
+ describe('upgrade banner for non-Premium user', () => {
+ beforeEach(() => {
+ createComponent({ initialProjectKey: '', showJiraIssuesIntegration: false });
+ });
+
+ it('shows upgrade banner', () => {
+ expect(wrapper.text()).toContain(expectedBannerText);
+ });
+
+ it('does not show checkbox and input field', () => {
+ expect(findEnableCheckbox().exists()).toBe(false);
+ expect(findProjectKey().exists()).toBe(false);
+ });
+ });
+
+ describe('Enable Jira issues checkbox', () => {
+ beforeEach(() => {
+ createComponent({ initialProjectKey: '' });
+ });
+
+ it('does not show upgrade banner', () => {
+ expect(wrapper.text()).not.toContain(expectedBannerText);
+ });
+
+ // As per https://vuejs.org/v2/guide/forms.html#Checkbox-1,
+ // browsers don't include unchecked boxes in form submissions.
+ it('includes issues_enabled as false even if unchecked', () => {
+ expect(wrapper.contains('input[name="service[issues_enabled]"]')).toBe(true);
+ });
+
+ it('disables project_key input', () => {
+ expect(findProjectKey().attributes('disabled')).toBe('disabled');
+ });
+
+ it('does not require project_key', () => {
+ expect(findProjectKey().attributes('required')).toBeUndefined();
+ });
+
+ describe('on enable issues', () => {
+ it('enables project_key input', () => {
+ findEnableCheckbox().vm.$emit('input', true);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findProjectKey().attributes('disabled')).toBeUndefined();
+ });
+ });
+
+ it('requires project_key input', () => {
+ findEnableCheckbox().vm.$emit('input', true);
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findProjectKey().attributes('required')).toBe('required');
+ });
+ });
+ });
+ });
+
+ it('contains link to editProjectPath', () => {
+ createComponent();
+
+ expect(wrapper.contains(`a[href="${defaultProps.editProjectPath}"]`)).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js b/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
index e4c2a0be6a3..782930eb6a2 100644
--- a/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/jira_trigger_fields_spec.js
@@ -1,6 +1,6 @@
import { mount } from '@vue/test-utils';
-import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
import { GlFormCheckbox } from '@gitlab/ui';
+import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
describe('JiraTriggerFields', () => {
let wrapper;
@@ -11,9 +11,12 @@ describe('JiraTriggerFields', () => {
initialEnableComments: false,
};
- const createComponent = props => {
+ const createComponent = (props, isInheriting = false) => {
wrapper = mount(JiraTriggerFields, {
propsData: { ...defaultProps, ...props },
+ computed: {
+ isInheriting: () => isInheriting,
+ },
});
};
@@ -93,5 +96,23 @@ describe('JiraTriggerFields', () => {
expect(findCommentDetail().isVisible()).toBe(true);
});
});
+
+ it('disables checkboxes and radios if inheriting', () => {
+ createComponent(
+ {
+ initialTriggerCommit: true,
+ initialEnableComments: true,
+ },
+ true,
+ );
+
+ wrapper.findAll('[type=checkbox]').wrappers.forEach(checkbox => {
+ expect(checkbox.attributes('disabled')).toBe('disabled');
+ });
+
+ wrapper.findAll('[type=radio]').wrappers.forEach(radio => {
+ expect(radio.attributes('disabled')).toBe('disabled');
+ });
+ });
});
});
diff --git a/spec/frontend/integrations/edit/components/trigger_fields_spec.js b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
index 337876c6d16..41bccb8ada0 100644
--- a/spec/frontend/integrations/edit/components/trigger_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
@@ -9,9 +9,12 @@ describe('TriggerFields', () => {
type: 'slack',
};
- const createComponent = props => {
+ const createComponent = (props, isInheriting = false) => {
wrapper = mount(TriggerFields, {
propsData: { ...defaultProps, ...props },
+ computed: {
+ isInheriting: () => isInheriting,
+ },
});
};
@@ -22,10 +25,11 @@ describe('TriggerFields', () => {
}
});
+ const findAllGlFormGroups = () => wrapper.find('#trigger-fields').findAll(GlFormGroup);
const findAllGlFormCheckboxes = () => wrapper.findAll(GlFormCheckbox);
const findAllGlFormInputs = () => wrapper.findAll(GlFormInput);
- describe('template', () => {
+ describe.each([true, false])('template, isInheriting = `%p`', isInheriting => {
it('renders a label with text "Trigger"', () => {
createComponent();
@@ -51,9 +55,12 @@ describe('TriggerFields', () => {
];
beforeEach(() => {
- createComponent({
- events,
- });
+ createComponent(
+ {
+ events,
+ },
+ isInheriting,
+ );
});
it('does not render GlFormInput for each event', () => {
@@ -69,8 +76,10 @@ describe('TriggerFields', () => {
});
});
- it('renders GlFormCheckbox for each event', () => {
- const checkboxes = findAllGlFormCheckboxes();
+ it(`renders GlFormCheckbox and corresponding hidden input for each event, which ${
+ isInheriting ? 'is' : 'is not'
+ } disabled`, () => {
+ const checkboxes = findAllGlFormGroups();
const expectedResults = [
{ labelText: 'Push', inputName: 'service[push_event]' },
{ labelText: 'Merge Request', inputName: 'service[merge_requests_event]' },
@@ -78,14 +87,22 @@ describe('TriggerFields', () => {
expect(checkboxes).toHaveLength(2);
checkboxes.wrappers.forEach((checkbox, index) => {
+ const checkBox = checkbox.find(GlFormCheckbox);
+
expect(checkbox.find('label').text()).toBe(expectedResults[index].labelText);
- expect(checkbox.find('input').attributes('name')).toBe(expectedResults[index].inputName);
- expect(checkbox.vm.$attrs.checked).toBe(events[index].value);
+ expect(checkbox.find('[type=hidden]').attributes('name')).toBe(
+ expectedResults[index].inputName,
+ );
+ expect(checkbox.find('[type=hidden]').attributes('value')).toBe(
+ events[index].value.toString(),
+ );
+ expect(checkBox.vm.$attrs.disabled).toBe(isInheriting);
+ expect(checkBox.vm.$attrs.checked).toBe(events[index].value);
});
});
});
- describe('events with field property', () => {
+ describe('events with field property, isInheriting = `%p`', () => {
const events = [
{
field: {
@@ -102,16 +119,21 @@ describe('TriggerFields', () => {
];
beforeEach(() => {
- createComponent({
- events,
- });
+ createComponent(
+ {
+ events,
+ },
+ isInheriting,
+ );
});
it('renders GlFormCheckbox for each event', () => {
expect(findAllGlFormCheckboxes()).toHaveLength(2);
});
- it('renders GlFormInput for each event', () => {
+ it(`renders GlFormInput for each event, which ${
+ isInheriting ? 'is' : 'is not'
+ } readonly`, () => {
const fields = findAllGlFormInputs();
const expectedResults = [
{
@@ -128,6 +150,7 @@ describe('TriggerFields', () => {
fields.wrappers.forEach((field, index) => {
expect(field.attributes()).toMatchObject(expectedResults[index]);
+ expect(field.vm.$attrs.readonly).toBe(isInheriting);
expect(field.vm.$attrs.value).toBe(events[index].field.value);
});
});
diff --git a/spec/frontend/integrations/edit/mock_data.js b/spec/frontend/integrations/edit/mock_data.js
new file mode 100644
index 00000000000..da2758ec15c
--- /dev/null
+++ b/spec/frontend/integrations/edit/mock_data.js
@@ -0,0 +1,18 @@
+// eslint-disable-next-line import/prefer-default-export
+export const mockIntegrationProps = {
+ id: 25,
+ activeToggleProps: {
+ initialActivated: true,
+ },
+ showActive: true,
+ triggerFieldsProps: {
+ initialTriggerCommit: false,
+ initialTriggerMergeRequest: false,
+ initialEnableComments: false,
+ },
+ jiraIssuesProps: {},
+ triggerEvents: [],
+ fields: [],
+ type: '',
+ inheritFromId: 25,
+};
diff --git a/spec/frontend/integrations/edit/store/actions_spec.js b/spec/frontend/integrations/edit/store/actions_spec.js
new file mode 100644
index 00000000000..c3ce6e51a3d
--- /dev/null
+++ b/spec/frontend/integrations/edit/store/actions_spec.js
@@ -0,0 +1,19 @@
+import createState from '~/integrations/edit/store/state';
+import { setOverride } from '~/integrations/edit/store/actions';
+import * as types from '~/integrations/edit/store/mutation_types';
+
+import testAction from 'helpers/vuex_action_helper';
+
+describe('Integration form store actions', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe('setOverride', () => {
+ it('should commit override mutation', () => {
+ return testAction(setOverride, true, state, [{ type: types.SET_OVERRIDE, payload: true }]);
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/store/getters_spec.js b/spec/frontend/integrations/edit/store/getters_spec.js
new file mode 100644
index 00000000000..700d36edaad
--- /dev/null
+++ b/spec/frontend/integrations/edit/store/getters_spec.js
@@ -0,0 +1,71 @@
+import { currentKey, isInheriting, propsSource } from '~/integrations/edit/store/getters';
+import createState from '~/integrations/edit/store/state';
+import { mockIntegrationProps } from '../mock_data';
+
+describe('Integration form store getters', () => {
+ let state;
+ const customState = { ...mockIntegrationProps, type: 'CustomState' };
+ const adminState = { ...mockIntegrationProps, type: 'AdminState' };
+
+ beforeEach(() => {
+ state = createState({ customState });
+ });
+
+ describe('isInheriting', () => {
+ describe('when adminState is null', () => {
+ it('returns false', () => {
+ expect(isInheriting(state)).toBe(false);
+ });
+ });
+
+ describe('when adminState is an object', () => {
+ beforeEach(() => {
+ state.adminState = adminState;
+ });
+
+ describe('when override is false', () => {
+ beforeEach(() => {
+ state.override = false;
+ });
+
+ it('returns false', () => {
+ expect(isInheriting(state)).toBe(true);
+ });
+ });
+
+ describe('when override is true', () => {
+ beforeEach(() => {
+ state.override = true;
+ });
+
+ it('returns true', () => {
+ expect(isInheriting(state)).toBe(false);
+ });
+ });
+ });
+ });
+
+ describe('propsSource', () => {
+ beforeEach(() => {
+ state.adminState = adminState;
+ });
+
+ it('equals adminState if inheriting', () => {
+ expect(propsSource(state, { isInheriting: true })).toEqual(adminState);
+ });
+
+ it('equals customState if not inheriting', () => {
+ expect(propsSource(state, { isInheriting: false })).toEqual(customState);
+ });
+ });
+
+ describe('currentKey', () => {
+ it('equals `admin` if inheriting', () => {
+ expect(currentKey(state, { isInheriting: true })).toEqual('admin');
+ });
+
+ it('equals `custom` if not inheriting', () => {
+ expect(currentKey(state, { isInheriting: false })).toEqual('custom');
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/store/mutations_spec.js b/spec/frontend/integrations/edit/store/mutations_spec.js
new file mode 100644
index 00000000000..4b733726d44
--- /dev/null
+++ b/spec/frontend/integrations/edit/store/mutations_spec.js
@@ -0,0 +1,19 @@
+import mutations from '~/integrations/edit/store/mutations';
+import createState from '~/integrations/edit/store/state';
+import * as types from '~/integrations/edit/store/mutation_types';
+
+describe('Integration form store mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState();
+ });
+
+ describe(`${types.SET_OVERRIDE}`, () => {
+ it('sets override', () => {
+ mutations[types.SET_OVERRIDE](state, true);
+
+ expect(state.override).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/store/state_spec.js b/spec/frontend/integrations/edit/store/state_spec.js
new file mode 100644
index 00000000000..a8b431aa310
--- /dev/null
+++ b/spec/frontend/integrations/edit/store/state_spec.js
@@ -0,0 +1,26 @@
+import createState from '~/integrations/edit/store/state';
+
+describe('Integration form state factory', () => {
+ it('states default to null', () => {
+ expect(createState()).toEqual({
+ adminState: null,
+ customState: {},
+ override: false,
+ });
+ });
+
+ describe('override is initialized correctly', () => {
+ it.each([
+ [{ id: 25 }, { inheritFromId: null }, true],
+ [{ id: 25 }, { inheritFromId: 27 }, true],
+ [{ id: 25 }, { inheritFromId: 25 }, false],
+ [null, { inheritFromId: null }, false],
+ [null, { inheritFromId: 25 }, false],
+ ])(
+ 'for adminState: %p, customState: %p: override = `%p`',
+ (adminState, customState, expected) => {
+ expect(createState({ adminState, customState }).override).toEqual(expected);
+ },
+ );
+ });
+});