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:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 21:18:33 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-16 21:18:33 +0300
commitf64a639bcfa1fc2bc89ca7db268f594306edfd7c (patch)
treea2c3c2ebcc3b45e596949db485d6ed18ffaacfa1 /spec/frontend/vue_mr_widget
parentbfbc3e0d6583ea1a91f627528bedc3d65ba4b10f (diff)
Add latest changes from gitlab-org/gitlab@13-10-stable-eev13.10.0-rc40
Diffstat (limited to 'spec/frontend/vue_mr_widget')
-rw-r--r--spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_collapsible_extension_spec.js14
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js46
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_pipeline_container_spec.js8
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js38
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js51
-rw-r--r--spec/frontend/vue_mr_widget/components/review_app_link_spec.js26
-rw-r--r--spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js109
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js38
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js12
-rw-r--r--spec/frontend/vue_mr_widget/deployment/deployment_list_spec.js101
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_options_spec.js12
13 files changed, 258 insertions, 201 deletions
diff --git a/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js b/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js
index b2cc7d9be6b..e2386bc7f2b 100644
--- a/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js
+++ b/spec/frontend/vue_mr_widget/components/artifacts_list_app_spec.js
@@ -48,7 +48,7 @@ describe('Merge Requests Artifacts list app', () => {
};
const findButtons = () => wrapper.findAll('button');
- const findTitle = () => wrapper.find('.js-title');
+ const findTitle = () => wrapper.find('[data-testid="mr-collapsible-title"]');
const findErrorMessage = () => wrapper.find('.js-error-state');
const findTableRows = () => wrapper.findAll('tbody tr');
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 94d4cccab5f..1aeb080aa04 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
@@ -1,4 +1,4 @@
-import { GlLoadingIcon } from '@gitlab/ui';
+import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MrCollapsibleSection from '~/vue_merge_request_widget/components/mr_collapsible_extension.vue';
@@ -15,12 +15,14 @@ describe('Merge Request Collapsible Extension', () => {
},
slots: {
default: '<div class="js-slot">Foo</div>',
+ header: '<span data-testid="collapsed-header">hello there</span>',
},
});
};
- const findTitle = () => wrapper.find('.js-title');
+ const findTitle = () => wrapper.find('[data-testid="mr-collapsible-title"]');
const findErrorMessage = () => wrapper.find('.js-error-state');
+ const findIcon = () => wrapper.find(GlIcon);
afterEach(() => {
wrapper.destroy();
@@ -35,8 +37,12 @@ describe('Merge Request Collapsible Extension', () => {
expect(findTitle().text()).toBe(data.title);
});
+ it('renders the header slot', () => {
+ expect(wrapper.find('[data-testid="collapsed-header"]').text()).toBe('hello there');
+ });
+
it('renders angle-right icon', () => {
- expect(wrapper.vm.arrowIconName).toBe('angle-right');
+ expect(findIcon().props('name')).toBe('angle-right');
});
describe('onClick', () => {
@@ -54,7 +60,7 @@ describe('Merge Request Collapsible Extension', () => {
});
it('renders angle-down icon', () => {
- expect(wrapper.vm.arrowIconName).toBe('angle-down');
+ expect(findIcon().props('name')).toBe('angle-down');
});
});
});
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
deleted file mode 100644
index 53a74bf7456..00000000000
--- a/spec/frontend/vue_mr_widget/components/mr_widget_merge_help_spec.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import MergeHelpComponent from '~/vue_merge_request_widget/components/mr_widget_merge_help.vue';
-
-describe('MRWidgetMergeHelp', () => {
- let wrapper;
-
- const createComponent = ({ props = {} } = {}) => {
- wrapper = shallowMount(MergeHelpComponent, {
- propsData: {
- missingBranch: 'this-is-not-the-branch-you-are-looking-for',
- ...props,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('with missing branch', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders missing branch information', () => {
- 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(() => {
- createComponent({
- props: { missingBranch: '' },
- });
- });
-
- it('renders information about how to merge manually', () => {
- expect(wrapper.find('.mr-widget-help').text()).toContain(
- 'You can merge this merge request manually',
- );
- });
- });
-});
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 3baade5161e..5ec719b17d6 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
@@ -2,6 +2,7 @@ import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import ArtifactsApp from '~/vue_merge_request_widget/components/artifacts_list_app.vue';
+import DeploymentList from '~/vue_merge_request_widget/components/deployment/deployment_list.vue';
import MrWidgetPipeline from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue';
import MrWidgetPipelineContainer from '~/vue_merge_request_widget/components/mr_widget_pipeline_container.vue';
import { mockStore } from '../mock_data';
@@ -28,6 +29,8 @@ describe('MrWidgetPipelineContainer', () => {
wrapper.destroy();
});
+ const findDeploymentList = () => wrapper.findComponent(DeploymentList);
+
describe('when pre merge', () => {
beforeEach(() => {
factory();
@@ -55,6 +58,9 @@ describe('MrWidgetPipelineContainer', () => {
const deployments = wrapper.findAll('.mr-widget-extension .js-pre-deployment');
+ expect(findDeploymentList().exists()).toBe(true);
+ expect(findDeploymentList().props('deployments')).toBe(mockStore.deployments);
+
expect(deployments.wrappers.map((x) => x.props())).toEqual(expectedProps);
});
});
@@ -100,6 +106,8 @@ describe('MrWidgetPipelineContainer', () => {
const deployments = wrapper.findAll('.mr-widget-extension .js-post-deployment');
+ expect(findDeploymentList().exists()).toBe(true);
+ expect(findDeploymentList().props('deployments')).toBe(mockStore.postMergeDeployments);
expect(deployments.wrappers.map((x) => x.props())).toEqual(expectedProps);
});
});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js
index b93236d4628..28492018600 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_pipeline_spec.js
@@ -1,7 +1,8 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import { trimText } from 'helpers/text_helper';
-import PipelineStage from '~/pipelines/components/pipelines_list/stage.vue';
+import PipelineMiniGraph from '~/pipelines/components/pipelines_list/pipeline_mini_graph.vue';
+import PipelineStage from '~/pipelines/components/pipelines_list/pipeline_stage.vue';
import PipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue';
import { SUCCESS } from '~/vue_merge_request_widget/constants';
import mockData from '../mock_data';
@@ -25,7 +26,7 @@ describe('MRWidgetPipeline', () => {
const findPipelineID = () => wrapper.find('[data-testid="pipeline-id"]');
const findPipelineInfoContainer = () => wrapper.find('[data-testid="pipeline-info-container"]');
const findCommitLink = () => wrapper.find('[data-testid="commit-link"]');
- const findPipelineGraph = () => wrapper.find('[data-testid="widget-mini-pipeline-graph"]');
+ const findPipelineMiniGraph = () => wrapper.find(PipelineMiniGraph);
const findAllPipelineStages = () => wrapper.findAll(PipelineStage);
const findPipelineCoverage = () => wrapper.find('[data-testid="pipeline-coverage"]');
const findPipelineCoverageDelta = () => wrapper.find('[data-testid="pipeline-coverage-delta"]');
@@ -35,7 +36,7 @@ describe('MRWidgetPipeline', () => {
wrapper.find('[data-testid="monitoring-pipeline-message"]');
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
- const createWrapper = (props, mountFn = shallowMount) => {
+ const createWrapper = (props = {}, mountFn = shallowMount) => {
wrapper = mountFn(PipelineComponent, {
propsData: {
...defaultProps,
@@ -65,10 +66,13 @@ describe('MRWidgetPipeline', () => {
describe('with a pipeline', () => {
beforeEach(() => {
- createWrapper({
- pipelineCoverageDelta: mockData.pipelineCoverageDelta,
- buildsWithCoverage: mockData.buildsWithCoverage,
- });
+ createWrapper(
+ {
+ pipelineCoverageDelta: mockData.pipelineCoverageDelta,
+ buildsWithCoverage: mockData.buildsWithCoverage,
+ },
+ mount,
+ );
});
it('should render pipeline ID', () => {
@@ -84,8 +88,8 @@ describe('MRWidgetPipeline', () => {
});
it('should render pipeline graph', () => {
- expect(findPipelineGraph().exists()).toBe(true);
- expect(findAllPipelineStages().length).toBe(mockData.pipeline.details.stages.length);
+ expect(findPipelineMiniGraph().exists()).toBe(true);
+ expect(findAllPipelineStages()).toHaveLength(mockData.pipeline.details.stages.length);
});
describe('should render pipeline coverage information', () => {
@@ -136,7 +140,7 @@ describe('MRWidgetPipeline', () => {
const mockCopy = JSON.parse(JSON.stringify(mockData));
delete mockCopy.pipeline.commit;
- createWrapper({});
+ createWrapper({}, mount);
});
it('should render pipeline ID', () => {
@@ -147,9 +151,15 @@ describe('MRWidgetPipeline', () => {
expect(findPipelineInfoContainer().text()).toMatch(mockData.pipeline.details.status.label);
});
- it('should render pipeline graph', () => {
- expect(findPipelineGraph().exists()).toBe(true);
- expect(findAllPipelineStages().length).toBe(mockData.pipeline.details.stages.length);
+ it('should render pipeline graph with correct styles', () => {
+ const stagesCount = mockData.pipeline.details.stages.length;
+
+ expect(findPipelineMiniGraph().exists()).toBe(true);
+ expect(findPipelineMiniGraph().findAll('.mr-widget-pipeline-stages')).toHaveLength(
+ stagesCount,
+ );
+
+ expect(findAllPipelineStages()).toHaveLength(stagesCount);
});
it('should render coverage information', () => {
@@ -181,7 +191,7 @@ describe('MRWidgetPipeline', () => {
});
it('should not render a pipeline graph', () => {
- expect(findPipelineGraph().exists()).toBe(false);
+ expect(findPipelineMiniGraph().exists()).toBe(false);
});
});
diff --git a/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js b/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js
index a33401c5ba9..a879b06e858 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js
@@ -1,85 +1,88 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import relatedLinksComponent from '~/vue_merge_request_widget/components/mr_widget_related_links.vue';
+import { shallowMount } from '@vue/test-utils';
+import RelatedLinks from '~/vue_merge_request_widget/components/mr_widget_related_links.vue';
describe('MRWidgetRelatedLinks', () => {
- let vm;
+ let wrapper;
- const createComponent = (data) => {
- const Component = Vue.extend(relatedLinksComponent);
-
- return mountComponent(Component, data);
+ const createComponent = (propsData = {}) => {
+ wrapper = shallowMount(RelatedLinks, { propsData });
};
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
describe('computed', () => {
describe('closesText', () => {
it('returns Closes text for open merge request', () => {
- vm = createComponent({ state: 'open', relatedLinks: {} });
+ createComponent({ state: 'open', relatedLinks: {} });
- expect(vm.closesText).toEqual('Closes');
+ expect(wrapper.vm.closesText).toBe('Closes');
});
it('returns correct text for closed merge request', () => {
- vm = createComponent({ state: 'closed', relatedLinks: {} });
+ createComponent({ state: 'closed', relatedLinks: {} });
- expect(vm.closesText).toEqual('Did not close');
+ expect(wrapper.vm.closesText).toBe('Did not close');
});
it('returns correct tense for merged request', () => {
- vm = createComponent({ state: 'merged', relatedLinks: {} });
+ createComponent({ state: 'merged', relatedLinks: {} });
- expect(vm.closesText).toEqual('Closed');
+ expect(wrapper.vm.closesText).toBe('Closed');
});
});
});
it('should have only have closing issues text', () => {
- vm = createComponent({
+ createComponent({
relatedLinks: {
closing: '<a href="#">#23</a> and <a>#42</a>',
},
});
- const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
+ const content = wrapper
+ .text()
+ .replace(/\n(\s)+/g, ' ')
+ .trim();
expect(content).toContain('Closes #23 and #42');
expect(content).not.toContain('Mentions');
});
it('should have only have mentioned issues text', () => {
- vm = createComponent({
+ createComponent({
relatedLinks: {
mentioned: '<a href="#">#7</a>',
},
});
- expect(vm.$el.innerText).toContain('Mentions #7');
- expect(vm.$el.innerText).not.toContain('Closes');
+ expect(wrapper.text().trim()).toContain('Mentions #7');
+ expect(wrapper.text().trim()).not.toContain('Closes');
});
it('should have closing and mentioned issues at the same time', () => {
- vm = createComponent({
+ createComponent({
relatedLinks: {
closing: '<a href="#">#7</a>',
mentioned: '<a href="#">#23</a> and <a>#42</a>',
},
});
- const content = vm.$el.textContent.replace(/\n(\s)+/g, ' ').trim();
+ const content = wrapper
+ .text()
+ .replace(/\n(\s)+/g, ' ')
+ .trim();
expect(content).toContain('Closes #7');
expect(content).toContain('Mentions #23 and #42');
});
it('should have assing issues link', () => {
- vm = createComponent({
+ createComponent({
relatedLinks: {
assignToMe: '<a href="#">Assign yourself to these issues</a>',
},
});
- expect(vm.$el.innerText).toContain('Assign yourself to these issues');
+ expect(wrapper.text().trim()).toContain('Assign yourself to these issues');
});
});
diff --git a/spec/frontend/vue_mr_widget/components/review_app_link_spec.js b/spec/frontend/vue_mr_widget/components/review_app_link_spec.js
index 81a52890db7..e393b56034d 100644
--- a/spec/frontend/vue_mr_widget/components/review_app_link_spec.js
+++ b/spec/frontend/vue_mr_widget/components/review_app_link_spec.js
@@ -1,10 +1,8 @@
-import Vue from 'vue';
+import { shallowMount } from '@vue/test-utils';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import component from '~/vue_merge_request_widget/components/review_app_link.vue';
+import ReviewAppLink from '~/vue_merge_request_widget/components/review_app_link.vue';
describe('review app link', () => {
- const Component = Vue.extend(component);
const props = {
link: '/review',
cssClass: 'js-link',
@@ -13,37 +11,35 @@ describe('review app link', () => {
tooltip: '',
},
};
- let vm;
- let el;
+ let wrapper;
beforeEach(() => {
- vm = mountComponent(Component, props);
- el = vm.$el;
+ wrapper = shallowMount(ReviewAppLink, { propsData: props });
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
it('renders provided link as href attribute', () => {
- expect(el.getAttribute('href')).toEqual(props.link);
+ expect(wrapper.attributes('href')).toBe(props.link);
});
it('renders provided cssClass as class attribute', () => {
- expect(el.getAttribute('class')).toContain(props.cssClass);
+ expect(wrapper.classes('js-link')).toBe(true);
});
it('renders View app text', () => {
- expect(el.textContent.trim()).toEqual('View app');
+ expect(wrapper.text().trim()).toBe('View app');
});
it('renders svg icon', () => {
- expect(el.querySelector('svg')).not.toBeNull();
+ expect(wrapper.find('svg')).not.toBeNull();
});
it('tracks an event when clicked', () => {
- const spy = mockTracking('_category_', el, jest.spyOn);
- triggerEvent(el);
+ const spy = mockTracking('_category_', wrapper.element, jest.spyOn);
+ triggerEvent(wrapper.element);
expect(spy).toHaveBeenCalledWith('_category_', 'open_review_app', {
label: 'review_app',
diff --git a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
index c425a3a86a9..e5862df5dda 100644
--- a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
+++ b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_auto_merge_enabled_spec.js.snap
@@ -16,6 +16,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is disabled template should have
>
<span
class="gl-mr-3"
+ data-qa-selector="merge_request_status_content"
>
<span
class="js-status-text-before-author"
@@ -107,6 +108,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is enabled template should have c
>
<span
class="gl-mr-3"
+ data-qa-selector="merge_request_status_content"
>
<span
class="js-status-text-before-author"
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 d3fc1e0e05b..dc2f227b29c 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,36 +1,41 @@
-import { createLocalVue, shallowMount } from '@vue/test-utils';
-import $ from 'jquery';
+import { GlPopover } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
import { TEST_HOST } from 'helpers/test_constants';
import { removeBreakLine } from 'helpers/text_helper';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ConflictsComponent from '~/vue_merge_request_widget/components/states/mr_widget_conflicts.vue';
describe('MRWidgetConflicts', () => {
- let vm;
+ let wrapper;
let mergeRequestWidgetGraphql = null;
const path = '/conflicts';
- function createComponent(propsData = {}) {
- const localVue = createLocalVue();
+ const findPopover = () => wrapper.find(GlPopover);
+ const findResolveButton = () => wrapper.findByTestId('resolve-conflicts-button');
+ const findMergeLocalButton = () => wrapper.findByTestId('merge-locally-button');
- vm = shallowMount(localVue.extend(ConflictsComponent), {
- propsData,
- provide: {
- glFeatures: {
- mergeRequestWidgetGraphql,
+ function createComponent(propsData = {}) {
+ wrapper = extendedWrapper(
+ shallowMount(ConflictsComponent, {
+ propsData,
+ provide: {
+ glFeatures: {
+ mergeRequestWidgetGraphql,
+ },
},
- },
- mocks: {
- $apollo: {
- queries: {
- userPermissions: { loading: false },
- stateData: { loading: false },
+ mocks: {
+ $apollo: {
+ queries: {
+ userPermissions: { loading: false },
+ stateData: { loading: false },
+ },
},
},
- },
- });
+ }),
+ );
if (mergeRequestWidgetGraphql) {
- vm.setData({
+ wrapper.setData({
userPermissions: {
canMerge: propsData.mr.canMerge,
pushToSourceBranch: propsData.mr.canPushToSourceBranch,
@@ -42,16 +47,12 @@ describe('MRWidgetConflicts', () => {
});
}
- return vm.vm.$nextTick();
+ return wrapper.vm.$nextTick();
}
- beforeEach(() => {
- jest.spyOn($.fn, 'popover');
- });
-
afterEach(() => {
mergeRequestWidgetGraphql = null;
- vm.destroy();
+ wrapper.destroy();
});
[false, true].forEach((featureEnabled) => {
@@ -82,18 +83,16 @@ describe('MRWidgetConflicts', () => {
});
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');
+ expect(wrapper.text()).toContain('There are merge conflicts');
+ expect(wrapper.text()).not.toContain('ask someone with write access');
});
it('should not allow you to resolve the conflicts', () => {
- expect(vm.text()).not.toContain('Resolve conflicts');
+ expect(wrapper.text()).not.toContain('Resolve conflicts');
});
it('should have merge buttons', () => {
- const mergeLocallyButton = vm.find('.js-merge-locally-button');
-
- expect(mergeLocallyButton.text()).toContain('Merge locally');
+ expect(findMergeLocalButton().text()).toContain('Merge locally');
});
});
@@ -110,19 +109,17 @@ describe('MRWidgetConflicts', () => {
});
it('should tell you about conflicts', () => {
- expect(vm.text()).toContain('There are merge conflicts');
- expect(vm.text()).toContain('ask someone with write access');
+ expect(wrapper.text()).toContain('There are merge conflicts');
+ expect(wrapper.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);
+ expect(findResolveButton().text()).toContain('Resolve conflicts');
+ expect(findResolveButton().attributes('href')).toEqual(path);
});
it('should not have merge buttons', () => {
- expect(vm.text()).not.toContain('Merge locally');
+ expect(wrapper.text()).not.toContain('Merge locally');
});
});
@@ -139,21 +136,17 @@ describe('MRWidgetConflicts', () => {
});
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');
+ expect(wrapper.text()).toContain('There are merge conflicts');
+ expect(wrapper.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);
+ expect(findResolveButton().text()).toContain('Resolve conflicts');
+ expect(findResolveButton().attributes('href')).toEqual(path);
});
it('should have merge buttons', () => {
- const mergeLocallyButton = vm.find('.js-merge-locally-button');
-
- expect(mergeLocallyButton.text()).toContain('Merge locally');
+ expect(findMergeLocalButton().text()).toContain('Merge locally');
});
});
@@ -167,7 +160,7 @@ describe('MRWidgetConflicts', () => {
},
});
- expect(vm.text().trim().replace(/\s\s+/g, ' ')).toContain(
+ expect(wrapper.text().trim().replace(/\s\s+/g, ' ')).toContain(
'ask someone with write access',
);
});
@@ -181,8 +174,8 @@ describe('MRWidgetConflicts', () => {
},
});
- expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false);
- expect(vm.find('.js-merge-locally-button').exists()).toBe(false);
+ expect(findResolveButton().exists()).toBe(false);
+ expect(findMergeLocalButton().exists()).toBe(false);
});
it('should not have resolve button when no conflict resolution path', async () => {
@@ -194,7 +187,7 @@ describe('MRWidgetConflicts', () => {
},
});
- expect(vm.find('.js-resolve-conflicts-button').exists()).toBe(false);
+ expect(findResolveButton().exists()).toBe(false);
});
});
@@ -207,7 +200,7 @@ describe('MRWidgetConflicts', () => {
},
});
- expect(removeBreakLine(vm.text()).trim()).toContain(
+ expect(removeBreakLine(wrapper.text()).trim()).toContain(
'Fast-forward merge is not possible. To merge this request, first rebase locally.',
);
});
@@ -227,11 +220,11 @@ describe('MRWidgetConflicts', () => {
});
it('sets resolve button as disabled', () => {
- expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe('true');
+ expect(findResolveButton().attributes('disabled')).toBe('true');
});
- it('renders popover', () => {
- expect($.fn.popover).toHaveBeenCalled();
+ it('shows the popover', () => {
+ expect(findPopover().exists()).toBe(true);
});
});
@@ -249,11 +242,11 @@ describe('MRWidgetConflicts', () => {
});
it('sets resolve button as disabled', () => {
- expect(vm.find('.js-resolve-conflicts-button').attributes('disabled')).toBe(undefined);
+ expect(findResolveButton().attributes('disabled')).toBe(undefined);
});
- it('renders popover', () => {
- expect($.fn.popover).not.toHaveBeenCalled();
+ it('does not show the popover', () => {
+ expect(findPopover().exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
index 222cb74cc66..b16fb5171e7 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_merging_spec.js
@@ -1,29 +1,30 @@
-import Vue from 'vue';
-import mountComponent from 'helpers/vue_mount_component_helper';
-import mergingComponent from '~/vue_merge_request_widget/components/states/mr_widget_merging.vue';
+import { shallowMount } from '@vue/test-utils';
+import MrWidgetMerging from '~/vue_merge_request_widget/components/states/mr_widget_merging.vue';
describe('MRWidgetMerging', () => {
- let vm;
- beforeEach(() => {
- const Component = Vue.extend(mergingComponent);
+ let wrapper;
- vm = mountComponent(Component, {
- mr: {
- targetBranchPath: '/branch-path',
- targetBranch: 'branch',
+ beforeEach(() => {
+ wrapper = shallowMount(MrWidgetMerging, {
+ propsData: {
+ mr: {
+ targetBranchPath: '/branch-path',
+ targetBranch: 'branch',
+ },
},
});
});
afterEach(() => {
- vm.$destroy();
+ wrapper.destroy();
});
it('renders information about merge request being merged', () => {
expect(
- vm.$el
- .querySelector('.media-body')
- .textContent.trim()
+ wrapper
+ .find('.media-body')
+ .text()
+ .trim()
.replace(/\s\s+/g, ' ')
.replace(/[\r\n]+/g, ' '),
).toContain('This merge request is in the process of being merged');
@@ -31,13 +32,14 @@ describe('MRWidgetMerging', () => {
it('renders branch information', () => {
expect(
- vm.$el
- .querySelector('.mr-info-list')
- .textContent.trim()
+ wrapper
+ .find('.mr-info-list')
+ .text()
+ .trim()
.replace(/\s\s+/g, ' ')
.replace(/[\r\n]+/g, ' '),
).toEqual('The changes will be merged into branch');
- expect(vm.$el.querySelector('a').getAttribute('href')).toEqual('/branch-path');
+ expect(wrapper.find('a').attributes('href')).toBe('/branch-path');
});
});
diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
index bd0bd36ebc2..2c04905d3a9 100644
--- a/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
+++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_nothing_to_merge_spec.js
@@ -14,20 +14,14 @@ describe('NothingToMerge', () => {
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
- expect(vm.$el.querySelector('a').href).toContain(newBlobPath);
- expect(vm.$el.innerText).toContain(
- "Currently there are no changes in this merge request's source branch",
- );
-
- expect(vm.$el.innerText.replace(/\s\s+/g, ' ')).toContain(
- 'Please push new commits or use a different branch.',
- );
+ expect(vm.$el.querySelector('[data-testid="createFileButton"]').href).toContain(newBlobPath);
+ expect(vm.$el.innerText).toContain('Use merge requests to propose changes to your project');
});
it('should not show new blob link if there is no link available', () => {
vm.mr.newBlobPath = null;
Vue.nextTick(() => {
- expect(vm.$el.querySelector('a')).toEqual(null);
+ expect(vm.$el.querySelector('[data-testid="createFileButton"]')).toEqual(null);
});
});
});
diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_list_spec.js b/spec/frontend/vue_mr_widget/deployment/deployment_list_spec.js
new file mode 100644
index 00000000000..dd0c483b28a
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/deployment/deployment_list_spec.js
@@ -0,0 +1,101 @@
+import { mount } from '@vue/test-utils';
+import { zip } from 'lodash';
+import { trimText } from 'helpers/text_helper';
+import Deployment from '~/vue_merge_request_widget/components/deployment/deployment.vue';
+import DeploymentList from '~/vue_merge_request_widget/components/deployment/deployment_list.vue';
+import MrCollapsibleExtension from '~/vue_merge_request_widget/components/mr_collapsible_extension.vue';
+import { mockStore } from '../mock_data';
+
+const DEFAULT_PROPS = {
+ showVisualReviewAppLink: false,
+ hasDeploymentMetrics: false,
+ deploymentClass: 'js-pre-deployment',
+};
+
+describe('~/vue_merge_request_widget/components/deployment/deployment_list.vue', () => {
+ let wrapper;
+ let propsData;
+
+ const factory = (props = {}) => {
+ propsData = {
+ ...DEFAULT_PROPS,
+ deployments: mockStore.deployments,
+ ...props,
+ };
+ wrapper = mount(DeploymentList, {
+ propsData,
+ });
+ };
+
+ afterEach(() => {
+ wrapper?.destroy?.();
+ wrapper = null;
+ });
+
+ describe('with few deployments', () => {
+ beforeEach(() => {
+ factory();
+ });
+
+ it('shows all deployments', () => {
+ const deploymentWrappers = wrapper.findAllComponents(Deployment);
+ expect(wrapper.findComponent(MrCollapsibleExtension).exists()).toBe(false);
+ expect(deploymentWrappers).toHaveLength(propsData.deployments.length);
+
+ zip(deploymentWrappers.wrappers, propsData.deployments).forEach(
+ ([deploymentWrapper, deployment]) => {
+ expect(deploymentWrapper.props('deployment')).toEqual(deployment);
+ expect(deploymentWrapper.props()).toMatchObject({
+ showVisualReviewApp: DEFAULT_PROPS.showVisualReviewAppLink,
+ showMetrics: DEFAULT_PROPS.hasDeploymentMetrics,
+ });
+ expect(deploymentWrapper.classes(DEFAULT_PROPS.deploymentClass)).toBe(true);
+ expect(deploymentWrapper.text()).toEqual(expect.any(String));
+ expect(deploymentWrapper.text()).not.toBe('');
+ },
+ );
+ });
+ });
+ describe('with many deployments', () => {
+ let deployments;
+ let collapsibleExtension;
+
+ beforeEach(() => {
+ deployments = [
+ ...mockStore.deployments,
+ ...mockStore.deployments.map((deployment) => ({
+ ...deployment,
+ id: deployment.id + mockStore.deployments.length,
+ })),
+ ];
+ factory({ deployments });
+
+ collapsibleExtension = wrapper.findComponent(MrCollapsibleExtension);
+ });
+
+ it('shows collapsed deployments', () => {
+ expect(collapsibleExtension.exists()).toBe(true);
+ expect(trimText(collapsibleExtension.text())).toBe(
+ `${deployments.length} environments impacted. View all environments.`,
+ );
+ });
+ it('shows all deployments on click', async () => {
+ await collapsibleExtension.find('button').trigger('click');
+ const deploymentWrappers = wrapper.findAllComponents(Deployment);
+ expect(deploymentWrappers).toHaveLength(deployments.length);
+
+ zip(deploymentWrappers.wrappers, propsData.deployments).forEach(
+ ([deploymentWrapper, deployment]) => {
+ expect(deploymentWrapper.props('deployment')).toEqual(deployment);
+ expect(deploymentWrapper.props()).toMatchObject({
+ showVisualReviewApp: DEFAULT_PROPS.showVisualReviewAppLink,
+ showMetrics: DEFAULT_PROPS.hasDeploymentMetrics,
+ });
+ expect(deploymentWrapper.classes(DEFAULT_PROPS.deploymentClass)).toBe(true);
+ expect(deploymentWrapper.text()).toEqual(expect.any(String));
+ expect(deploymentWrapper.text()).not.toBe('');
+ },
+ );
+ });
+ });
+});
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 7b020813bd5..c4962b608e1 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
@@ -91,18 +91,6 @@ describe('MrWidgetOptions', () => {
});
});
- describe('shouldRenderMergeHelp', () => {
- it('should return false for the initial merged state', () => {
- expect(wrapper.vm.shouldRenderMergeHelp).toBeFalsy();
- });
-
- it('should return true for a state which requires help widget', () => {
- wrapper.vm.mr.state = 'conflicts';
-
- expect(wrapper.vm.shouldRenderMergeHelp).toBeTruthy();
- });
- });
-
describe('shouldRenderPipelines', () => {
it('should return true when hasCI is true', () => {
wrapper.vm.mr.hasCI = true;