diff options
author | Phil Hughes <me@iamphill.com> | 2017-08-29 15:38:22 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2017-08-29 15:38:22 +0000 |
commit | 0229ab481488d0a2a900474cee8b51a5129a87dc (patch) | |
tree | 642e7a3f1d9fef2b7604f0d91d05e7d246727f2e | |
parent | 2a8dec2c27726cd0af995de97e596eab78e6efbf (diff) | |
parent | efd5e533b6d45abb258501356496e1af0c112e7d (diff) | |
download | gitlab-ce-0229ab481488d0a2a900474cee8b51a5129a87dc.tar.gz |
Merge branch '35048-empty-badges' into 'master'
Prevents rendering empty badge when pipeline request fails
Closes #35048
See merge request !13897
4 files changed, 170 insertions, 20 deletions
diff --git a/app/assets/javascripts/pipelines/components/navigation_tabs.vue b/app/assets/javascripts/pipelines/components/navigation_tabs.vue index d2f6d47f043..73f7e3a0cad 100644 --- a/app/assets/javascripts/pipelines/components/navigation_tabs.vue +++ b/app/assets/javascripts/pipelines/components/navigation_tabs.vue @@ -1,23 +1,29 @@ <script> -export default { - name: 'PipelineNavigationTabs', - props: { - scope: { - type: String, - required: true, + export default { + name: 'PipelineNavigationTabs', + props: { + scope: { + type: String, + required: true, + }, + count: { + type: Object, + required: true, + }, + paths: { + type: Object, + required: true, + }, }, - count: { - type: Object, - required: true, + mounted() { + $(document).trigger('init.scrolling-tabs'); }, - paths: { - type: Object, - required: true, + methods: { + shouldRenderBadge(count) { + // 0 is valid in a badge, but evaluates to false, we need to check for undefined + return count !== undefined; + }, }, - }, - mounted() { - $(document).trigger('init.scrolling-tabs'); - }, }; </script> <template> @@ -27,7 +33,9 @@ export default { :class="{ active: scope === 'all'}"> <a :href="paths.allPath"> All - <span class="badge js-totalbuilds-count"> + <span + v-if="shouldRenderBadge(count.all)" + class="badge js-totalbuilds-count"> {{count.all}} </span> </a> @@ -37,7 +45,9 @@ export default { :class="{ active: scope === 'pending'}"> <a :href="paths.pendingPath"> Pending - <span class="badge"> + <span + v-if="shouldRenderBadge(count.pending)" + class="badge"> {{count.pending}} </span> </a> @@ -47,7 +57,9 @@ export default { :class="{ active: scope === 'running'}"> <a :href="paths.runningPath"> Running - <span class="badge"> + <span + v-if="shouldRenderBadge(count.running)" + class="badge"> {{count.running}} </span> </a> @@ -57,7 +69,9 @@ export default { :class="{ active: scope === 'finished'}"> <a :href="paths.finishedPath"> Finished - <span class="badge"> + <span + v-if="shouldRenderBadge(count.finished)" + class="badge"> {{count.finished}} </span> </a> diff --git a/changelogs/unreleased/35048-empty-badges.yml b/changelogs/unreleased/35048-empty-badges.yml new file mode 100644 index 00000000000..816fe82887c --- /dev/null +++ b/changelogs/unreleased/35048-empty-badges.yml @@ -0,0 +1,5 @@ +--- +title: Prevents rendering empty badges when request fails +merge_request: +author: +type: fixed diff --git a/spec/javascripts/helpers/vue_mount_component_helper.js b/spec/javascripts/helpers/vue_mount_component_helper.js new file mode 100644 index 00000000000..d7a2e86771c --- /dev/null +++ b/spec/javascripts/helpers/vue_mount_component_helper.js @@ -0,0 +1,4 @@ +export default (Component, props = {}) => new Component({ + propsData: props, +}).$mount(); + diff --git a/spec/javascripts/pipelines/navigation_tabs_spec.js b/spec/javascripts/pipelines/navigation_tabs_spec.js new file mode 100644 index 00000000000..53a88e6322f --- /dev/null +++ b/spec/javascripts/pipelines/navigation_tabs_spec.js @@ -0,0 +1,127 @@ +import Vue from 'vue'; +import navigationTabs from '~/pipelines/components/navigation_tabs.vue'; +import mountComponent from '../helpers/vue_mount_component_helper'; + +describe('navigation tabs pipeline component', () => { + let vm; + let Component; + let data; + + beforeEach(() => { + data = { + scope: 'all', + count: { + all: 16, + running: 1, + pending: 10, + finished: 0, + }, + paths: { + allPath: '/gitlab-org/gitlab-ce/pipelines', + pendingPath: '/gitlab-org/gitlab-ce/pipelines?scope=pending', + finishedPath: '/gitlab-org/gitlab-ce/pipelines?scope=finished', + runningPath: '/gitlab-org/gitlab-ce/pipelines?scope=running', + branchesPath: '/gitlab-org/gitlab-ce/pipelines?scope=branches', + tagsPath: '/gitlab-org/gitlab-ce/pipelines?scope=tags', + }, + }; + + Component = Vue.extend(navigationTabs); + }); + + afterEach(() => { + vm.$destroy(); + }); + + it('should render tabs with correct paths', () => { + vm = mountComponent(Component, data); + + // All + const allTab = vm.$el.querySelector('.js-pipelines-tab-all a'); + expect(allTab.textContent.trim()).toContain('All'); + expect(allTab.getAttribute('href')).toEqual(data.paths.allPath); + + // Pending + const pendingTab = vm.$el.querySelector('.js-pipelines-tab-pending a'); + expect(pendingTab.textContent.trim()).toContain('Pending'); + expect(pendingTab.getAttribute('href')).toEqual(data.paths.pendingPath); + + // Running + const runningTab = vm.$el.querySelector('.js-pipelines-tab-running a'); + expect(runningTab.textContent.trim()).toContain('Running'); + expect(runningTab.getAttribute('href')).toEqual(data.paths.runningPath); + + // Finished + const finishedTab = vm.$el.querySelector('.js-pipelines-tab-finished a'); + expect(finishedTab.textContent.trim()).toContain('Finished'); + expect(finishedTab.getAttribute('href')).toEqual(data.paths.finishedPath); + + // Branches + const branchesTab = vm.$el.querySelector('.js-pipelines-tab-branches a'); + expect(branchesTab.textContent.trim()).toContain('Branches'); + + // Tags + const tagsTab = vm.$el.querySelector('.js-pipelines-tab-tags a'); + expect(tagsTab.textContent.trim()).toContain('Tags'); + }); + + describe('scope', () => { + it('should render scope provided as active tab', () => { + vm = mountComponent(Component, data); + expect(vm.$el.querySelector('.js-pipelines-tab-all').className).toContain('active'); + }); + }); + + describe('badges', () => { + it('should render provided number', () => { + vm = mountComponent(Component, data); + // All + expect( + vm.$el.querySelector('.js-totalbuilds-count').textContent.trim(), + ).toContain(data.count.all); + + // Pending + expect( + vm.$el.querySelector('.js-pipelines-tab-pending .badge').textContent.trim(), + ).toContain(data.count.pending); + + // Running + expect( + vm.$el.querySelector('.js-pipelines-tab-running .badge').textContent.trim(), + ).toContain(data.count.running); + + // Finished + expect( + vm.$el.querySelector('.js-pipelines-tab-finished .badge').textContent.trim(), + ).toContain(data.count.finished); + }); + + it('should not render badge when number is undefined', () => { + vm = mountComponent(Component, { + scope: 'all', + paths: {}, + count: {}, + }); + + // All + expect( + vm.$el.querySelector('.js-totalbuilds-count'), + ).toEqual(null); + + // Pending + expect( + vm.$el.querySelector('.js-pipelines-tab-pending .badge'), + ).toEqual(null); + + // Running + expect( + vm.$el.querySelector('.js-pipelines-tab-running .badge'), + ).toEqual(null); + + // Finished + expect( + vm.$el.querySelector('.js-pipelines-tab-finished .badge'), + ).toEqual(null); + }); + }); +}); |