diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2017-05-06 20:02:06 +0300 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2017-05-06 20:04:48 +0300 |
commit | aa440eb1c0947d2dc551c61abbd9d271b9002050 (patch) | |
tree | 907f60233034d904edd1b5d8ea4c9d6df9278ec5 /spec/javascripts/pipelines | |
parent | c17e6a6c68b0412b3433632802b852db474a7b30 (diff) |
Single commit squash of all changes for https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/10878
It's needed due to https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/10777 being merged with squash.
Diffstat (limited to 'spec/javascripts/pipelines')
6 files changed, 339 insertions, 0 deletions
diff --git a/spec/javascripts/pipelines/graph/action_component_spec.js b/spec/javascripts/pipelines/graph/action_component_spec.js new file mode 100644 index 00000000000..f033956c071 --- /dev/null +++ b/spec/javascripts/pipelines/graph/action_component_spec.js @@ -0,0 +1,40 @@ +import Vue from 'vue'; +import actionComponent from '~/pipelines/components/graph/action_component.vue'; + +describe('pipeline graph action component', () => { + let component; + + beforeEach(() => { + const ActionComponent = Vue.extend(actionComponent); + component = new ActionComponent({ + propsData: { + tooltipText: 'bar', + link: 'foo', + actionMethod: 'post', + actionIcon: 'icon_action_cancel', + }, + }).$mount(); + }); + + it('should render a link', () => { + expect(component.$el.getAttribute('href')).toEqual('foo'); + }); + + it('should render the provided title as a bootstrap tooltip', () => { + expect(component.$el.getAttribute('data-original-title')).toEqual('bar'); + }); + + it('should update bootstrap tooltip when title changes', (done) => { + component.tooltipText = 'changed'; + + Vue.nextTick(() => { + expect(component.$el.getAttribute('data-original-title')).toBe('changed'); + done(); + }); + }); + + it('should render an svg', () => { + expect(component.$el.querySelector('.ci-action-icon-wrapper')).toBeDefined(); + expect(component.$el.querySelector('svg')).toBeDefined(); + }); +}); diff --git a/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js b/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js new file mode 100644 index 00000000000..14ff1b0d25c --- /dev/null +++ b/spec/javascripts/pipelines/graph/dropdown_action_component_spec.js @@ -0,0 +1,30 @@ +import Vue from 'vue'; +import dropdownActionComponent from '~/pipelines/components/graph/dropdown_action_component.vue'; + +describe('action component', () => { + let component; + + beforeEach(() => { + const DropdownActionComponent = Vue.extend(dropdownActionComponent); + component = new DropdownActionComponent({ + propsData: { + tooltipText: 'bar', + link: 'foo', + actionMethod: 'post', + actionIcon: 'icon_action_cancel', + }, + }).$mount(); + }); + + it('should render a link', () => { + expect(component.$el.getAttribute('href')).toEqual('foo'); + }); + + it('should render the provided title as a bootstrap tooltip', () => { + expect(component.$el.getAttribute('data-original-title')).toEqual('bar'); + }); + + it('should render an svg', () => { + expect(component.$el.querySelector('svg')).toBeDefined(); + }); +}); diff --git a/spec/javascripts/pipelines/graph/graph_component_spec.js b/spec/javascripts/pipelines/graph/graph_component_spec.js new file mode 100644 index 00000000000..a756617e65e --- /dev/null +++ b/spec/javascripts/pipelines/graph/graph_component_spec.js @@ -0,0 +1,83 @@ +import Vue from 'vue'; +import graphComponent from '~/pipelines/components/graph/graph_component.vue'; + +describe('graph component', () => { + preloadFixtures('static/graph.html.raw'); + + let GraphComponent; + + beforeEach(() => { + loadFixtures('static/graph.html.raw'); + GraphComponent = Vue.extend(graphComponent); + }); + + describe('while is loading', () => { + it('should render a loading icon', () => { + const component = new GraphComponent().$mount('#js-pipeline-graph-vue'); + expect(component.$el.querySelector('.loading-icon')).toBeDefined(); + }); + }); + + describe('with a successfull response', () => { + const interceptor = (request, next) => { + next(request.respondWith(JSON.stringify({ + details: { + stages: [{ + name: 'test', + title: 'test: passed', + status: { + icon: 'icon_status_success', + text: 'passed', + label: 'passed', + details_path: '/root/ci-mock/pipelines/123#test', + }, + path: '/root/ci-mock/pipelines/123#test', + groups: [{ + name: 'test', + size: 1, + jobs: [{ + id: 4153, + name: 'test', + status: { + icon: 'icon_status_success', + text: 'passed', + label: 'passed', + details_path: '/root/ci-mock/builds/4153', + action: { + icon: 'icon_action_retry', + title: 'Retry', + path: '/root/ci-mock/builds/4153/retry', + method: 'post', + }, + }, + }], + }], + }], + }, + }), { + status: 200, + })); + }; + + beforeEach(() => { + Vue.http.interceptors.push(interceptor); + }); + + afterEach(() => { + Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor); + }); + + it('should render the graph', (done) => { + const component = new GraphComponent().$mount('#js-pipeline-graph-vue'); + + setTimeout(() => { + expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true); + + expect(component.$el.querySelector('loading-icon')).toBe(null); + + expect(component.$el.querySelector('.stage-column-list')).toBeDefined(); + done(); + }, 0); + }); + }); +}); diff --git a/spec/javascripts/pipelines/graph/job_component_spec.js b/spec/javascripts/pipelines/graph/job_component_spec.js new file mode 100644 index 00000000000..63986b6c0db --- /dev/null +++ b/spec/javascripts/pipelines/graph/job_component_spec.js @@ -0,0 +1,117 @@ +import Vue from 'vue'; +import jobComponent from '~/pipelines/components/graph/job_component.vue'; + +describe('pipeline graph job component', () => { + let JobComponent; + + const mockJob = { + id: 4256, + name: 'test', + status: { + icon: 'icon_status_success', + text: 'passed', + label: 'passed', + group: 'success', + details_path: '/root/ci-mock/builds/4256', + action: { + icon: 'icon_action_retry', + title: 'Retry', + path: '/root/ci-mock/builds/4256/retry', + method: 'post', + }, + }, + }; + + beforeEach(() => { + JobComponent = Vue.extend(jobComponent); + }); + + describe('name with link', () => { + it('should render the job name and status with a link', () => { + const component = new JobComponent({ + propsData: { + job: mockJob, + }, + }).$mount(); + + const link = component.$el.querySelector('a'); + + expect(link.getAttribute('href')).toEqual(mockJob.status.details_path); + + expect( + link.getAttribute('data-original-title'), + ).toEqual(`${mockJob.name} - ${mockJob.status.label}`); + + expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined(); + + expect( + component.$el.querySelector('.ci-status-text').textContent.trim(), + ).toEqual(mockJob.name); + }); + }); + + describe('name without link', () => { + it('it should render status and name', () => { + const component = new JobComponent({ + propsData: { + job: { + id: 4256, + name: 'test', + status: { + icon: 'icon_status_success', + text: 'passed', + label: 'passed', + group: 'success', + details_path: '/root/ci-mock/builds/4256', + }, + }, + }, + }).$mount(); + + expect(component.$el.querySelector('.js-status-icon-success')).toBeDefined(); + + expect( + component.$el.querySelector('.ci-status-text').textContent.trim(), + ).toEqual(mockJob.name); + }); + }); + + describe('action icon', () => { + it('it should render the action icon', () => { + const component = new JobComponent({ + propsData: { + job: mockJob, + }, + }).$mount(); + + expect(component.$el.querySelector('a.ci-action-icon-container')).toBeDefined(); + expect(component.$el.querySelector('i.ci-action-icon-wrapper')).toBeDefined(); + }); + }); + + describe('dropdown', () => { + it('should render the dropdown action icon', () => { + const component = new JobComponent({ + propsData: { + job: mockJob, + isDropdown: true, + }, + }).$mount(); + + expect(component.$el.querySelector('a.ci-action-icon-wrapper')).toBeDefined(); + }); + }); + + it('should render provided class name', () => { + const component = new JobComponent({ + propsData: { + job: mockJob, + cssClassJobName: 'css-class-job-name', + }, + }).$mount(); + + expect( + component.$el.querySelector('a').classList.contains('css-class-job-name'), + ).toBe(true); + }); +}); diff --git a/spec/javascripts/pipelines/graph/job_name_component_spec.js b/spec/javascripts/pipelines/graph/job_name_component_spec.js new file mode 100644 index 00000000000..8e2071ba0b3 --- /dev/null +++ b/spec/javascripts/pipelines/graph/job_name_component_spec.js @@ -0,0 +1,27 @@ +import Vue from 'vue'; +import jobNameComponent from '~/pipelines/components/graph/job_name_component.vue'; + +describe('job name component', () => { + let component; + + beforeEach(() => { + const JobNameComponent = Vue.extend(jobNameComponent); + component = new JobNameComponent({ + propsData: { + name: 'foo', + status: { + icon: 'icon_status_success', + }, + }, + }).$mount(); + }); + + it('should render the provided name', () => { + expect(component.$el.querySelector('.ci-status-text').textContent.trim()).toEqual('foo'); + }); + + it('should render an icon with the provided status', () => { + expect(component.$el.querySelector('.ci-status-icon-success')).toBeDefined(); + expect(component.$el.querySelector('.ci-status-icon-success svg')).toBeDefined(); + }); +}); diff --git a/spec/javascripts/pipelines/graph/stage_column_component_spec.js b/spec/javascripts/pipelines/graph/stage_column_component_spec.js new file mode 100644 index 00000000000..aa4d6eedaf4 --- /dev/null +++ b/spec/javascripts/pipelines/graph/stage_column_component_spec.js @@ -0,0 +1,42 @@ +import Vue from 'vue'; +import stageColumnComponent from '~/pipelines/components/graph/stage_column_component.vue'; + +describe('stage column component', () => { + let component; + const mockJob = { + id: 4256, + name: 'test', + status: { + icon: 'icon_status_success', + text: 'passed', + label: 'passed', + group: 'success', + details_path: '/root/ci-mock/builds/4256', + action: { + icon: 'icon_action_retry', + title: 'Retry', + path: '/root/ci-mock/builds/4256/retry', + method: 'post', + }, + }, + }; + + beforeEach(() => { + const StageColumnComponent = Vue.extend(stageColumnComponent); + + component = new StageColumnComponent({ + propsData: { + title: 'foo', + jobs: [mockJob, mockJob, mockJob], + }, + }).$mount(); + }); + + it('should render provided title', () => { + expect(component.$el.querySelector('.stage-name').textContent.trim()).toEqual('foo'); + }); + + it('should render the provided jobs', () => { + expect(component.$el.querySelectorAll('.builds-container > ul > li').length).toEqual(3); + }); +}); |