2020-07-28 23:09:34 +05:30
import { GlLoadingIcon } from '@gitlab/ui' ;
2021-03-11 19:13:27 +05:30
import { shallowMount , mount } from '@vue/test-utils' ;
2021-12-11 22:18:48 +05:30
import axios from 'axios' ;
import MockAdapter from 'axios-mock-adapter' ;
2020-06-23 00:09:42 +05:30
import { trimText } from 'helpers/text_helper' ;
2021-04-29 21:17:54 +05:30
import { extendedWrapper } from 'helpers/vue_test_utils_helper' ;
2021-04-17 20:07:23 +05:30
import PipelineMiniGraph from '~/pipelines/components/pipelines_list/pipeline_mini_graph.vue' ;
import PipelineStage from '~/pipelines/components/pipelines_list/pipeline_stage.vue' ;
2021-03-11 19:13:27 +05:30
import PipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline.vue' ;
import { SUCCESS } from '~/vue_merge_request_widget/constants' ;
2017-08-17 22:00:37 +05:30
import mockData from '../mock_data' ;
describe ( 'MRWidgetPipeline' , ( ) => {
2020-07-28 23:09:34 +05:30
let wrapper ;
const defaultProps = {
pipeline : mockData . pipeline ,
ciStatus : SUCCESS ,
hasCi : true ,
mrTroubleshootingDocsPath : 'help' ,
ciTroubleshootingDocsPath : 'ci-help' ,
} ;
const ciErrorMessage =
'Could not retrieve the pipeline status. For troubleshooting steps, read the documentation.' ;
const monitoringMessage = 'Checking pipeline status.' ;
2021-04-29 21:17:54 +05:30
const findCIErrorMessage = ( ) => wrapper . findByTestId ( 'ci-error-message' ) ;
const findPipelineID = ( ) => wrapper . findByTestId ( 'pipeline-id' ) ;
const findPipelineInfoContainer = ( ) => wrapper . findByTestId ( 'pipeline-info-container' ) ;
const findCommitLink = ( ) => wrapper . findByTestId ( 'commit-link' ) ;
const findPipelineFinishedAt = ( ) => wrapper . findByTestId ( 'finished-at' ) ;
const findPipelineMiniGraph = ( ) => wrapper . findComponent ( PipelineMiniGraph ) ;
const findAllPipelineStages = ( ) => wrapper . findAllComponents ( PipelineStage ) ;
const findPipelineCoverage = ( ) => wrapper . findByTestId ( 'pipeline-coverage' ) ;
const findPipelineCoverageDelta = ( ) => wrapper . findByTestId ( 'pipeline-coverage-delta' ) ;
2020-11-24 15:15:51 +05:30
const findPipelineCoverageTooltipText = ( ) =>
2021-04-29 21:17:54 +05:30
wrapper . findByTestId ( 'pipeline-coverage-tooltip' ) . text ( ) ;
const findPipelineCoverageDeltaTooltipText = ( ) =>
wrapper . findByTestId ( 'pipeline-coverage-delta-tooltip' ) . text ( ) ;
const findMonitoringPipelineMessage = ( ) => wrapper . findByTestId ( 'monitoring-pipeline-message' ) ;
const findLoadingIcon = ( ) => wrapper . findComponent ( GlLoadingIcon ) ;
2020-07-28 23:09:34 +05:30
2021-12-11 22:18:48 +05:30
const mockArtifactsRequest = ( ) => new MockAdapter ( axios ) . onGet ( ) . reply ( 200 , [ ] ) ;
2021-04-17 20:07:23 +05:30
const createWrapper = ( props = { } , mountFn = shallowMount ) => {
2021-04-29 21:17:54 +05:30
wrapper = extendedWrapper (
mountFn ( PipelineComponent , {
propsData : {
... defaultProps ,
... props ,
} ,
} ) ,
) ;
2020-07-28 23:09:34 +05:30
} ;
2017-08-17 22:00:37 +05:30
2018-03-17 18:26:18 +05:30
afterEach ( ( ) => {
2020-07-28 23:09:34 +05:30
if ( wrapper ? . destroy ) {
wrapper . destroy ( ) ;
wrapper = null ;
}
2017-08-17 22:00:37 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render CI error if there is a pipeline, but no status' , ( ) => {
createWrapper ( { ciStatus : null } , mount ) ;
expect ( findCIErrorMessage ( ) . text ( ) ) . toBe ( ciErrorMessage ) ;
} ) ;
2018-03-17 18:26:18 +05:30
2020-11-24 15:15:51 +05:30
it ( 'should render a loading state when no pipeline is found' , ( ) => {
createWrapper ( { pipeline : { } } , mount ) ;
2018-03-17 18:26:18 +05:30
2020-11-24 15:15:51 +05:30
expect ( findMonitoringPipelineMessage ( ) . text ( ) ) . toBe ( monitoringMessage ) ;
expect ( findLoadingIcon ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2020-07-28 23:09:34 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'with a pipeline' , ( ) => {
beforeEach ( ( ) => {
2021-12-11 22:18:48 +05:30
mockArtifactsRequest ( ) ;
2021-04-17 20:07:23 +05:30
createWrapper (
{
pipelineCoverageDelta : mockData . pipelineCoverageDelta ,
buildsWithCoverage : mockData . buildsWithCoverage ,
} ,
mount ,
) ;
2017-08-17 22:00:37 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render pipeline ID' , ( ) => {
2021-03-08 18:12:59 +05:30
expect ( findPipelineID ( ) . text ( ) . trim ( ) ) . toBe ( ` # ${ mockData . pipeline . id } ` ) ;
2020-11-24 15:15:51 +05:30
} ) ;
2017-08-17 22:00:37 +05:30
2020-11-24 15:15:51 +05:30
it ( 'should render pipeline status and commit id' , ( ) => {
expect ( findPipelineInfoContainer ( ) . text ( ) ) . toMatch ( mockData . pipeline . details . status . label ) ;
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
expect ( findCommitLink ( ) . text ( ) . trim ( ) ) . toBe ( mockData . pipeline . commit . short _id ) ;
2017-08-17 22:00:37 +05:30
2020-11-24 15:15:51 +05:30
expect ( findCommitLink ( ) . attributes ( 'href' ) ) . toBe ( mockData . pipeline . commit . commit _path ) ;
} ) ;
2020-07-28 23:09:34 +05:30
2021-04-29 21:17:54 +05:30
it ( 'should render pipeline finished timestamp' , ( ) => {
expect ( findPipelineFinishedAt ( ) . attributes ( ) ) . toMatchObject ( {
2021-09-04 01:27:46 +05:30
title : 'Apr 7, 2017 2:00pm UTC' ,
2021-04-29 21:17:54 +05:30
datetime : mockData . pipeline . details . finished _at ,
} ) ;
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render pipeline graph' , ( ) => {
2021-04-17 20:07:23 +05:30
expect ( findPipelineMiniGraph ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findAllPipelineStages ( ) ) . toHaveLength ( mockData . pipeline . details . stages . length ) ;
2017-08-17 22:00:37 +05:30
} ) ;
2020-01-01 13:55:28 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'should render pipeline coverage information' , ( ) => {
it ( 'should render coverage percentage' , ( ) => {
2021-04-29 21:17:54 +05:30
expect ( findPipelineCoverage ( ) . text ( ) ) . toMatch (
` Test coverage ${ mockData . pipeline . coverage } % ` ,
) ;
2020-07-28 23:09:34 +05:30
} ) ;
2020-01-01 13:55:28 +05:30
2020-11-24 15:15:51 +05:30
it ( 'should render coverage delta' , ( ) => {
expect ( findPipelineCoverageDelta ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findPipelineCoverageDelta ( ) . text ( ) ) . toBe ( ` ( ${ mockData . pipelineCoverageDelta } %) ` ) ;
2020-01-01 13:55:28 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render tooltip for jobs contributing to code coverage' , ( ) => {
const tooltipText = findPipelineCoverageTooltipText ( ) ;
2021-04-29 21:17:54 +05:30
const expectedDescription = ` Test coverage value for this pipeline was calculated by averaging the resulting coverage values of ${ mockData . buildsWithCoverage . length } jobs. ` ;
2020-07-28 23:09:34 +05:30
2020-11-24 15:15:51 +05:30
expect ( tooltipText ) . toContain ( expectedDescription ) ;
2020-01-01 13:55:28 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it . each ( mockData . buildsWithCoverage ) (
'should have name and coverage for build %s listed in tooltip' ,
2021-03-08 18:12:59 +05:30
( build ) => {
2020-11-24 15:15:51 +05:30
const tooltipText = findPipelineCoverageTooltipText ( ) ;
expect ( tooltipText ) . toContain ( ` ${ build . name } ( ${ build . coverage } %) ` ) ;
} ,
) ;
2021-04-29 21:17:54 +05:30
describe . each `
style | coverageState | coverageChangeText | styleClass | pipelineCoverageDelta
$ { 'no special' } | $ { 'the same' } | $ { 'not change' } | $ { '' } | $ { '0' }
$ { 'success' } | $ { 'increased' } | $ { 'increase' } | $ { 'text-success' } | $ { '10' }
$ { 'danger' } | $ { 'decreased' } | $ { 'decrease' } | $ { 'text-danger' } | $ { '-10' }
` (
'if test coverage is $coverageState' ,
( { style , styleClass , coverageChangeText , pipelineCoverageDelta } ) => {
it ( ` coverage delta should have ${ style } ` , ( ) => {
createWrapper ( { pipelineCoverageDelta } ) ;
expect ( findPipelineCoverageDelta ( ) . classes ( ) ) . toEqual ( styleClass ? [ styleClass ] : [ ] ) ;
} ) ;
it ( ` coverage delta tooltip should say that the coverage will ${ coverageChangeText } ` , ( ) => {
createWrapper ( { pipelineCoverageDelta } ) ;
expect ( findPipelineCoverageDeltaTooltipText ( ) ) . toContain ( coverageChangeText ) ;
} ) ;
} ,
) ;
2020-01-01 13:55:28 +05:30
} ) ;
2017-08-17 22:00:37 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
describe ( 'without commit path' , ( ) => {
2020-07-28 23:09:34 +05:30
beforeEach ( ( ) => {
2020-11-24 15:15:51 +05:30
const mockCopy = JSON . parse ( JSON . stringify ( mockData ) ) ;
delete mockCopy . pipeline . commit ;
2017-08-17 22:00:37 +05:30
2021-04-17 20:07:23 +05:30
createWrapper ( { } , mount ) ;
2019-07-31 22:56:46 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render pipeline ID' , ( ) => {
2021-03-08 18:12:59 +05:30
expect ( findPipelineID ( ) . text ( ) . trim ( ) ) . toBe ( ` # ${ mockData . pipeline . id } ` ) ;
2020-05-24 23:13:21 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render pipeline status' , ( ) => {
expect ( findPipelineInfoContainer ( ) . text ( ) ) . toMatch ( mockData . pipeline . details . status . label ) ;
} ) ;
2020-01-01 13:55:28 +05:30
2021-04-17 20:07:23 +05:30
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 ) ;
2018-10-15 14:42:47 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should render coverage information' , ( ) => {
2021-04-29 21:17:54 +05:30
expect ( findPipelineCoverage ( ) . text ( ) ) . toMatch ( ` Test coverage ${ mockData . pipeline . coverage } % ` ) ;
2020-11-24 15:15:51 +05:30
} ) ;
} ) ;
2018-10-15 14:42:47 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'without coverage' , ( ) => {
beforeEach ( ( ) => {
const mockCopy = JSON . parse ( JSON . stringify ( mockData ) ) ;
delete mockCopy . pipeline . coverage ;
2018-10-15 14:42:47 +05:30
2020-11-24 15:15:51 +05:30
createWrapper ( { pipeline : mockCopy . pipeline } ) ;
} ) ;
2018-10-15 14:42:47 +05:30
2020-11-24 15:15:51 +05:30
it ( 'should not render a coverage component' , ( ) => {
expect ( findPipelineCoverage ( ) . exists ( ) ) . toBe ( false ) ;
} ) ;
} ) ;
2018-10-15 14:42:47 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'without a pipeline graph' , ( ) => {
beforeEach ( ( ) => {
const mockCopy = JSON . parse ( JSON . stringify ( mockData ) ) ;
delete mockCopy . pipeline . details . stages ;
2018-10-15 14:42:47 +05:30
2020-11-24 15:15:51 +05:30
createWrapper ( {
pipeline : mockCopy . pipeline ,
2017-08-17 22:00:37 +05:30
} ) ;
} ) ;
2020-11-24 15:15:51 +05:30
it ( 'should not render a pipeline graph' , ( ) => {
2021-04-17 20:07:23 +05:30
expect ( findPipelineMiniGraph ( ) . exists ( ) ) . toBe ( false ) ;
2017-08-17 22:00:37 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
} ) ;
2017-08-17 22:00:37 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'for each type of pipeline' , ( ) => {
let pipeline ;
2018-03-17 18:26:18 +05:30
2020-11-24 15:15:51 +05:30
beforeEach ( ( ) => {
( { pipeline } = JSON . parse ( JSON . stringify ( mockData ) ) ) ;
2017-08-17 22:00:37 +05:30
2020-11-24 15:15:51 +05:30
pipeline . details . name = 'Pipeline' ;
pipeline . merge _request _event _type = undefined ;
pipeline . ref . tag = false ;
pipeline . ref . branch = false ;
2017-08-17 22:00:37 +05:30
} ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
const factory = ( ) => {
createWrapper ( {
pipeline ,
sourceBranchLink : mockData . source _branch _link ,
2019-07-07 11:18:12 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
} ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'for a branch pipeline' , ( ) => {
it ( 'renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"' , ( ) => {
pipeline . ref . branch = true ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
factory ( ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
const expected = ` Pipeline # ${ pipeline . id } ${ pipeline . details . status . label } for ${ pipeline . commit . short _id } on ${ mockData . source _branch _link } ` ;
const actual = trimText ( findPipelineInfoContainer ( ) . text ( ) ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
expect ( actual ) . toBe ( expected ) ;
2019-07-07 11:18:12 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
} ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'for a tag pipeline' , ( ) => {
it ( 'renders a pipeline widget that reads "Pipeline <ID> <status> for <SHA> on <branch>"' , ( ) => {
pipeline . ref . tag = true ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
factory ( ) ;
2019-12-04 20:38:33 +05:30
2020-11-24 15:15:51 +05:30
const expected = ` Pipeline # ${ pipeline . id } ${ pipeline . details . status . label } for ${ pipeline . commit . short _id } ` ;
const actual = trimText ( findPipelineInfoContainer ( ) . text ( ) ) ;
2019-12-04 20:38:33 +05:30
2020-11-24 15:15:51 +05:30
expect ( actual ) . toBe ( expected ) ;
2019-12-04 20:38:33 +05:30
} ) ;
2020-11-24 15:15:51 +05:30
} ) ;
2019-12-04 20:38:33 +05:30
2020-11-24 15:15:51 +05:30
describe ( 'for a detached merge request pipeline' , ( ) => {
it ( 'renders a pipeline widget that reads "Detached merge request pipeline <ID> <status> for <SHA>"' , ( ) => {
pipeline . details . name = 'Detached merge request pipeline' ;
pipeline . merge _request _event _type = 'detached' ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
factory ( ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
const expected = ` Detached merge request pipeline # ${ pipeline . id } ${ pipeline . details . status . label } for ${ pipeline . commit . short _id } ` ;
const actual = trimText ( findPipelineInfoContainer ( ) . text ( ) ) ;
2019-07-07 11:18:12 +05:30
2020-11-24 15:15:51 +05:30
expect ( actual ) . toBe ( expected ) ;
2019-07-07 11:18:12 +05:30
} ) ;
} ) ;
2017-08-17 22:00:37 +05:30
} ) ;
} ) ;