summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinnie Hellmann <winnie@gitlab.com>2018-10-22 14:32:30 +0200
committerWinnie Hellmann <winnie@gitlab.com>2018-10-22 17:04:56 +0200
commit0be930cb9ee90234a8b7e548f0b4faab9605c25a (patch)
tree313149cfca4830210f807e92d6da973017ed87ae
parent100b8d3759a96df4414ed17aed11f580a2aed6cf (diff)
downloadgitlab-ce-winh-extract-job-container-item.tar.gz
Extract JobContainerItem componentwinh-extract-job-container-item
-rw-r--r--app/assets/javascripts/jobs/components/job_container_item.vue65
-rw-r--r--app/assets/javascripts/jobs/components/jobs_container.vue53
-rw-r--r--spec/javascripts/jobs/components/job_container_item_spec.js73
3 files changed, 145 insertions, 46 deletions
diff --git a/app/assets/javascripts/jobs/components/job_container_item.vue b/app/assets/javascripts/jobs/components/job_container_item.vue
new file mode 100644
index 00000000000..8cb0decc8d3
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/job_container_item.vue
@@ -0,0 +1,65 @@
+<script>
+import _ from 'underscore';
+import CiIcon from '~/vue_shared/components/ci_icon.vue';
+import Icon from '~/vue_shared/components/icon.vue';
+import tooltip from '~/vue_shared/directives/tooltip';
+
+export default {
+ components: {
+ CiIcon,
+ Icon,
+ },
+
+ directives: {
+ tooltip,
+ },
+
+ props: {
+ job: {
+ type: Object,
+ required: true,
+ },
+ isActive: {
+ type: Boolean,
+ required: true,
+ },
+ },
+
+ computed: {
+ tooltipText() {
+ return `${_.escape(this.job.name)} - ${this.job.status.tooltip}`;
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="build-job"
+ :class="{ retried: job.retried, active: isActive }"
+ >
+ <a
+ v-tooltip
+ :href="job.status.details_path"
+ :title="tooltipText"
+ data-container="body"
+ data-boundary="viewport"
+ >
+ <icon
+ v-if="isActive"
+ name="arrow-right"
+ class="js-arrow-right icon-arrow-right"
+ />
+
+ <ci-icon :status="job.status" />
+
+ <span>{{ job.name ? job.name : job.id }}</span>
+
+ <icon
+ v-if="job.retried"
+ name="retry"
+ class="js-retry-icon"
+ />
+ </a>
+ </div>
+</template>
diff --git a/app/assets/javascripts/jobs/components/jobs_container.vue b/app/assets/javascripts/jobs/components/jobs_container.vue
index 03f36ec5c8b..951bcb36600 100644
--- a/app/assets/javascripts/jobs/components/jobs_container.vue
+++ b/app/assets/javascripts/jobs/components/jobs_container.vue
@@ -1,17 +1,11 @@
<script>
-import _ from 'underscore';
-import CiIcon from '~/vue_shared/components/ci_icon.vue';
-import Icon from '~/vue_shared/components/icon.vue';
-import tooltip from '~/vue_shared/directives/tooltip';
+import JobContainerItem from './job_container_item.vue';
export default {
components: {
- CiIcon,
- Icon,
- },
- directives: {
- tooltip,
+ JobContainerItem,
},
+
props: {
jobs: {
type: Array,
@@ -26,49 +20,16 @@ export default {
isJobActive(currentJobId) {
return this.jobId === currentJobId;
},
- tooltipText(job) {
- return `${_.escape(job.name)} - ${job.status.tooltip}`;
- },
},
};
</script>
<template>
<div class="js-jobs-container builds-container">
- <div
+ <job-container-item
v-for="job in jobs"
:key="job.id"
- class="build-job"
- :class="{ retried: job.retried, active: isJobActive(job.id) }"
- >
- <a
- v-tooltip
- :href="job.status.details_path"
- :title="tooltipText(job)"
- data-container="body"
- >
- <icon
- v-if="isJobActive(job.id)"
- name="arrow-right"
- class="js-arrow-right icon-arrow-right"
- />
-
- <ci-icon :status="job.status" />
-
- <span>
- <template v-if="job.name">
- {{ job.name }}
- </template>
- <template v-else>
- {{ job.id }}
- </template>
- </span>
-
- <icon
- v-if="job.retried"
- name="retry"
- class="js-retry-icon"
- />
- </a>
- </div>
+ :job="job"
+ :is-active="isJobActive(job.id)"
+ />
</div>
</template>
diff --git a/spec/javascripts/jobs/components/job_container_item_spec.js b/spec/javascripts/jobs/components/job_container_item_spec.js
new file mode 100644
index 00000000000..60f91081045
--- /dev/null
+++ b/spec/javascripts/jobs/components/job_container_item_spec.js
@@ -0,0 +1,73 @@
+import Vue from 'vue';
+import JobContainerItem from '~/jobs/components/job_container_item.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import job from '../mock_data';
+
+describe('JobContainerItem', () => {
+ const Component = Vue.extend(JobContainerItem);
+ let vm;
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ const sharedTests = () => {
+ it('displays a status icon', () => {
+ expect(vm.$el).toHaveSpriteIcon(job.status.icon);
+ });
+
+ it('displays the job name', () => {
+ expect(vm.$el).toContainText(job.name);
+ });
+
+ it('displays a link to the job', () => {
+ const link = vm.$el.querySelector('a');
+
+ expect(link.href).toBe(job.status.details_path);
+ });
+ };
+
+ describe('when a job is not active and not retied', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job,
+ isActive: false,
+ });
+ });
+
+ sharedTests();
+ });
+
+ describe('when a job is active', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job,
+ isActive: true,
+ });
+ });
+
+ sharedTests();
+
+ it('displays an arrow', () => {
+ expect(vm.$el).toHaveSpriteIcon('arrow-right');
+ });
+ });
+
+ describe('when a job is retried', () => {
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ job: {
+ ...job,
+ retried: true,
+ },
+ isActive: false,
+ });
+ });
+
+ sharedTests();
+
+ it('displays an icon', () => {
+ expect(vm.$el).toHaveSpriteIcon('retry');
+ });
+ });
+});