diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-19 15:07:35 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-19 15:07:35 +0300 |
commit | e3764d340e2849fccee8c06278d1f5f686edd35b (patch) | |
tree | 23de7fe0eaa58a82c3a72eb8ff4a195e24627eb7 /spec | |
parent | e3d67bcff7b8bc6a453d0814d404a9a61d97bc0f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
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 = {}; |