diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-08 18:10:43 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-01-08 18:10:43 +0000 |
commit | 9bcb655610575956a858ae6fdb1d00deef5f6ad8 (patch) | |
tree | 8c2e013c86cf94d2596655bceab865feef53bd38 /spec/frontend | |
parent | 6e734c809b18a0470d81c78e1ecd9b3f8278de89 (diff) | |
download | gitlab-ce-9bcb655610575956a858ae6fdb1d00deef5f6ad8.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
16 files changed, 647 insertions, 109 deletions
diff --git a/spec/frontend/feature_flags/components/feature_flags_table_spec.js b/spec/frontend/feature_flags/components/feature_flags_table_spec.js index a488662470e..8881cfae88d 100644 --- a/spec/frontend/feature_flags/components/feature_flags_table_spec.js +++ b/spec/frontend/feature_flags/components/feature_flags_table_spec.js @@ -120,13 +120,11 @@ describe('Feature flag table', () => { describe('when active and with an update toggle', () => { let toggle; - let spy; beforeEach(() => { props.featureFlags[0].update_path = props.featureFlags[0].destroy_path; createWrapper(props); toggle = wrapper.find(GlToggle); - spy = mockTracking('_category_', toggle.element, jest.spyOn); }); it('should have a toggle', () => { @@ -142,14 +140,6 @@ describe('Feature flag table', () => { expect(wrapper.emitted('toggle-flag')).toEqual([[flag]]); }); }); - - it('should track a click', () => { - toggle.trigger('click'); - - expect(spy).toHaveBeenCalledWith('_category_', 'click_button', { - label: 'feature_flag_toggle', - }); - }); }); describe('with an active scope and a percentage rollout strategy', () => { @@ -180,6 +170,8 @@ describe('Feature flag table', () => { }); describe('with a new version flag', () => { + let toggle; + let spy; let badges; beforeEach(() => { @@ -194,6 +186,7 @@ describe('Feature flag table', () => { description: 'flag description', destroy_path: 'destroy/path', edit_path: 'edit/path', + update_path: 'update/path', version: NEW_VERSION_FLAG, scopes: [], strategies: [ @@ -226,6 +219,8 @@ describe('Feature flag table', () => { provide: { csrfToken: 'fakeToken', glFeatures: { featureFlagsNewVersion: true } }, }); + toggle = wrapper.find(GlToggle); + spy = mockTracking('_category_', toggle.element, jest.spyOn); badges = wrapper.findAll('[data-testid="strategy-badge"]'); }); @@ -254,6 +249,14 @@ describe('Feature flag table', () => { it('shows the name of a user list for user list', () => { expect(badges.at(3).text()).toContain('User List - test list'); }); + + it('tracks a click', () => { + toggle.trigger('click'); + + expect(spy).toHaveBeenCalledWith('_category_', 'click_button', { + label: 'feature_flag_toggle', + }); + }); }); it('renders a feature flag without an iid', () => { diff --git a/spec/frontend/fixtures/project_analytics.rb b/spec/frontend/fixtures/project_analytics.rb deleted file mode 100644 index f0be5e8b97d..00000000000 --- a/spec/frontend/fixtures/project_analytics.rb +++ /dev/null @@ -1,69 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Project Analytics (JavaScript fixtures)' do - include ApiHelpers - include JavaScriptFixturesHelpers - - let_it_be(:reporter) { create(:user) } - let_it_be(:project) { create(:project, :repository) } - let_it_be(:environment) { create(:environment, project: project, name: 'production') } - - let!(:deployments) do - [ - 1.minute.ago, - 2.days.ago, - 3.days.ago, - 3.days.ago, - 3.days.ago, - 8.days.ago, - 32.days.ago, - 91.days.ago - ].map do |finished_at| - create(:deployment, - :success, - project: project, - environment: environment, - finished_at: finished_at) - end - end - - before do - stub_licensed_features(project_activity_analytics: true) - project.add_reporter(reporter) - sign_in(reporter) - end - - after(:all) do - remove_repository(project) - end - - describe API::Analytics::ProjectDeploymentFrequency, type: :request do - before(:all) do - clean_frontend_fixtures('api/project_analytics/') - end - - let(:shared_params) { { environment: environment.name, interval: 'daily' } } - - def make_request(additional_query_params:) - params = shared_params.merge(additional_query_params) - get api("/projects/#{project.id}/analytics/deployment_frequency?#{params.to_query}", reporter) - end - - it 'api/project_analytics/daily_deployment_frequencies_for_last_week.json' do - make_request(additional_query_params: { from: 1.week.ago }) - expect(response).to be_successful - end - - it 'api/project_analytics/daily_deployment_frequencies_for_last_month.json' do - make_request(additional_query_params: { from: 1.month.ago }) - expect(response).to be_successful - end - - it 'api/project_analytics/daily_deployment_frequencies_for_last_90_days.json' do - make_request(additional_query_params: { from: 90.days.ago }) - expect(response).to be_successful - end - end -end diff --git a/spec/frontend/gl_form_spec.js b/spec/frontend/gl_form_spec.js index 5dbded720bb..d9a01f7bcc1 100644 --- a/spec/frontend/gl_form_spec.js +++ b/spec/frontend/gl_form_spec.js @@ -114,6 +114,26 @@ describe('GLForm', () => { }); }); + describe('autofocus', () => { + it('focus the textarea when autofocus is true', () => { + testContext.textarea.data('autofocus', true); + jest.spyOn($.prototype, 'focus'); + + testContext.glForm = new GLForm(testContext.form, false); + + expect($.prototype.focus).toHaveBeenCalled(); + }); + + it("doesn't focus the textarea when autofocus is false", () => { + testContext.textarea.data('autofocus', false); + jest.spyOn($.prototype, 'focus'); + + testContext.glForm = new GLForm(testContext.form, false); + + expect($.prototype.focus).not.toHaveBeenCalled(); + }); + }); + describe('supportsQuickActions', () => { it('should return false if textarea does not support quick actions', () => { const glForm = new GLForm(testContext.form, false); diff --git a/spec/frontend/pipelines/pipelines_artifacts_spec.js b/spec/frontend/pipelines/pipelines_artifacts_spec.js index 83f6cb68eba..4f4c15fd4cc 100644 --- a/spec/frontend/pipelines/pipelines_artifacts_spec.js +++ b/spec/frontend/pipelines/pipelines_artifacts_spec.js @@ -1,12 +1,12 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlLink } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; import PipelineArtifacts from '~/pipelines/components/pipelines_list/pipelines_artifacts.vue'; describe('Pipelines Artifacts dropdown', () => { let wrapper; const createComponent = () => { - wrapper = shallowMount(PipelineArtifacts, { + wrapper = mount(PipelineArtifacts, { propsData: { artifacts: [ { @@ -22,8 +22,8 @@ describe('Pipelines Artifacts dropdown', () => { }); }; - const findGlLink = () => wrapper.find(GlLink); - const findAllGlLinks = () => wrapper.find('.dropdown-menu').findAll(GlLink); + const findFirstGlDropdownItem = () => wrapper.find(GlDropdownItem); + const findAllGlDropdownItems = () => wrapper.find(GlDropdown).findAll(GlDropdownItem); beforeEach(() => { createComponent(); @@ -35,12 +35,12 @@ describe('Pipelines Artifacts dropdown', () => { }); it('should render a dropdown with all the provided artifacts', () => { - expect(findAllGlLinks()).toHaveLength(2); + expect(findAllGlDropdownItems()).toHaveLength(2); }); it('should render a link with the provided path', () => { - expect(findGlLink().attributes('href')).toEqual('/download/path'); + expect(findFirstGlDropdownItem().find('a').attributes('href')).toEqual('/download/path'); - expect(findGlLink().text()).toContain('artifact'); + expect(findFirstGlDropdownItem().text()).toContain('artifact'); }); }); diff --git a/spec/frontend/projects/commit/components/branches_dropdown_spec.js b/spec/frontend/projects/commit/components/branches_dropdown_spec.js new file mode 100644 index 00000000000..308bb9f5ea8 --- /dev/null +++ b/spec/frontend/projects/commit/components/branches_dropdown_spec.js @@ -0,0 +1,166 @@ +import Vue from 'vue'; +import Vuex from 'vuex'; +import { shallowMount } from '@vue/test-utils'; +import { extendedWrapper } from 'jest/helpers/vue_test_utils_helper'; +import { GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui'; +import BranchesDropdown from '~/projects/commit/components/branches_dropdown.vue'; + +Vue.use(Vuex); + +describe('BranchesDropdown', () => { + let wrapper; + let store; + const spyFetchBranches = jest.fn(); + + const createComponent = (term, state = { isFetching: false }) => { + store = new Vuex.Store({ + getters: { + joinedBranches: () => ['_master_', '_branch_1_', '_branch_2_'], + }, + actions: { + fetchBranches: spyFetchBranches, + }, + state, + }); + + wrapper = extendedWrapper( + shallowMount(BranchesDropdown, { + store, + propsData: { + value: term, + }, + }), + ); + }; + + const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); + const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType); + const findDropdownItemByIndex = (index) => wrapper.findAllComponents(GlDropdownItem).at(index); + const findNoResults = () => wrapper.findByTestId('empty-result-message'); + const findLoading = () => wrapper.findByTestId('dropdown-text-loading-icon'); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + spyFetchBranches.mockReset(); + }); + + describe('On mount', () => { + beforeEach(() => { + createComponent(''); + }); + + it('invokes fetchBranches', () => { + expect(spyFetchBranches).toHaveBeenCalled(); + }); + }); + + describe('Loading states', () => { + it('shows loading icon while fetching', () => { + createComponent('', { isFetching: true }); + + expect(findLoading().isVisible()).toBe(true); + }); + + it('does not show loading icon', () => { + createComponent(''); + + expect(findLoading().isVisible()).toBe(false); + }); + }); + + describe('No branches found', () => { + beforeEach(() => { + createComponent('_non_existent_branch_'); + }); + + it('renders empty results message', () => { + expect(findNoResults().text()).toBe('No matching results'); + }); + + it('shows GlSearchBoxByType with default attributes', () => { + expect(findSearchBoxByType().exists()).toBe(true); + expect(findSearchBoxByType().vm.$attrs).toMatchObject({ + placeholder: 'Search branches', + debounce: 250, + }); + }); + }); + + describe('Search term is empty', () => { + beforeEach(() => { + createComponent(''); + }); + + it('renders all branches when search term is empty', () => { + expect(findAllDropdownItems()).toHaveLength(3); + expect(findDropdownItemByIndex(0).text()).toBe('_master_'); + expect(findDropdownItemByIndex(1).text()).toBe('_branch_1_'); + expect(findDropdownItemByIndex(2).text()).toBe('_branch_2_'); + }); + + it('should not be selected on the inactive branch', () => { + expect(wrapper.vm.isSelected('_master_')).toBe(false); + }); + }); + + describe('When searching', () => { + beforeEach(() => { + createComponent(''); + }); + + it('invokes fetchBranches', async () => { + const spy = jest.spyOn(wrapper.vm, 'fetchBranches'); + + findSearchBoxByType().vm.$emit('input', '_anything_'); + + await wrapper.vm.$nextTick(); + + expect(spy).toHaveBeenCalledWith('_anything_'); + expect(wrapper.vm.searchTerm).toBe('_anything_'); + }); + }); + + describe('Branches found', () => { + beforeEach(() => { + createComponent('_branch_1_', { branch: '_branch_1_' }); + }); + + it('renders only the branch searched for', () => { + expect(findAllDropdownItems()).toHaveLength(1); + expect(findDropdownItemByIndex(0).text()).toBe('_branch_1_'); + }); + + it('should not display empty results message', () => { + expect(findNoResults().exists()).toBe(false); + }); + + it('should signify this branch is selected', () => { + expect(wrapper.vm.isSelected('_branch_1_')).toBe(true); + }); + + it('should signify the branch is not selected', () => { + expect(wrapper.vm.isSelected('_not_selected_branch_')).toBe(false); + }); + + describe('Custom events', () => { + it('should emit selectBranch if an branch is clicked', () => { + findDropdownItemByIndex(0).vm.$emit('click'); + + expect(wrapper.emitted('selectBranch')).toEqual([['_branch_1_']]); + expect(wrapper.vm.searchTerm).toBe('_branch_1_'); + }); + }); + }); + + describe('Case insensitive for search term', () => { + beforeEach(() => { + createComponent('_BrAnCh_1_'); + }); + + it('renders only the branch searched for', () => { + expect(findAllDropdownItems()).toHaveLength(1); + expect(findDropdownItemByIndex(0).text()).toBe('_branch_1_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/components/form_modal_spec.js b/spec/frontend/projects/commit/components/form_modal_spec.js new file mode 100644 index 00000000000..0c7f09e2520 --- /dev/null +++ b/spec/frontend/projects/commit/components/form_modal_spec.js @@ -0,0 +1,155 @@ +import MockAdapter from 'axios-mock-adapter'; +import { shallowMount, mount, createWrapper } from '@vue/test-utils'; +import { extendedWrapper } from 'jest/helpers/vue_test_utils_helper'; +import { GlModal, GlForm, GlFormCheckbox, GlSprintf } from '@gitlab/ui'; +import { within } from '@testing-library/dom'; +import axios from '~/lib/utils/axios_utils'; +import eventHub from '~/projects/commit/event_hub'; +import CommitFormModal from '~/projects/commit/components/form_modal.vue'; +import BranchesDropdown from '~/projects/commit/components/branches_dropdown.vue'; +import createStore from '~/projects/commit/store'; +import mockData from '../mock_data'; + +describe('CommitFormModal', () => { + let wrapper; + let store; + let axiosMock; + + const createComponent = (method, state = {}, provide = {}) => { + store = createStore({ ...mockData.mockModal, ...state }); + wrapper = extendedWrapper( + method(CommitFormModal, { + provide, + propsData: { ...mockData.modalPropsData }, + store, + attrs: { + static: true, + visible: true, + }, + }), + ); + }; + + const findModal = () => wrapper.findComponent(GlModal); + const findStartBranch = () => wrapper.find('#start_branch'); + const findDropdown = () => wrapper.findComponent(BranchesDropdown); + const findForm = () => findModal().findComponent(GlForm); + const findCheckBox = () => findForm().findComponent(GlFormCheckbox); + const findPrependedText = () => wrapper.findByTestId('prepended-text'); + const findAppendedText = () => wrapper.findByTestId('appended-text'); + const getByText = (text, options) => + createWrapper(within(findModal().element).getByText(text, options)); + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + }); + + afterEach(() => { + wrapper.destroy(); + axiosMock.restore(); + }); + + describe('Basic interactions', () => { + it('Listens for opening of modal on mount', () => { + jest.spyOn(eventHub, '$on'); + + createComponent(shallowMount); + + expect(eventHub.$on).toHaveBeenCalledWith(mockData.modalPropsData.openModal, wrapper.vm.show); + }); + + it('Shows modal', () => { + createComponent(shallowMount); + const rootEmit = jest.spyOn(wrapper.vm.$root, '$emit'); + + wrapper.vm.show(); + + expect(rootEmit).toHaveBeenCalledWith('bv::show::modal', mockData.modalPropsData.modalId); + }); + + it('Clears the modal state once modal is hidden', () => { + createComponent(shallowMount); + jest.spyOn(store, 'dispatch').mockImplementation(); + wrapper.vm.checked = false; + + findModal().vm.$emit('hidden'); + + expect(store.dispatch).toHaveBeenCalledWith('clearModal'); + expect(store.dispatch).toHaveBeenCalledWith('setSelectedBranch', ''); + expect(wrapper.vm.checked).toBe(true); + }); + + it('Shows the checkbox for new merge request', () => { + createComponent(shallowMount); + + expect(findCheckBox().exists()).toBe(true); + }); + + it('Shows the prepended text', () => { + createComponent(shallowMount, {}, { prependedText: '_prepended_text_' }); + + expect(findPrependedText().exists()).toBe(true); + expect(findPrependedText().find(GlSprintf).attributes('message')).toBe('_prepended_text_'); + }); + + it('Does not show prepended text', () => { + createComponent(shallowMount); + + expect(findPrependedText().exists()).toBe(false); + }); + + it('Does not show extra message text', () => { + createComponent(shallowMount); + + expect(findModal().find('[data-testid="appended-text"]').exists()).toBe(false); + }); + + it('Does not show the checkbox for new merge request', () => { + createComponent(shallowMount, { pushCode: false }); + + expect(findCheckBox().exists()).toBe(false); + }); + + it('Shows the branch in fork message', () => { + createComponent(shallowMount, { pushCode: false }); + + expect(findAppendedText().exists()).toBe(true); + expect(findAppendedText().find(GlSprintf).attributes('message')).toContain( + mockData.modalPropsData.i18n.branchInFork, + ); + }); + + it('Shows the branch collaboration message', () => { + createComponent(shallowMount, { pushCode: false, branchCollaboration: true }); + + expect(findAppendedText().exists()).toBe(true); + expect(findAppendedText().find(GlSprintf).attributes('message')).toContain( + mockData.modalPropsData.i18n.existingBranch, + ); + }); + }); + + describe('Taking action on the form', () => { + beforeEach(() => { + createComponent(mount); + }); + + it('Action primary button dispatches submit action', () => { + const submitSpy = jest.spyOn(findForm().element, 'submit'); + + getByText(mockData.modalPropsData.i18n.actionPrimaryText).trigger('click'); + + expect(submitSpy).toHaveBeenCalled(); + + submitSpy.mockRestore(); + }); + + it('Changes the start_branch input value', async () => { + findDropdown().vm.$emit('selectBranch', '_changed_branch_value_'); + + await wrapper.vm.$nextTick(); + + expect(findStartBranch().attributes('value')).toBe('_changed_branch_value_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/components/form_trigger_spec.js b/spec/frontend/projects/commit/components/form_trigger_spec.js new file mode 100644 index 00000000000..ca51419d6a5 --- /dev/null +++ b/spec/frontend/projects/commit/components/form_trigger_spec.js @@ -0,0 +1,44 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLink } from '@gitlab/ui'; +import FormTrigger from '~/projects/commit/components/form_trigger.vue'; +import eventHub from '~/projects/commit/event_hub'; + +const displayText = '_display_text_'; + +const createComponent = () => { + return shallowMount(FormTrigger, { + provide: { displayText }, + propsData: { openModal: '_open_modal_' }, + }); +}; + +describe('FormTrigger', () => { + let wrapper; + let spy; + + beforeEach(() => { + spy = jest.spyOn(eventHub, '$emit'); + wrapper = createComponent(); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + const findLink = () => wrapper.find(GlLink); + + describe('displayText', () => { + it('includes the correct displayText for the link', () => { + expect(findLink().text()).toBe(displayText); + }); + }); + + describe('clicking the link', () => { + it('emits openModal', () => { + findLink().vm.$emit('click'); + + expect(spy).toHaveBeenCalledWith('_open_modal_'); + }); + }); +}); diff --git a/spec/frontend/projects/commit/mock_data.js b/spec/frontend/projects/commit/mock_data.js new file mode 100644 index 00000000000..2b3b5a14c98 --- /dev/null +++ b/spec/frontend/projects/commit/mock_data.js @@ -0,0 +1,27 @@ +import { I18N_MODAL } from '~/projects/commit/constants'; + +export default { + mockModal: { + modalTitle: '_modal_title_', + endpoint: '_endpoint_', + branch: '_branch_', + pushCode: true, + defaultBranch: '_branch_', + existingBranch: '_existing_branch', + branchesEndpoint: '_branches_endpoint_', + }, + modalPropsData: { + i18n: { + branchLabel: '_branch_label_', + actionPrimaryText: '_action_primary_text_', + startMergeRequest: '_start_merge_request_', + existingBranch: I18N_MODAL.existingBranch, + branchInFork: '_new_branch_in_fork_message_', + newMergeRequest: '_new merge request_', + actionCancelText: '_action_cancel_text_', + }, + modalId: '_modal_id_', + openModal: '_open_modal_', + }, + mockBranches: ['_branch_1', '_abc_', '_master_'], +}; diff --git a/spec/frontend/projects/commit/store/actions_spec.js b/spec/frontend/projects/commit/store/actions_spec.js new file mode 100644 index 00000000000..ec528d4ee88 --- /dev/null +++ b/spec/frontend/projects/commit/store/actions_spec.js @@ -0,0 +1,111 @@ +import MockAdapter from 'axios-mock-adapter'; +import testAction from 'helpers/vuex_action_helper'; +import axios from '~/lib/utils/axios_utils'; +import createFlash from '~/flash'; +import getInitialState from '~/projects/commit/store/state'; +import * as actions from '~/projects/commit/store/actions'; +import * as types from '~/projects/commit/store/mutation_types'; +import mockData from '../mock_data'; +import { PROJECT_BRANCHES_ERROR } from '~/projects/commit/constants'; + +jest.mock('~/flash.js'); + +describe('Commit form modal store actions', () => { + let axiosMock; + let state; + + beforeEach(() => { + axiosMock = new MockAdapter(axios); + state = getInitialState(); + }); + + afterEach(() => { + axiosMock.restore(); + }); + + describe('clearModal', () => { + it('commits CLEAR_MODAL mutation', () => { + testAction(actions.clearModal, {}, {}, [ + { + type: types.CLEAR_MODAL, + }, + ]); + }); + }); + + describe('requestBranches', () => { + it('commits REQUEST_BRANCHES mutation', () => { + testAction(actions.requestBranches, {}, {}, [ + { + type: types.REQUEST_BRANCHES, + }, + ]); + }); + }); + + describe('fetchBranches', () => { + it('dispatch correct actions on fetchBranches', (done) => { + jest + .spyOn(axios, 'get') + .mockImplementation(() => Promise.resolve({ data: mockData.mockBranches })); + + testAction( + actions.fetchBranches, + {}, + state, + [ + { + type: types.RECEIVE_BRANCHES_SUCCESS, + payload: mockData.mockBranches, + }, + ], + [{ type: 'requestBranches' }], + () => { + done(); + }, + ); + }); + + it('should show flash error and set error in state on fetchBranches failure', (done) => { + jest.spyOn(axios, 'get').mockRejectedValue(); + + testAction(actions.fetchBranches, {}, state, [], [{ type: 'requestBranches' }], () => { + expect(createFlash).toHaveBeenCalledWith({ message: PROJECT_BRANCHES_ERROR }); + done(); + }); + }); + }); + + describe('setBranch', () => { + it('commits SET_BRANCH mutation', () => { + testAction( + actions.setBranch, + {}, + {}, + [ + { + type: types.SET_BRANCH, + payload: {}, + }, + ], + [ + { + type: 'setSelectedBranch', + payload: {}, + }, + ], + ); + }); + }); + + describe('setSelectedBranch', () => { + it('commits SET_SELECTED_BRANCH mutation', () => { + testAction(actions.setSelectedBranch, {}, {}, [ + { + type: types.SET_SELECTED_BRANCH, + payload: {}, + }, + ]); + }); + }); +}); diff --git a/spec/frontend/projects/commit/store/getters_spec.js b/spec/frontend/projects/commit/store/getters_spec.js new file mode 100644 index 00000000000..bd0cb356854 --- /dev/null +++ b/spec/frontend/projects/commit/store/getters_spec.js @@ -0,0 +1,21 @@ +import * as getters from '~/projects/commit/store/getters'; +import mockData from '../mock_data'; + +describe('Commit form modal getters', () => { + describe('joinedBranches', () => { + it('should join fetched branches with variable branches', () => { + const state = { + branches: mockData.mockBranches, + }; + + expect(getters.joinedBranches(state)).toEqual(mockData.mockBranches.sort()); + }); + + it('should provide a uniq list of branches', () => { + const branches = ['_branch_', '_branch_', '_different_branch']; + const state = { branches }; + + expect(getters.joinedBranches(state)).toEqual(branches.slice(1)); + }); + }); +}); diff --git a/spec/frontend/projects/commit/store/mutations_spec.js b/spec/frontend/projects/commit/store/mutations_spec.js new file mode 100644 index 00000000000..59ab3d9a74a --- /dev/null +++ b/spec/frontend/projects/commit/store/mutations_spec.js @@ -0,0 +1,57 @@ +import mutations from '~/projects/commit/store/mutations'; +import * as types from '~/projects/commit/store/mutation_types'; + +describe('Commit form modal mutations', () => { + let stateCopy; + + describe('REQUEST_BRANCHES', () => { + it('should set isFetching to true', () => { + stateCopy = { isFetching: false }; + + mutations[types.REQUEST_BRANCHES](stateCopy); + + expect(stateCopy.isFetching).toBe(true); + }); + }); + + describe('RECEIVE_BRANCHES_SUCCESS', () => { + it('should set branches', () => { + stateCopy = { branch: '_existing_branch_', isFetching: true }; + + mutations[types.RECEIVE_BRANCHES_SUCCESS](stateCopy, ['_branch_1_', '_branch_2_']); + + expect(stateCopy.branches).toEqual(['_existing_branch_', '_branch_1_', '_branch_2_']); + expect(stateCopy.isFetching).toEqual(false); + }); + }); + + describe('CLEAR_MODAL', () => { + it('should clear modal state ', () => { + stateCopy = { branch: '_master_', defaultBranch: '_default_branch_' }; + + mutations[types.CLEAR_MODAL](stateCopy); + + expect(stateCopy.branch).toEqual('_default_branch_'); + }); + }); + + describe('SET_BRANCH', () => { + it('should set branch', () => { + stateCopy = { branch: '_master_' }; + + mutations[types.SET_BRANCH](stateCopy, '_changed_branch_'); + + expect(stateCopy.branch).toBe('_changed_branch_'); + }); + }); + + describe('SET_SELECTED_BRANCH', () => { + it('should set selectedBranch', () => { + stateCopy = { selectedBranch: '_master_' }; + + mutations[types.SET_SELECTED_BRANCH](stateCopy, '_changed_branch_'); + + expect(stateCopy.selectedBranch).toBe('_changed_branch_'); + }); + }); +}); diff --git a/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js b/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js index 6b2a4d928f0..2e1e21299b3 100644 --- a/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js +++ b/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js @@ -7,7 +7,7 @@ import { TEST_HOST as FAKE_ENDPOINT } from 'helpers/test_constants'; import axios from '~/lib/utils/axios_utils'; import ArtifactsListApp from '~/vue_merge_request_widget/components/artifacts_list_app.vue'; import { getStoreConfig } from '~/vue_merge_request_widget/stores/artifacts_list'; -import { artifactsList } from './mock_data'; +import { artifacts } from '../mock_data'; Vue.use(Vuex); @@ -78,9 +78,9 @@ describe('Merge Requests Artifacts list app', () => { describe('with results', () => { beforeEach(() => { createComponent(); - mock.onGet(FAKE_ENDPOINT).reply(200, artifactsList, {}); + mock.onGet(FAKE_ENDPOINT).reply(200, artifacts, {}); store.dispatch('receiveArtifactsSuccess', { - data: artifactsList, + data: artifacts, status: 200, }); return nextTick(); diff --git a/spec/frontend/vue_mr_widget/components/artifacts_list_spec.js b/spec/frontend/vue_mr_widget/components/artifacts_list_spec.js index 07b569ea07a..fd432381512 100644 --- a/spec/frontend/vue_mr_widget/components/artifacts_list_spec.js +++ b/spec/frontend/vue_mr_widget/components/artifacts_list_spec.js @@ -1,13 +1,13 @@ import { shallowMount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; import ArtifactsList from '~/vue_merge_request_widget/components/artifacts_list.vue'; -import { artifactsList } from './mock_data'; +import { artifacts } from '../mock_data'; describe('Artifacts List', () => { let wrapper; const data = { - artifacts: artifactsList, + artifacts, }; const mountComponent = (props) => { diff --git a/spec/frontend/vue_mr_widget/components/mock_data.js b/spec/frontend/vue_mr_widget/components/mock_data.js deleted file mode 100644 index 73e254f2b1a..00000000000 --- a/spec/frontend/vue_mr_widget/components/mock_data.js +++ /dev/null @@ -1,14 +0,0 @@ -export const artifactsList = [ - { - text: 'result.txt', - url: 'bar', - job_name: 'generate-artifact', - job_path: 'bar', - }, - { - text: 'foo.txt', - url: 'foo', - job_name: 'foo-artifact', - job_path: 'foo', - }, -]; diff --git a/spec/frontend/vue_mr_widget/mock_data.js b/spec/frontend/vue_mr_widget/mock_data.js index 7f82f3ee233..aa2345abccf 100644 --- a/spec/frontend/vue_mr_widget/mock_data.js +++ b/spec/frontend/vue_mr_widget/mock_data.js @@ -1,5 +1,20 @@ import { SUCCESS } from '~/vue_merge_request_widget/components/deployment/constants'; +export const artifacts = [ + { + text: 'result.txt', + url: 'bar', + job_name: 'generate-artifact', + job_path: 'bar', + }, + { + text: 'foo.txt', + url: 'foo', + job_name: 'foo-artifact', + job_path: 'foo', + }, +]; + export default { id: 132, iid: 22, @@ -84,6 +99,7 @@ export default { coverage: '92.16', path: '/root/acets-app/pipelines/172', details: { + artifacts, status: { icon: 'status_success', favicon: 'favicon_status_success', @@ -127,7 +143,6 @@ export default { dropdown_path: '/root/acets-app/pipelines/172/stage.json?stage=review', }, ], - artifacts: [], manual_actions: [ { name: 'stop_review', @@ -275,6 +290,7 @@ export const mockStore = { pipeline: { id: 0, details: { + artifacts, status: { details_path: '/root/review-app-tester/pipelines/66', favicon: @@ -294,6 +310,7 @@ export const mockStore = { mergePipeline: { id: 1, details: { + artifacts, status: { details_path: '/root/review-app-tester/pipelines/66', favicon: diff --git a/spec/frontend/vue_mr_widget/stores/artifacts_list/getters_spec.js b/spec/frontend/vue_mr_widget/stores/artifacts_list/getters_spec.js index 62ee6f5f189..dc90fef63c6 100644 --- a/spec/frontend/vue_mr_widget/stores/artifacts_list/getters_spec.js +++ b/spec/frontend/vue_mr_widget/stores/artifacts_list/getters_spec.js @@ -1,6 +1,6 @@ import { title } from '~/vue_merge_request_widget/stores/artifacts_list/getters'; import state from '~/vue_merge_request_widget/stores/artifacts_list/state'; -import { artifactsList } from '../../components/mock_data'; +import { artifacts } from '../../mock_data'; describe('Artifacts Store Getters', () => { let localState; @@ -24,7 +24,7 @@ describe('Artifacts Store Getters', () => { }); describe('when it has artifacts', () => { it('returns artifacts message', () => { - localState.artifacts = artifactsList; + localState.artifacts = artifacts; expect(title(localState)).toBe('View 2 exposed artifacts'); }); }); |