Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-03 12:08:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-03 12:08:42 +0300
commitf14507e586a7f75f0fb71a1d8468b7361be860d4 (patch)
treea8aa547b517a7ae5626c902bfb558c1fc5386c4e /spec/frontend
parentf4d27d532e3abeecd1caffeb3a56e698ae982e5b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/error_tracking_settings/store/getters_spec.js2
-rw-r--r--spec/frontend/ide/components/ide_status_list_spec.js2
-rw-r--r--spec/frontend/mr_popover/mr_popover_spec.js2
-rw-r--r--spec/frontend/registry/settings/components/registry_settings_app_spec.js2
-rw-r--r--spec/frontend/registry/settings/components/settings_form_spec.js217
-rw-r--r--spec/frontend/registry/settings/store/actions_spec.js13
-rw-r--r--spec/frontend/registry/settings/store/getters_spec.js4
-rw-r--r--spec/frontend/registry/settings/store/mutations_spec.js4
-rw-r--r--spec/frontend/registry/shared/components/__snapshots__/expiration_policy_form_spec.js.snap (renamed from spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap)10
-rw-r--r--spec/frontend/registry/shared/components/expiration_policy_form_spec.js237
-rw-r--r--spec/frontend/registry/shared/mock_data.js (renamed from spec/frontend/registry/settings/mock_data.js)0
-rw-r--r--spec/frontend/releases/detail/components/app_spec.js2
-rw-r--r--spec/frontend/sidebar/confidential_issue_sidebar_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/recaptcha_modal_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/slot_switch_spec.js2
15 files changed, 281 insertions, 220 deletions
diff --git a/spec/frontend/error_tracking_settings/store/getters_spec.js b/spec/frontend/error_tracking_settings/store/getters_spec.js
index 2c5ff084b8a..b135fdee40b 100644
--- a/spec/frontend/error_tracking_settings/store/getters_spec.js
+++ b/spec/frontend/error_tracking_settings/store/getters_spec.js
@@ -47,7 +47,7 @@ describe('Error Tracking Settings - Getters', () => {
it('should display correctly when a project is selected', () => {
[state.selectedProject] = projectList;
- expect(getters.dropdownLabel(state, mockGetters)).toEqual('organizationName | name');
+ expect(getters.dropdownLabel(state, mockGetters)).toEqual('organizationName | slug');
});
it('should display correctly when no project is selected', () => {
diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js
index 2762adfb57d..99c27ca30fb 100644
--- a/spec/frontend/ide/components/ide_status_list_spec.js
+++ b/spec/frontend/ide/components/ide_status_list_spec.js
@@ -1,6 +1,6 @@
import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils';
-import IdeStatusList from '~/ide/components/ide_status_list';
+import IdeStatusList from '~/ide/components/ide_status_list.vue';
const TEST_FILE = {
name: 'lorem.md',
diff --git a/spec/frontend/mr_popover/mr_popover_spec.js b/spec/frontend/mr_popover/mr_popover_spec.js
index 0c0d4c73d91..3f62dca4a57 100644
--- a/spec/frontend/mr_popover/mr_popover_spec.js
+++ b/spec/frontend/mr_popover/mr_popover_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import MRPopover from '~/mr_popover/components/mr_popover';
+import MRPopover from '~/mr_popover/components/mr_popover.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
describe('MR Popover', () => {
diff --git a/spec/frontend/registry/settings/components/registry_settings_app_spec.js b/spec/frontend/registry/settings/components/registry_settings_app_spec.js
index 8a5c5d84198..e9ba65e4387 100644
--- a/spec/frontend/registry/settings/components/registry_settings_app_spec.js
+++ b/spec/frontend/registry/settings/components/registry_settings_app_spec.js
@@ -4,7 +4,7 @@ import component from '~/registry/settings/components/registry_settings_app.vue'
import SettingsForm from '~/registry/settings/components/settings_form.vue';
import { createStore } from '~/registry/settings/store/';
import { SET_IS_DISABLED } from '~/registry/settings/store/mutation_types';
-import { FETCH_SETTINGS_ERROR_MESSAGE } from '~/registry/settings/constants';
+import { FETCH_SETTINGS_ERROR_MESSAGE } from '~/registry/shared/constants';
describe('Registry Settings App', () => {
let wrapper;
diff --git a/spec/frontend/registry/settings/components/settings_form_spec.js b/spec/frontend/registry/settings/components/settings_form_spec.js
index 89dd161ec3e..eefb0313a0b 100644
--- a/spec/frontend/registry/settings/components/settings_form_spec.js
+++ b/spec/frontend/registry/settings/components/settings_form_spec.js
@@ -1,49 +1,33 @@
-import { mount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import Tracking from '~/tracking';
-import stubChildren from 'helpers/stub_children';
import component from '~/registry/settings/components/settings_form.vue';
+import expirationPolicyForm from '~/registry/shared/components/expiration_policy_form.vue';
import { createStore } from '~/registry/settings/store/';
import {
- NAME_REGEX_LENGTH,
UPDATE_SETTINGS_ERROR_MESSAGE,
UPDATE_SETTINGS_SUCCESS_MESSAGE,
-} from '~/registry/settings/constants';
-import { stringifiedFormOptions } from '../mock_data';
+} from '~/registry/shared/constants';
+import { stringifiedFormOptions } from '../../shared/mock_data';
describe('Settings Form', () => {
let wrapper;
let store;
let dispatchSpy;
- const FORM_ELEMENTS_ID_PREFIX = '#expiration-policy';
const trackingPayload = {
label: 'docker_container_retention_and_expiration_policies',
};
- const GlLoadingIcon = { name: 'gl-loading-icon-stub', template: '<svg></svg>' };
+ const findForm = () => wrapper.find(expirationPolicyForm);
- const findFormGroup = name => wrapper.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}-group`);
- const findFormElements = (name, parent = wrapper) =>
- parent.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}`);
- const findCancelButton = () => wrapper.find({ ref: 'cancel-button' });
- const findSaveButton = () => wrapper.find({ ref: 'save-button' });
- const findForm = () => wrapper.find({ ref: 'form-element' });
- const findLoadingIcon = (parent = wrapper) => parent.find(GlLoadingIcon);
-
- const mountComponent = (options = {}) => {
- wrapper = mount(component, {
- stubs: {
- ...stubChildren(component),
- GlCard: false,
- GlLoadingIcon,
- },
+ const mountComponent = () => {
+ wrapper = shallowMount(component, {
mocks: {
$toast: {
show: jest.fn(),
},
},
store,
- ...options,
});
};
@@ -59,170 +43,50 @@ describe('Settings Form', () => {
wrapper.destroy();
});
- it('renders', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
-
- describe.each`
- elementName | modelName | value | disabledByToggle
- ${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
- ${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
- ${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
- ${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
- ${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
- `(
- `${FORM_ELEMENTS_ID_PREFIX}-$elementName form element`,
- ({ elementName, modelName, value, disabledByToggle }) => {
- let formGroup;
- beforeEach(() => {
- formGroup = findFormGroup(elementName);
- });
- it(`${elementName} form group exist in the dom`, () => {
- expect(formGroup.exists()).toBe(true);
- });
-
- it(`${elementName} form group has a label-for property`, () => {
- expect(formGroup.attributes('label-for')).toBe(`expiration-policy-${elementName}`);
- });
-
- it(`${elementName} form group has a label-cols property`, () => {
- expect(formGroup.attributes('label-cols')).toBe(`${wrapper.vm.$options.labelsConfig.cols}`);
- });
-
- it(`${elementName} form group has a label-align property`, () => {
- expect(formGroup.attributes('label-align')).toBe(
- `${wrapper.vm.$options.labelsConfig.align}`,
- );
- });
-
- it(`${elementName} form group contains an input element`, () => {
- expect(findFormElements(elementName, formGroup).exists()).toBe(true);
- });
-
- it(`${elementName} form element change updated ${modelName} with ${value}`, () => {
- const element = findFormElements(elementName, formGroup);
- const modelUpdateEvent = element.vm.$options.model
- ? element.vm.$options.model.event
- : 'input';
- element.vm.$emit(modelUpdateEvent, value);
- return wrapper.vm.$nextTick().then(() => {
- expect(wrapper.vm[modelName]).toBe(value);
- });
- });
-
- it(`${elementName} is ${disabledByToggle} by enabled set to false`, () => {
- store.dispatch('updateSettings', { enabled: false });
- const expectation = disabledByToggle === 'disabled' ? 'true' : undefined;
- expect(findFormElements(elementName, formGroup).attributes('disabled')).toBe(expectation);
- });
- },
- );
-
- describe('form actions', () => {
+ describe('form', () => {
let form;
beforeEach(() => {
form = findForm();
});
- describe('cancel button', () => {
- it('has type reset', () => {
- expect(findCancelButton().attributes('type')).toBe('reset');
- });
-
- it('is disabled the form was not changed from his original value', () => {
- store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
- return wrapper.vm.$nextTick().then(() => {
- expect(findCancelButton().attributes('disabled')).toBe('true');
- });
- });
-
- it('is disabled when the form data is loading', () => {
- store.dispatch('toggleLoading');
- return wrapper.vm.$nextTick().then(() => {
- expect(findCancelButton().attributes('disabled')).toBe('true');
- });
- });
-
- it('is enabled when the user changed something in the form and the data is not being loaded', () => {
- store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
- store.dispatch('updateSettings', { foo: 'baz' });
- return wrapper.vm.$nextTick().then(() => {
- expect(findCancelButton().attributes('disabled')).toBe(undefined);
- });
+ describe('data binding', () => {
+ it('v-model change update the settings property', () => {
+ dispatchSpy.mockReturnValue();
+ form.vm.$emit('input', 'foo');
+ expect(dispatchSpy).toHaveBeenCalledWith('updateSettings', { settings: 'foo' });
});
});
- describe('form cancel event', () => {
+ describe('form reset event', () => {
it('calls the appropriate function', () => {
dispatchSpy.mockReturnValue();
- form.trigger('reset');
+ form.vm.$emit('reset');
expect(dispatchSpy).toHaveBeenCalledWith('resetSettings');
});
it('tracks the reset event', () => {
dispatchSpy.mockReturnValue();
- form.trigger('reset');
+ form.vm.$emit('reset');
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'reset_form', trackingPayload);
});
});
- it('save has type submit', () => {
- expect(findSaveButton().attributes('type')).toBe('submit');
- });
-
- describe('when isLoading is true', () => {
- beforeEach(() => {
- store.dispatch('toggleLoading');
- });
-
- afterEach(() => {
- store.dispatch('toggleLoading');
- });
-
- it.each`
- elementName
- ${'toggle'}
- ${'interval'}
- ${'schedule'}
- ${'latest'}
- ${'name-matching'}
- `(`${FORM_ELEMENTS_ID_PREFIX}-$elementName is disabled`, ({ elementName }) => {
- expect(findFormElements(elementName).attributes('disabled')).toBe('true');
- });
-
- it('submit button is disabled and shows a spinner', () => {
- const button = findSaveButton();
- expect(button.attributes('disabled')).toBeTruthy();
- expect(findLoadingIcon(button)).toExist();
- });
-
- it('cancel button is disabled', () => {
- expect(findCancelButton().attributes('disabled')).toBeTruthy();
- });
- });
-
describe('form submit event ', () => {
- it('calls the appropriate function', () => {
- dispatchSpy.mockResolvedValue();
- form.trigger('submit');
- expect(dispatchSpy).toHaveBeenCalled();
- });
-
it('dispatches the saveSettings action', () => {
dispatchSpy.mockResolvedValue();
- form.trigger('submit');
+ form.vm.$emit('submit');
expect(dispatchSpy).toHaveBeenCalledWith('saveSettings');
});
it('tracks the submit event', () => {
dispatchSpy.mockResolvedValue();
- form.trigger('submit');
+ form.vm.$emit('submit');
expect(Tracking.event).toHaveBeenCalledWith(undefined, 'submit_form', trackingPayload);
});
it('show a success toast when submit succeed', () => {
dispatchSpy.mockResolvedValue();
- form.trigger('submit');
+ form.vm.$emit('submit');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE, {
type: 'success',
@@ -232,7 +96,7 @@ describe('Settings Form', () => {
it('show an error toast when submit fails', () => {
dispatchSpy.mockRejectedValue();
- form.trigger('submit');
+ form.vm.$emit('submit');
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE, {
type: 'error',
@@ -241,45 +105,4 @@ describe('Settings Form', () => {
});
});
});
-
- describe('form validation', () => {
- describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
- const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
- beforeEach(() => {
- store.dispatch('updateSettings', { name_regex: invalidString });
- });
-
- it('save btn is disabled', () => {
- expect(findSaveButton().attributes('disabled')).toBeTruthy();
- });
-
- it('nameRegexState is false', () => {
- expect(wrapper.vm.nameRegexState).toBe(false);
- });
- });
-
- it('if the user did not type validation is null', () => {
- store.dispatch('updateSettings', { name_regex: null });
- expect(wrapper.vm.nameRegexState).toBe(null);
- return wrapper.vm.$nextTick().then(() => {
- expect(findSaveButton().attributes('disabled')).toBeFalsy();
- });
- });
-
- it(`if the user typed and is less than ${NAME_REGEX_LENGTH} state is true`, () => {
- store.dispatch('updateSettings', { name_regex: 'abc' });
- expect(wrapper.vm.nameRegexState).toBe(true);
- });
- });
-
- describe('help text', () => {
- it('toggleDescriptionText text reflects enabled property', () => {
- const toggleHelpText = findFormGroup('toggle').find('span');
- expect(toggleHelpText.html()).toContain('disabled');
- wrapper.setData({ enabled: true });
- return wrapper.vm.$nextTick().then(() => {
- expect(toggleHelpText.html()).toContain('enabled');
- });
- });
- });
});
diff --git a/spec/frontend/registry/settings/store/actions_spec.js b/spec/frontend/registry/settings/store/actions_spec.js
index f904d0b660a..5038dc82416 100644
--- a/spec/frontend/registry/settings/store/actions_spec.js
+++ b/spec/frontend/registry/settings/store/actions_spec.js
@@ -10,11 +10,14 @@ describe('Actions Registry Store', () => {
${'updateSettings'} | ${types.UPDATE_SETTINGS} | ${'foo'}
${'toggleLoading'} | ${types.TOGGLE_LOADING} | ${undefined}
${'resetSettings'} | ${types.RESET_SETTINGS} | ${undefined}
- `('%s action invokes %s mutation with payload %s', ({ actionName, mutationName, payload }) => {
- it('should set the initial state', done => {
- testAction(actions[actionName], payload, {}, [{ type: mutationName, payload }], [], done);
- });
- });
+ `(
+ '$actionName invokes $mutationName with payload $payload',
+ ({ actionName, mutationName, payload }) => {
+ it('should set state', done => {
+ testAction(actions[actionName], payload, {}, [{ type: mutationName, payload }], [], done);
+ });
+ },
+ );
describe('receiveSettingsSuccess', () => {
it('calls SET_SETTINGS when data is present', () => {
diff --git a/spec/frontend/registry/settings/store/getters_spec.js b/spec/frontend/registry/settings/store/getters_spec.js
index d9ee53766d6..44631b97a39 100644
--- a/spec/frontend/registry/settings/store/getters_spec.js
+++ b/spec/frontend/registry/settings/store/getters_spec.js
@@ -1,6 +1,6 @@
import * as getters from '~/registry/settings/store/getters';
-import * as utils from '~/registry/settings/utils';
-import { formOptions } from '../mock_data';
+import * as utils from '~/registry/shared/utils';
+import { formOptions } from '../../shared/mock_data';
describe('Getters registry settings store', () => {
const settings = {
diff --git a/spec/frontend/registry/settings/store/mutations_spec.js b/spec/frontend/registry/settings/store/mutations_spec.js
index deb59089d60..8ab0196fd4d 100644
--- a/spec/frontend/registry/settings/store/mutations_spec.js
+++ b/spec/frontend/registry/settings/store/mutations_spec.js
@@ -1,7 +1,7 @@
import mutations from '~/registry/settings/store/mutations';
import * as types from '~/registry/settings/store/mutation_types';
import createState from '~/registry/settings/store/state';
-import { formOptions, stringifiedFormOptions } from '../mock_data';
+import { formOptions, stringifiedFormOptions } from '../../shared/mock_data';
describe('Mutations Registry Store', () => {
let mockState;
@@ -28,7 +28,7 @@ describe('Mutations Registry Store', () => {
mockState.settings = { foo: 'bar' };
const payload = { foo: 'baz' };
const expectedState = { ...mockState, settings: payload };
- mutations[types.UPDATE_SETTINGS](mockState, payload);
+ mutations[types.UPDATE_SETTINGS](mockState, { settings: payload });
expect(mockState.settings).toEqual(expectedState.settings);
});
});
diff --git a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_form_spec.js.snap
index 06f73c8f456..b53736951e1 100644
--- a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
+++ b/spec/frontend/registry/shared/components/__snapshots__/expiration_policy_form_spec.js.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Settings Form renders 1`] = `
-<form>
+exports[`Expiration Policy Form renders 1`] = `
+<form
+ class="lh-2"
+>
<div
class="card"
>
@@ -56,7 +58,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-interval"
- value="bar"
>
<option
value="foo"
@@ -85,7 +86,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-schedule"
- value="bar"
>
<option
value="foo"
@@ -114,7 +114,6 @@ exports[`Settings Form renders 1`] = `
<glformselect-stub
disabled="true"
id="expiration-policy-latest"
- value="bar"
>
<option
value="foo"
@@ -159,7 +158,6 @@ exports[`Settings Form renders 1`] = `
>
<glbutton-stub
class="mr-2 d-block"
- disabled="true"
size="md"
type="reset"
variant="secondary"
diff --git a/spec/frontend/registry/shared/components/expiration_policy_form_spec.js b/spec/frontend/registry/shared/components/expiration_policy_form_spec.js
new file mode 100644
index 00000000000..b51519925f1
--- /dev/null
+++ b/spec/frontend/registry/shared/components/expiration_policy_form_spec.js
@@ -0,0 +1,237 @@
+import { mount } from '@vue/test-utils';
+import stubChildren from 'helpers/stub_children';
+import component from '~/registry/shared/components/expiration_policy_form.vue';
+
+import { NAME_REGEX_LENGTH } from '~/registry/shared/constants';
+import { formOptions } from '../mock_data';
+
+describe('Expiration Policy Form', () => {
+ let wrapper;
+
+ const FORM_ELEMENTS_ID_PREFIX = '#expiration-policy';
+
+ const GlLoadingIcon = { name: 'gl-loading-icon-stub', template: '<svg></svg>' };
+
+ const findFormGroup = name => wrapper.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}-group`);
+ const findFormElements = (name, parent = wrapper) =>
+ parent.find(`${FORM_ELEMENTS_ID_PREFIX}-${name}`);
+ const findCancelButton = () => wrapper.find({ ref: 'cancel-button' });
+ const findSaveButton = () => wrapper.find({ ref: 'save-button' });
+ const findForm = () => wrapper.find({ ref: 'form-element' });
+ const findLoadingIcon = (parent = wrapper) => parent.find(GlLoadingIcon);
+
+ const mountComponent = props => {
+ wrapper = mount(component, {
+ stubs: {
+ ...stubChildren(component),
+ GlCard: false,
+ GlLoadingIcon,
+ },
+ propsData: {
+ formOptions,
+ ...props,
+ },
+ methods: {
+ // override idGenerator to avoid having to test with dynamic uid
+ idGenerator: value => value,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders', () => {
+ mountComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ describe.each`
+ elementName | modelName | value | disabledByToggle
+ ${'toggle'} | ${'enabled'} | ${true} | ${'not disabled'}
+ ${'interval'} | ${'older_than'} | ${'foo'} | ${'disabled'}
+ ${'schedule'} | ${'cadence'} | ${'foo'} | ${'disabled'}
+ ${'latest'} | ${'keep_n'} | ${'foo'} | ${'disabled'}
+ ${'name-matching'} | ${'name_regex'} | ${'foo'} | ${'disabled'}
+ `(
+ `${FORM_ELEMENTS_ID_PREFIX}-$elementName form element`,
+ ({ elementName, modelName, value, disabledByToggle }) => {
+ it(`${elementName} form group exist in the dom`, () => {
+ mountComponent();
+ const formGroup = findFormGroup(elementName);
+ expect(formGroup.exists()).toBe(true);
+ });
+
+ it(`${elementName} form group has a label-for property`, () => {
+ mountComponent();
+ const formGroup = findFormGroup(elementName);
+ expect(formGroup.attributes('label-for')).toBe(`expiration-policy-${elementName}`);
+ });
+
+ it(`${elementName} form group has a label-cols property`, () => {
+ mountComponent({ labelCols: '1' });
+ const formGroup = findFormGroup(elementName);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(formGroup.attributes('label-cols')).toBe('1');
+ });
+ });
+
+ it(`${elementName} form group has a label-align property`, () => {
+ mountComponent({ labelAlign: 'foo' });
+ const formGroup = findFormGroup(elementName);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(formGroup.attributes('label-align')).toBe('foo');
+ });
+ });
+
+ it(`${elementName} form group contains an input element`, () => {
+ mountComponent();
+ const formGroup = findFormGroup(elementName);
+ expect(findFormElements(elementName, formGroup).exists()).toBe(true);
+ });
+
+ it(`${elementName} form element change updated ${modelName} with ${value}`, () => {
+ mountComponent();
+ const formGroup = findFormGroup(elementName);
+ const element = findFormElements(elementName, formGroup);
+
+ const modelUpdateEvent = element.vm.$options.model
+ ? element.vm.$options.model.event
+ : 'input';
+ element.vm.$emit(modelUpdateEvent, value);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.emitted('input')).toEqual([[{ [modelName]: value }]]);
+ });
+ });
+
+ it(`${elementName} is ${disabledByToggle} by enabled set to false`, () => {
+ mountComponent({ settings: { enabled: false } });
+ const formGroup = findFormGroup(elementName);
+ const expectation = disabledByToggle === 'disabled' ? 'true' : undefined;
+ expect(findFormElements(elementName, formGroup).attributes('disabled')).toBe(expectation);
+ });
+ },
+ );
+
+ describe('form actions', () => {
+ describe('cancel button', () => {
+ it('has type reset', () => {
+ mountComponent();
+ expect(findCancelButton().attributes('type')).toBe('reset');
+ });
+
+ it('is disabled when disableCancelButton is true', () => {
+ mountComponent({ disableCancelButton: true });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ it('is disabled isLoading is true', () => {
+ mountComponent({ isLoading: true });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ it('is enabled when isLoading and disableCancelButton are false', () => {
+ mountComponent({ disableCancelButton: false, isLoading: false });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe(undefined);
+ });
+ });
+ });
+
+ describe('form cancel event', () => {
+ it('calls the appropriate function', () => {
+ mountComponent();
+ findForm().trigger('reset');
+ expect(wrapper.emitted('reset')).toBeTruthy();
+ });
+ });
+
+ it('save has type submit', () => {
+ mountComponent();
+ expect(findSaveButton().attributes('type')).toBe('submit');
+ });
+
+ describe('when isLoading is true', () => {
+ beforeEach(() => {
+ mountComponent({ isLoading: true });
+ });
+
+ it.each`
+ elementName
+ ${'toggle'}
+ ${'interval'}
+ ${'schedule'}
+ ${'latest'}
+ ${'name-matching'}
+ `(`${FORM_ELEMENTS_ID_PREFIX}-$elementName is disabled`, ({ elementName }) => {
+ expect(findFormElements(elementName).attributes('disabled')).toBe('true');
+ });
+
+ it('submit button is disabled and shows a spinner', () => {
+ const button = findSaveButton();
+ expect(button.attributes('disabled')).toBeTruthy();
+ expect(findLoadingIcon(button)).toExist();
+ });
+ });
+
+ describe('form submit event ', () => {
+ it('calls the appropriate function', () => {
+ mountComponent();
+ findForm().trigger('submit');
+ expect(wrapper.emitted('submit')).toBeTruthy();
+ });
+ });
+ });
+
+ describe('form validation', () => {
+ describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
+ const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
+
+ beforeEach(() => {
+ mountComponent({ value: { name_regex: invalidString } });
+ });
+
+ it('save btn is disabled', () => {
+ expect(findSaveButton().attributes('disabled')).toBeTruthy();
+ });
+
+ it('nameRegexState is false', () => {
+ expect(wrapper.vm.nameRegexState).toBe(false);
+ });
+ });
+
+ it('if the user did not type validation is null', () => {
+ mountComponent({ value: { name_regex: '' } });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.nameRegexState).toBe(null);
+ expect(findSaveButton().attributes('disabled')).toBeFalsy();
+ });
+ });
+
+ it(`if the user typed and is less than ${NAME_REGEX_LENGTH} state is true`, () => {
+ mountComponent({ value: { name_regex: 'foo' } });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.nameRegexState).toBe(true);
+ });
+ });
+ });
+
+ describe('help text', () => {
+ it('toggleDescriptionText show disabled when settings.enabled is false', () => {
+ mountComponent();
+ const toggleHelpText = findFormGroup('toggle').find('span');
+ expect(toggleHelpText.html()).toContain('disabled');
+ });
+
+ it('toggleDescriptionText show enabled when settings.enabled is true', () => {
+ mountComponent({ value: { enabled: true } });
+ const toggleHelpText = findFormGroup('toggle').find('span');
+ expect(toggleHelpText.html()).toContain('enabled');
+ });
+ });
+});
diff --git a/spec/frontend/registry/settings/mock_data.js b/spec/frontend/registry/shared/mock_data.js
index 411363c2c95..411363c2c95 100644
--- a/spec/frontend/registry/settings/mock_data.js
+++ b/spec/frontend/registry/shared/mock_data.js
diff --git a/spec/frontend/releases/detail/components/app_spec.js b/spec/frontend/releases/detail/components/app_spec.js
index fd5239ad44e..894cd3a8f14 100644
--- a/spec/frontend/releases/detail/components/app_spec.js
+++ b/spec/frontend/releases/detail/components/app_spec.js
@@ -1,6 +1,6 @@
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
-import ReleaseDetailApp from '~/releases/detail/components/app';
+import ReleaseDetailApp from '~/releases/detail/components/app.vue';
import { release } from '../../mock_data';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
diff --git a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
index 13b7c426366..4853d9795b1 100644
--- a/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
+++ b/spec/frontend/sidebar/confidential_issue_sidebar_spec.js
@@ -4,7 +4,7 @@ import ConfidentialIssueSidebar from '~/sidebar/components/confidential/confiden
import EditForm from '~/sidebar/components/confidential/edit_form.vue';
import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
-import RecaptchaModal from '~/vue_shared/components/recaptcha_modal';
+import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
diff --git a/spec/frontend/vue_shared/components/recaptcha_modal_spec.js b/spec/frontend/vue_shared/components/recaptcha_modal_spec.js
index 223e7187d99..8ab65efd388 100644
--- a/spec/frontend/vue_shared/components/recaptcha_modal_spec.js
+++ b/spec/frontend/vue_shared/components/recaptcha_modal_spec.js
@@ -2,7 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import { eventHub } from '~/vue_shared/components/recaptcha_eventhub';
-import RecaptchaModal from '~/vue_shared/components/recaptcha_modal';
+import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
describe('RecaptchaModal', () => {
const recaptchaFormId = 'recaptcha-form';
diff --git a/spec/frontend/vue_shared/components/slot_switch_spec.js b/spec/frontend/vue_shared/components/slot_switch_spec.js
index 71e6087c272..73307b5573f 100644
--- a/spec/frontend/vue_shared/components/slot_switch_spec.js
+++ b/spec/frontend/vue_shared/components/slot_switch_spec.js
@@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import SlotSwitch from '~/vue_shared/components/slot_switch';
+import SlotSwitch from '~/vue_shared/components/slot_switch.vue';
describe('SlotSwitch', () => {
const slots = {