summaryrefslogtreecommitdiff
path: root/spec/frontend
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-31 12:06:26 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-31 12:06:26 +0000
commit0be510a49f6e4f8e27b19b707fd1dac61571f78f (patch)
tree97ca0053d4fad66e900d25fdba61b2adb611efb0 /spec/frontend
parent6026bddcd51eca573c530240c421392045172b89 (diff)
downloadgitlab-ce-0be510a49f6e4f8e27b19b707fd1dac61571f78f.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/pipelines/graph/action_component_spec.js75
-rw-r--r--spec/frontend/pipelines/pipeline_triggerer_spec.js57
-rw-r--r--spec/frontend/pipelines/pipelines_table_row_spec.js228
3 files changed, 360 insertions, 0 deletions
diff --git a/spec/frontend/pipelines/graph/action_component_spec.js b/spec/frontend/pipelines/graph/action_component_spec.js
new file mode 100644
index 00000000000..38ffe98c79b
--- /dev/null
+++ b/spec/frontend/pipelines/graph/action_component_spec.js
@@ -0,0 +1,75 @@
+import { mount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import waitForPromises from 'helpers/wait_for_promises';
+import axios from '~/lib/utils/axios_utils';
+import ActionComponent from '~/pipelines/components/graph/action_component.vue';
+
+describe('pipeline graph action component', () => {
+ let wrapper;
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+
+ mock.onPost('foo.json').reply(200);
+
+ wrapper = mount(ActionComponent, {
+ propsData: {
+ tooltipText: 'bar',
+ link: 'foo',
+ actionIcon: 'cancel',
+ },
+ sync: false,
+ });
+ });
+
+ afterEach(() => {
+ mock.restore();
+ wrapper.destroy();
+ });
+
+ it('should render the provided title as a bootstrap tooltip', () => {
+ expect(wrapper.attributes('data-original-title')).toBe('bar');
+ });
+
+ it('should update bootstrap tooltip when title changes', done => {
+ wrapper.setProps({ tooltipText: 'changed' });
+
+ wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(wrapper.attributes('data-original-title')).toBe('changed');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('should render an svg', () => {
+ expect(wrapper.find('.ci-action-icon-wrapper')).toBeDefined();
+ expect(wrapper.find('svg')).toBeDefined();
+ });
+
+ describe('on click', () => {
+ it('emits `pipelineActionRequestComplete` after a successful request', done => {
+ jest.spyOn(wrapper.vm, '$emit');
+
+ wrapper.find('button').trigger('click');
+
+ waitForPromises()
+ .then(() => {
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('pipelineActionRequestComplete');
+ done();
+ })
+ .catch(done.fail);
+ });
+
+ it('renders a loading icon while waiting for request', done => {
+ wrapper.find('button').trigger('click');
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.js-action-icon-loading').exists()).toBe(true);
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/pipeline_triggerer_spec.js b/spec/frontend/pipelines/pipeline_triggerer_spec.js
new file mode 100644
index 00000000000..45ac278dd38
--- /dev/null
+++ b/spec/frontend/pipelines/pipeline_triggerer_spec.js
@@ -0,0 +1,57 @@
+import { mount } from '@vue/test-utils';
+import pipelineTriggerer from '~/pipelines/components/pipeline_triggerer.vue';
+
+describe('Pipelines Triggerer', () => {
+ let wrapper;
+
+ const mockData = {
+ pipeline: {
+ user: {
+ name: 'foo',
+ avatar_url: '/avatar',
+ path: '/path',
+ },
+ },
+ };
+
+ const createComponent = () => {
+ wrapper = mount(pipelineTriggerer, {
+ propsData: mockData,
+ sync: false,
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render a table cell', () => {
+ expect(wrapper.contains('.table-section')).toBe(true);
+ });
+
+ it('should render triggerer information when triggerer is provided', () => {
+ const link = wrapper.find('.js-pipeline-url-user');
+
+ expect(link.attributes('href')).toEqual(mockData.pipeline.user.path);
+ expect(link.find('.js-user-avatar-image-toolip').text()).toEqual(mockData.pipeline.user.name);
+ expect(link.find('img.avatar').attributes('src')).toEqual(
+ `${mockData.pipeline.user.avatar_url}?width=26`,
+ );
+ });
+
+ it('should render "API" when no triggerer is provided', () => {
+ wrapper.setProps({
+ pipeline: {
+ user: null,
+ },
+ });
+
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.js-pipeline-url-api').text()).toEqual('API');
+ });
+ });
+});
diff --git a/spec/frontend/pipelines/pipelines_table_row_spec.js b/spec/frontend/pipelines/pipelines_table_row_spec.js
new file mode 100644
index 00000000000..1c785ec6ffe
--- /dev/null
+++ b/spec/frontend/pipelines/pipelines_table_row_spec.js
@@ -0,0 +1,228 @@
+import { mount } from '@vue/test-utils';
+import PipelinesTableRowComponent from '~/pipelines/components/pipelines_table_row.vue';
+import eventHub from '~/pipelines/event_hub';
+
+describe('Pipelines Table Row', () => {
+ const jsonFixtureName = 'pipelines/pipelines.json';
+
+ const createWrapper = pipeline =>
+ mount(PipelinesTableRowComponent, {
+ propsData: {
+ pipeline,
+ autoDevopsHelpPath: 'foo',
+ viewType: 'root',
+ },
+ sync: false,
+ });
+
+ let wrapper;
+ let pipeline;
+ let pipelineWithoutAuthor;
+ let pipelineWithoutCommit;
+
+ preloadFixtures(jsonFixtureName);
+
+ beforeEach(() => {
+ const { pipelines } = getJSONFixture(jsonFixtureName);
+
+ pipeline = pipelines.find(p => p.user !== null && p.commit !== null);
+ pipelineWithoutAuthor = pipelines.find(p => p.user === null && p.commit !== null);
+ pipelineWithoutCommit = pipelines.find(p => p.user === null && p.commit === null);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('should render a table row', () => {
+ wrapper = createWrapper(pipeline);
+
+ expect(wrapper.attributes('class')).toContain('gl-responsive-table-row');
+ });
+
+ describe('status column', () => {
+ beforeEach(() => {
+ wrapper = createWrapper(pipeline);
+ });
+
+ it('should render a pipeline link', () => {
+ expect(wrapper.find('.table-section.commit-link a').attributes('href')).toEqual(
+ pipeline.path,
+ );
+ });
+
+ it('should render status text', () => {
+ expect(wrapper.find('.table-section.commit-link a').text()).toContain(
+ pipeline.details.status.text,
+ );
+ });
+ });
+
+ describe('information column', () => {
+ beforeEach(() => {
+ wrapper = createWrapper(pipeline);
+ });
+
+ it('should render a pipeline link', () => {
+ expect(wrapper.find('.table-section:nth-child(2) a').attributes('href')).toEqual(
+ pipeline.path,
+ );
+ });
+
+ it('should render pipeline ID', () => {
+ expect(wrapper.find('.table-section:nth-child(2) a > span').text()).toEqual(
+ `#${pipeline.id}`,
+ );
+ });
+
+ describe('when a user is provided', () => {
+ it('should render user information', () => {
+ expect(
+ wrapper.find('.table-section:nth-child(3) .js-pipeline-url-user').attributes('href'),
+ ).toEqual(pipeline.user.path);
+
+ expect(
+ wrapper
+ .find('.table-section:nth-child(3) .js-user-avatar-image-toolip')
+ .text()
+ .trim(),
+ ).toEqual(pipeline.user.name);
+ });
+ });
+ });
+
+ describe('commit column', () => {
+ it('should render link to commit', () => {
+ wrapper = createWrapper(pipeline);
+
+ const commitLink = wrapper.find('.branch-commit .commit-sha');
+
+ expect(commitLink.attributes('href')).toEqual(pipeline.commit.commit_path);
+ });
+
+ const findElements = () => {
+ const commitTitleElement = wrapper.find('.branch-commit .commit-title');
+ const commitAuthorElement = commitTitleElement.find('a.avatar-image-container');
+
+ if (!commitAuthorElement.exists()) {
+ return {
+ commitAuthorElement,
+ };
+ }
+
+ const commitAuthorLink = commitAuthorElement.attributes('href');
+ const commitAuthorName = commitAuthorElement
+ .find('.js-user-avatar-image-toolip')
+ .text()
+ .trim();
+
+ return {
+ commitAuthorElement,
+ commitAuthorLink,
+ commitAuthorName,
+ };
+ };
+
+ it('renders nothing without commit', () => {
+ expect(pipelineWithoutCommit.commit).toBe(null);
+
+ wrapper = createWrapper(pipelineWithoutCommit);
+ const { commitAuthorElement } = findElements();
+
+ expect(commitAuthorElement.exists()).toBe(false);
+ });
+
+ it('renders commit author', () => {
+ wrapper = createWrapper(pipeline);
+ const { commitAuthorLink, commitAuthorName } = findElements();
+
+ expect(commitAuthorLink).toEqual(pipeline.commit.author.path);
+ expect(commitAuthorName).toEqual(pipeline.commit.author.username);
+ });
+
+ it('renders commit with unregistered author', () => {
+ expect(pipelineWithoutAuthor.commit.author).toBe(null);
+
+ wrapper = createWrapper(pipelineWithoutAuthor);
+ const { commitAuthorLink, commitAuthorName } = findElements();
+
+ expect(commitAuthorLink).toEqual(`mailto:${pipelineWithoutAuthor.commit.author_email}`);
+ expect(commitAuthorName).toEqual(pipelineWithoutAuthor.commit.author_name);
+ });
+ });
+
+ describe('stages column', () => {
+ beforeEach(() => {
+ wrapper = createWrapper(pipeline);
+ });
+
+ it('should render an icon for each stage', () => {
+ expect(
+ wrapper.findAll('.table-section:nth-child(4) .js-builds-dropdown-button').length,
+ ).toEqual(pipeline.details.stages.length);
+ });
+ });
+
+ describe('actions column', () => {
+ const scheduledJobAction = {
+ name: 'some scheduled job',
+ };
+
+ beforeEach(() => {
+ const withActions = Object.assign({}, pipeline);
+ withActions.details.scheduled_actions = [scheduledJobAction];
+ withActions.flags.cancelable = true;
+ withActions.flags.retryable = true;
+ withActions.cancel_path = '/cancel';
+ withActions.retry_path = '/retry';
+
+ wrapper = createWrapper(withActions);
+ });
+
+ it('should render the provided actions', () => {
+ expect(wrapper.find('.js-pipelines-retry-button').exists()).toBe(true);
+ expect(wrapper.find('.js-pipelines-cancel-button').exists()).toBe(true);
+ const dropdownMenu = wrapper.find('.dropdown-menu');
+
+ expect(dropdownMenu.text()).toContain(scheduledJobAction.name);
+ });
+
+ it('emits `retryPipeline` event when retry button is clicked and toggles loading', () => {
+ eventHub.$on('retryPipeline', endpoint => {
+ expect(endpoint).toBe('/retry');
+ });
+
+ wrapper.find('.js-pipelines-retry-button').trigger('click');
+ expect(wrapper.vm.isRetrying).toBe(true);
+ });
+
+ it('emits `openConfirmationModal` event when cancel button is clicked and toggles loading', () => {
+ eventHub.$once('openConfirmationModal', data => {
+ const { id, ref, commit } = pipeline;
+
+ expect(data.endpoint).toBe('/cancel');
+ expect(data.pipeline).toEqual(
+ expect.objectContaining({
+ id,
+ ref,
+ commit,
+ }),
+ );
+ });
+
+ wrapper.find('.js-pipelines-cancel-button').trigger('click');
+ });
+
+ it('renders a loading icon when `cancelingPipeline` matches pipeline id', done => {
+ wrapper.setProps({ cancelingPipeline: pipeline.id });
+ wrapper.vm
+ .$nextTick()
+ .then(() => {
+ expect(wrapper.vm.isCancelling).toBe(true);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});