summaryrefslogtreecommitdiff
path: root/spec/frontend
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-01-08 18:10:43 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-01-08 18:10:43 +0000
commit9bcb655610575956a858ae6fdb1d00deef5f6ad8 (patch)
tree8c2e013c86cf94d2596655bceab865feef53bd38 /spec/frontend
parent6e734c809b18a0470d81c78e1ecd9b3f8278de89 (diff)
downloadgitlab-ce-9bcb655610575956a858ae6fdb1d00deef5f6ad8.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/feature_flags/components/feature_flags_table_spec.js23
-rw-r--r--spec/frontend/fixtures/project_analytics.rb69
-rw-r--r--spec/frontend/gl_form_spec.js20
-rw-r--r--spec/frontend/pipelines/pipelines_artifacts_spec.js16
-rw-r--r--spec/frontend/projects/commit/components/branches_dropdown_spec.js166
-rw-r--r--spec/frontend/projects/commit/components/form_modal_spec.js155
-rw-r--r--spec/frontend/projects/commit/components/form_trigger_spec.js44
-rw-r--r--spec/frontend/projects/commit/mock_data.js27
-rw-r--r--spec/frontend/projects/commit/store/actions_spec.js111
-rw-r--r--spec/frontend/projects/commit/store/getters_spec.js21
-rw-r--r--spec/frontend/projects/commit/store/mutations_spec.js57
-rw-r--r--spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js6
-rw-r--r--spec/frontend/vue_mr_widget/components/artifacts_list_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/mock_data.js14
-rw-r--r--spec/frontend/vue_mr_widget/mock_data.js19
-rw-r--r--spec/frontend/vue_mr_widget/stores/artifacts_list/getters_spec.js4
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');
});
});