diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
commit | 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch) | |
tree | 544930fb309b30317ae9797a9683768705d664c4 /spec/frontend/vue_mr_widget | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) | |
download | gitlab-ce-8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca.tar.gz |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'spec/frontend/vue_mr_widget')
10 files changed, 384 insertions, 321 deletions
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js index 266c906ba60..f9b6ac721d2 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_header_spec.js @@ -164,9 +164,7 @@ describe('MRWidgetHeader', () => { it('renders checkout branch button with modal trigger', () => { const button = vm.$el.querySelector('.js-check-out-branch'); - expect(button.textContent.trim()).toEqual('Check out branch'); - expect(button.getAttribute('data-target')).toEqual('#modal_merge_info'); - expect(button.getAttribute('data-toggle')).toEqual('modal'); + expect(button.textContent.trim()).toBe('Check out branch'); }); it('renders web ide button', () => { diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js index 00e79a22485..53a74bf7456 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js @@ -1,69 +1,45 @@ -import Vue from 'vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import mergeHelpComponent from '~/vue_merge_request_widget/components/mr_widget_merge_help.vue'; +import { shallowMount } from '@vue/test-utils'; +import MergeHelpComponent from '~/vue_merge_request_widget/components/mr_widget_merge_help.vue'; describe('MRWidgetMergeHelp', () => { - let vm; - let Component; + let wrapper; - beforeEach(() => { - Component = Vue.extend(mergeHelpComponent); - }); + const createComponent = ({ props = {} } = {}) => { + wrapper = shallowMount(MergeHelpComponent, { + propsData: { + missingBranch: 'this-is-not-the-branch-you-are-looking-for', + ...props, + }, + }); + }; afterEach(() => { - vm.$destroy(); + wrapper.destroy(); + wrapper = null; }); describe('with missing branch', () => { beforeEach(() => { - vm = mountComponent(Component, { - missingBranch: 'this-is-not-the-branch-you-are-looking-for', - }); + createComponent(); }); it('renders missing branch information', () => { - expect( - vm.$el.textContent - .trim() - .replace(/[\r\n]+/g, ' ') - .replace(/\s\s+/g, ' '), - ).toEqual( - 'If the this-is-not-the-branch-you-are-looking-for branch exists in your local repository, you can merge this merge request manually using the command line', - ); - }); - - it('renders button to open help modal', () => { - expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual( - '#modal_merge_info', - ); - - expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual( - 'modal', + expect(wrapper.find('.mr-widget-help').text()).toContain( + 'If the this-is-not-the-branch-you-are-looking-for branch exists in your local repository', ); }); }); describe('without missing branch', () => { beforeEach(() => { - vm = mountComponent(Component); + createComponent({ + props: { missingBranch: '' }, + }); }); it('renders information about how to merge manually', () => { - expect( - vm.$el.textContent - .trim() - .replace(/[\r\n]+/g, ' ') - .replace(/\s\s+/g, ' '), - ).toEqual('You can merge this merge request manually using the command line'); - }); - - it('renders element to open a modal', () => { - expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-target')).toEqual( - '#modal_merge_info', - ); - - expect(vm.$el.querySelector('.js-open-modal-help').getAttribute('data-toggle')).toEqual( - 'modal', + expect(wrapper.find('.mr-widget-help').text()).toContain( + 'You can merge this merge request manually', ); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js index 19f8a67d066..ad21e6e6f4f 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js @@ -6,6 +6,7 @@ import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_ describe('MRWidgetConflicts', () => { let vm; + let mergeRequestWidgetGraphql = null; const path = '/conflicts'; function createComponent(propsData = {}) { @@ -13,7 +14,35 @@ describe('MRWidgetConflicts', () => { vm = shallowMount(localVue.extend(ConflictsComponent), { propsData, + provide: { + glFeatures: { + mergeRequestWidgetGraphql, + }, + }, + mocks: { + $apollo: { + queries: { + userPermissions: { loading: false }, + stateData: { loading: false }, + }, + }, + }, }); + + if (mergeRequestWidgetGraphql) { + vm.setData({ + userPermissions: { + canMerge: propsData.mr.canMerge, + pushToSourceBranch: propsData.mr.canPushToSourceBranch, + }, + stateData: { + shouldBeRebased: propsData.mr.shouldBeRebased, + sourceBranchProtected: propsData.mr.sourceBranchProtected, + }, + }); + } + + return vm.vm.$nextTick(); } beforeEach(() => { @@ -21,206 +50,215 @@ describe('MRWidgetConflicts', () => { }); afterEach(() => { + mergeRequestWidgetGraphql = null; vm.destroy(); }); - // There are two permissions we need to consider: - // - // 1. Is the user allowed to merge to the target branch? - // 2. Is the user allowed to push to the source branch? - // - // This yields 4 possible permutations that we need to test, and - // we test them below. A user who can push to the source - // branch should be allowed to resolve conflicts. This is - // consistent with what the backend does. - describe('when allowed to merge but not allowed to push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: false, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, + [false, true].forEach(featureEnabled => { + describe(`with GraphQL feature flag ${featureEnabled ? 'enabled' : 'disabled'}`, () => { + beforeEach(() => { + mergeRequestWidgetGraphql = featureEnabled; }); - }); - - it('should tell you about conflicts without bothering other people', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).not.toContain('ask someone with write access'); - }); - - it('should not allow you to resolve the conflicts', () => { - expect(vm.text()).not.toContain('Resolve conflicts'); - }); - - it('should have merge buttons', () => { - const mergeLocallyButton = vm.find('.js-merge-locally-button'); - - expect(mergeLocallyButton.text()).toContain('Merge locally'); - }); - }); - describe('when not allowed to merge but allowed to push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: true, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, - }); - }); - - it('should tell you about conflicts', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).toContain('ask someone with write access'); - }); - - it('should allow you to resolve the conflicts', () => { - const resolveButton = vm.find('.js-resolve-conflicts-button'); - - expect(resolveButton.text()).toContain('Resolve conflicts'); - expect(resolveButton.attributes('href')).toEqual(path); - }); - - it('should not have merge buttons', () => { - expect(vm.text()).not.toContain('Merge locally'); - }); - }); - - describe('when allowed to merge and push to source branch', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: path, - conflictsDocsPath: '', - }, + // There are two permissions we need to consider: + // + // 1. Is the user allowed to merge to the target branch? + // 2. Is the user allowed to push to the source branch? + // + // This yields 4 possible permutations that we need to test, and + // we test them below. A user who can push to the source + // branch should be allowed to resolve conflicts. This is + // consistent with what the backend does. + describe('when allowed to merge but not allowed to push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: false, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts without bothering other people', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).not.toContain('ask someone with write access'); + }); + + it('should not allow you to resolve the conflicts', () => { + expect(vm.text()).not.toContain('Resolve conflicts'); + }); + + it('should have merge buttons', () => { + const mergeLocallyButton = vm.find('.js-merge-locally-button'); + + expect(mergeLocallyButton.text()).toContain('Merge locally'); + }); }); - }); - - it('should tell you about conflicts without bothering other people', () => { - expect(vm.text()).toContain('There are merge conflicts'); - expect(vm.text()).not.toContain('ask someone with write access'); - }); - it('should allow you to resolve the conflicts', () => { - const resolveButton = vm.find('.js-resolve-conflicts-button'); - - expect(resolveButton.text()).toContain('Resolve conflicts'); - expect(resolveButton.attributes('href')).toEqual(path); - }); - - it('should have merge buttons', () => { - const mergeLocallyButton = vm.find('.js-merge-locally-button'); - - expect(mergeLocallyButton.text()).toContain('Merge locally'); - }); - }); - - describe('when user does not have permission to push to source branch', () => { - it('should show proper message', () => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: false, - conflictsDocsPath: '', - }, + describe('when not allowed to merge but allowed to push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: true, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).toContain('ask someone with write access'); + }); + + it('should allow you to resolve the conflicts', () => { + const resolveButton = vm.find('.js-resolve-conflicts-button'); + + expect(resolveButton.text()).toContain('Resolve conflicts'); + expect(resolveButton.attributes('href')).toEqual(path); + }); + + it('should not have merge buttons', () => { + expect(vm.text()).not.toContain('Merge locally'); + }); }); - expect( - vm - .text() - .trim() - .replace(/\s\s+/g, ' '), - ).toContain('ask someone with write access'); - }); - - it('should not have action buttons', () => { - createComponent({ - mr: { - canMerge: false, - canPushToSourceBranch: false, - conflictsDocsPath: '', - }, + describe('when allowed to merge and push to source branch', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: path, + conflictsDocsPath: '', + }, + }); + }); + + it('should tell you about conflicts without bothering other people', () => { + expect(vm.text()).toContain('There are merge conflicts'); + expect(vm.text()).not.toContain('ask someone with write access'); + }); + + it('should allow you to resolve the conflicts', () => { + const resolveButton = vm.find('.js-resolve-conflicts-button'); + + expect(resolveButton.text()).toContain('Resolve conflicts'); + expect(resolveButton.attributes('href')).toEqual(path); + }); + + it('should have merge buttons', () => { + const mergeLocallyButton = vm.find('.js-merge-locally-button'); + + expect(mergeLocallyButton.text()).toContain('Merge locally'); + }); }); - expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); - expect(vm.find('.js-merge-locally-button').exists()).toBe(false); - }); - - it('should not have resolve button when no conflict resolution path', () => { - createComponent({ - mr: { - canMerge: true, - conflictResolutionPath: null, - conflictsDocsPath: '', - }, + describe('when user does not have permission to push to source branch', () => { + it('should show proper message', async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: false, + conflictsDocsPath: '', + }, + }); + + expect( + vm + .text() + .trim() + .replace(/\s\s+/g, ' '), + ).toContain('ask someone with write access'); + }); + + it('should not have action buttons', async () => { + await createComponent({ + mr: { + canMerge: false, + canPushToSourceBranch: false, + conflictsDocsPath: '', + }, + }); + + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); + expect(vm.find('.js-merge-locally-button').exists()).toBe(false); + }); + + it('should not have resolve button when no conflict resolution path', async () => { + await createComponent({ + mr: { + canMerge: true, + conflictResolutionPath: null, + conflictsDocsPath: '', + }, + }); + + expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); + }); }); - expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false); - }); - }); - - describe('when fast-forward or semi-linear merge enabled', () => { - it('should tell you to rebase locally', () => { - createComponent({ - mr: { - shouldBeRebased: true, - conflictsDocsPath: '', - }, + describe('when fast-forward or semi-linear merge enabled', () => { + it('should tell you to rebase locally', async () => { + await createComponent({ + mr: { + shouldBeRebased: true, + conflictsDocsPath: '', + }, + }); + + expect(removeBreakLine(vm.text()).trim()).toContain( + 'Fast-forward merge is not possible. To merge this request, first rebase locally.', + ); + }); }); - expect(removeBreakLine(vm.text()).trim()).toContain( - 'Fast-forward merge is not possible. To merge this request, first rebase locally.', - ); - }); - }); - - describe('when source branch protected', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: TEST_HOST, - sourceBranchProtected: true, - conflictsDocsPath: '', - }, + describe('when source branch protected', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: TEST_HOST, + sourceBranchProtected: true, + conflictsDocsPath: '', + }, + }); + }); + + it('sets resolve button as disabled', () => { + expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('true'); + }); + + it('renders popover', () => { + expect($.fn.popover).toHaveBeenCalled(); + }); }); - }); - - it('sets resolve button as disabled', () => { - expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('disabled'); - }); - it('renders popover', () => { - expect($.fn.popover).toHaveBeenCalled(); - }); - }); - - describe('when source branch not protected', () => { - beforeEach(() => { - createComponent({ - mr: { - canMerge: true, - canPushToSourceBranch: true, - conflictResolutionPath: TEST_HOST, - sourceBranchProtected: false, - conflictsDocsPath: '', - }, + describe('when source branch not protected', () => { + beforeEach(async () => { + await createComponent({ + mr: { + canMerge: true, + canPushToSourceBranch: true, + conflictResolutionPath: TEST_HOST, + sourceBranchProtected: false, + conflictsDocsPath: '', + }, + }); + }); + + it('sets resolve button as disabled', () => { + expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined); + }); + + it('renders popover', () => { + expect($.fn.popover).not.toHaveBeenCalled(); + }); }); }); - - it('sets resolve button as disabled', () => { - expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined); - }); - - it('renders popover', () => { - expect($.fn.popover).not.toHaveBeenCalled(); - }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js index 3f03ebdb047..f45368bf443 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_missing_branch_spec.js @@ -1,40 +1,46 @@ -import Vue from 'vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import missingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue'; - -describe('MRWidgetMissingBranch', () => { - let vm; - - beforeEach(() => { - const Component = Vue.extend(missingBranchComponent); - vm = mountComponent(Component, { mr: { sourceBranchRemoved: true } }); - }); - - afterEach(() => { - vm.$destroy(); +import { shallowMount } from '@vue/test-utils'; +import MissingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue'; + +let wrapper; + +function factory(sourceBranchRemoved, mergeRequestWidgetGraphql) { + wrapper = shallowMount(MissingBranchComponent, { + propsData: { + mr: { sourceBranchRemoved }, + }, + provide: { + glFeatures: { mergeRequestWidgetGraphql }, + }, }); - describe('computed', () => { - describe('missingBranchName', () => { - it('should return proper branch name', () => { - expect(vm.missingBranchName).toEqual('source'); + if (mergeRequestWidgetGraphql) { + wrapper.setData({ state: { sourceBranchExists: !sourceBranchRemoved } }); + } - vm.mr.sourceBranchRemoved = false; + return wrapper.vm.$nextTick(); +} - expect(vm.missingBranchName).toEqual('target'); - }); - }); +describe('MRWidgetMissingBranch', () => { + afterEach(() => { + wrapper.destroy(); }); - describe('template', () => { - it('should have correct elements', () => { - const el = vm.$el; - const content = el.textContent.replace(/\n(\s)+/g, ' ').trim(); - - expect(el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy(); - expect(content.replace(/\s\s+/g, ' ')).toContain('source branch does not exist.'); - expect(content).toContain('Please restore it or use a different source branch'); + [true, false].forEach(mergeRequestWidgetGraphql => { + describe(`widget GraphQL feature flag is ${ + mergeRequestWidgetGraphql ? 'enabled' : 'disabled' + }`, () => { + it.each` + sourceBranchRemoved | branchName + ${true} | ${'source'} + ${false} | ${'target'} + `( + 'should set missing branch name as $branchName when sourceBranchRemoved is $sourceBranchRemoved', + async ({ sourceBranchRemoved, branchName }) => { + await factory(sourceBranchRemoved, mergeRequestWidgetGraphql); + + expect(wrapper.find('[data-testid="missingBranchName"]').text()).toContain(branchName); + }, + ); }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js index 5326d63cb8a..f9490ac77ff 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_squash_before_merge_spec.js @@ -1,4 +1,5 @@ import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { GlFormCheckbox } from '@gitlab/ui'; import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue'; import { SQUASH_BEFORE_MERGE } from '~/vue_merge_request_widget/i18n'; @@ -20,17 +21,15 @@ describe('Squash before merge component', () => { wrapper.destroy(); }); - const findLabel = () => wrapper.find('[data-testid="squashLabel"]'); + const findCheckbox = () => wrapper.find(GlFormCheckbox); describe('checkbox', () => { - const findCheckbox = () => wrapper.find('.js-squash-checkbox'); - it('is unchecked if passed value prop is false', () => { createComponent({ value: false, }); - expect(findCheckbox().element.checked).toBeFalsy(); + expect(findCheckbox().vm.$attrs.checked).toBe(false); }); it('is checked if passed value prop is true', () => { @@ -38,22 +37,7 @@ describe('Squash before merge component', () => { value: true, }); - expect(findCheckbox().element.checked).toBeTruthy(); - }); - - it('changes value on click', done => { - createComponent({ - value: false, - }); - - findCheckbox().element.checked = true; - - findCheckbox().trigger('change'); - - wrapper.vm.$nextTick(() => { - expect(findCheckbox().element.checked).toBeTruthy(); - done(); - }); + expect(findCheckbox().vm.$attrs.checked).toBe(true); }); it('is disabled if isDisabled prop is true', () => { @@ -62,31 +46,12 @@ describe('Squash before merge component', () => { isDisabled: true, }); - expect(findCheckbox().attributes('disabled')).toBeTruthy(); - }); - }); - - describe('label', () => { - describe.each` - isDisabled | expectation - ${true} | ${'grays out text if it is true'} - ${false} | ${'does not gray out text if it is false'} - `('isDisabled prop', ({ isDisabled, expectation }) => { - beforeEach(() => { - createComponent({ - value: false, - isDisabled, - }); - }); - - it(expectation, () => { - expect(findLabel().classes('gl-text-gray-400')).toBe(isDisabled); - }); + expect(findCheckbox().vm.$attrs.disabled).toBe(true); }); }); describe('tooltip', () => { - const tooltipTitle = () => findLabel().attributes('title'); + const tooltipTitle = () => findCheckbox().attributes('title'); it('does not render when isDisabled is false', () => { createComponent({ @@ -114,7 +79,7 @@ describe('Squash before merge component', () => { const aboutLink = wrapper.find('a'); - expect(aboutLink.exists()).toBeFalsy(); + expect(aboutLink.exists()).toBe(false); }); it('is rendered if help path is passed', () => { @@ -125,7 +90,7 @@ describe('Squash before merge component', () => { const aboutLink = wrapper.find('a'); - expect(aboutLink.exists()).toBeTruthy(); + expect(aboutLink.exists()).toBe(true); }); it('should have a correct help path if passed', () => { diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_spec.js b/spec/frontend/vue_mr_widget/deployment/deployment_spec.js index 17d7fcc4bff..19a5566c3b1 100644 --- a/spec/frontend/vue_mr_widget/deployment/deployment_spec.js +++ b/spec/frontend/vue_mr_widget/deployment/deployment_spec.js @@ -8,6 +8,7 @@ import { SUCCESS, FAILED, CANCELED, + SKIPPED, } from '~/vue_merge_request_widget/components/deployment/constants'; import { deploymentMockData, playDetails, retryDetails } from './deployment_mock_data'; @@ -77,6 +78,10 @@ describe('Deployment component', () => { ${CANCELED} | ${true} | ${noDetails} | ${'Canceled deployment to'} | ${defaultGroup} ${CANCELED} | ${false} | ${deployDetail} | ${'Canceled deployment to'} | ${noActions} ${CANCELED} | ${false} | ${noDetails} | ${'Canceled deployment to'} | ${noActions} + ${SKIPPED} | ${true} | ${deployDetail} | ${'Skipped deployment to'} | ${defaultGroup} + ${SKIPPED} | ${true} | ${noDetails} | ${'Skipped deployment to'} | ${defaultGroup} + ${SKIPPED} | ${false} | ${deployDetail} | ${'Skipped deployment to'} | ${noActions} + ${SKIPPED} | ${false} | ${noDetails} | ${'Skipped deployment to'} | ${noActions} `( '$status + previous: $previous + manual: $deploymentDetails.isManual', ({ status, previous, deploymentDetails, text, actionButtons }) => { diff --git a/spec/frontend/vue_mr_widget/mock_data.js b/spec/frontend/vue_mr_widget/mock_data.js index 144283dc507..8ee920f06a1 100644 --- a/spec/frontend/vue_mr_widget/mock_data.js +++ b/spec/frontend/vue_mr_widget/mock_data.js @@ -41,6 +41,7 @@ export default { user_callouts_path: 'some/callout/path', suggest_pipeline_feature_id: 'suggest_pipeline', new_project_pipeline_path: '/group2/project2/pipelines/new', + source_project_default_url: '/gitlab-org/html5-boilerplate.git', metrics: { merged_by: { name: 'Administrator', @@ -263,6 +264,8 @@ export default { merge_trains_count: 3, merge_train_index: 1, security_reports_docs_path: 'security-reports-docs-path', + sast_comparison_path: '/sast_comparison_path', + secret_scanning_comparison_path: '/secret_scanning_comparison_path', }; export const mockStore = { diff --git a/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js b/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js new file mode 100644 index 00000000000..aaaee3327a8 --- /dev/null +++ b/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js @@ -0,0 +1,68 @@ +import { GlModal, GlSprintf } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import MrWidgetHowToMergeModal from '~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue'; + +describe('MRWidgetHowToMerge', () => { + let wrapper; + + function mountComponent({ data = {}, props = {} } = {}) { + wrapper = shallowMount(MrWidgetHowToMergeModal, { + data() { + return { ...data }; + }, + propsData: { + ...props, + }, + stubs: {}, + }); + } + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + beforeEach(() => { + mountComponent(); + }); + + const findModal = () => wrapper.find(GlModal); + const findInstructionsFields = () => + wrapper.findAll('[ data-testid="how-to-merge-instructions"]'); + const findTipLink = () => wrapper.find(GlSprintf); + + it('renders a modal', () => { + expect(findModal().exists()).toBe(true); + }); + + it('renders a selection of markdown fields', () => { + expect(findInstructionsFields().length).toBe(3); + }); + + it('renders a tip including a link to docs when a valid link is present', () => { + mountComponent({ props: { reviewingDocsPath: '/gitlab-org/help' } }); + expect(findTipLink().exists()).toBe(true); + }); + + it('should not render a tip including a link to docs when a valid link is not present', () => { + expect(findTipLink().exists()).toBe(false); + }); + + it('should render different instructions based on if the user can merge', () => { + mountComponent({ props: { canMerge: true } }); + expect( + findInstructionsFields() + .at(2) + .text(), + ).toContain('git push origin'); + }); + + it('should render different instructions based on if the merge is based off a fork', () => { + mountComponent({ props: { isFork: true } }); + expect( + findInstructionsFields() + .at(0) + .text(), + ).toContain('FETCH_HEAD'); + }); +}); diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js index cb0006548d4..a20cd5b4400 100644 --- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js @@ -863,7 +863,7 @@ describe('mrWidgetOptions', () => { }); }); - describe('suggestPipeline feature flag', () => { + describe('suggestPipeline', () => { beforeEach(() => { mock.onAny().reply(200); @@ -874,8 +874,6 @@ describe('mrWidgetOptions', () => { describe('given feature flag is enabled', () => { beforeEach(() => { - gon.features = { suggestPipeline: true }; - createComponent(); vm.mr.hasCI = false; @@ -905,19 +903,5 @@ describe('mrWidgetOptions', () => { expect(findSuggestPipeline()).toBeNull(); }); }); - - describe('given feature flag is not enabled', () => { - beforeEach(() => { - gon.features = { suggestPipeline: false }; - - createComponent(); - - vm.mr.hasCI = false; - }); - - it('should not suggest pipelines when none exist', () => { - expect(findSuggestPipeline()).toBeNull(); - }); - }); }); }); 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 index f73f78d6f6e..8b2c10ec50a 100644 --- a/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js +++ b/spec/frontend/vue_mr_widget/stores/mr_widget_store_spec.js @@ -1,3 +1,4 @@ +import { convertToCamelCase } from '~/lib/utils/text_utility'; 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'; @@ -141,10 +142,29 @@ describe('MergeRequestStore', () => { expect(store.newPipelinePath).toBe('/group2/project2/pipelines/new'); }); + it('should set sourceProjectDefaultUrl', () => { + store.setPaths({ ...mockData }); + + expect(store.sourceProjectDefaultUrl).toBe('/gitlab-org/html5-boilerplate.git'); + }); + it('should set securityReportsDocsPath', () => { store.setPaths({ ...mockData }); expect(store.securityReportsDocsPath).toBe('security-reports-docs-path'); }); + + it.each(['sast_comparison_path', 'secret_scanning_comparison_path'])( + 'should set %s path', + property => { + // Ensure something is set in the mock data + expect(property in mockData).toBe(true); + const expectedValue = mockData[property]; + + store.setPaths({ ...mockData }); + + expect(store[convertToCamelCase(property)]).toBe(expectedValue); + }, + ); }); }); |