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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-12-19 15:07:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-12-19 15:07:35 +0300
commite3764d340e2849fccee8c06278d1f5f686edd35b (patch)
tree23de7fe0eaa58a82c3a72eb8ff4a195e24627eb7 /spec
parente3d67bcff7b8bc6a453d0814d404a9a61d97bc0f (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/error_tracking/projects_controller_spec.rb2
-rw-r--r--spec/features/merge_request/user_suggests_changes_on_diff_spec.rb4
-rw-r--r--spec/frontend/api_spec.js15
-rw-r--r--spec/frontend/registry/settings/components/__snapshots__/registry_settings_app_spec.js.snap14
-rw-r--r--spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap155
-rw-r--r--spec/frontend/registry/settings/components/registry_settings_app_spec.js36
-rw-r--r--spec/frontend/registry/settings/components/settings_form_spec.js154
-rw-r--r--spec/frontend/registry/settings/store/actions_spec.js120
-rw-r--r--spec/frontend/registry/settings/store/mutations_spec.js54
-rw-r--r--spec/frontend/registry/settings/stores/actions_spec.js20
-rw-r--r--spec/frontend/registry/settings/stores/mutations_spec.js21
-rw-r--r--spec/frontend/vuex_shared/bindings_spec.js51
-rw-r--r--spec/javascripts/diffs/components/app_spec.js15
-rw-r--r--spec/javascripts/diffs/store/actions_spec.js4
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js10
15 files changed, 606 insertions, 69 deletions
diff --git a/spec/controllers/projects/error_tracking/projects_controller_spec.rb b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
index e55495700c2..1737528b597 100644
--- a/spec/controllers/projects/error_tracking/projects_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking/projects_controller_spec.rb
@@ -11,7 +11,7 @@ describe Projects::ErrorTracking::ProjectsController do
project.add_maintainer(user)
end
- describe 'POST #index' do
+ describe 'GET #index' do
context 'with insufficient permissions' do
before do
project.add_guest(user)
diff --git a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
index 7fe72e1bc8a..859638f1a52 100644
--- a/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
+++ b/spec/features/merge_request/user_suggests_changes_on_diff_spec.rb
@@ -97,9 +97,7 @@ describe 'User comments on a diff', :js do
end
context 'multiple suggestions in expanded lines' do
- # Report issue: https://gitlab.com/gitlab-org/gitlab/issues/38277
- # Fix issue: https://gitlab.com/gitlab-org/gitlab/issues/39095
- it 'suggestions are appliable', :quarantine do
+ it 'suggestions are appliable' do
diff_file = merge_request.diffs(paths: ['files/ruby/popen.rb']).diff_files.first
hash = Digest::SHA1.hexdigest(diff_file.file_path)
diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js
index cef50bf553c..c0126b2330d 100644
--- a/spec/frontend/api_spec.js
+++ b/spec/frontend/api_spec.js
@@ -151,6 +151,21 @@ describe('Api', () => {
});
});
+ describe('updateProject', () => {
+ it('update a project with the given payload', done => {
+ const projectPath = 'foo';
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectPath}`;
+ mock.onPut(expectedUrl).reply(200, { foo: 'bar' });
+
+ Api.updateProject(projectPath, { foo: 'bar' })
+ .then(({ data }) => {
+ expect(data.foo).toBe('bar');
+ done();
+ })
+ .catch(done.fail);
+ });
+ });
+
describe('projectUsers', () => {
it('fetches all users of a particular project', done => {
const query = 'dummy query';
diff --git a/spec/frontend/registry/settings/components/__snapshots__/registry_settings_app_spec.js.snap b/spec/frontend/registry/settings/components/__snapshots__/registry_settings_app_spec.js.snap
index c6dbb1da8e9..77f031db120 100644
--- a/spec/frontend/registry/settings/components/__snapshots__/registry_settings_app_spec.js.snap
+++ b/spec/frontend/registry/settings/components/__snapshots__/registry_settings_app_spec.js.snap
@@ -1,10 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`Registry List renders 1`] = `
+exports[`Registry Settings App renders 1`] = `
<div>
<p>
- Tag retention policies are designed to:
+ Tag expiration policy is designed to:
</p>
@@ -20,14 +20,6 @@ exports[`Registry List renders 1`] = `
</li>
</ul>
- <p>
- Read more about the
- <a
- href="foo"
- target="_blank"
- >
- Container Registry tag retention policies
- </a>
- </p>
+ <settingsform-stub />
</div>
`;
diff --git a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
new file mode 100644
index 00000000000..0ae37f70273
--- /dev/null
+++ b/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
@@ -0,0 +1,155 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Settings Form renders 1`] = `
+<div
+ class="card"
+>
+ <form>
+ <div
+ class="card-header"
+ >
+
+ Tag expiration policy
+
+ </div>
+
+ <div
+ class="card-body"
+ >
+ <glformgroup-stub
+ id="expiration-policy-toggle-group"
+ label="Expiration policy:"
+ label-align="right"
+ label-cols="3"
+ label-for="expiration-policy-toggle"
+ >
+ <div
+ class="d-flex align-items-start"
+ >
+ <gltoggle-stub
+ id="expiration-policy-toggle"
+ labeloff="Toggle Status: OFF"
+ labelon="Toggle Status: ON"
+ />
+
+ <span
+ class="mb-2 ml-1 lh-2"
+ >
+ Docker tag expiration policy is
+ <strong>
+ disabled
+ </strong>
+ </span>
+ </div>
+ </glformgroup-stub>
+
+ <glformgroup-stub
+ id="expiration-policy-interval-group"
+ label="Expiration interval:"
+ label-align="right"
+ label-cols="3"
+ label-for="expiration-policy-interval"
+ >
+ <glformselect-stub
+ id="expiration-policy-interval"
+ >
+ <option
+ value="1"
+ >
+ Option 1
+ </option>
+
+ <option
+ value="2"
+ >
+ Option 2
+ </option>
+ </glformselect-stub>
+ </glformgroup-stub>
+
+ <glformgroup-stub
+ id="expiration-policy-schedule-group"
+ label="Expiration schedule:"
+ label-align="right"
+ label-cols="3"
+ label-for="expiration-policy-schedule"
+ >
+ <glformselect-stub
+ id="expiration-policy-schedule"
+ >
+ <option
+ value="1"
+ >
+ Option 1
+ </option>
+
+ <option
+ value="2"
+ >
+ Option 2
+ </option>
+ </glformselect-stub>
+ </glformgroup-stub>
+
+ <glformgroup-stub
+ id="expiration-policy-latest-group"
+ label="Expiration latest:"
+ label-align="right"
+ label-cols="3"
+ label-for="expiration-policy-latest"
+ >
+ <glformselect-stub
+ id="expiration-policy-latest"
+ >
+ <option
+ value="1"
+ >
+ Option 1
+ </option>
+
+ <option
+ value="2"
+ >
+ Option 2
+ </option>
+ </glformselect-stub>
+ </glformgroup-stub>
+
+ <glformgroup-stub
+ id="expiration-policy-name-matching-group"
+ invalid-feedback="The value of this input should be less than 255 characters"
+ label="Expire Docker tags with name matching:"
+ label-align="right"
+ label-cols="3"
+ label-for="expiration-policy-name-matching"
+ >
+ <glformtextarea-stub
+ id="expiration-policy-name-matching"
+ placeholder=".*"
+ trim=""
+ value=""
+ />
+ </glformgroup-stub>
+ </div>
+
+ <div
+ class="card-footer text-right"
+ >
+ <glbutton-stub
+ type="reset"
+ >
+ Cancel
+ </glbutton-stub>
+
+ <glbutton-stub
+ type="submit"
+ variant="success"
+ >
+
+ Save Expiration Policy
+
+ </glbutton-stub>
+ </div>
+ </form>
+</div>
+`;
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 666d970aa6b..e0fe6172064 100644
--- a/spec/frontend/registry/settings/components/registry_settings_app_spec.js
+++ b/spec/frontend/registry/settings/components/registry_settings_app_spec.js
@@ -1,29 +1,34 @@
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import component from '~/registry/settings/components/registry_settings_app.vue';
-import { createStore } from '~/registry/settings/stores/';
+import { createStore } from '~/registry/settings/store/';
const localVue = createLocalVue();
localVue.use(Vuex);
-describe('Registry List', () => {
+describe('Registry Settings App', () => {
let wrapper;
let store;
+ let fetchSpy;
- const helpPagePath = 'foo';
- const findHelpLink = () => wrapper.find({ ref: 'help-link' }).find('a');
+ const findSettingsComponent = () => wrapper.find({ ref: 'settings-form' });
+ const findLoadingComponent = () => wrapper.find({ ref: 'loading-icon' });
- const mountComponent = (options = {}) =>
- shallowMount(component, {
+ const mountComponent = (options = {}) => {
+ fetchSpy = jest.fn();
+ wrapper = shallowMount(component, {
sync: false,
store,
+ methods: {
+ fetchSettings: fetchSpy,
+ },
...options,
});
+ };
beforeEach(() => {
store = createStore();
- store.dispatch('setInitialState', { helpPagePath });
- wrapper = mountComponent();
+ mountComponent();
});
afterEach(() => {
@@ -34,7 +39,18 @@ describe('Registry List', () => {
expect(wrapper.element).toMatchSnapshot();
});
- it('renders an help link dependant on the helphPagePath', () => {
- expect(findHelpLink().attributes('href')).toBe(helpPagePath);
+ it('call the store function to load the data on mount', () => {
+ expect(fetchSpy).toHaveBeenCalled();
+ });
+
+ it('renders a loader if isLoading is true', () => {
+ store.dispatch('toggleLoading');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findLoadingComponent().exists()).toBe(true);
+ expect(findSettingsComponent().exists()).toBe(false);
+ });
+ });
+ it('renders the setting form', () => {
+ expect(findSettingsComponent().exists()).toBe(true);
});
});
diff --git a/spec/frontend/registry/settings/components/settings_form_spec.js b/spec/frontend/registry/settings/components/settings_form_spec.js
new file mode 100644
index 00000000000..6d69b987c7f
--- /dev/null
+++ b/spec/frontend/registry/settings/components/settings_form_spec.js
@@ -0,0 +1,154 @@
+import Vuex from 'vuex';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import component from '~/registry/settings/components/settings_form.vue';
+import { createStore } from '~/registry/settings/store/';
+import { NAME_REGEX_LENGTH } from '~/registry/settings/constants';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Settings Form', () => {
+ let wrapper;
+ let store;
+ let saveSpy;
+ let resetSpy;
+
+ const helpPagePath = 'foo';
+ const findFormGroup = name => wrapper.find(`#expiration-policy-${name}-group`);
+ const findFormElements = (name, father = wrapper) => father.find(`#expiration-policy-${name}`);
+ const findCancelButton = () => wrapper.find({ ref: 'cancel-button' });
+ const findSaveButton = () => wrapper.find({ ref: 'save-button' });
+ const findForm = () => wrapper.find({ ref: 'form-element' });
+
+ const mountComponent = (options = {}) => {
+ saveSpy = jest.fn();
+ resetSpy = jest.fn();
+ wrapper = shallowMount(component, {
+ sync: false,
+ store,
+ methods: {
+ saveSettings: saveSpy,
+ resetSettings: resetSpy,
+ },
+ ...options,
+ });
+ };
+
+ beforeEach(() => {
+ store = createStore();
+ store.dispatch('setInitialState', { helpPagePath });
+ mountComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ describe.each`
+ elementName | modelName | value
+ ${'toggle'} | ${'enabled'} | ${true}
+ ${'interval'} | ${'older_than'} | ${'foo'}
+ ${'schedule'} | ${'cadence'} | ${'foo'}
+ ${'latest'} | ${'keep_n'} | ${'foo'}
+ ${'name-matching'} | ${'name_regex'} | ${'foo'}
+ `('%s form element', ({ elementName, modelName, value }) => {
+ 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);
+ element.vm.$emit('input', value);
+ expect(wrapper.vm[modelName]).toBe(value);
+ });
+ });
+
+ describe('form actions', () => {
+ let form;
+ beforeEach(() => {
+ form = findForm();
+ });
+ it('cancel has type reset', () => {
+ expect(findCancelButton().attributes('type')).toBe('reset');
+ });
+
+ it('form reset event call the appropriate function', () => {
+ form.trigger('reset');
+ expect(resetSpy).toHaveBeenCalled();
+ });
+
+ it('save has type submit', () => {
+ expect(findSaveButton().attributes('type')).toBe('submit');
+ });
+
+ it('form submit event call the appropriate function', () => {
+ form.trigger('submit');
+ expect(saveSpy).toHaveBeenCalled();
+ });
+ });
+
+ 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.vm.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
new file mode 100644
index 00000000000..71c815cd19c
--- /dev/null
+++ b/spec/frontend/registry/settings/store/actions_spec.js
@@ -0,0 +1,120 @@
+import Api from '~/api';
+import createFlash from '~/flash';
+import testAction from 'helpers/vuex_action_helper';
+import * as actions from '~/registry/settings/store/actions';
+import * as types from '~/registry/settings/store/mutation_types';
+import {
+ UPDATE_SETTINGS_ERROR_MESSAGE,
+ FETCH_SETTINGS_ERROR_MESSAGE,
+ UPDATE_SETTINGS_SUCCESS_MESSAGE,
+} from '~/registry/settings/constants';
+
+jest.mock('~/flash');
+
+describe('Actions Registry Store', () => {
+ describe.each`
+ actionName | mutationName | payload
+ ${'setInitialState'} | ${types.SET_INITIAL_STATE} | ${'foo'}
+ ${'updateSettings'} | ${types.UPDATE_SETTINGS} | ${'foo'}
+ ${'receiveSettingsSuccess'} | ${types.SET_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);
+ });
+ });
+
+ describe.each`
+ actionName | message
+ ${'receiveSettingsError'} | ${FETCH_SETTINGS_ERROR_MESSAGE}
+ ${'updateSettingsError'} | ${UPDATE_SETTINGS_ERROR_MESSAGE}
+ `('%s action', ({ actionName, message }) => {
+ it(`should call createFlash with ${message}`, done => {
+ testAction(actions[actionName], null, null, [], [], () => {
+ expect(createFlash).toHaveBeenCalledWith(message);
+ done();
+ });
+ });
+ });
+
+ describe('fetchSettings', () => {
+ const state = {
+ projectId: 'bar',
+ };
+
+ const payload = {
+ tag_expiration_policies: 'foo',
+ };
+
+ it('should fetch the data from the API', done => {
+ Api.project = jest.fn().mockResolvedValue(payload);
+ testAction(
+ actions.fetchSettings,
+ null,
+ state,
+ [],
+ [
+ { type: 'toggleLoading' },
+ { type: 'receiveSettingsSuccess', payload: payload.tag_expiration_policies },
+ { type: 'toggleLoading' },
+ ],
+ done,
+ );
+ });
+
+ it('should call receiveSettingsError on error', done => {
+ Api.project = jest.fn().mockRejectedValue();
+ testAction(
+ actions.fetchSettings,
+ null,
+ state,
+ [],
+ [{ type: 'toggleLoading' }, { type: 'receiveSettingsError' }, { type: 'toggleLoading' }],
+ done,
+ );
+ });
+ });
+
+ describe('saveSettings', () => {
+ const state = {
+ projectId: 'bar',
+ settings: 'baz',
+ };
+
+ const payload = {
+ tag_expiration_policies: 'foo',
+ };
+
+ it('should fetch the data from the API', done => {
+ Api.updateProject = jest.fn().mockResolvedValue(payload);
+ testAction(
+ actions.saveSettings,
+ null,
+ state,
+ [],
+ [
+ { type: 'toggleLoading' },
+ { type: 'receiveSettingsSuccess', payload: payload.tag_expiration_policies },
+ { type: 'toggleLoading' },
+ ],
+ () => {
+ expect(createFlash).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
+ done();
+ },
+ );
+ });
+
+ it('should call receiveSettingsError on error', done => {
+ Api.updateProject = jest.fn().mockRejectedValue();
+ testAction(
+ actions.saveSettings,
+ null,
+ state,
+ [],
+ [{ type: 'toggleLoading' }, { type: 'updateSettingsError' }, { type: 'toggleLoading' }],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/registry/settings/store/mutations_spec.js b/spec/frontend/registry/settings/store/mutations_spec.js
new file mode 100644
index 00000000000..a8c7ed3bafa
--- /dev/null
+++ b/spec/frontend/registry/settings/store/mutations_spec.js
@@ -0,0 +1,54 @@
+import mutations from '~/registry/settings/store/mutations';
+import * as types from '~/registry/settings/store/mutation_types';
+import createState from '~/registry/settings/store/state';
+
+describe('Mutations Registry Store', () => {
+ let mockState;
+
+ beforeEach(() => {
+ mockState = createState();
+ });
+
+ describe('SET_INITIAL_STATE', () => {
+ it('should set the initial state', () => {
+ const payload = { helpPagePath: 'foo', projectId: 'bar' };
+ const expectedState = { ...mockState, ...payload };
+ mutations[types.SET_INITIAL_STATE](mockState, payload);
+
+ expect(mockState.projectId).toEqual(expectedState.projectId);
+ });
+ });
+
+ describe('UPDATE_SETTINGS', () => {
+ it('should update the settings', () => {
+ mockState.settings = { foo: 'bar' };
+ const payload = { foo: 'baz' };
+ const expectedState = { ...mockState, settings: payload };
+ mutations[types.UPDATE_SETTINGS](mockState, payload);
+ expect(mockState.settings).toEqual(expectedState.settings);
+ });
+ });
+ describe('SET_SETTINGS', () => {
+ it('should set the settings and original', () => {
+ const payload = { foo: 'baz' };
+ const expectedState = { ...mockState, settings: payload };
+ mutations[types.SET_SETTINGS](mockState, payload);
+ expect(mockState.settings).toEqual(expectedState.settings);
+ expect(mockState.original).toEqual(expectedState.settings);
+ });
+ });
+ describe('RESET_SETTINGS', () => {
+ it('should copy original over settings', () => {
+ mockState.settings = { foo: 'bar' };
+ mockState.original = { foo: 'baz' };
+ mutations[types.RESET_SETTINGS](mockState);
+ expect(mockState.settings).toEqual(mockState.original);
+ });
+ });
+ describe('TOGGLE_LOADING', () => {
+ it('should toggle the loading', () => {
+ mutations[types.TOGGLE_LOADING](mockState);
+ expect(mockState.isLoading).toEqual(true);
+ });
+ });
+});
diff --git a/spec/frontend/registry/settings/stores/actions_spec.js b/spec/frontend/registry/settings/stores/actions_spec.js
deleted file mode 100644
index 484f1b2dc0a..00000000000
--- a/spec/frontend/registry/settings/stores/actions_spec.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import testAction from 'helpers/vuex_action_helper';
-import * as actions from '~/registry/settings/stores/actions';
-import * as types from '~/registry/settings/stores/mutation_types';
-
-jest.mock('~/flash.js');
-
-describe('Actions Registry Store', () => {
- describe('setInitialState', () => {
- it('should set the initial state', done => {
- testAction(
- actions.setInitialState,
- 'foo',
- {},
- [{ type: types.SET_INITIAL_STATE, payload: 'foo' }],
- [],
- done,
- );
- });
- });
-});
diff --git a/spec/frontend/registry/settings/stores/mutations_spec.js b/spec/frontend/registry/settings/stores/mutations_spec.js
deleted file mode 100644
index 421cd3f13cb..00000000000
--- a/spec/frontend/registry/settings/stores/mutations_spec.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import mutations from '~/registry/settings/stores/mutations';
-import * as types from '~/registry/settings/stores/mutation_types';
-import createState from '~/registry/settings/stores/state';
-
-describe('Mutations Registry Store', () => {
- let mockState;
-
- beforeEach(() => {
- mockState = createState();
- });
-
- describe('SET_INITIAL_STATE', () => {
- it('should set the initial state', () => {
- const payload = { helpPagePath: 'foo', registrySettingsEndpoint: 'bar' };
- const expectedState = { ...mockState, ...payload };
- mutations[types.SET_INITIAL_STATE](mockState, payload);
-
- expect(mockState.endpoint).toEqual(expectedState.endpoint);
- });
- });
-});
diff --git a/spec/frontend/vuex_shared/bindings_spec.js b/spec/frontend/vuex_shared/bindings_spec.js
new file mode 100644
index 00000000000..022d9e8e84c
--- /dev/null
+++ b/spec/frontend/vuex_shared/bindings_spec.js
@@ -0,0 +1,51 @@
+import { shallowMount } from '@vue/test-utils';
+import { mapComputed } from '~/vuex_shared/bindings';
+
+describe('Binding utils', () => {
+ describe('mapComputed', () => {
+ const dummyComponent = {
+ computed: {
+ ...mapComputed('foo', 'bar', ['baz']),
+ },
+ render() {
+ return null;
+ },
+ };
+ it('returns an object with keys equal to the last fn parameter ', () => {
+ const keyList = ['foo1', 'foo2'];
+ const result = mapComputed('foo', 'bar', keyList);
+ expect(Object.keys(result)).toEqual(keyList);
+ });
+ it('returned object has set and get function', () => {
+ const result = mapComputed('foo', 'bar', ['baz']);
+ expect(result.baz.set).toBeDefined();
+ expect(result.baz.get).toBeDefined();
+ });
+
+ it('set function invokes $store.dispatch', () => {
+ const context = shallowMount(dummyComponent, {
+ mocks: {
+ $store: {
+ dispatch: jest.fn(),
+ },
+ },
+ });
+ context.vm.baz = 'a';
+ expect(context.vm.$store.dispatch).toHaveBeenCalledWith('bar', { baz: 'a' });
+ });
+ it('get function returns $store.state[root][key]', () => {
+ const context = shallowMount(dummyComponent, {
+ mocks: {
+ $store: {
+ state: {
+ foo: {
+ baz: 1,
+ },
+ },
+ },
+ },
+ });
+ expect(context.vm.baz).toBe(1);
+ });
+ });
+});
diff --git a/spec/javascripts/diffs/components/app_spec.js b/spec/javascripts/diffs/components/app_spec.js
index 48e1ed18a2f..25754eca336 100644
--- a/spec/javascripts/diffs/components/app_spec.js
+++ b/spec/javascripts/diffs/components/app_spec.js
@@ -69,13 +69,19 @@ describe('diffs/components/app', () => {
describe('fetch diff methods', () => {
beforeEach(() => {
+ const fetchResolver = () => {
+ store.state.diffs.retrievingBatches = false;
+ return Promise.resolve();
+ };
spyOn(window, 'requestIdleCallback').and.callFake(fn => fn());
createComponent();
- spyOn(wrapper.vm, 'fetchDiffFiles').and.callFake(() => Promise.resolve());
- spyOn(wrapper.vm, 'fetchDiffFilesMeta').and.callFake(() => Promise.resolve());
- spyOn(wrapper.vm, 'fetchDiffFilesBatch').and.callFake(() => Promise.resolve());
+ spyOn(wrapper.vm, 'fetchDiffFiles').and.callFake(fetchResolver);
+ spyOn(wrapper.vm, 'fetchDiffFilesMeta').and.callFake(fetchResolver);
+ spyOn(wrapper.vm, 'fetchDiffFilesBatch').and.callFake(fetchResolver);
spyOn(wrapper.vm, 'setDiscussions');
spyOn(wrapper.vm, 'startRenderDiffsQueue');
+ spyOn(wrapper.vm, 'unwatchDiscussions');
+ store.state.diffs.retrievingBatches = true;
});
it('calls fetchDiffFiles if diffsBatchLoad is not enabled', done => {
@@ -87,6 +93,7 @@ describe('diffs/components/app', () => {
expect(wrapper.vm.startRenderDiffsQueue).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesMeta).not.toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesBatch).not.toHaveBeenCalled();
+ expect(wrapper.vm.unwatchDiscussions).toHaveBeenCalled();
done();
});
@@ -102,6 +109,7 @@ describe('diffs/components/app', () => {
expect(wrapper.vm.startRenderDiffsQueue).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled();
+ expect(wrapper.vm.unwatchDiscussions).toHaveBeenCalled();
});
});
@@ -114,6 +122,7 @@ describe('diffs/components/app', () => {
expect(wrapper.vm.startRenderDiffsQueue).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesMeta).toHaveBeenCalled();
expect(wrapper.vm.fetchDiffFilesBatch).toHaveBeenCalled();
+ expect(wrapper.vm.unwatchDiscussions).toHaveBeenCalled();
});
});
});
diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js
index b23334d38dc..98a5348c3bc 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/javascripts/diffs/store/actions_spec.js
@@ -163,10 +163,12 @@ describe('DiffsStoreActions', () => {
{ endpointBatch },
[
{ type: types.SET_BATCH_LOADING, payload: true },
+ { type: types.SET_RETRIEVING_BATCHES, payload: true },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: res1.diff_files } },
{ type: types.SET_BATCH_LOADING, payload: false },
{ type: types.SET_DIFF_DATA_BATCH, payload: { diff_files: [] } },
{ type: types.SET_BATCH_LOADING, payload: false },
+ { type: types.SET_RETRIEVING_BATCHES, payload: false },
],
[],
() => {
@@ -215,6 +217,8 @@ describe('DiffsStoreActions', () => {
describe('assignDiscussionsToDiff', () => {
it('should merge discussions into diffs', done => {
+ window.location.hash = 'ABC_123';
+
const state = {
diffFiles: [
{
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 13f16e4f9a6..93dbf03e1ed 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -40,6 +40,16 @@ describe('DiffsStoreMutations', () => {
});
});
+ describe('SET_RETRIEVING_BATCHES', () => {
+ it('should set retrievingBatches state', () => {
+ const state = {};
+
+ mutations[types.SET_RETRIEVING_BATCHES](state, false);
+
+ expect(state.retrievingBatches).toEqual(false);
+ });
+ });
+
describe('SET_DIFF_DATA', () => {
it('should set diff data type properly', () => {
const state = {};