diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-10-21 07:08:36 +0000 |
commit | 48aff82709769b098321c738f3444b9bdaa694c6 (patch) | |
tree | e00c7c43e2d9b603a5a6af576b1685e400410dee /spec/frontend/vue_mr_widget | |
parent | 879f5329ee916a948223f8f43d77fba4da6cd028 (diff) | |
download | gitlab-ce-48aff82709769b098321c738f3444b9bdaa694c6.tar.gz |
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'spec/frontend/vue_mr_widget')
12 files changed, 112 insertions, 81 deletions
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js index 58ed92298bf..78efcb6e695 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_author_time_spec.js @@ -35,9 +35,7 @@ describe('MrWidgetAuthorTime', () => { }); it('renders provided time', () => { - expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toEqual( - '2017-03-23T23:02:00.807Z', - ); + expect(vm.$el.querySelector('time').getAttribute('title')).toEqual('2017-03-23T23:02:00.807Z'); expect(vm.$el.querySelector('time').textContent.trim()).toEqual('12 hours ago'); }); 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 caea9a757ae..015f8bbac51 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 @@ -130,7 +130,7 @@ describe('MRWidgetHeader', () => { }); it('renders clipboard button', () => { - expect(vm.$el.querySelector('.btn-clipboard')).not.toEqual(null); + expect(vm.$el.querySelector('[data-testid="mr-widget-copy-clipboard"]')).not.toEqual(null); }); it('renders target branch', () => { diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js index 6ec30493f8b..9923434a7dd 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js @@ -6,6 +6,10 @@ import component from '~/vue_merge_request_widget/components/states/mr_widget_re describe('Merge request widget rebase component', () => { let Component; let vm; + + const findRebaseMessageEl = () => vm.$el.querySelector('[data-testid="rebase-message"]'); + const findRebaseMessageElText = () => findRebaseMessageEl().textContent.trim(); + beforeEach(() => { Component = Vue.extend(component); }); @@ -21,9 +25,7 @@ describe('Merge request widget rebase component', () => { service: {}, }); - expect( - vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(), - ).toContain('Rebase in progress'); + expect(findRebaseMessageElText()).toContain('Rebase in progress'); }); }); @@ -39,9 +41,7 @@ describe('Merge request widget rebase component', () => { }); it('it should render rebase button and warning message', () => { - const text = vm.$el - .querySelector('.rebase-state-find-class-convention span') - .textContent.trim(); + const text = findRebaseMessageElText(); expect(text).toContain('Fast-forward merge is not possible.'); expect(text.replace(/\s\s+/g, ' ')).toContain( @@ -53,9 +53,7 @@ describe('Merge request widget rebase component', () => { vm.rebasingError = 'Something went wrong!'; Vue.nextTick(() => { - expect( - vm.$el.querySelector('.rebase-state-find-class-convention span').textContent.trim(), - ).toContain('Something went wrong!'); + expect(findRebaseMessageElText()).toContain('Something went wrong!'); done(); }); }); @@ -72,9 +70,7 @@ describe('Merge request widget rebase component', () => { service: {}, }); - const text = vm.$el - .querySelector('.rebase-state-find-class-convention span') - .textContent.trim(); + const text = findRebaseMessageElText(); expect(text).toContain('Fast-forward merge is not possible.'); expect(text).toContain('Rebase the source branch onto'); @@ -93,7 +89,7 @@ describe('Merge request widget rebase component', () => { service: {}, }); - const elem = vm.$el.querySelector('.rebase-state-find-class-convention span'); + const elem = findRebaseMessageEl(); expect(elem.innerHTML).toContain( `Fast-forward merge is not possible. Rebase the source branch onto <span class="label-branch">${targetBranch}</span> to allow this merge request to be merged.`, diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js index 98af44b0975..aae9b8660e2 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js @@ -1,12 +1,12 @@ import { shallowMount } from '@vue/test-utils'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlLoadingIcon, GlButton } from '@gitlab/ui'; import AutoMergeFailedComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue'; import eventHub from '~/vue_merge_request_widget/event_hub'; describe('MRWidgetAutoMergeFailed', () => { let wrapper; const mergeError = 'This is the merge error'; - const findButton = () => wrapper.find('button'); + const findButton = () => wrapper.find(GlButton); const createComponent = (props = {}) => { wrapper = shallowMount(AutoMergeFailedComponent, { @@ -38,17 +38,13 @@ describe('MRWidgetAutoMergeFailed', () => { it('emits event and shows loading icon when button is clicked', () => { jest.spyOn(eventHub, '$emit'); - findButton().trigger('click'); + findButton().vm.$emit('click'); expect(eventHub.$emit.mock.calls[0][0]).toBe('MRWidgetUpdateRequested'); return wrapper.vm.$nextTick(() => { - expect(findButton().attributes('disabled')).toEqual('disabled'); - expect( - findButton() - .find(GlLoadingIcon) - .exists(), - ).toBe(true); + expect(findButton().attributes('disabled')).toBe('true'); + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js index 1921599ae95..9b51e8583ba 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merged_spec.js @@ -212,8 +212,6 @@ describe('MRWidgetMerged', () => { }); it('should use mergedEvent mergedAt as tooltip title', () => { - expect(vm.$el.querySelector('time').getAttribute('data-original-title')).toBe( - 'Jan 24, 2018 1:02pm GMT+0000', - ); + expect(vm.$el.querySelector('time').getAttribute('title')).toBe('Jan 24, 2018 1:02pm GMT+0000'); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js index 5eb24315ca6..9057ffaea45 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -101,8 +101,6 @@ describe('ReadyToMerge', () => { expect(vm.isMakingRequest).toBeFalsy(); expect(vm.isMergingImmediately).toBeFalsy(); expect(vm.commitMessage).toBe(vm.mr.commitMessage); - expect(vm.successSvg).toBeDefined(); - expect(vm.warningSvg).toBeDefined(); }); }); @@ -494,19 +492,6 @@ describe('ReadyToMerge', () => { }); }); - it('hides close button', done => { - jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged')); - jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {}); - - vm.handleMergePolling(() => {}, () => {}); - - setImmediate(() => { - expect(document.querySelector('.btn-close').classList.contains('hidden')).toBeTruthy(); - - done(); - }); - }); - it('updates merge request count badge', done => { jest.spyOn(vm.service, 'poll').mockReturnValue(returnPromise('merged')); jest.spyOn(vm, 'initiateRemoveSourceBranchPolling').mockImplementation(() => {}); 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 4c213899dbd..5326d63cb8a 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,5 +1,6 @@ import { createLocalVue, shallowMount } from '@vue/test-utils'; import SquashBeforeMerge from '~/vue_merge_request_widget/components/states/squash_before_merge.vue'; +import { SQUASH_BEFORE_MERGE } from '~/vue_merge_request_widget/i18n'; const localVue = createLocalVue(); @@ -85,7 +86,7 @@ describe('Squash before merge component', () => { }); describe('tooltip', () => { - const tooltipTitle = () => findLabel().element.dataset.title; + const tooltipTitle = () => findLabel().attributes('title'); it('does not render when isDisabled is false', () => { createComponent({ @@ -101,7 +102,7 @@ describe('Squash before merge component', () => { isDisabled: true, }); - expect(tooltipTitle()).toBe('Required in this project.'); + expect(tooltipTitle()).toBe(SQUASH_BEFORE_MERGE.tooltipTitle); }); }); diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js b/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js index 1711efb5512..13c0665f929 100644 --- a/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js +++ b/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js @@ -31,10 +31,7 @@ describe('DeploymentAction component', () => { wrapper.destroy(); } - wrapper = mount(DeploymentActions, { - ...options, - provide: { glFeatures: { deployFromFooter: true } }, - }); + wrapper = mount(DeploymentActions, options); }; const findStopButton = () => wrapper.find('.js-stop-env'); diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_spec.js b/spec/frontend/vue_mr_widget/deployment/deployment_spec.js index ce395de3b5d..17d7fcc4bff 100644 --- a/spec/frontend/vue_mr_widget/deployment/deployment_spec.js +++ b/spec/frontend/vue_mr_widget/deployment/deployment_spec.js @@ -19,10 +19,7 @@ describe('Deployment component', () => { if (wrapper && wrapper.destroy) { wrapper.destroy(); } - wrapper = mount(DeploymentComponent, { - ...options, - provide: { glFeatures: { deployFromFooter: true } }, - }); + wrapper = mount(DeploymentComponent, options); }; beforeEach(() => { diff --git a/spec/frontend/vue_mr_widget/mock_data.js b/spec/frontend/vue_mr_widget/mock_data.js index 4688af30269..144283dc507 100644 --- a/spec/frontend/vue_mr_widget/mock_data.js +++ b/spec/frontend/vue_mr_widget/mock_data.js @@ -262,6 +262,7 @@ export default { merge_trains_enabled: true, merge_trains_count: 3, merge_train_index: 1, + security_reports_docs_path: 'security-reports-docs-path', }; export const mockStore = { 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 a2ade44b7c4..25c967996e3 100644 --- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js @@ -1,6 +1,8 @@ import Vue from 'vue'; import MockAdapter from 'axios-mock-adapter'; import mountComponent from 'helpers/vue_mount_component_helper'; +import { withGonExperiment } from 'helpers/experimentation_helper'; +import Api from '~/api'; import axios from '~/lib/utils/axios_utils'; import mrWidgetOptions from '~/vue_merge_request_widget/mr_widget_options.vue'; import eventHub from '~/vue_merge_request_widget/event_hub'; @@ -50,13 +52,13 @@ describe('mrWidgetOptions', () => { gon.features = {}; }); - const createComponent = () => { + const createComponent = (mrData = mockData) => { if (vm) { vm.$destroy(); } vm = mountComponent(MrWidgetOptions, { - mrData: { ...mockData }, + mrData: { ...mrData }, }); return axios.waitForAll(); @@ -64,6 +66,7 @@ describe('mrWidgetOptions', () => { const findSuggestPipeline = () => vm.$el.querySelector('[data-testid="mr-suggest-pipeline"]'); const findSuggestPipelineButton = () => findSuggestPipeline().querySelector('button'); + const findSecurityMrWidget = () => vm.$el.querySelector('[data-testid="security-mr-widget"]'); describe('default', () => { beforeEach(() => { @@ -533,7 +536,7 @@ describe('mrWidgetOptions', () => { const tooltip = vm.$el.querySelector('[data-testid="question-o-icon"]'); expect(vm.$el.textContent).toContain('Deletes source branch'); - expect(tooltip.getAttribute('data-original-title')).toBe( + expect(tooltip.getAttribute('title')).toBe( 'A user with write access to the source branch selected this option', ); @@ -812,43 +815,96 @@ describe('mrWidgetOptions', () => { }); }); - describe('given suggestPipeline feature flag is enabled', () => { + describe('security widget', () => { + describe.each` + context | hasPipeline | reportType | isFlagEnabled | shouldRender + ${'security report and flag enabled'} | ${true} | ${'sast'} | ${true} | ${true} + ${'security report and flag disabled'} | ${true} | ${'sast'} | ${false} | ${false} + ${'no security report and flag enabled'} | ${true} | ${'foo'} | ${true} | ${false} + ${'no pipeline and flag enabled'} | ${false} | ${'sast'} | ${true} | ${false} + `('given $context', ({ hasPipeline, reportType, isFlagEnabled, shouldRender }) => { + beforeEach(() => { + gon.features.coreSecurityMrWidget = isFlagEnabled; + + if (hasPipeline) { + jest.spyOn(Api, 'pipelineJobs').mockResolvedValue({ + data: [{ artifacts: [{ file_type: reportType }] }], + }); + } + + return createComponent({ + ...mockData, + ...(hasPipeline ? {} : { pipeline: undefined }), + }); + }); + + if (shouldRender) { + it('renders', () => { + expect(findSecurityMrWidget()).toEqual(expect.any(HTMLElement)); + }); + } else { + it('does not render', () => { + expect(findSecurityMrWidget()).toBeNull(); + }); + } + }); + }); + + describe('suggestPipeline Experiment', () => { beforeEach(() => { mock.onAny().reply(200); // This is needed because some grandchildren Bootstrap components throw warnings // https://gitlab.com/gitlab-org/gitlab/issues/208458 jest.spyOn(console, 'warn').mockImplementation(); + }); - gon.features = { suggestPipeline: true }; + describe('given experiment is enabled', () => { + withGonExperiment('suggestPipeline'); - createComponent(); + beforeEach(() => { + createComponent(); - vm.mr.hasCI = false; - }); + vm.mr.hasCI = false; + }); - it('should suggest pipelines when none exist', () => { - expect(findSuggestPipeline()).toEqual(expect.any(Element)); - }); + it('should suggest pipelines when none exist', () => { + expect(findSuggestPipeline()).toEqual(expect.any(Element)); + }); - it.each([ - { isDismissedSuggestPipeline: true }, - { mergeRequestAddCiConfigPath: null }, - { hasCI: true }, - ])('with %s, should not suggest pipeline', async obj => { - Object.assign(vm.mr, obj); + it.each([ + { isDismissedSuggestPipeline: true }, + { mergeRequestAddCiConfigPath: null }, + { hasCI: true }, + ])('with %s, should not suggest pipeline', async obj => { + Object.assign(vm.mr, obj); - await vm.$nextTick(); + await vm.$nextTick(); - expect(findSuggestPipeline()).toBeNull(); + expect(findSuggestPipeline()).toBeNull(); + }); + + it('should allow dismiss of the suggest pipeline message', async () => { + findSuggestPipelineButton().click(); + + await vm.$nextTick(); + + expect(findSuggestPipeline()).toBeNull(); + }); }); - it('should allow dismiss of the suggest pipeline message', async () => { - findSuggestPipelineButton().click(); + describe('given suggestPipeline experiment is not enabled', () => { + withGonExperiment('suggestPipeline', false); - await vm.$nextTick(); + beforeEach(() => { + createComponent(); - expect(findSuggestPipeline()).toBeNull(); + 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 b691a366a0f..f73f78d6f6e 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 @@ -118,27 +118,33 @@ describe('MergeRequestStore', () => { describe('setPaths', () => { it('should set the add ci config path', () => { - store.setData({ ...mockData }); + store.setPaths({ ...mockData }); expect(store.mergeRequestAddCiConfigPath).toBe('/group2/project2/new/pipeline'); }); it('should set humanAccess=Maintainer when user has that role', () => { - store.setData({ ...mockData }); + store.setPaths({ ...mockData }); expect(store.humanAccess).toBe('Maintainer'); }); it('should set pipelinesEmptySvgPath', () => { - store.setData({ ...mockData }); + store.setPaths({ ...mockData }); expect(store.pipelinesEmptySvgPath).toBe('/path/to/svg'); }); it('should set newPipelinePath', () => { - store.setData({ ...mockData }); + store.setPaths({ ...mockData }); expect(store.newPipelinePath).toBe('/group2/project2/pipelines/new'); }); + + it('should set securityReportsDocsPath', () => { + store.setPaths({ ...mockData }); + + expect(store.securityReportsDocsPath).toBe('security-reports-docs-path'); + }); }); }); |