diff options
Diffstat (limited to 'spec/frontend/vue_mr_widget/components')
11 files changed, 181 insertions, 132 deletions
diff --git a/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js b/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js index e39f66d3f30..65ca3639dcc 100644 --- a/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js +++ b/spec/frontend/vue_mr_widget/components/approvals/approvals_spec.js @@ -3,7 +3,7 @@ import { GlButton } from '@gitlab/ui'; import Approvals from '~/vue_merge_request_widget/components/approvals/approvals.vue'; import ApprovalsSummary from '~/vue_merge_request_widget/components/approvals/approvals_summary.vue'; import ApprovalsSummaryOptional from '~/vue_merge_request_widget/components/approvals/approvals_summary_optional.vue'; -import createFlash from '~/flash'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; import { FETCH_LOADING, FETCH_ERROR, diff --git a/spec/frontend/vue_mr_widget/components/approvals/approvals_summary_optional_spec.js b/spec/frontend/vue_mr_widget/components/approvals/approvals_summary_optional_spec.js index 77fad7f51ab..d9a5230f55f 100644 --- a/spec/frontend/vue_mr_widget/components/approvals/approvals_summary_optional_spec.js +++ b/spec/frontend/vue_mr_widget/components/approvals/approvals_summary_optional_spec.js @@ -1,9 +1,5 @@ import { shallowMount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; -import { - OPTIONAL, - OPTIONAL_CAN_APPROVE, -} from '~/vue_merge_request_widget/components/approvals/messages'; import ApprovalsSummaryOptional from '~/vue_merge_request_widget/components/approvals/approvals_summary_optional.vue'; const TEST_HELP_PATH = 'help/path'; @@ -29,10 +25,6 @@ describe('MRWidget approvals summary optional', () => { createComponent({ canApprove: true, helpPath: TEST_HELP_PATH }); }); - it('shows optional can approve message', () => { - expect(wrapper.text()).toEqual(OPTIONAL_CAN_APPROVE); - }); - it('shows help link', () => { const link = findHelpLink(); @@ -46,10 +38,6 @@ describe('MRWidget approvals summary optional', () => { createComponent({ canApprove: false, helpPath: TEST_HELP_PATH }); }); - it('shows optional message', () => { - expect(wrapper.text()).toEqual(OPTIONAL); - }); - it('does not show help link', () => { expect(findHelpLink().exists()).toBe(false); }); 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 index 5f3a8654990..d67f1adadf2 100644 --- 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 @@ -1,9 +1,9 @@ import { mount } from '@vue/test-utils'; +import MockAdapter from 'axios-mock-adapter'; 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', () => { diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js index d6c996f7501..8fcc982ac99 100644 --- a/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js +++ b/spec/frontend/vue_mr_widget/components/mr_widget_suggest_pipeline_spec.js @@ -1,119 +1,156 @@ -import { mount } from '@vue/test-utils'; +import { mount, shallowMount } from '@vue/test-utils'; import { GlLink, GlSprintf } from '@gitlab/ui'; +import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper'; +import MockAdapter from 'axios-mock-adapter'; import suggestPipelineComponent from '~/vue_merge_request_widget/components/mr_widget_suggest_pipeline.vue'; import MrWidgetIcon from '~/vue_merge_request_widget/components/mr_widget_icon.vue'; -import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper'; -import { popoverProps, iconName } from './pipeline_tour_mock_data'; +import dismissibleContainer from '~/vue_shared/components/dismissible_container.vue'; +import { suggestProps, iconName } from './pipeline_tour_mock_data'; +import axios from '~/lib/utils/axios_utils'; +import { + SP_TRACK_LABEL, + SP_LINK_TRACK_EVENT, + SP_SHOW_TRACK_EVENT, + SP_LINK_TRACK_VALUE, + SP_SHOW_TRACK_VALUE, + SP_HELP_URL, +} from '~/vue_merge_request_widget/constants'; describe('MRWidgetSuggestPipeline', () => { - let wrapper; - let trackingSpy; - - const mockTrackingOnWrapper = () => { - unmockTracking(); - trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); - }; - - beforeEach(() => { - document.body.dataset.page = 'projects:merge_requests:show'; - trackingSpy = mockTracking('_category_', undefined, jest.spyOn); - - wrapper = mount(suggestPipelineComponent, { - propsData: popoverProps, - stubs: { - GlSprintf, - }, + describe('template', () => { + let wrapper; + + afterEach(() => { + wrapper.destroy(); }); - }); - afterEach(() => { - wrapper.destroy(); - unmockTracking(); - }); + describe('core functionality', () => { + const findOkBtn = () => wrapper.find('[data-testid="ok"]'); + let trackingSpy; + let mockAxios; + + const mockTrackingOnWrapper = () => { + unmockTracking(); + trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); + }; + + beforeEach(() => { + mockAxios = new MockAdapter(axios); + document.body.dataset.page = 'projects:merge_requests:show'; + trackingSpy = mockTracking('_category_', undefined, jest.spyOn); + + wrapper = mount(suggestPipelineComponent, { + propsData: suggestProps, + stubs: { + GlSprintf, + }, + }); + }); - describe('template', () => { - const findOkBtn = () => wrapper.find('[data-testid="ok"]'); + afterEach(() => { + unmockTracking(); + mockAxios.restore(); + }); - it('renders add pipeline file link', () => { - const link = wrapper.find(GlLink); + it('renders add pipeline file link', () => { + const link = wrapper.find(GlLink); - expect(link.exists()).toBe(true); - expect(link.attributes().href).toBe(popoverProps.pipelinePath); - }); + expect(link.exists()).toBe(true); + expect(link.attributes().href).toBe(suggestProps.pipelinePath); + }); - it('renders the expected text', () => { - const messageText = /\s*No pipeline\s*Add the .gitlab-ci.yml file\s*to create one./; + it('renders the expected text', () => { + const messageText = /\s*No pipeline\s*Add the .gitlab-ci.yml file\s*to create one./; - expect(wrapper.text()).toMatch(messageText); - }); + expect(wrapper.text()).toMatch(messageText); + }); - it('renders widget icon', () => { - const icon = wrapper.find(MrWidgetIcon); + it('renders widget icon', () => { + const icon = wrapper.find(MrWidgetIcon); - expect(icon.exists()).toBe(true); - expect(icon.props()).toEqual( - expect.objectContaining({ - name: iconName, - }), - ); - }); + expect(icon.exists()).toBe(true); + expect(icon.props()).toEqual( + expect.objectContaining({ + name: iconName, + }), + ); + }); - it('renders the show me how button', () => { - const button = findOkBtn(); + it('renders the show me how button', () => { + const button = findOkBtn(); - expect(button.exists()).toBe(true); - expect(button.classes('btn-info')).toEqual(true); - expect(button.attributes('href')).toBe(popoverProps.pipelinePath); - }); + expect(button.exists()).toBe(true); + expect(button.classes('btn-info')).toEqual(true); + expect(button.attributes('href')).toBe(suggestProps.pipelinePath); + }); - it('renders the help link', () => { - const link = wrapper.find('[data-testid="help"]'); + it('renders the help link', () => { + const link = wrapper.find('[data-testid="help"]'); - expect(link.exists()).toBe(true); - expect(link.attributes('href')).toBe(wrapper.vm.$options.helpURL); - }); + expect(link.exists()).toBe(true); + expect(link.attributes('href')).toBe(SP_HELP_URL); + }); - it('renders the empty pipelines image', () => { - const image = wrapper.find('[data-testid="pipeline-image"]'); + it('renders the empty pipelines image', () => { + const image = wrapper.find('[data-testid="pipeline-image"]'); - expect(image.exists()).toBe(true); - expect(image.attributes().src).toBe(popoverProps.pipelineSvgPath); - }); + expect(image.exists()).toBe(true); + expect(image.attributes().src).toBe(suggestProps.pipelineSvgPath); + }); - describe('tracking', () => { - it('send event for basic view of the suggest pipeline widget', () => { - const expectedCategory = undefined; - const expectedAction = undefined; + describe('tracking', () => { + it('send event for basic view of the suggest pipeline widget', () => { + const expectedCategory = undefined; + const expectedAction = undefined; - expect(trackingSpy).toHaveBeenCalledWith(expectedCategory, expectedAction, { - label: wrapper.vm.$options.trackLabel, - property: popoverProps.humanAccess, + expect(trackingSpy).toHaveBeenCalledWith(expectedCategory, expectedAction, { + label: SP_TRACK_LABEL, + property: suggestProps.humanAccess, + }); }); - }); - it('send an event when add pipeline link is clicked', () => { - mockTrackingOnWrapper(); - const link = wrapper.find('[data-testid="add-pipeline-link"]'); - triggerEvent(link.element); + it('send an event when add pipeline link is clicked', () => { + mockTrackingOnWrapper(); + const link = wrapper.find('[data-testid="add-pipeline-link"]'); + triggerEvent(link.element); - expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_link', { - label: wrapper.vm.$options.trackLabel, - property: popoverProps.humanAccess, - value: '30', + expect(trackingSpy).toHaveBeenCalledWith('_category_', SP_LINK_TRACK_EVENT, { + label: SP_TRACK_LABEL, + property: suggestProps.humanAccess, + value: SP_LINK_TRACK_VALUE.toString(), + }); }); - }); - it('send an event when ok button is clicked', () => { - mockTrackingOnWrapper(); - const okBtn = findOkBtn(); - triggerEvent(okBtn.element); + it('send an event when ok button is clicked', () => { + mockTrackingOnWrapper(); + const okBtn = findOkBtn(); + triggerEvent(okBtn.element); - expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_button', { - label: wrapper.vm.$options.trackLabel, - property: popoverProps.humanAccess, - value: '10', + expect(trackingSpy).toHaveBeenCalledWith('_category_', SP_SHOW_TRACK_EVENT, { + label: SP_TRACK_LABEL, + property: suggestProps.humanAccess, + value: SP_SHOW_TRACK_VALUE.toString(), + }); }); }); }); + + describe('dismissible', () => { + const findDismissContainer = () => wrapper.find(dismissibleContainer); + + beforeEach(() => { + wrapper = shallowMount(suggestPipelineComponent, { propsData: suggestProps }); + }); + + it('renders the dismissal container', () => { + expect(findDismissContainer().exists()).toBe(true); + }); + + it('emits dismiss upon dismissal button click', () => { + findDismissContainer().vm.$emit('dismiss'); + + expect(wrapper.emitted().dismiss).toBeTruthy(); + }); + }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/pipeline_tour_mock_data.js b/spec/frontend/vue_mr_widget/components/pipeline_tour_mock_data.js index c749c434079..eef087d62b8 100644 --- a/spec/frontend/vue_mr_widget/components/pipeline_tour_mock_data.js +++ b/spec/frontend/vue_mr_widget/components/pipeline_tour_mock_data.js @@ -1,7 +1,9 @@ -export const popoverProps = { +export const suggestProps = { pipelinePath: '/foo/bar/add/pipeline/path', pipelineSvgPath: 'assets/illustrations/something.svg', humanAccess: 'maintainer', + userCalloutsPath: 'some/callout/path', + userCalloutFeatureId: 'suggest_pipeline', }; export const iconName = 'status_notfound'; diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_commit_message_dropdown_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_commit_message_dropdown_spec.js index 56832f82b05..5c7e6a87c16 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_commit_message_dropdown_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_commit_message_dropdown_spec.js @@ -1,5 +1,5 @@ import { shallowMount } from '@vue/test-utils'; -import { GlDropdownItem } from '@gitlab/ui'; +import { GlDeprecatedDropdownItem } from '@gitlab/ui'; import CommitMessageDropdown from '~/vue_merge_request_widget/components/states/commit_message_dropdown.vue'; const commits = [ @@ -39,7 +39,7 @@ describe('Commits message dropdown component', () => { wrapper.destroy(); }); - const findDropdownElements = () => wrapper.findAll(GlDropdownItem); + const findDropdownElements = () => wrapper.findAll(GlDeprecatedDropdownItem); const findFirstDropdownElement = () => findDropdownElements().at(0); it('should have 3 elements in dropdown list', () => { 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 d3482b457ad..c3a16a776a7 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 @@ -1,8 +1,8 @@ import $ from 'jquery'; import { createLocalVue, shallowMount } from '@vue/test-utils'; import { removeBreakLine } from 'helpers/text_helper'; -import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue'; import { TEST_HOST } from 'helpers/test_constants'; +import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue'; describe('MRWidgetConflicts', () => { let vm; 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 1542b0939aa..4c213899dbd 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 @@ -79,7 +79,7 @@ describe('Squash before merge component', () => { }); it(expectation, () => { - expect(findLabel().classes('gl-text-gray-600')).toBe(isDisabled); + expect(findLabel().classes('gl-text-gray-400')).toBe(isDisabled); }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js index 33e52f4fd36..a5531577a8c 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_unresolved_discussions_spec.js @@ -1,46 +1,68 @@ -import Vue from 'vue'; -import mountComponent from 'helpers/vue_mount_component_helper'; -import UnresolvedDiscussions from '~/vue_merge_request_widget/components/states/unresolved_discussions.vue'; +import { mount } from '@vue/test-utils'; import { TEST_HOST } from 'helpers/test_constants'; +import UnresolvedDiscussions from '~/vue_merge_request_widget/components/states/unresolved_discussions.vue'; +import notesEventHub from '~/notes/event_hub'; + +function createComponent({ path = '' } = {}) { + return mount(UnresolvedDiscussions, { + propsData: { + mr: { + createIssueToResolveDiscussionsPath: path, + }, + }, + }); +} describe('UnresolvedDiscussions', () => { - const Component = Vue.extend(UnresolvedDiscussions); - let vm; + let wrapper; + + beforeEach(() => { + wrapper = createComponent(); + }); afterEach(() => { - vm.$destroy(); + wrapper.destroy(); + }); + + it('triggers the correct notes event when the jump to first unresolved discussion button is clicked', () => { + jest.spyOn(notesEventHub, '$emit'); + + wrapper.find('[data-testid="jump-to-first"]').trigger('click'); + + expect(notesEventHub.$emit).toHaveBeenCalledWith('jumpToFirstUnresolvedDiscussion'); }); describe('with threads path', () => { beforeEach(() => { - vm = mountComponent(Component, { - mr: { - createIssueToResolveDiscussionsPath: TEST_HOST, - }, - }); + wrapper = createComponent({ path: TEST_HOST }); + }); + + afterEach(() => { + wrapper.destroy(); }); it('should have correct elements', () => { - expect(vm.$el.innerText).toContain( - 'There are unresolved threads. Please resolve these threads', + expect(wrapper.element.innerText).toContain( + `Before this can be merged, one or more threads must be resolved.`, ); - expect(vm.$el.innerText).toContain('Create an issue to resolve them later'); - expect(vm.$el.querySelector('.js-create-issue').getAttribute('href')).toEqual(TEST_HOST); + expect(wrapper.element.innerText).toContain('Jump to first unresolved thread'); + expect(wrapper.element.innerText).toContain('Resolve all threads in new issue'); + expect(wrapper.element.querySelector('.js-create-issue').getAttribute('href')).toEqual( + TEST_HOST, + ); }); }); describe('without threads path', () => { - beforeEach(() => { - vm = mountComponent(Component, { mr: {} }); - }); - it('should not show create issue link if user cannot create issue', () => { - expect(vm.$el.innerText).toContain( - 'There are unresolved threads. Please resolve these threads', + expect(wrapper.element.innerText).toContain( + `Before this can be merged, one or more threads must be resolved.`, ); - expect(vm.$el.querySelector('.js-create-issue')).toEqual(null); + expect(wrapper.element.innerText).toContain('Jump to first unresolved thread'); + expect(wrapper.element.innerText).not.toContain('Resolve all threads in new issue'); + expect(wrapper.element.querySelector('.js-create-issue')).toEqual(null); }); }); }); diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js index 6fa555b4fc4..6ccf1e1f56b 100644 --- a/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_wip_spec.js @@ -1,7 +1,7 @@ import Vue from 'vue'; import WorkInProgress from '~/vue_merge_request_widget/components/states/work_in_progress.vue'; import eventHub from '~/vue_merge_request_widget/event_hub'; -import createFlash from '~/flash'; +import { deprecatedCreateFlash as createFlash } from '~/flash'; jest.mock('~/flash'); @@ -84,11 +84,11 @@ describe('Wip', () => { it('should have correct elements', () => { expect(el.classList.contains('mr-widget-body')).toBeTruthy(); - expect(el.innerText).toContain('This is a Work in Progress'); + expect(el.innerText).toContain('This merge request is still a work in progress.'); expect(el.querySelector('button').getAttribute('disabled')).toBeTruthy(); expect(el.querySelector('button').innerText).toContain('Merge'); expect(el.querySelector('.js-remove-wip').innerText.replace(/\s\s+/g, ' ')).toContain( - 'Resolve WIP status', + 'Mark as ready', ); }); diff --git a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js index be43f10c03e..ffcf9b1477a 100644 --- a/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js +++ b/spec/frontend/vue_mr_widget/components/terraform/mr_widget_terraform_container_spec.js @@ -1,8 +1,8 @@ import { GlSkeletonLoading, GlSprintf } from '@gitlab/ui'; -import { invalidPlanWithName, plans, validPlanWithName } from './mock_data'; import { shallowMount } from '@vue/test-utils'; -import axios from '~/lib/utils/axios_utils'; import MockAdapter from 'axios-mock-adapter'; +import { invalidPlanWithName, plans, validPlanWithName } from './mock_data'; +import axios from '~/lib/utils/axios_utils'; import MrWidgetExpanableSection from '~/vue_merge_request_widget/components/mr_widget_expandable_section.vue'; import MrWidgetTerraformContainer from '~/vue_merge_request_widget/components/terraform/mr_widget_terraform_container.vue'; import Poll from '~/lib/utils/poll'; |