Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Friend <nathan@gitlab.com>2019-06-11 17:19:22 +0300
committerNathan Friend <nathan@gitlab.com>2019-06-11 17:27:51 +0300
commit35ae9d8a7449ebe4b5c1878825bcb931a82e7a59 (patch)
tree4e5c698fbcce2c9bffa0a1cdfe1ce449f750ad05 /spec/javascripts/vue_mr_widget
parentfc27c93e4b060db069f1651d1395d59e121595f7 (diff)
Add merge train support to MR merge button (CE)
This commit updates the merge request widget's "Merge" button to support merge trains.
Diffstat (limited to 'spec/javascripts/vue_mr_widget')
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js (renamed from spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js)62
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js136
-rw-r--r--spec/javascripts/vue_mr_widget/mock_data.js7
-rw-r--r--spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js42
4 files changed, 180 insertions, 67 deletions
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
index 8e0415b813b..2ea8c169add 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_merge_when_pipeline_succeeds_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_enabled_spec.js
@@ -1,17 +1,19 @@
import Vue from 'vue';
-import mwpsComponent from '~/vue_merge_request_widget/components/states/mr_widget_merge_when_pipeline_succeeds.vue';
+import autoMergeEnabledComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue';
import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
import eventHub from '~/vue_merge_request_widget/event_hub';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import { trimText } from 'spec/helpers/text_helper';
+import { MWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
-describe('MRWidgetMergeWhenPipelineSucceeds', () => {
+describe('MRWidgetAutoMergeEnabled', () => {
let vm;
const targetBranchPath = '/foo/bar';
const targetBranch = 'foo';
const sha = '1EA2EZ34';
beforeEach(() => {
- const Component = Vue.extend(mwpsComponent);
+ const Component = Vue.extend(autoMergeEnabledComponent);
spyOn(eventHub, '$emit');
vm = mountComponent(Component, {
@@ -25,6 +27,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
sha,
targetBranchPath,
targetBranch,
+ autoMergeStrategy: MWPS_MERGE_STRATEGY,
},
service: new MRWidgetService({}),
});
@@ -66,6 +69,32 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
expect(vm.canRemoveSourceBranch).toBeFalsy();
});
});
+
+ describe('statusTextBeforeAuthor', () => {
+ it('should return "Set by" if the MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextBeforeAuthor).toBe('Set by');
+ });
+ });
+
+ describe('statusTextAfterAuthor', () => {
+ it('should return "to be merged automatically..." if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.statusTextAfterAuthor).toBe(
+ 'to be merged automatically when the pipeline succeeds',
+ );
+ });
+ });
+
+ describe('cancelButtonText', () => {
+ it('should return "Cancel automatic merge" if MWPS is selected', () => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.cancelButtonText).toBe('Cancel automatic merge');
+ });
+ });
});
describe('methods', () => {
@@ -96,7 +125,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
spyOn(vm.service, 'merge').and.returnValue(
Promise.resolve({
data: {
- status: 'merge_when_pipeline_succeeds',
+ status: MWPS_MERGE_STRATEGY,
},
}),
);
@@ -106,7 +135,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
expect(vm.service.merge).toHaveBeenCalledWith({
sha,
- auto_merge_strategy: 'merge_when_pipeline_succeeds',
+ auto_merge_strategy: MWPS_MERGE_STRATEGY,
should_remove_source_branch: true,
});
done();
@@ -119,6 +148,7 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.innerText).toContain('to be merged automatically when the pipeline succeeds');
+
expect(vm.$el.innerText).toContain('The changes will be merged into');
expect(vm.$el.innerText).toContain(targetBranch);
expect(vm.$el.innerText).toContain('The source branch will not be deleted');
@@ -174,5 +204,27 @@ describe('MRWidgetMergeWhenPipelineSucceeds', () => {
done();
});
});
+
+ it('should render the status text as "...to merged automatically" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const statusText = trimText(vm.$el.querySelector('.js-status-text-after-author').innerText);
+
+ expect(statusText).toBe('to be merged automatically when the pipeline succeeds');
+ done();
+ });
+ });
+
+ it('should render the cancel button as "Cancel automatic merge" if MWPS is selected', done => {
+ Vue.set(vm.mr, 'autoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ Vue.nextTick(() => {
+ const cancelButtonText = trimText(vm.$el.querySelector('.js-cancel-auto-merge').innerText);
+
+ expect(cancelButtonText).toBe('Cancel automatic merge');
+ done();
+ });
+ });
});
});
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
index 3ae773b6ccb..bb76616be56 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js
@@ -6,6 +6,7 @@ import CommitEdit from '~/vue_merge_request_widget/components/states/commit_edit
import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue';
import eventHub from '~/vue_merge_request_widget/event_hub';
import { createLocalVue, shallowMount } from '@vue/test-utils';
+import { MWPS_MERGE_STRATEGY, ATMTWPS_MERGE_STRATEGY } from '~/vue_merge_request_widget/constants';
const commitMessage = 'This is the commit message';
const squashCommitMessage = 'This is the squash commit message';
@@ -29,6 +30,8 @@ const createTestMr = customConfig => {
shouldRemoveSourceBranch: true,
canRemoveSourceBranch: false,
targetBranch: 'master',
+ preferredAutoMergeStrategy: MWPS_MERGE_STRATEGY,
+ availableAutoMergeStrategies: [MWPS_MERGE_STRATEGY],
};
Object.assign(mr, customConfig.mr);
@@ -80,7 +83,6 @@ describe('ReadyToMerge', () => {
it('should have default data', () => {
expect(vm.mergeWhenBuildSucceeds).toBeFalsy();
expect(vm.useCommitMessageWithDescription).toBeFalsy();
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.showCommitMessageEditor).toBeFalsy();
expect(vm.isMakingRequest).toBeFalsy();
expect(vm.isMergingImmediately).toBeFalsy();
@@ -91,47 +93,51 @@ describe('ReadyToMerge', () => {
});
describe('computed', () => {
- describe('shouldShowAutoMergeText', () => {
- it('should return true with active pipeline', () => {
- vm.mr.isPipelineActive = true;
+ describe('isAutoMergeAvailable', () => {
+ it('should return true when at least one merge strategy is available', () => {
+ vm.mr.availableAutoMergeStrategies = [MWPS_MERGE_STRATEGY];
- expect(vm.shouldShowAutoMergeText).toBeTruthy();
+ expect(vm.isAutoMergeAvailable).toBe(true);
});
- it('should return false with inactive pipeline', () => {
- vm.mr.isPipelineActive = false;
+ it('should return false when no merge strategies are available', () => {
+ vm.mr.availableAutoMergeStrategies = [];
- expect(vm.shouldShowAutoMergeText).toBeFalsy();
+ expect(vm.isAutoMergeAvailable).toBe(false);
});
});
describe('status', () => {
it('defaults to success', () => {
- vm.mr.pipeline = true;
+ Vue.set(vm.mr, 'pipeline', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
expect(vm.status).toEqual('success');
});
it('returns failed when MR has CI but also has an unknown status', () => {
- vm.mr.hasCI = true;
+ Vue.set(vm.mr, 'hasCI', true);
expect(vm.status).toEqual('failed');
});
it('returns default when MR has no pipeline', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.status).toEqual('success');
});
it('returns pending when pipeline is active', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineActive', true);
expect(vm.status).toEqual('pending');
});
it('returns failed when pipeline is failed', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineFailed = true;
+ Vue.set(vm.mr, 'pipeline', {});
+ Vue.set(vm.mr, 'isPipelineFailed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
expect(vm.status).toEqual('failed');
});
@@ -143,18 +149,20 @@ describe('ReadyToMerge', () => {
const inActionClass = `${defaultClass} btn-info`;
it('defaults to success class', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.mergeButtonClass).toEqual(defaultClass);
});
it('returns success class for success status', () => {
- vm.mr.pipeline = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'pipeline', true);
expect(vm.mergeButtonClass).toEqual(defaultClass);
});
it('returns info class for pending status', () => {
- vm.mr.pipeline = {};
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
expect(vm.mergeButtonClass).toEqual(inActionClass);
});
@@ -198,69 +206,82 @@ describe('ReadyToMerge', () => {
});
describe('mergeButtonText', () => {
- it('should return Merge', () => {
+ it('should return "Merge" when no auto merge strategies are available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
expect(vm.mergeButtonText).toEqual('Merge');
});
- it('should return Merge in progress', () => {
- vm.isMergingImmediately = true;
+ it('should return "Merge in progress"', () => {
+ Vue.set(vm, 'isMergingImmediately', true);
expect(vm.mergeButtonText).toEqual('Merge in progress');
});
- it('should return Merge when pipeline succeeds', () => {
- vm.isMergingImmediately = false;
- vm.mr.isPipelineActive = true;
+ it('should return "Merge when pipeline succeeds" when the MWPS auto merge strategy is available', () => {
+ Vue.set(vm, 'isMergingImmediately', false);
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
expect(vm.mergeButtonText).toEqual('Merge when pipeline succeeds');
});
});
+ describe('autoMergeText', () => {
+ it('should return Merge when pipeline succeeds', () => {
+ Vue.set(vm.mr, 'preferredAutoMergeStrategy', MWPS_MERGE_STRATEGY);
+
+ expect(vm.autoMergeText).toEqual('Merge when pipeline succeeds');
+ });
+ });
+
describe('shouldShowMergeOptionsDropdown', () => {
- it('should return false with initial data', () => {
- expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy();
+ it('should return false when no auto merge strategies are available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(false);
});
- it('should return true when pipeline active', () => {
- vm.mr.isPipelineActive = true;
+ it('should return true when at least one auto merge strategy is available', () => {
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeOptionsDropdown).toBeTruthy();
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(true);
});
it('should return false when pipeline active but only merge when pipeline succeeds set in project options', () => {
- vm.mr.isPipelineActive = true;
- vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [ATMTWPS_MERGE_STRATEGY]);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
- expect(vm.shouldShowMergeOptionsDropdown).toBeFalsy();
+ expect(vm.shouldShowMergeOptionsDropdown).toBe(false);
});
});
describe('isMergeButtonDisabled', () => {
it('should return false with initial data', () => {
- vm.mr.isMergeAllowed = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
- expect(vm.isMergeButtonDisabled).toBeFalsy();
+ expect(vm.isMergeButtonDisabled).toBe(false);
});
it('should return true when there is no commit message', () => {
- vm.mr.isMergeAllowed = true;
- vm.commitMessage = '';
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'commitMessage', '');
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
it('should return true if merge is not allowed', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.onlyAllowMergeIfPipelineSucceeds = true;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
+ Vue.set(vm.mr, 'onlyAllowMergeIfPipelineSucceeds', true);
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
it('should return true when the vm instance is making request', () => {
- vm.mr.isMergeAllowed = true;
- vm.isMakingRequest = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm, 'isMakingRequest', true);
- expect(vm.isMergeButtonDisabled).toBeTruthy();
+ expect(vm.isMergeButtonDisabled).toBe(true);
});
});
});
@@ -268,31 +289,31 @@ describe('ReadyToMerge', () => {
describe('methods', () => {
describe('shouldShowMergeControls', () => {
it('should return false when an external pipeline is running and required to succeed', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.isPipelineActive = false;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- expect(vm.shouldShowMergeControls).toBeFalsy();
+ expect(vm.shouldShowMergeControls).toBe(false);
});
it('should return true when the build succeeded or build not required to succeed', () => {
- vm.mr.isMergeAllowed = true;
- vm.mr.isPipelineActive = false;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', []);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
it('should return true when showing the MWPS button and a pipeline is running that needs to be successful', () => {
- vm.mr.isMergeAllowed = false;
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'isMergeAllowed', false);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
it('should return true when showing the MWPS button but not required for the pipeline to succeed', () => {
- vm.mr.isMergeAllowed = true;
- vm.mr.isPipelineActive = true;
+ Vue.set(vm.mr, 'isMergeAllowed', true);
+ Vue.set(vm.mr, 'availableAutoMergeStrategies', [MWPS_MERGE_STRATEGY]);
- expect(vm.shouldShowMergeControls).toBeTruthy();
+ expect(vm.shouldShowMergeControls).toBe(true);
});
});
@@ -325,7 +346,6 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick(true);
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBe('merge_when_pipeline_succeeds');
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('MRWidgetUpdateRequested');
@@ -349,14 +369,13 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick(false, true);
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.isMakingRequest).toBeTruthy();
expect(eventHub.$emit).toHaveBeenCalledWith('FailedToMerge', undefined);
const params = vm.service.merge.calls.argsFor(0)[0];
expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.merge_when_pipeline_succeeds).toBeFalsy();
+ expect(params.auto_merge_strategy).toBeUndefined();
done();
}, 333);
});
@@ -367,14 +386,13 @@ describe('ReadyToMerge', () => {
vm.handleMergeButtonClick();
setTimeout(() => {
- expect(vm.autoMergeStrategy).toBeUndefined();
expect(vm.isMakingRequest).toBeTruthy();
expect(vm.initiateMergePolling).toHaveBeenCalled();
const params = vm.service.merge.calls.argsFor(0)[0];
expect(params.should_remove_source_branch).toBeTruthy();
- expect(params.merge_when_pipeline_succeeds).toBeFalsy();
+ expect(params.auto_merge_strategy).toBeUndefined();
done();
}, 333);
});
diff --git a/spec/javascripts/vue_mr_widget/mock_data.js b/spec/javascripts/vue_mr_widget/mock_data.js
index edbd0d54151..3c9a5cece90 100644
--- a/spec/javascripts/vue_mr_widget/mock_data.js
+++ b/spec/javascripts/vue_mr_widget/mock_data.js
@@ -25,7 +25,6 @@ export default {
},
merge_status: 'can_be_merged',
merge_user_id: null,
- merge_when_pipeline_succeeds: false,
source_branch: 'daaaa',
source_branch_link: 'daaaa',
source_project_id: 19,
@@ -210,8 +209,7 @@ export default {
source_branch_path: '/root/acets-app/branches/daaaa',
conflict_resolution_ui_path: '/root/acets-app/merge_requests/22/conflicts',
remove_wip_path: '/root/acets-app/merge_requests/22/remove_wip',
- cancel_merge_when_pipeline_succeeds_path:
- '/root/acets-app/merge_requests/22/cancel_merge_when_pipeline_succeeds',
+ cancel_auto_merge_path: '/root/acets-app/merge_requests/22/cancel_auto_merge',
create_issue_to_resolve_discussions_path:
'/root/acets-app/issues/new?merge_request_to_resolve_discussions_of=22',
merge_path: '/root/acets-app/merge_requests/22/merge',
@@ -237,6 +235,9 @@ export default {
merge_request_pipelines_docs_path: '/help/ci/merge_request_pipelines/index.md',
squash: true,
visual_review_app_available: true,
+ merge_trains_enabled: true,
+ merge_trains_count: 3,
+ merge_train_index: 1,
};
export const mockStore = {
diff --git a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
index e2cd0f084fd..e27a506f426 100644
--- a/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
+++ b/spec/javascripts/vue_mr_widget/stores/mr_widget_store_spec.js
@@ -82,5 +82,47 @@ describe('MergeRequestStore', () => {
expect(store.isNothingToMergeState).toEqual(false);
});
});
+
+ describe('mergePipelinesEnabled', () => {
+ it('should set mergePipelinesEnabled = true when merge_pipelines_enabled is true', () => {
+ store.setData({ ...mockData, merge_pipelines_enabled: true });
+
+ expect(store.mergePipelinesEnabled).toBe(true);
+ });
+
+ it('should set mergePipelinesEnabled = false when merge_pipelines_enabled is not provided', () => {
+ store.setData({ ...mockData, merge_pipelines_enabled: undefined });
+
+ expect(store.mergePipelinesEnabled).toBe(false);
+ });
+ });
+
+ describe('mergeTrainsCount', () => {
+ it('should set mergeTrainsCount when merge_trains_count is provided', () => {
+ store.setData({ ...mockData, merge_trains_count: 3 });
+
+ expect(store.mergeTrainsCount).toBe(3);
+ });
+
+ it('should set mergeTrainsCount = 0 when merge_trains_count is not provided', () => {
+ store.setData({ ...mockData, merge_trains_count: undefined });
+
+ expect(store.mergeTrainsCount).toBe(0);
+ });
+ });
+
+ describe('mergeTrainIndex', () => {
+ it('should set mergeTrainIndex when merge_train_index is provided', () => {
+ store.setData({ ...mockData, merge_train_index: 3 });
+
+ expect(store.mergeTrainIndex).toBe(3);
+ });
+
+ it('should not set mergeTrainIndex when merge_train_index is not provided', () => {
+ store.setData({ ...mockData, merge_train_index: undefined });
+
+ expect(store.mergeTrainIndex).toBeUndefined();
+ });
+ });
});
});