summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_mr_widget
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
commit9f46488805e86b1bc341ea1620b866016c2ce5ed (patch)
treef9748c7e287041e37d6da49e0a29c9511dc34768 /spec/frontend/vue_mr_widget
parentdfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff)
downloadgitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/frontend/vue_mr_widget')
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js100
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js18
-rw-r--r--spec/frontend/vue_mr_widget/stores/artifacts_list/actions_spec.js165
-rw-r--r--spec/frontend/vue_mr_widget/stores/get_state_key_spec.js24
-rw-r--r--spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js112
6 files changed, 421 insertions, 2 deletions
diff --git a/spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js b/spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js
index a7ecb863cfb..8a604355625 100644
--- a/spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js
@@ -61,7 +61,7 @@ describe('Merge Request Collapsible Extension', () => {
describe('while loading', () => {
beforeEach(() => {
- mountComponent(Object.assign({}, data, { isLoading: true }));
+ mountComponent({ ...data, isLoading: true });
});
it('renders the buttons disabled', () => {
@@ -86,7 +86,7 @@ describe('Merge Request Collapsible Extension', () => {
describe('with error', () => {
beforeEach(() => {
- mountComponent(Object.assign({}, data, { hasError: true }));
+ mountComponent({ ...data, hasError: true });
});
it('does not render the buttons', () => {
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js
new file mode 100644
index 00000000000..5f3a8654990
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js
@@ -0,0 +1,100 @@
+import { mount } from '@vue/test-utils';
+import MrWidgetPipelineContainer from '~/vue_merge_request_widget/components/mr_widget_pipeline_container.vue';
+import MrWidgetPipeline from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue';
+import ArtifactsApp from '~/vue_merge_request_widget/components/artifacts_list_app.vue';
+import { mockStore } from '../mock_data';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+
+describe('MrWidgetPipelineContainer', () => {
+ let wrapper;
+ let mock;
+
+ const factory = (props = {}) => {
+ wrapper = mount(MrWidgetPipelineContainer, {
+ propsData: {
+ mr: { ...mockStore },
+ ...props,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ mock.onGet().reply(200, {});
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when pre merge', () => {
+ beforeEach(() => {
+ factory();
+ });
+
+ it('renders pipeline', () => {
+ expect(wrapper.find(MrWidgetPipeline).exists()).toBe(true);
+ expect(wrapper.find(MrWidgetPipeline).props()).toMatchObject({
+ pipeline: mockStore.pipeline,
+ pipelineCoverageDelta: mockStore.pipelineCoverageDelta,
+ ciStatus: mockStore.ciStatus,
+ hasCi: mockStore.hasCI,
+ sourceBranch: mockStore.sourceBranch,
+ sourceBranchLink: mockStore.sourceBranchLink,
+ });
+ });
+
+ it('renders deployments', () => {
+ const expectedProps = mockStore.deployments.map(dep =>
+ expect.objectContaining({
+ deployment: dep,
+ showMetrics: false,
+ }),
+ );
+
+ const deployments = wrapper.findAll('.mr-widget-extension .js-pre-deployment');
+
+ expect(deployments.wrappers.map(x => x.props())).toEqual(expectedProps);
+ });
+ });
+
+ describe('when post merge', () => {
+ beforeEach(() => {
+ factory({
+ isPostMerge: true,
+ });
+ });
+
+ it('renders pipeline', () => {
+ expect(wrapper.find(MrWidgetPipeline).exists()).toBe(true);
+ expect(wrapper.find(MrWidgetPipeline).props()).toMatchObject({
+ pipeline: mockStore.mergePipeline,
+ pipelineCoverageDelta: mockStore.pipelineCoverageDelta,
+ ciStatus: mockStore.ciStatus,
+ hasCi: mockStore.hasCI,
+ sourceBranch: mockStore.targetBranch,
+ sourceBranchLink: mockStore.targetBranch,
+ });
+ });
+
+ it('renders deployments', () => {
+ const expectedProps = mockStore.postMergeDeployments.map(dep =>
+ expect.objectContaining({
+ deployment: dep,
+ showMetrics: true,
+ }),
+ );
+
+ const deployments = wrapper.findAll('.mr-widget-extension .js-post-deployment');
+
+ expect(deployments.wrappers.map(x => x.props())).toEqual(expectedProps);
+ });
+ });
+
+ describe('with artifacts path', () => {
+ it('renders the artifacts app', () => {
+ expect(wrapper.find(ArtifactsApp).isVisible()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
index 1951b56587a..91e95b2bdb1 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_terraform_plan_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
import MrWidgetTerraformPlan from '~/vue_merge_request_widget/components/mr_widget_terraform_plan.vue';
+import Poll from '~/lib/utils/poll';
const plan = {
create: 10,
@@ -57,11 +58,23 @@ describe('MrWidgetTerraformPlan', () => {
});
describe('successful poll', () => {
+ let pollRequest;
+ let pollStop;
+
beforeEach(() => {
+ pollRequest = jest.spyOn(Poll.prototype, 'makeRequest');
+ pollStop = jest.spyOn(Poll.prototype, 'stop');
+
mockPollingApi(200, { 'tfplan.json': plan }, {});
+
return mountWrapper();
});
+ afterEach(() => {
+ pollRequest.mockRestore();
+ pollStop.mockRestore();
+ });
+
it('content change text', () => {
expect(wrapper.find(GlSprintf).exists()).toBe(true);
});
@@ -69,6 +82,11 @@ describe('MrWidgetTerraformPlan', () => {
it('renders button when url is found', () => {
expect(wrapper.find('a').text()).toContain('View full log');
});
+
+ it('does not make additional requests after poll is successful', () => {
+ expect(pollRequest).toHaveBeenCalledTimes(1);
+ expect(pollStop).toHaveBeenCalledTimes(1);
+ });
});
describe('polling fails', () => {
diff --git a/spec/frontend/vue_mr_widget/stores/artifacts_list/actions_spec.js b/spec/frontend/vue_mr_widget/stores/artifacts_list/actions_spec.js
new file mode 100644
index 00000000000..026ea0e4d0a
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/stores/artifacts_list/actions_spec.js
@@ -0,0 +1,165 @@
+import MockAdapter from 'axios-mock-adapter';
+import testAction from 'helpers/vuex_action_helper';
+import { TEST_HOST } from 'helpers/test_constants';
+import axios from '~/lib/utils/axios_utils';
+import {
+ setEndpoint,
+ requestArtifacts,
+ clearEtagPoll,
+ stopPolling,
+ fetchArtifacts,
+ receiveArtifactsSuccess,
+ receiveArtifactsError,
+} from '~/vue_merge_request_widget/stores/artifacts_list/actions';
+import state from '~/vue_merge_request_widget/stores/artifacts_list/state';
+import * as types from '~/vue_merge_request_widget/stores/artifacts_list/mutation_types';
+
+describe('Artifacts App Store Actions', () => {
+ let mockedState;
+
+ beforeEach(() => {
+ mockedState = state();
+ });
+
+ describe('setEndpoint', () => {
+ it('should commit SET_ENDPOINT mutation', done => {
+ testAction(
+ setEndpoint,
+ 'endpoint.json',
+ mockedState,
+ [{ type: types.SET_ENDPOINT, payload: 'endpoint.json' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('requestArtifacts', () => {
+ it('should commit REQUEST_ARTIFACTS mutation', done => {
+ testAction(
+ requestArtifacts,
+ null,
+ mockedState,
+ [{ type: types.REQUEST_ARTIFACTS }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('fetchArtifacts', () => {
+ let mock;
+
+ beforeEach(() => {
+ mockedState.endpoint = `${TEST_HOST}/endpoint.json`;
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ stopPolling();
+ clearEtagPoll();
+ });
+
+ describe('success', () => {
+ it('dispatches requestArtifacts and receiveArtifactsSuccess ', done => {
+ mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, [
+ {
+ text: 'result.txt',
+ url: 'asda',
+ job_name: 'generate-artifact',
+ job_path: 'asda',
+ },
+ ]);
+
+ testAction(
+ fetchArtifacts,
+ null,
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestArtifacts',
+ },
+ {
+ payload: {
+ data: [
+ {
+ text: 'result.txt',
+ url: 'asda',
+ job_name: 'generate-artifact',
+ job_path: 'asda',
+ },
+ ],
+ status: 200,
+ },
+ type: 'receiveArtifactsSuccess',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ beforeEach(() => {
+ mock.onGet(`${TEST_HOST}/endpoint.json`).reply(500);
+ });
+
+ it('dispatches requestArtifacts and receiveArtifactsError ', done => {
+ testAction(
+ fetchArtifacts,
+ null,
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestArtifacts',
+ },
+ {
+ type: 'receiveArtifactsError',
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('receiveArtifactsSuccess', () => {
+ it('should commit RECEIVE_ARTIFACTS_SUCCESS mutation with 200', done => {
+ testAction(
+ receiveArtifactsSuccess,
+ { data: { summary: {} }, status: 200 },
+ mockedState,
+ [{ type: types.RECEIVE_ARTIFACTS_SUCCESS, payload: { summary: {} } }],
+ [],
+ done,
+ );
+ });
+
+ it('should not commit RECEIVE_ARTIFACTS_SUCCESS mutation with 204', done => {
+ testAction(
+ receiveArtifactsSuccess,
+ { data: { summary: {} }, status: 204 },
+ mockedState,
+ [],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('receiveArtifactsError', () => {
+ it('should commit RECEIVE_ARTIFACTS_ERROR mutation', done => {
+ testAction(
+ receiveArtifactsError,
+ null,
+ mockedState,
+ [{ type: types.RECEIVE_ARTIFACTS_ERROR }],
+ [],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js b/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
index 0f5d47b3bfe..e54cd345a37 100644
--- a/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
+++ b/spec/frontend/vue_mr_widget/stores/get_state_key_spec.js
@@ -35,10 +35,12 @@ describe('getStateKey', () => {
expect(bound()).toEqual('autoMergeEnabled');
+ context.canMerge = true;
context.isSHAMismatch = true;
expect(bound()).toEqual('shaMismatch');
+ context.canMerge = false;
context.isPipelineBlocked = true;
expect(bound()).toEqual('pipelineBlocked');
@@ -100,4 +102,26 @@ describe('getStateKey', () => {
expect(bound()).toEqual('rebase');
});
+
+ it.each`
+ canMerge | isSHAMismatch | stateKey
+ ${true} | ${true} | ${'shaMismatch'}
+ ${false} | ${true} | ${'notAllowedToMerge'}
+ ${false} | ${false} | ${'notAllowedToMerge'}
+ `(
+ 'returns $stateKey when canMerge is $canMerge and isSHAMismatch is $isSHAMismatch',
+ ({ canMerge, isSHAMismatch, stateKey }) => {
+ const bound = getStateKey.bind(
+ {
+ canMerge,
+ isSHAMismatch,
+ },
+ {
+ commits_count: 2,
+ },
+ );
+
+ expect(bound()).toEqual(stateKey);
+ },
+ );
});
diff --git a/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js
new file mode 100644
index 00000000000..48326eda404
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -0,0 +1,112 @@
+import MergeRequestStore from '~/vue_merge_request_widget/stores/mr_widget_store';
+import { stateKey } from '~/vue_merge_request_widget/stores/state_maps';
+import mockData from '../mock_data';
+
+describe('MergeRequestStore', () => {
+ let store;
+
+ beforeEach(() => {
+ store = new MergeRequestStore(mockData);
+ });
+
+ describe('setData', () => {
+ it('should set isSHAMismatch when the diff SHA changes', () => {
+ store.setData({ ...mockData, diff_head_sha: 'a-different-string' });
+
+ expect(store.isSHAMismatch).toBe(true);
+ });
+
+ it('should not set isSHAMismatch when other data changes', () => {
+ store.setData({ ...mockData, work_in_progress: !mockData.work_in_progress });
+
+ expect(store.isSHAMismatch).toBe(false);
+ });
+
+ it('should update cached sha after rebasing', () => {
+ store.setData({ ...mockData, diff_head_sha: 'abc123' }, true);
+
+ expect(store.isSHAMismatch).toBe(false);
+ expect(store.sha).toBe('abc123');
+ });
+
+ describe('isPipelinePassing', () => {
+ it('is true when the CI status is `success`', () => {
+ store.setData({ ...mockData, ci_status: 'success' });
+
+ expect(store.isPipelinePassing).toBe(true);
+ });
+
+ it('is true when the CI status is `success-with-warnings`', () => {
+ store.setData({ ...mockData, ci_status: 'success-with-warnings' });
+
+ expect(store.isPipelinePassing).toBe(true);
+ });
+
+ it('is false when the CI status is `failed`', () => {
+ store.setData({ ...mockData, ci_status: 'failed' });
+
+ expect(store.isPipelinePassing).toBe(false);
+ });
+
+ it('is false when the CI status is anything except `success`', () => {
+ store.setData({ ...mockData, ci_status: 'foobarbaz' });
+
+ expect(store.isPipelinePassing).toBe(false);
+ });
+ });
+
+ describe('isPipelineSkipped', () => {
+ it('should set isPipelineSkipped=true when the CI status is `skipped`', () => {
+ store.setData({ ...mockData, ci_status: 'skipped' });
+
+ expect(store.isPipelineSkipped).toBe(true);
+ });
+
+ it('should set isPipelineSkipped=false when the CI status is anything except `skipped`', () => {
+ store.setData({ ...mockData, ci_status: 'foobarbaz' });
+
+ expect(store.isPipelineSkipped).toBe(false);
+ });
+ });
+
+ describe('isNothingToMergeState', () => {
+ it('returns true when nothingToMerge', () => {
+ store.state = stateKey.nothingToMerge;
+
+ expect(store.isNothingToMergeState).toBe(true);
+ });
+
+ it('returns false when not nothingToMerge', () => {
+ store.state = 'state';
+
+ expect(store.isNothingToMergeState).toBe(false);
+ });
+ });
+ });
+
+ describe('setPaths', () => {
+ it('should set the add ci config path', () => {
+ store.setData({ ...mockData });
+
+ expect(store.mergeRequestAddCiConfigPath).toBe('/group2/project2/new/pipeline');
+ });
+
+ it('should set humanAccess=Maintainer when user has that role', () => {
+ store.setData({ ...mockData });
+
+ expect(store.humanAccess).toBe('Maintainer');
+ });
+
+ it('should set pipelinesEmptySvgPath', () => {
+ store.setData({ ...mockData });
+
+ expect(store.pipelinesEmptySvgPath).toBe('/path/to/svg');
+ });
+
+ it('should set newPipelinePath', () => {
+ store.setData({ ...mockData });
+
+ expect(store.newPipelinePath).toBe('/group2/project2/pipelines/new');
+ });
+ });
+});