diff options
Diffstat (limited to 'spec/javascripts/pipelines')
-rw-r--r-- | spec/javascripts/pipelines/async_button_spec.js | 44 | ||||
-rw-r--r-- | spec/javascripts/pipelines/pipelines_actions_spec.js | 31 | ||||
-rw-r--r-- | spec/javascripts/pipelines/pipelines_table_row_spec.js | 161 | ||||
-rw-r--r-- | spec/javascripts/pipelines/pipelines_table_spec.js | 67 |
4 files changed, 233 insertions, 70 deletions
diff --git a/spec/javascripts/pipelines/async_button_spec.js b/spec/javascripts/pipelines/async_button_spec.js index 28c9c7ab282..48620898357 100644 --- a/spec/javascripts/pipelines/async_button_spec.js +++ b/spec/javascripts/pipelines/async_button_spec.js @@ -1,25 +1,20 @@ import Vue from 'vue'; import asyncButtonComp from '~/pipelines/components/async_button.vue'; +import eventHub from '~/pipelines/event_hub'; describe('Pipelines Async Button', () => { let component; - let spy; let AsyncButtonComponent; beforeEach(() => { AsyncButtonComponent = Vue.extend(asyncButtonComp); - spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); - component = new AsyncButtonComponent({ propsData: { endpoint: '/foo', title: 'Foo', icon: 'fa fa-foo', cssClass: 'bar', - service: { - postAction: spy, - }, }, }).$mount(); }); @@ -33,7 +28,7 @@ describe('Pipelines Async Button', () => { }); it('should render the provided title', () => { - expect(component.$el.getAttribute('title')).toContain('Foo'); + expect(component.$el.getAttribute('data-original-title')).toContain('Foo'); expect(component.$el.getAttribute('aria-label')).toContain('Foo'); }); @@ -41,37 +36,12 @@ describe('Pipelines Async Button', () => { expect(component.$el.getAttribute('class')).toContain('bar'); }); - it('should call the service when it is clicked with the provided endpoint', () => { - component.$el.click(); - expect(spy).toHaveBeenCalledWith('/foo'); - }); - - it('should hide loading if request fails', () => { - spy = jasmine.createSpy('spy').and.returnValue(Promise.reject()); - - component = new AsyncButtonComponent({ - propsData: { - endpoint: '/foo', - title: 'Foo', - icon: 'fa fa-foo', - cssClass: 'bar', - dataAttributes: { - 'data-foo': 'foo', - }, - service: { - postAction: spy, - }, - }, - }).$mount(); - - component.$el.click(); - expect(component.$el.querySelector('.fa-spinner')).toBe(null); - }); - describe('With confirm dialog', () => { it('should call the service when confimation is positive', () => { spyOn(window, 'confirm').and.returnValue(true); - spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); + eventHub.$on('postAction', (endpoint) => { + expect(endpoint).toEqual('/foo'); + }); component = new AsyncButtonComponent({ propsData: { @@ -79,15 +49,11 @@ describe('Pipelines Async Button', () => { title: 'Foo', icon: 'fa fa-foo', cssClass: 'bar', - service: { - postAction: spy, - }, confirmActionMessage: 'bar', }, }).$mount(); component.$el.click(); - expect(spy).toHaveBeenCalledWith('/foo'); }); }); }); diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js index 8a58b77f1e3..72fb0a8f9ef 100644 --- a/spec/javascripts/pipelines/pipelines_actions_spec.js +++ b/spec/javascripts/pipelines/pipelines_actions_spec.js @@ -3,7 +3,6 @@ import pipelinesActionsComp from '~/pipelines/components/pipelines_actions.vue'; describe('Pipelines Actions dropdown', () => { let component; - let spy; let actions; let ActionsComponent; @@ -22,14 +21,9 @@ describe('Pipelines Actions dropdown', () => { }, ]; - spy = jasmine.createSpy('spy').and.returnValue(Promise.resolve()); - component = new ActionsComponent({ propsData: { actions, - service: { - postAction: spy, - }, }, }).$mount(); }); @@ -40,31 +34,6 @@ describe('Pipelines Actions dropdown', () => { ).toEqual(actions.length); }); - it('should call the service when an action is clicked', () => { - component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click(); - component.$el.querySelector('.js-pipeline-action-link').click(); - - expect(spy).toHaveBeenCalledWith(actions[0].path); - }); - - it('should hide loading if request fails', () => { - spy = jasmine.createSpy('spy').and.returnValue(Promise.reject()); - - component = new ActionsComponent({ - propsData: { - actions, - service: { - postAction: spy, - }, - }, - }).$mount(); - - component.$el.querySelector('.js-pipeline-dropdown-manual-actions').click(); - component.$el.querySelector('.js-pipeline-action-link').click(); - - expect(component.$el.querySelector('.fa-spinner')).toEqual(null); - }); - it('should render a disabled action when it\'s not playable', () => { expect( component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'), diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js new file mode 100644 index 00000000000..7ce39dca112 --- /dev/null +++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js @@ -0,0 +1,161 @@ +import Vue from 'vue'; +import tableRowComp from '~/pipelines/components/pipelines_table_row.vue'; + +describe('Pipelines Table Row', () => { + const jsonFixtureName = 'pipelines/pipelines.json'; + const buildComponent = (pipeline) => { + const PipelinesTableRowComponent = Vue.extend(tableRowComp); + return new PipelinesTableRowComponent({ + el: document.querySelector('.test-dom-element'), + propsData: { + pipeline, + service: {}, + }, + }).$mount(); + }; + + let component; + let pipeline; + let pipelineWithoutAuthor; + let pipelineWithoutCommit; + + preloadFixtures(jsonFixtureName); + + beforeEach(() => { + const pipelines = getJSONFixture(jsonFixtureName).pipelines; + pipeline = pipelines.find(p => p.id === 1); + pipelineWithoutAuthor = pipelines.find(p => p.id === 2); + pipelineWithoutCommit = pipelines.find(p => p.id === 3); + }); + + afterEach(() => { + component.$destroy(); + }); + + it('should render a table row', () => { + component = buildComponent(pipeline); + expect(component.$el.getAttribute('class')).toContain('gl-responsive-table-row'); + }); + + describe('status column', () => { + beforeEach(() => { + component = buildComponent(pipeline); + }); + + it('should render a pipeline link', () => { + expect( + component.$el.querySelector('.table-section.commit-link a').getAttribute('href'), + ).toEqual(pipeline.path); + }); + + it('should render status text', () => { + expect( + component.$el.querySelector('.table-section.commit-link a').textContent, + ).toContain(pipeline.details.status.text); + }); + }); + + describe('information column', () => { + beforeEach(() => { + component = buildComponent(pipeline); + }); + + it('should render a pipeline link', () => { + expect( + component.$el.querySelector('.table-section:nth-child(2) a').getAttribute('href'), + ).toEqual(pipeline.path); + }); + + it('should render pipeline ID', () => { + expect( + component.$el.querySelector('.table-section:nth-child(2) a > span').textContent, + ).toEqual(`#${pipeline.id}`); + }); + + describe('when a user is provided', () => { + it('should render user information', () => { + expect( + component.$el.querySelector('.table-section:nth-child(2) a:nth-child(3)').getAttribute('href'), + ).toEqual(pipeline.user.path); + + expect( + component.$el.querySelector('.table-section:nth-child(2) img').getAttribute('data-original-title'), + ).toEqual(pipeline.user.name); + }); + }); + }); + + describe('commit column', () => { + it('should render link to commit', () => { + component = buildComponent(pipeline); + + const commitLink = component.$el.querySelector('.branch-commit .commit-sha'); + expect(commitLink.getAttribute('href')).toEqual(pipeline.commit.commit_path); + }); + + const findElements = () => { + const commitTitleElement = component.$el.querySelector('.branch-commit .commit-title'); + const commitAuthorElement = commitTitleElement.querySelector('a.avatar-image-container'); + + if (!commitAuthorElement) { + return { commitAuthorElement }; + } + + const commitAuthorLink = commitAuthorElement.getAttribute('href'); + const commitAuthorName = commitAuthorElement.querySelector('img.avatar').getAttribute('data-original-title'); + + return { commitAuthorElement, commitAuthorLink, commitAuthorName }; + }; + + it('renders nothing without commit', () => { + expect(pipelineWithoutCommit.commit).toBe(null); + component = buildComponent(pipelineWithoutCommit); + + const { commitAuthorElement } = findElements(); + + expect(commitAuthorElement).toBe(null); + }); + + it('renders commit author', () => { + component = buildComponent(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); + component = buildComponent(pipelineWithoutAuthor); + + const { commitAuthorLink, commitAuthorName } = findElements(); + + expect(commitAuthorLink).toEqual(`mailto:${pipelineWithoutAuthor.commit.author_email}`); + expect(commitAuthorName).toEqual(pipelineWithoutAuthor.commit.author_name); + }); + }); + + describe('stages column', () => { + beforeEach(() => { + component = buildComponent(pipeline); + }); + + it('should render an icon for each stage', () => { + expect( + component.$el.querySelectorAll('.table-section:nth-child(4) .js-builds-dropdown-button').length, + ).toEqual(pipeline.details.stages.length); + }); + }); + + describe('actions column', () => { + beforeEach(() => { + component = buildComponent(pipeline); + }); + + it('should render the provided actions', () => { + expect( + component.$el.querySelectorAll('.table-section:nth-child(6) ul li').length, + ).toEqual(pipeline.details.manual_actions.length); + }); + }); +}); diff --git a/spec/javascripts/pipelines/pipelines_table_spec.js b/spec/javascripts/pipelines/pipelines_table_spec.js new file mode 100644 index 00000000000..3afe89c8db4 --- /dev/null +++ b/spec/javascripts/pipelines/pipelines_table_spec.js @@ -0,0 +1,67 @@ +import Vue from 'vue'; +import pipelinesTableComp from '~/pipelines/components/pipelines_table.vue'; +import '~/lib/utils/datetime_utility'; + +describe('Pipelines Table', () => { + const jsonFixtureName = 'pipelines/pipelines.json'; + + let pipeline; + let PipelinesTableComponent; + + preloadFixtures(jsonFixtureName); + + beforeEach(() => { + PipelinesTableComponent = Vue.extend(pipelinesTableComp); + const pipelines = getJSONFixture(jsonFixtureName).pipelines; + pipeline = pipelines.find(p => p.id === 1); + }); + + describe('table', () => { + let component; + beforeEach(() => { + component = new PipelinesTableComponent({ + propsData: { + pipelines: [], + }, + }).$mount(); + }); + + afterEach(() => { + component.$destroy(); + }); + + it('should render a table', () => { + expect(component.$el.getAttribute('class')).toContain('ci-table'); + }); + + it('should render table head with correct columns', () => { + expect(component.$el.querySelector('.table-section.js-pipeline-status').textContent.trim()).toEqual('Status'); + expect(component.$el.querySelector('.table-section.js-pipeline-info').textContent.trim()).toEqual('Pipeline'); + expect(component.$el.querySelector('.table-section.js-pipeline-commit').textContent.trim()).toEqual('Commit'); + expect(component.$el.querySelector('.table-section.js-pipeline-stages').textContent.trim()).toEqual('Stages'); + }); + }); + + describe('without data', () => { + it('should render an empty table', () => { + const component = new PipelinesTableComponent({ + propsData: { + pipelines: [], + }, + }).$mount(); + expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(0); + }); + }); + + describe('with data', () => { + it('should render rows', () => { + const component = new PipelinesTableComponent({ + propsData: { + pipelines: [pipeline], + }, + }).$mount(); + + expect(component.$el.querySelectorAll('.commit.gl-responsive-table-row').length).toEqual(1); + }); + }); +}); |