Commit 71a44d34 authored by Bryce Johnson's avatar Bryce Johnson

Add linked pipelines to mini pipeline graph in MR Widget

parent dbc7bbc3
import PipelineStage from '../../pipelines/components/stage.vue'; import PipelineStage from '../../pipelines/components/stage.vue';
import ciIcon from '../../vue_shared/components/ci_icon.vue'; import ciIcon from '../../vue_shared/components/ci_icon.vue';
import { statusIconEntityMap } from '../../vue_shared/ci_status_icons'; import { statusIconEntityMap } from '../../vue_shared/ci_status_icons';
import linkedPipelinesMiniList from '../../vue_shared/components/linked_pipelines_mini_list.vue';
export default { export default {
name: 'MRWidgetPipeline', name: 'MRWidgetPipeline',
...@@ -10,6 +11,7 @@ export default { ...@@ -10,6 +11,7 @@ export default {
components: { components: {
'pipeline-stage': PipelineStage, 'pipeline-stage': PipelineStage,
ciIcon, ciIcon,
linkedPipelinesMiniList,
}, },
computed: { computed: {
hasCIError() { hasCIError() {
...@@ -26,6 +28,18 @@ export default { ...@@ -26,6 +28,18 @@ export default {
status() { status() {
return this.mr.pipeline.details.status || {}; return this.mr.pipeline.details.status || {};
}, },
/* We typically set defaults ([]) in the store or prop declarations, but because triggered
* and triggeredBy are appended to `pipeline`, we can't set defaults in the store, and we
* need to check their length here to prevent initializing linked-pipeline-mini-lists
* unneccessarily. */
triggered() {
return this.mr.pipeline.triggered || [];
},
triggeredBy() {
return this.mr.pipeline.triggered_by || [];
},
}, },
template: ` template: `
<div class="mr-widget-heading"> <div class="mr-widget-heading">
...@@ -61,12 +75,25 @@ export default { ...@@ -61,12 +75,25 @@ export default {
</span> </span>
<div class="mr-widget-pipeline-graph"> <div class="mr-widget-pipeline-graph">
<div class="stage-cell"> <div class="stage-cell">
<linked-pipelines-mini-list
v-if="triggeredBy.length"
:triggered-by="triggeredBy"
/>
<div <div
v-if="mr.pipeline.details.stages.length > 0" v-if="mr.pipeline.details.stages.length > 0"
v-for="stage in mr.pipeline.details.stages" v-for="(stage, index) in mr.pipeline.details.stages"
class="stage-container dropdown js-mini-pipeline-graph"> class="stage-container dropdown js-mini-pipeline-graph"
:class="{
'has-downstream': index === mr.pipeline.details.stages.length - 1 && triggered.length
}">
<pipeline-stage :stage="stage" /> <pipeline-stage :stage="stage" />
</div> </div>
<linked-pipelines-mini-list
v-if="triggered.length"
:triggered="triggered"
/>
</div> </div>
</div> </div>
<span> <span>
......
<script>
import arrowSvg from 'icons/_arrow_mini_pipeline_graph.svg';
import { borderlessStatusIconEntityMap } from '../../vue_shared/ci_status_icons';
import ciStatus from './ci_icon.vue';
import tooltipMixin from '../mixins/tooltip';
export default {
props: {
triggeredBy: {
type: Array,
required: false,
default: () => [],
},
triggered: {
type: Array,
required: false,
default: () => [],
},
pipelinePath: {
type: String,
required: false,
default: '',
},
},
data() {
return {
arrowSvg,
maxRenderedPipelines: 3,
};
},
mixins: [
tooltipMixin,
],
components: {
ciStatus,
},
computed: {
// Exactly one of these (triggeredBy and triggered) must be truthy. Never both. Never neither.
isUpstream() {
return !!this.triggeredBy.length && !this.triggered.length;
},
isDownstream() {
return !this.triggeredBy.length && !!this.triggered.length;
},
linkedPipelines() {
return this.isUpstream ? this.triggeredBy : this.triggered;
},
totalPipelineCount() {
return this.linkedPipelines.length;
},
linkedPipelinesTrimmed() {
return (this.totalPipelineCount > this.maxRenderedPipelines) ?
this.linkedPipelines.slice(0, this.maxRenderedPipelines) :
this.linkedPipelines;
},
shouldRenderCounter() {
return this.isDownstream && this.linkedPipelines.length > this.maxRenderedPipelines;
},
counterLabel() {
return `+${this.linkedPipelines.length - this.maxRenderedPipelines}`;
},
counterTooltipText() {
return `${this.counterLabel} more downstream pipelines`;
},
},
methods: {
pipelineTooltipText(pipeline) {
return `${pipeline.project.name} - ${pipeline.details.status.label}`;
},
getStatusIcon(icon) {
return borderlessStatusIconEntityMap[icon];
},
triggerButtonClass(group) {
return `ci-status-icon-${group}`;
},
},
};
</script>
<template>
<span
v-if="linkedPipelines"
class="linked-pipeline-mini-list"
:class="{
'is-upstream' : isUpstream,
'is-downstream': isDownstream
}">
<span
class="arrow-icon"
v-if="isDownstream"
v-html="arrowSvg"
aria-hidden="true">
</span>
<a
class="linked-pipeline-mini-item"
v-for="(pipeline, index) in linkedPipelinesTrimmed"
:key="pipeline.id"
:href="pipeline.path"
:title="pipelineTooltipText(pipeline)"
data-toggle="tooltip"
data-placement="top"
data-container="body"
ref="tooltip"
:class="triggerButtonClass(pipeline.details.status.group)"
v-html="getStatusIcon(pipeline.details.status.icon)">
</a>
<a
v-if="shouldRenderCounter"
class="linked-pipelines-counter linked-pipeline-mini-item"
:title="counterTooltipText"
:href="pipelinePath"
data-toggle="tooltip"
data-placement="top"
data-container="body"
ref="tooltip">
{{ counterLabel }}
</a>
<span
class="arrow-icon"
v-if="isUpstream"
v-html="arrowSvg"
aria-hidden="true">
</span>
</span>
</template>
...@@ -644,7 +644,8 @@ ...@@ -644,7 +644,8 @@
} }
// Dropdown button in mini pipeline graph // Dropdown button in mini pipeline graph
.mini-pipeline-graph-dropdown-toggle { .mini-pipeline-graph-dropdown-toggle,
.linked-pipeline-mini-item {
border-radius: 100px; border-radius: 100px;
background-color: $white-light; background-color: $white-light;
border-width: 1px; border-width: 1px;
...@@ -998,6 +999,93 @@ ...@@ -998,6 +999,93 @@
} }
} }
.linked-pipeline-mini-list {
display: inline-block;
&.is-downstream {
margin-left: -4px;
}
.arrow-icon {
display: inline-block;
vertical-align: middle;
margin: -2px 5px 0;
svg {
fill: $gray-darkest;
}
}
&:hover {
.linked-pipeline-mini-item {
margin-left: 0;
}
}
.linked-pipeline-mini-item {
position: relative;
display: inline-block;
vertical-align: middle;
height: 20px;
width: 20px;
transition: margin .2s linear;
margin: 2px 5px 3px -12px;
svg {
top: 0;
right: 0;
width: 18px;
height: 18px;
}
// override dropdown-toggle width expansion
&:hover {
width: 20px;
}
&:first-of-type:last-of-type {
margin-right: 1px;
}
&:nth-of-type(1) {
margin-left: 0;
z-index: 100;
}
&:nth-of-type(2):not(.linked-pipelines-counter) {
z-index: 99;
}
&:nth-of-type(3) {
z-index: 98;
}
&:nth-of-type(4) {
z-index: 97;
}
}
.linked-pipelines-counter {
position: relative;
font-size: 12px;
vertical-align: middle;
line-height: 20px;
height: 22px;
width: 22px;
padding-left: 1px;
margin-left: -15px;
border-radius: 2em;
background: $gray-darkest;
color: $white-light;
z-index: 96;
text-decoration: none;
&:hover {
width: 22px;
background: darken($gray-darkest, 10%);
}
}
}
/** /**
* Cross-project pipelines (applied conditionally to pipeline graph) * Cross-project pipelines (applied conditionally to pipeline graph)
*/ */
......
<svg width="16" height="8" viewBox="0 0 16 8" xmlns="http://www.w3.org/2000/svg"><path d="M10 3H0v2h10v3l5.549-3.7c.251-.167.25-.435 0-.6L10 0v3z" fill-rule="nonzero"/></svg>
/* eslint-disable quote-props, quotes, comma-dangle */ /* eslint-disable quote-props, quotes, comma-dangle */
export default { export default {
"triggered_by": [ "triggered_by": [{
{ "id": 129,
"id": 129, "active": true,
"active": true, "path": "/gitlab-org/gitlab-ce/pipelines/129",
"path": "/gitlab-org/gitlab-ce/pipelines/129", "project": {
"project": { "name": "GitLabCE"
"name": "GitLabCE" },
}, "details": {
"details": { "status": {
"status": { "icon": "icon_status_running",
"icon": "icon_status_running", "text": "running",
"text": "running", "label": "running",
"label": "running", "group": "running",
"group": "running", "has_details": true,
"has_details": true, "details_path": "/gitlab-org/gitlab-ce/pipelines/129",
"details_path": "/gitlab-org/gitlab-ce/pipelines/129", "favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico" }
} },
}, "flags": {
"flags": { "latest": false,
"latest": false, "triggered": false,
"triggered": false, "stuck": false,
"stuck": false, "yaml_errors": false,
"yaml_errors": false, "retryable": true,
"retryable": true, "cancelable": true
"cancelable": true },
}, "ref": {
"ref": { "name": "7-5-stable",
"name": "7-5-stable", "path": "/gitlab-org/gitlab-ce/commits/7-5-stable",
"path": "/gitlab-org/gitlab-ce/commits/7-5-stable", "tag": false,
"tag": false, "branch": true
"branch": true },
}, "commit": {
"commit": { "id": "23433d4d8b20d7e45c103d0b6048faad38a130ab",
"id": "23433d4d8b20d7e45c103d0b6048faad38a130ab", "short_id": "23433d4d",
"short_id": "23433d4d", "title": "Version 7.5.0.rc1",
"title": "Version 7.5.0.rc1", "created_at": "2014-11-17T15:44:14.000+01:00",
"created_at": "2014-11-17T15:44:14.000+01:00", "parent_ids": [
"parent_ids": [ "30ac909f30f58d319b42ed1537664483894b18cd"
"30ac909f30f58d319b42ed1537664483894b18cd" ],
], "message": "Version 7.5.0.rc1\n",
"message": "Version 7.5.0.rc1\n", "author_name": "Jacob Vosmaer",
"author_name": "Jacob Vosmaer", "author_email": "contact@jacobvosmaer.nl",
"author_email": "contact@jacobvosmaer.nl", "authored_date": "2014-11-17T15:44:14.000+01:00",
"authored_date": "2014-11-17T15:44:14.000+01:00", "committer_name": "Jacob Vosmaer",
"committer_name": "Jacob Vosmaer", "committer_email": "contact@jacobvosmaer.nl",
"committer_email": "contact@jacobvosmaer.nl", "committed_date": "2014-11-17T15:44:14.000+01:00",
"committed_date": "2014-11-17T15:44:14.000+01:00", "author_gravatar_url": "http://www.gravatar.com/avatar/e66d11c0eedf8c07b3b18fca46599807?s=80&d=identicon",
"author_gravatar_url": "http://www.gravatar.com/avatar/e66d11c0eedf8c07b3b18fca46599807?s=80&d=identicon", "commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab", "commit_path": "/gitlab-org/gitlab-ce/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab"
"commit_path": "/gitlab-org/gitlab-ce/commit/23433d4d8b20d7e45c103d0b6048faad38a130ab" },
}, "retry_path": "/gitlab-org/gitlab-ce/pipelines/129/retry",
"retry_path": "/gitlab-org/gitlab-ce/pipelines/129/retry", "cancel_path": "/gitlab-org/gitlab-ce/pipelines/129/cancel",
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/129/cancel", "created_at": "2017-05-24T14:46:20.090Z",
"created_at": "2017-05-24T14:46:20.090Z", "updated_at": "2017-05-24T14:46:29.906Z"
"updated_at": "2017-05-24T14:46:29.906Z" }],
} "triggered": [{
], "id": 132,
"triggered": [ "active": true,
{ "path": "/gitlab-org/gitlab-ce/pipelines/132",
"id": 132, "project": {
"active": true, "name": "GitLabCE"
"path": "/gitlab-org/gitlab-ce/pipelines/132", },
"project": { "details": {
"name": "GitLabCE" "status": {
}, "icon": "icon_status_running",
"details": { "text": "running",
"status": { "label": "running",
"icon": "icon_status_running", "group": "running",
"text": "running", "has_details": true,
"label": "running", "details_path": "/gitlab-org/gitlab-ce/pipelines/132",
"group": "running", "favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
"has_details": true, }
"details_path": "/gitlab-org/gitlab-ce/pipelines/132", },
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico" "flags": {
} "latest": false,
}, "triggered": false,
"flags": { "stuck": false,
"latest": false, "yaml_errors": false,
"triggered": false, "retryable": true,
"stuck": false, "cancelable": true
"yaml_errors": false, },
"retryable": true, "ref": {
"cancelable": true "name": "crowd",
}, "path": "/gitlab-org/gitlab-ce/commits/crowd",
"ref": { "tag": false,
"name": "crowd", "branch": true
"path": "/gitlab-org/gitlab-ce/commits/crowd", },
"tag": false, "commit": {
"branch": true "id": "b9d58c4cecd06be74c3cc32ccfb522b31544ab2e",
}, "short_id": "b9d58c4c",
"commit": { "title": "getting user keys publically through http without any authentication, the github…",
"id": "b9d58c4cecd06be74c3cc32ccfb522b31544ab2e", "created_at": "2013-10-03T12:50:33.000+05:30",
"short_id": "b9d58c4c", "parent_ids": [
"title": "getting user keys publically through http without any authentication, the github…", "e219cf7246c6a0495e4507deaffeba11e79f13b8"
"created_at": "2013-10-03T12:50:33.000+05:30", ],
"parent_ids": [ "message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n",
"e219cf7246c6a0495e4507deaffeba11e79f13b8" "author_name": "devaroop",
], "author_email": "devaroop123@yahoo.co.in",
"message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n", "authored_date": "2013-10-02T20:39:29.000+05:30",
"author_name": "devaroop", "committer_name": "devaroop",
"author_email": "devaroop123@yahoo.co.in", "committer_email": "devaroop123@yahoo.co.in",
"authored_date": "2013-10-02T20:39:29.000+05:30", "committed_date": "2013-10-03T12:50:33.000+05:30",
"committer_name": "devaroop", "author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon",
"committer_email": "devaroop123@yahoo.co.in", "commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e",
"committed_date": "2013-10-03T12:50:33.000+05:30", "commit_path": "/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e"
"author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon", },
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e", "retry_path": "/gitlab-org/gitlab-ce/pipelines/132/retry",
"commit_path": "/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e" "cancel_path": "/gitlab-org/gitlab-ce/pipelines/132/cancel",
}, "created_at": "2017-05-24T14:46:24.644Z",
"retry_path": "/gitlab-org/gitlab-ce/pipelines/132/retry", "updated_at": "2017-05-24T14:48:55.226Z"
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/132/cancel", }, {
"created_at": "2017-05-24T14:46:24.644Z", "id": 133,
"updated_at": "2017-05-24T14:48:55.226Z" "active": true,
}, "path": "/gitlab-org/gitlab-ce/pipelines/133",
{ "project": {
"id": 133, "name": "GitLabCE"
"active": true, },
"path": "/gitlab-org/gitlab-ce/pipelines/133", "details": {
"project": { "status": {
"name": "GitLabCE" "icon": "icon_status_running",
}, "text": "running",
"details": { "label": "running",
"status": { "group": "running",
"icon": "icon_status_running", "has_details": true,
"text": "running", "details_path": "/gitlab-org/gitlab-ce/pipelines/133",
"label": "running", "favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
"group": "running", }
"has_details": true, },
"details_path": "/gitlab-org/gitlab-ce/pipelines/133", "flags": {
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico" "latest": false,
} "triggered": false,
}, "stuck": false,
"flags": { "yaml_errors": false,
"latest": false, "retryable": true,
"triggered": false, "cancelable": true
"stuck": false, },
"yaml_errors": false, "ref": {
"retryable": true, "name": "crowd",
"cancelable": true "path": "/gitlab-org/gitlab-ce/commits/crowd",
}, "tag": false,
"ref": { "branch": true
"name": "crowd", },
"path": "/gitlab-org/gitlab-ce/commits/crowd", "commit": {
"tag": false, "id": "b6bd4856a33df3d144be66c4ed1f1396009bb08b",
"branch": true "short_id": "b6bd4856",
}, "title": "getting user keys publically through http without any authentication, the github…",
"commit": { "created_at": "2013-10-02T20:39:29.000+05:30",
"id": "b6bd4856a33df3d144be66c4ed1f1396009bb08b", "parent_ids": [
"short_id": "b6bd4856", "e219cf7246c6a0495e4507deaffeba11e79f13b8"
"title": "getting user keys publically through http without any authentication, the github…", ],
"created_at": "2013-10-02T20:39:29.000+05:30", "message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n",
"parent_ids": [ "author_name": "devaroop",
"e219cf7246c6a0495e4507deaffeba11e79f13b8" "author_email": "devaroop123@yahoo.co.in",
], "authored_date": "2013-10-02T20:39:29.000+05:30",
"message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n", "committer_name": "devaroop",
"author_name": "devaroop", "committer_email": "devaroop123@yahoo.co.in",
"author_email": "devaroop123@yahoo.co.in", "committed_date": "2013-10-02T20:39:29.000+05:30",
"authored_date": "2013-10-02T20:39:29.000+05:30", "author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon",
"committer_name": "devaroop", "commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b",
"committer_email": "devaroop123@yahoo.co.in", "commit_path": "/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b"
"committed_date": "2013-10-02T20:39:29.000+05:30", },
"author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon", "retry_path": "/gitlab-org/gitlab-ce/pipelines/133/retry",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b", "cancel_path": "/gitlab-org/gitlab-ce/pipelines/133/cancel",
"commit_path": "/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b" "created_at": "2017-05-24T14:46:24.648Z",
}, "updated_at": "2017-05-24T14:48:59.673Z"
"retry_path": "/gitlab-org/gitlab-ce/pipelines/133/retry", }, {
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/133/cancel", "id": 130,
"created_at": "2017-05-24T14:46:24.648Z", "active": true,
"updated_at": "2017-05-24T14:48:59.673Z" "path": "/gitlab-org/gitlab-ce/pipelines/130",
}, "project": {
{ "name": "GitLabCE"
"id": 130, },
"active": true, "details": {
"path": "/gitlab-org/gitlab-ce/pipelines/130", "status": {
"project": { "icon": "icon_status_running",
"name": "GitLabCE" "text": "running",
}, "label": "running",
"details": { "group": "running",
"status": { "has_details": true,
"icon": "icon_status_running", "details_path": "/gitlab-org/gitlab-ce/pipelines/130",
"text": "running", "favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
"label": "running", }
"group": "running", },
"has_details": true, "flags": {
"details_path": "/gitlab-org/gitlab-ce/pipelines/130", "latest": false,
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico" "triggered": false,
} "stuck": false,
}, "yaml_errors": false,
"flags": { "retryable": true,
"latest": false, "cancelable": true
"triggered": false, },
"stuck": false, "ref": {
"yaml_errors": false, "name": "crowd",
"retryable": true, "path": "/gitlab-org/gitlab-ce/commits/crowd",
"cancelable": true "tag": false,
}, "branch": true
"ref": { },
"name": "crowd", "commit": {
"path": "/gitlab-org/gitlab-ce/commits/crowd", "id": "6d7ced4a2311eeff037c5575cca1868a6d3f586f",
"tag": false, "short_id": "6d7ced4a",
"branch": true "title": "Whitespace fixes to patch",
}, "created_at": "2013-10-08T13:53:22.000-05:00",
"commit": { "parent_ids": [
"id": "6d7ced4a2311eeff037c5575cca1868a6d3f586f", "1875141a963a4238bda29011d8f7105839485253"
"short_id": "6d7ced4a", ],
"title": "Whitespace fixes to patch", "message": "Whitespace fixes to patch\n",
"created_at": "2013-10-08T13:53:22.000-05:00", "author_name": "Dale Hamel",
"parent_ids": [ "author_email": "dale.hamel@srvthe.net",
"1875141a963a4238bda29011d8f7105839485253" "authored_date": "2013-10-08T13:53:22.000-05:00",
], "committer_name": "Dale Hamel",
"message": "Whitespace fixes to patch\n", "committer_email": "dale.hamel@invenia.ca",
"author_name": "Dale Hamel", "committed_date": "2013-10-08T13:53:22.000-05:00",
"author_email": "dale.hamel@srvthe.net", "author_gravatar_url": "http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon",
"authored_date": "2013-10-08T13:53:22.000-05:00", "commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f",
"committer_name": "Dale Hamel", "commit_path": "/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f"
"committer_email": "dale.hamel@invenia.ca", },
"committed_date": "2013-10-08T13:53:22.000-05:00", "retry_path": "/gitlab-org/gitlab-ce/pipelines/130/retry",
"author_gravatar_url": "http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon", "cancel_path": "/gitlab-org/gitlab-ce/pipelines/130/cancel",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f", "created_at": "2017-05-24T14:46:24.630Z",
"commit_path": "/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f" "updated_at": "2017-05-24T14:49:45.091Z"
}, }, {
"retry_path": "/gitlab-org/gitlab-ce/pipelines/130/retry", "id": 132,
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/130/cancel", "active": true,
"created_at": "2017-05-24T14:46:24.630Z", "path": "/gitlab-org/gitlab-ce/pipelines/132",
"updated_at": "2017-05-24T14:49:45.091Z" "project": {
} "name": "GitLabCE"
] },
"details": {
"status": {
"icon": "icon_status_running",
"text": "running",
"label": "running",
"group": "running",
"has_details": true,
"details_path": "/gitlab-org/gitlab-ce/pipelines/132",
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
}
},
"flags": {
"latest": false,
"triggered": false,
"stuck": false,
"yaml_errors": false,
"retryable": true,
"cancelable": true
},
"ref": {
"name": "crowd",
"path": "/gitlab-org/gitlab-ce/commits/crowd",
"tag": false,
"branch": true
},
"commit": {
"id": "b9d58c4cecd06be74c3cc32ccfb522b31544ab2e",
"short_id": "b9d58c4c",
"title": "getting user keys publically through http without any authentication, the github…",
"created_at": "2013-10-03T12:50:33.000+05:30",
"parent_ids": [
"e219cf7246c6a0495e4507deaffeba11e79f13b8"
],
"message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n\nchangelog updated to include ssh key retrieval feature update\n",
"author_name": "devaroop",
"author_email": "devaroop123@yahoo.co.in",
"authored_date": "2013-10-02T20:39:29.000+05:30",
"committer_name": "devaroop",
"committer_email": "devaroop123@yahoo.co.in",
"committed_date": "2013-10-03T12:50:33.000+05:30",
"author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e",
"commit_path": "/gitlab-org/gitlab-ce/commit/b9d58c4cecd06be74c3cc32ccfb522b31544ab2e"
},
"retry_path": "/gitlab-org/gitlab-ce/pipelines/132/retry",
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/132/cancel",
"created_at": "2017-05-24T14:46:24.644Z",
"updated_at": "2017-05-24T14:48:55.226Z"
}, {
"id": 133,
"active": true,
"path": "/gitlab-org/gitlab-ce/pipelines/133",
"project": {
"name": "GitLabCE"
},
"details": {
"status": {
"icon": "icon_status_running",
"text": "running",
"label": "running",
"group": "running",
"has_details": true,
"details_path": "/gitlab-org/gitlab-ce/pipelines/133",
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
}
},
"flags": {
"latest": false,
"triggered": false,
"stuck": false,
"yaml_errors": false,
"retryable": true,
"cancelable": true
},
"ref": {
"name": "crowd",
"path": "/gitlab-org/gitlab-ce/commits/crowd",
"tag": false,
"branch": true
},
"commit": {
"id": "b6bd4856a33df3d144be66c4ed1f1396009bb08b",
"short_id": "b6bd4856",
"title": "getting user keys publically through http without any authentication, the github…",
"created_at": "2013-10-02T20:39:29.000+05:30",
"parent_ids": [
"e219cf7246c6a0495e4507deaffeba11e79f13b8"
],
"message": "getting user keys publically through http without any authentication, the github way. E.g: http://github.com/devaroop.keys\n",
"author_name": "devaroop",
"author_email": "devaroop123@yahoo.co.in",
"authored_date": "2013-10-02T20:39:29.000+05:30",
"committer_name": "devaroop",
"committer_email": "devaroop123@yahoo.co.in",
"committed_date": "2013-10-02T20:39:29.000+05:30",
"author_gravatar_url": "http://www.gravatar.com/avatar/35df4b155ec66a3127d53459941cf8a2?s=80&d=identicon",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b",
"commit_path": "/gitlab-org/gitlab-ce/commit/b6bd4856a33df3d144be66c4ed1f1396009bb08b"
},
"retry_path": "/gitlab-org/gitlab-ce/pipelines/133/retry",
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/133/cancel",
"created_at": "2017-05-24T14:46:24.648Z",
"updated_at": "2017-05-24T14:48:59.673Z"
}, {
"id": 130,
"active": true,
"path": "/gitlab-org/gitlab-ce/pipelines/130",
"project": {
"name": "GitLabCE"
},
"details": {
"status": {
"icon": "icon_status_running",
"text": "running",
"label": "running",
"group": "running",
"has_details": true,
"details_path": "/gitlab-org/gitlab-ce/pipelines/130",
"favicon": "/assets/ci_favicons/dev/favicon_status_running-c3ad2fc53ea6079c174e5b6c1351ff349e99ec3af5a5622fb77b0fe53ea279c1.ico"
}
},
"flags": {
"latest": false,
"triggered": false,
"stuck": false,
"yaml_errors": false,
"retryable": true,
"cancelable": true
},
"ref": {
"name": "crowd",
"path": "/gitlab-org/gitlab-ce/commits/crowd",
"tag": false,
"branch": true
},
"commit": {
"id": "6d7ced4a2311eeff037c5575cca1868a6d3f586f",
"short_id": "6d7ced4a",
"title": "Whitespace fixes to patch",
"created_at": "2013-10-08T13:53:22.000-05:00",
"parent_ids": [
"1875141a963a4238bda29011d8f7105839485253"
],
"message": "Whitespace fixes to patch\n",
"author_name": "Dale Hamel",
"author_email": "dale.hamel@srvthe.net",
"authored_date": "2013-10-08T13:53:22.000-05:00",
"committer_name": "Dale Hamel",
"committer_email": "dale.hamel@invenia.ca",
"committed_date": "2013-10-08T13:53:22.000-05:00",
"author_gravatar_url": "http://www.gravatar.com/avatar/cd08930e69fa5ad1a669206e7bafe476?s=80&d=identicon",
"commit_url": "http://localhost:3000/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f",
"commit_path": "/gitlab-org/gitlab-ce/commit/6d7ced4a2311eeff037c5575cca1868a6d3f586f"
},
"retry_path": "/gitlab-org/gitlab-ce/pipelines/130/retry",
"cancel_path": "/gitlab-org/gitlab-ce/pipelines/130/cancel",
"created_at": "2017-05-24T14:46:24.630Z",
"updated_at": "2017-05-24T14:49:45.091Z"
}],
}; };
...@@ -2,6 +2,7 @@ import Vue from 'vue'; ...@@ -2,6 +2,7 @@ import Vue from 'vue';
import { statusIconEntityMap } from '~/vue_shared/ci_status_icons'; import { statusIconEntityMap } from '~/vue_shared/ci_status_icons';
import pipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline'; import pipelineComponent from '~/vue_merge_request_widget/components/mr_widget_pipeline';
import mockData from '../mock_data'; import mockData from '../mock_data';
import mockLinkedPipelines from '../../pipelines/graph/linked_pipelines_mock_data';
const createComponent = (mr) => { const createComponent = (mr) => {
const Component = Vue.extend(pipelineComponent); const Component = Vue.extend(pipelineComponent);
...@@ -77,6 +78,7 @@ describe('MRWidgetPipeline', () => { ...@@ -77,6 +78,7 @@ describe('MRWidgetPipeline', () => {
}); });
it('should render template elements correctly', () => { it('should render template elements correctly', () => {
// TODO: Break this into separate specs
expect(el.classList.contains('mr-widget-heading')).toBeTruthy(); expect(el.classList.contains('mr-widget-heading')).toBeTruthy();
expect(el.querySelectorAll('.ci-status-icon.ci-status-icon-success').length).toEqual(1); expect(el.querySelectorAll('.ci-status-icon.ci-status-icon-success').length).toEqual(1);
expect(el.querySelector('.pipeline-id').textContent).toContain(`#${pipeline.id}`); expect(el.querySelector('.pipeline-id').textContent).toContain(`#${pipeline.id}`);
...@@ -127,5 +129,53 @@ describe('MRWidgetPipeline', () => { ...@@ -127,5 +129,53 @@ describe('MRWidgetPipeline', () => {
done(); done();
}); });
}); });
it('should not render upstream or downstream pipelines', () => {
expect(el.querySelector('.linked-pipeline-mini-list')).toBeNull();
});
});
describe('when upstream pipelines are passed', function () {
beforeEach(function () {
const pipeline = Object.assign({}, mockData.pipeline, {
triggered_by: mockLinkedPipelines.triggered_by,
});
this.vm = createComponent({
pipeline,
pipelineDetailedStatus: mockData.pipeline.details.status,
hasCI: true,
ciStatus: 'success',
}).$mount();
});
it('should render the linked pipelines mini list', function (done) {
Vue.nextTick(() => {
expect(this.vm.$el.querySelector('.linked-pipeline-mini-list.is-upstream')).not.toBeNull();
done();
});
});
});
describe('when downstream pipelines are passed', function () {
beforeEach(function () {
const pipeline = Object.assign({}, mockData.pipeline, {
triggered: mockLinkedPipelines.triggered,
});
this.vm = createComponent({
pipeline,
pipelineDetailedStatus: mockData.pipeline.details.status,
hasCI: true,
ciStatus: 'success',
}).$mount();
});
it('should render the linked pipelines mini list', function (done) {
Vue.nextTick(() => {
expect(this.vm.$el.querySelector('.linked-pipeline-mini-list.is-downstream')).not.toBeNull();
done();
});
});
}); });
}); });
import Vue from 'vue';
import LinkedPipelinesMiniList from '~/vue_shared/components/linked_pipelines_mini_list.vue';
import mockData from '../../pipelines/graph/linked_pipelines_mock_data';
const ListComponent = Vue.extend(LinkedPipelinesMiniList);
describe('Linked pipeline mini list', () => {
describe('when passed an upstream pipeline as prop', () => {
beforeEach(() => {
this.component = new ListComponent({
propsData: {
triggeredBy: mockData.triggered_by,
},
}).$mount();
});
it('should render one linked pipeline item', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item').length).toBe(1);
});
it('should render a linked pipeline with the correct href', () => {
const linkElement = this.component.$el.querySelector('.linked-pipeline-mini-item');
expect(linkElement.getAttribute('href')).toBe('/gitlab-org/gitlab-ce/pipelines/129');
});
it('should render one ci status icon', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(1);
});
it('should render the correct ci status icon', () => {
const iconElement = this.component.$el.querySelector('.linked-pipeline-mini-item');
expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true);
expect(iconElement.innerHTML).toContain('<svg');
});
it('should render an arrow icon', () => {
const iconElement = this.component.$el.querySelector('.arrow-icon');
expect(iconElement).not.toBeNull();
expect(iconElement.innerHTML).toContain('<svg');
});
it('should have an activated tooltip', () => {
const itemElement = this.component.$el.querySelector('.linked-pipeline-mini-item');
expect(itemElement.getAttribute('data-original-title')).toBe('GitLabCE - running');
});
it('should correctly set is-upstream', () => {
expect(this.component.$el.classList.contains('is-upstream')).toBe(true);
});
it('should correctly compute shouldRenderCounter', () => {
expect(this.component.shouldRenderCounter).toBe(false);
});
it('should not render the pipeline counter', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter')).toBeNull();
});
});
describe('when passed downstream pipelines as props', () => {
beforeEach(() => {
this.component = new ListComponent({
propsData: {
triggered: mockData.triggered,
pipelinePath: 'my/pipeline/path',
},
}).$mount();
});
it('should render one linked pipeline item', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item:not(.linked-pipelines-counter)').length).toBe(3);
});
it('should render three ci status icons', () => {
expect(this.component.$el.querySelectorAll('.linked-pipeline-mini-item svg').length).toBe(3);
});
it('should render the correct ci status icon', () => {
const iconElement = this.component.$el.querySelector('.linked-pipeline-mini-item');
expect(iconElement.classList.contains('ci-status-icon-running')).toBe(true);
expect(iconElement.innerHTML).toContain('<svg');
});
it('should render an arrow icon', () => {
const iconElement = this.component.$el.querySelector('.arrow-icon');
expect(iconElement).not.toBeNull();
expect(iconElement.innerHTML).toContain('<svg');
});
it('should have prepped tooltips', () => {
const itemElement = this.component.$el.querySelectorAll('.linked-pipeline-mini-item')[2];
expect(itemElement.getAttribute('title')).toBe('GitLabCE - running');
});
it('should correctly set is-downstream', () => {
expect(this.component.$el.classList.contains('is-downstream')).toBe(true);
});
it('should correctly compute shouldRenderCounter', () => {
expect(this.component.shouldRenderCounter).toBe(true);
});
it('should correctly trim linkedPipelines', () => {
expect(this.component.triggered.length).toBe(6);
expect(this.component.linkedPipelinesTrimmed.length).toBe(3);
});
it('should render the pipeline counter', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter')).not.toBeNull();
});
it('should set the correct pipeline path', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter').getAttribute('href')).toBe('my/pipeline/path');
});
it('should render the correct counterTooltipText', () => {
expect(this.component.$el.querySelector('.linked-pipelines-counter').getAttribute('data-original-title')).toBe(this.component.counterTooltipText);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment