diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-21 18:21:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-21 18:21:10 +0300 |
commit | e33f87ac0fabaab468ce4b457996cc0f1b1bb648 (patch) | |
tree | 8bf0de72a9acac014cfdaddab7d463b208294af2 /spec/javascripts | |
parent | 5baf990db20a75078684702782c24399ef9eb0fa (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
9 files changed, 38 insertions, 816 deletions
diff --git a/spec/javascripts/pipelines/graph/graph_component_spec.js b/spec/javascripts/pipelines/graph/graph_component_spec.js deleted file mode 100644 index d2c10362ba3..00000000000 --- a/spec/javascripts/pipelines/graph/graph_component_spec.js +++ /dev/null @@ -1,274 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import PipelineStore from '~/pipelines/stores/pipeline_store'; -import graphComponent from '~/pipelines/components/graph/graph_component.vue'; -import graphJSON from './mock_data'; -import linkedPipelineJSON from '../linked_pipelines_mock.json'; -import PipelinesMediator from '~/pipelines/pipeline_details_mediator'; - -describe('graph component', () => { - const GraphComponent = Vue.extend(graphComponent); - const store = new PipelineStore(); - store.storePipeline(linkedPipelineJSON); - const mediator = new PipelinesMediator({ endpoint: '' }); - - let component; - - beforeEach(() => { - setFixtures(` - <div class="layout-page"></div> - `); - }); - - afterEach(() => { - component.$destroy(); - }); - - describe('while is loading', () => { - it('should render a loading icon', () => { - component = mountComponent(GraphComponent, { - isLoading: true, - pipeline: {}, - mediator, - }); - - expect(component.$el.querySelector('.loading-icon')).toBeDefined(); - }); - }); - - describe('with data', () => { - it('should render the graph', () => { - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: graphJSON, - mediator, - }); - - expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true); - - expect( - component.$el.querySelector('.stage-column:first-child').classList.contains('no-margin'), - ).toEqual(true); - - expect( - component.$el.querySelector('.stage-column:nth-child(2)').classList.contains('left-margin'), - ).toEqual(true); - - expect( - component.$el - .querySelector('.stage-column:nth-child(2) .build:nth-child(1)') - .classList.contains('left-connector'), - ).toEqual(true); - - expect(component.$el.querySelector('loading-icon')).toBe(null); - - expect(component.$el.querySelector('.stage-column-list')).toBeDefined(); - }); - }); - - describe('when linked pipelines are present', () => { - beforeEach(() => { - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: store.state.pipeline, - mediator, - }); - }); - - describe('rendered output', () => { - it('should include the pipelines graph', () => { - expect(component.$el.classList.contains('js-pipeline-graph')).toEqual(true); - }); - - it('should not include the loading icon', () => { - expect(component.$el.querySelector('.fa-spinner')).toBeNull(); - }); - - it('should include the stage column list', () => { - expect(component.$el.querySelector('.stage-column-list')).not.toBeNull(); - }); - - it('should include the no-margin class on the first child', () => { - const firstStageColumnElement = component.$el.querySelector( - '.stage-column-list .stage-column', - ); - - expect(firstStageColumnElement.classList.contains('no-margin')).toEqual(true); - }); - - it('should include the has-only-one-job class on the first child', () => { - const firstStageColumnElement = component.$el.querySelector( - '.stage-column-list .stage-column', - ); - - expect(firstStageColumnElement.classList.contains('has-only-one-job')).toEqual(true); - }); - - it('should include the left-margin class on the second child', () => { - const firstStageColumnElement = component.$el.querySelector( - '.stage-column-list .stage-column:last-child', - ); - - expect(firstStageColumnElement.classList.contains('left-margin')).toEqual(true); - }); - - it('should include the js-has-linked-pipelines flag', () => { - expect(component.$el.querySelector('.js-has-linked-pipelines')).not.toBeNull(); - }); - }); - - describe('computeds and methods', () => { - describe('capitalizeStageName', () => { - it('it capitalizes the stage name', () => { - expect(component.capitalizeStageName('mystage')).toBe('Mystage'); - }); - }); - - describe('stageConnectorClass', () => { - it('it returns left-margin when there is a triggerer', () => { - expect(component.stageConnectorClass(0, { groups: ['job'] })).toBe('no-margin'); - }); - }); - }); - - describe('linked pipelines components', () => { - beforeEach(() => { - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: store.state.pipeline, - mediator, - }); - }); - - it('should render an upstream pipelines column', () => { - expect(component.$el.querySelector('.linked-pipelines-column')).not.toBeNull(); - expect(component.$el.innerHTML).toContain('Upstream'); - }); - - it('should render a downstream pipelines column', () => { - expect(component.$el.querySelector('.linked-pipelines-column')).not.toBeNull(); - expect(component.$el.innerHTML).toContain('Downstream'); - }); - - describe('triggered by', () => { - describe('on click', () => { - it('should emit `onClickTriggeredBy` when triggered by linked pipeline is clicked', () => { - spyOn(component, '$emit'); - - component.$el.querySelector('#js-linked-pipeline-12').click(); - - expect(component.$emit).toHaveBeenCalledWith( - 'onClickTriggeredBy', - component.pipeline.triggered_by[0], - ); - }); - }); - - describe('with expanded pipeline', () => { - it('should render expanded pipeline', done => { - // expand the pipeline - store.state.pipeline.triggered_by[0].isExpanded = true; - - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: store.state.pipeline, - mediator, - }); - - Vue.nextTick() - .then(() => { - expect(component.$el.querySelector('.js-upstream-pipeline-12')).not.toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - }); - }); - - describe('triggered', () => { - describe('on click', () => { - it('should emit `onClickTriggered`', () => { - spyOn(component, '$emit'); - spyOn(component, 'calculateMarginTop').and.callFake(() => '16px'); - - component.$el.querySelector('#js-linked-pipeline-34993051').click(); - - expect(component.$emit).toHaveBeenCalledWith( - 'onClickTriggered', - component.pipeline.triggered[0], - ); - }); - }); - - describe('with expanded pipeline', () => { - it('should render expanded pipeline', done => { - // expand the pipeline - store.state.pipeline.triggered[0].isExpanded = true; - - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: store.state.pipeline, - mediator, - }); - - Vue.nextTick() - .then(() => { - expect( - component.$el.querySelector('.js-downstream-pipeline-34993051'), - ).not.toBeNull(); - }) - .then(done) - .catch(done.fail); - }); - }); - }); - }); - }); - - describe('when linked pipelines are not present', () => { - beforeEach(() => { - const pipeline = Object.assign(linkedPipelineJSON, { triggered: null, triggered_by: null }); - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline, - mediator, - }); - }); - - describe('rendered output', () => { - it('should include the first column with a no margin', () => { - const firstColumn = component.$el.querySelector('.stage-column:first-child'); - - expect(firstColumn.classList.contains('no-margin')).toEqual(true); - }); - - it('should not render a linked pipelines column', () => { - expect(component.$el.querySelector('.linked-pipelines-column')).toBeNull(); - }); - }); - - describe('stageConnectorClass', () => { - it('it returns left-margin when no triggerer and there is one job', () => { - expect(component.stageConnectorClass(0, { groups: ['job'] })).toBe('no-margin'); - }); - - it('it returns left-margin when no triggerer and not the first stage', () => { - expect(component.stageConnectorClass(99, { groups: ['job'] })).toBe('left-margin'); - }); - }); - }); - - describe('capitalizeStageName', () => { - it('capitalizes and escapes stage name', () => { - component = mountComponent(GraphComponent, { - isLoading: false, - pipeline: graphJSON, - mediator, - }); - - expect( - component.$el.querySelector('.stage-column:nth-child(2) .stage-name').textContent.trim(), - ).toEqual('Deploy <img src=x onerror=alert(document.domain)>'); - }); - }); -}); diff --git a/spec/javascripts/pipelines/graph/job_group_dropdown_spec.js b/spec/javascripts/pipelines/graph/job_group_dropdown_spec.js deleted file mode 100644 index a3957f94caa..00000000000 --- a/spec/javascripts/pipelines/graph/job_group_dropdown_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import JobGroupDropdown from '~/pipelines/components/graph/job_group_dropdown.vue'; - -describe('job group dropdown component', () => { - const Component = Vue.extend(JobGroupDropdown); - let vm; - - const group = { - jobs: [ - { - id: 4256, - name: '<img src=x onerror=alert(document.domain)>', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - tooltip: 'passed', - group: 'success', - details_path: '/root/ci-mock/builds/4256', - has_details: true, - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4256/retry', - method: 'post', - }, - }, - }, - { - id: 4299, - name: 'test', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - tooltip: 'passed', - group: 'success', - details_path: '/root/ci-mock/builds/4299', - has_details: true, - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4299/retry', - method: 'post', - }, - }, - }, - ], - name: 'rspec:linux', - size: 2, - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - tooltip: 'passed', - group: 'success', - details_path: '/root/ci-mock/builds/4256', - has_details: true, - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4256/retry', - method: 'post', - }, - }, - }; - - afterEach(() => { - vm.$destroy(); - }); - - beforeEach(() => { - vm = mountComponent(Component, { group }); - }); - - it('renders button with group name and size', () => { - expect(vm.$el.querySelector('button').textContent).toContain(group.name); - expect(vm.$el.querySelector('button').textContent).toContain(group.size); - }); - - it('renders dropdown with jobs', () => { - expect(vm.$el.querySelectorAll('.scrollable-menu>ul>li').length).toEqual(group.jobs.length); - }); -}); diff --git a/spec/javascripts/pipelines/graph/job_name_component_spec.js b/spec/javascripts/pipelines/graph/job_name_component_spec.js deleted file mode 100644 index c861d452dd0..00000000000 --- a/spec/javascripts/pipelines/graph/job_name_component_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -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: '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/linked_pipelines_column_spec.js b/spec/javascripts/pipelines/graph/linked_pipelines_column_spec.js deleted file mode 100644 index 613ab2a906f..00000000000 --- a/spec/javascripts/pipelines/graph/linked_pipelines_column_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import LinkedPipelinesColumn from '~/pipelines/components/graph/linked_pipelines_column.vue'; -import mockData from './linked_pipelines_mock_data'; - -describe('Linked Pipelines Column', () => { - const Component = Vue.extend(LinkedPipelinesColumn); - const props = { - columnTitle: 'Upstream', - linkedPipelines: mockData.triggered, - graphPosition: 'right', - projectId: 19, - }; - let vm; - - beforeEach(() => { - vm = mountComponent(Component, props); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders the pipeline orientation', () => { - const titleElement = vm.$el.querySelector('.linked-pipelines-column-title'); - - expect(titleElement.innerText).toContain(props.columnTitle); - }); - - it('has the correct number of linked pipeline child components', () => { - expect(vm.$children.length).toBe(props.linkedPipelines.length); - }); - - it('renders the correct number of linked pipelines', () => { - const linkedPipelineElements = vm.$el.querySelectorAll('.linked-pipeline'); - - expect(linkedPipelineElements.length).toBe(props.linkedPipelines.length); - }); - - it('renders cross project triangle when column is upstream', () => { - expect(vm.$el.querySelector('.cross-project-triangle')).toBeDefined(); - }); -}); diff --git a/spec/javascripts/pipelines/graph/linked_pipelines_mock_data.js b/spec/javascripts/pipelines/graph/linked_pipelines_mock_data.js deleted file mode 100644 index 3079d5e4e68..00000000000 --- a/spec/javascripts/pipelines/graph/linked_pipelines_mock_data.js +++ /dev/null @@ -1,3 +0,0 @@ -import mockData from '../../../frontend/pipelines/graph/linked_pipelines_mock_data'; - -export default mockData; diff --git a/spec/javascripts/pipelines/graph/mock_data.js b/spec/javascripts/pipelines/graph/mock_data.js deleted file mode 100644 index a4a5d78f906..00000000000 --- a/spec/javascripts/pipelines/graph/mock_data.js +++ /dev/null @@ -1,261 +0,0 @@ -export default { - id: 123, - user: { - name: 'Root', - username: 'root', - id: 1, - state: 'active', - avatar_url: null, - web_url: 'http://localhost:3000/root', - }, - active: false, - coverage: null, - path: '/root/ci-mock/pipelines/123', - details: { - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/pipelines/123', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - }, - duration: 9, - finished_at: '2017-04-19T14:30:27.542Z', - stages: [ - { - name: 'test', - title: 'test: passed', - groups: [ - { - name: 'test', - size: 1, - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4153', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4153/retry', - method: 'post', - }, - }, - jobs: [ - { - id: 4153, - name: 'test', - build_path: '/root/ci-mock/builds/4153', - retry_path: '/root/ci-mock/builds/4153/retry', - playable: false, - created_at: '2017-04-13T09:25:18.959Z', - updated_at: '2017-04-13T09:25:23.118Z', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4153', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4153/retry', - method: 'post', - }, - }, - }, - ], - }, - ], - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/pipelines/123#test', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - }, - path: '/root/ci-mock/pipelines/123#test', - dropdown_path: '/root/ci-mock/pipelines/123/stage.json?stage=test', - }, - { - name: 'deploy <img src=x onerror=alert(document.domain)>', - title: 'deploy: passed', - groups: [ - { - name: 'deploy to production', - size: 1, - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4166', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4166/retry', - method: 'post', - }, - }, - jobs: [ - { - id: 4166, - name: 'deploy to production', - build_path: '/root/ci-mock/builds/4166', - retry_path: '/root/ci-mock/builds/4166/retry', - playable: false, - created_at: '2017-04-19T14:29:46.463Z', - updated_at: '2017-04-19T14:30:27.498Z', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4166', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4166/retry', - method: 'post', - }, - }, - }, - ], - }, - { - name: 'deploy to staging', - size: 1, - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4159', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4159/retry', - method: 'post', - }, - }, - jobs: [ - { - id: 4159, - name: 'deploy to staging', - build_path: '/root/ci-mock/builds/4159', - retry_path: '/root/ci-mock/builds/4159/retry', - playable: false, - created_at: '2017-04-18T16:32:08.420Z', - updated_at: '2017-04-18T16:32:12.631Z', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/builds/4159', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4159/retry', - method: 'post', - }, - }, - }, - ], - }, - ], - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - has_details: true, - details_path: '/root/ci-mock/pipelines/123#deploy', - favicon: - '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png', - }, - path: '/root/ci-mock/pipelines/123#deploy', - dropdown_path: '/root/ci-mock/pipelines/123/stage.json?stage=deploy', - }, - ], - artifacts: [], - manual_actions: [ - { - name: 'deploy to production', - path: '/root/ci-mock/builds/4166/play', - playable: false, - }, - ], - }, - flags: { - latest: true, - triggered: false, - stuck: false, - yaml_errors: false, - retryable: false, - cancelable: false, - }, - ref: { - name: 'master', - path: '/root/ci-mock/tree/master', - tag: false, - branch: true, - }, - commit: { - id: '798e5f902592192afaba73f4668ae30e56eae492', - short_id: '798e5f90', - title: "Merge branch 'new-branch' into 'master'\r", - created_at: '2017-04-13T10:25:17.000+01:00', - parent_ids: [ - '54d483b1ed156fbbf618886ddf7ab023e24f8738', - 'c8e2d38a6c538822e81c57022a6e3a0cfedebbcc', - ], - message: - "Merge branch 'new-branch' into 'master'\r\n\r\nAdd new file\r\n\r\nSee merge request !1", - author_name: 'Root', - author_email: 'admin@example.com', - authored_date: '2017-04-13T10:25:17.000+01:00', - committer_name: 'Root', - committer_email: 'admin@example.com', - committed_date: '2017-04-13T10:25:17.000+01:00', - author: { - name: 'Root', - username: 'root', - id: 1, - state: 'active', - avatar_url: null, - web_url: 'http://localhost:3000/root', - }, - author_gravatar_url: null, - commit_url: - 'http://localhost:3000/root/ci-mock/commit/798e5f902592192afaba73f4668ae30e56eae492', - commit_path: '/root/ci-mock/commit/798e5f902592192afaba73f4668ae30e56eae492', - }, - created_at: '2017-04-13T09:25:18.881Z', - updated_at: '2017-04-19T14:30:27.561Z', -}; diff --git a/spec/javascripts/pipelines/graph/stage_column_component_spec.js b/spec/javascripts/pipelines/graph/stage_column_component_spec.js deleted file mode 100644 index dbfeeae43fe..00000000000 --- a/spec/javascripts/pipelines/graph/stage_column_component_spec.js +++ /dev/null @@ -1,122 +0,0 @@ -import Vue from 'vue'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; -import stageColumnComponent from '~/pipelines/components/graph/stage_column_component.vue'; - -describe('stage column component', () => { - let component; - const StageColumnComponent = Vue.extend(stageColumnComponent); - - const mockJob = { - id: 4250, - name: 'test', - status: { - icon: 'status_success', - text: 'passed', - label: 'passed', - group: 'success', - details_path: '/root/ci-mock/builds/4250', - action: { - icon: 'retry', - title: 'Retry', - path: '/root/ci-mock/builds/4250/retry', - method: 'post', - }, - }, - }; - - beforeEach(() => { - const mockGroups = []; - for (let i = 0; i < 3; i += 1) { - const mockedJob = Object.assign({}, mockJob); - mockedJob.id += i; - mockGroups.push(mockedJob); - } - - component = mountComponent(StageColumnComponent, { - title: 'foo', - groups: mockGroups, - hasTriggeredBy: false, - }); - }); - - it('should render provided title', () => { - expect(component.$el.querySelector('.stage-name').textContent.trim()).toEqual('foo'); - }); - - it('should render the provided groups', () => { - expect(component.$el.querySelectorAll('.builds-container > ul > li').length).toEqual(3); - }); - - describe('jobId', () => { - it('escapes job name', () => { - component = mountComponent(StageColumnComponent, { - groups: [ - { - id: 4259, - name: '<img src=x onerror=alert(document.domain)>', - status: { - icon: 'status_success', - label: 'success', - tooltip: '<img src=x onerror=alert(document.domain)>', - }, - }, - ], - title: 'test', - hasTriggeredBy: false, - }); - - expect(component.$el.querySelector('.builds-container li').getAttribute('id')).toEqual( - 'ci-badge-<img src=x onerror=alert(document.domain)>', - ); - }); - }); - - describe('with action', () => { - it('renders action button', () => { - component = mountComponent(StageColumnComponent, { - groups: [ - { - id: 4259, - name: '<img src=x onerror=alert(document.domain)>', - status: { - icon: 'status_success', - label: 'success', - tooltip: '<img src=x onerror=alert(document.domain)>', - }, - }, - ], - title: 'test', - hasTriggeredBy: false, - action: { - icon: 'play', - title: 'Play all', - path: 'action', - }, - }); - - expect(component.$el.querySelector('.js-stage-action')).not.toBeNull(); - }); - }); - - describe('without action', () => { - it('does not render action button', () => { - component = mountComponent(StageColumnComponent, { - groups: [ - { - id: 4259, - name: '<img src=x onerror=alert(document.domain)>', - status: { - icon: 'status_success', - label: 'success', - tooltip: '<img src=x onerror=alert(document.domain)>', - }, - }, - ], - title: 'test', - hasTriggeredBy: false, - }); - - expect(component.$el.querySelector('.js-stage-action')).toBeNull(); - }); - }); -}); diff --git a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js index bafc47c952a..9d7150d95cd 100644 --- a/spec/javascripts/reports/components/grouped_test_reports_app_spec.js +++ b/spec/javascripts/reports/components/grouped_test_reports_app_spec.js @@ -4,6 +4,7 @@ import axios from '~/lib/utils/axios_utils'; import state from '~/reports/store/state'; import component from '~/reports/components/grouped_test_reports_app.vue'; import mountComponent from '../../helpers/vue_mount_component_helper'; +import { failedReport } from '../mock_data/mock_data'; import newFailedTestReports from '../mock_data/new_failures_report.json'; import newErrorsTestReports from '../mock_data/new_errors_report.json'; import successTestReports from '../mock_data/no_failures_report.json'; @@ -199,6 +200,26 @@ describe('Grouped Test Reports App', () => { }); }); + describe('with a report that failed to load', () => { + beforeEach(() => { + mock.onGet('test_results.json').reply(200, failedReport, {}); + vm = mountComponent(Component, { + endpoint: 'test_results.json', + }); + }); + + it('renders an error status for the report', done => { + setTimeout(() => { + const { name } = failedReport.suites[0]; + + expect(vm.$el.querySelector('.report-block-list-issue').textContent).toContain( + `An error occurred while loading ${name} results`, + ); + done(); + }); + }); + }); + describe('with error', () => { beforeEach(() => { mock.onGet('test_results.json').reply(500, {}, {}); diff --git a/spec/javascripts/reports/mock_data/mock_data.js b/spec/javascripts/reports/mock_data/mock_data.js index 0d90253bad2..3caaab2fd79 100644 --- a/spec/javascripts/reports/mock_data/mock_data.js +++ b/spec/javascripts/reports/mock_data/mock_data.js @@ -1,4 +1,3 @@ -// eslint-disable-next-line import/prefer-default-export export const issue = { result: 'failure', name: 'Test#sum when a is 1 and b is 2 returns summary', @@ -6,3 +5,20 @@ export const issue = { system_output: "Failure/Error: is_expected.to eq(3)\n\n expected: 3\n got: -1\n\n (compared using ==)\n./spec/test_spec.rb:12:in `block (4 levels) in \u003ctop (required)\u003e'", }; + +export const failedReport = { + summary: { total: 11, resolved: 0, errored: 2, failed: 0 }, + suites: [ + { + name: 'rspec:pg', + status: 'error', + summary: { total: 0, resolved: 0, errored: 0, failed: 0 }, + new_failures: [], + resolved_failures: [], + existing_failures: [], + new_errors: [], + resolved_errors: [], + existing_errors: [], + }, + ], +}; |