diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue index 602b68ea5726691ef0d455690e3ddd6de8f2a867..7d366c495f087a421601654b998b40ba4fb3f55c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue @@ -1,66 +1,70 @@ <script> - import { n__ } from '~/locale'; - import statusIcon from '../mr_widget_status_icon.vue'; - import eventHub from '../../event_hub'; +import { n__ } from '~/locale'; +import statusIcon from '../mr_widget_status_icon.vue'; +import eventHub from '../../event_hub'; - export default { - name: 'MRWidgetFailedToMerge', +export default { + name: 'MRWidgetFailedToMerge', - components: { - statusIcon, - }, + components: { + statusIcon, + }, - props: { - mr: { - type: Object, - required: true, - default: () => ({}), - }, + props: { + mr: { + type: Object, + required: true, + default: () => ({}), }, + }, - data() { - return { - timer: 10, - isRefreshing: false, - }; - }, + data() { + return { + timer: 10, + isRefreshing: false, + intervalId: null, + }; + }, - computed: { - timerText() { - return n__( - 'Refreshing in a second to show the updated status...', - 'Refreshing in %d seconds to show the updated status...', - this.timer, - ); - }, + computed: { + timerText() { + return n__( + 'Refreshing in a second to show the updated status...', + 'Refreshing in %d seconds to show the updated status...', + this.timer, + ); }, + }, - mounted() { - setInterval(() => { - this.updateTimer(); - }, 1000); - }, + mounted() { + this.intervalId = setInterval(this.updateTimer, 1000); + }, - created() { - eventHub.$emit('DisablePolling'); - }, + created() { + eventHub.$emit('DisablePolling'); + }, - methods: { - refresh() { - this.isRefreshing = true; - eventHub.$emit('MRWidgetUpdateRequested'); - eventHub.$emit('EnablePolling'); - }, - updateTimer() { - this.timer = this.timer - 1; + beforeDestroy() { + if (this.intervalId) { + clearInterval(this.intervalId); + } + }, - if (this.timer === 0) { - this.refresh(); - } - }, + methods: { + refresh() { + this.isRefreshing = true; + eventHub.$emit('MRWidgetUpdateRequested'); + eventHub.$emit('EnablePolling'); }, + updateTimer() { + this.timer = this.timer - 1; - }; + if (this.timer === 0) { + this.refresh(); + } + }, + }, +}; </script> <template> <div class="mr-widget-body media"> diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js index dd1d62cd4edb6348866eef06352674b1bb260999..a0a74648328ad18a649ea7e51564eb93a2a499d6 100644 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js +++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_failed_to_merge_spec.js @@ -4,21 +4,37 @@ import eventHub from '~/vue_merge_request_widget/event_hub'; import mountComponent from 'spec/helpers/vue_mount_component_helper'; describe('MRWidgetFailedToMerge', () => { + const dummyIntervalId = 1337; let Component; let vm; beforeEach(() => { Component = Vue.extend(failedToMergeComponent); spyOn(eventHub, '$emit'); - vm = mountComponent(Component, { mr: { - mergeError: 'Merge error happened.', - } }); + spyOn(window, 'setInterval').and.returnValue(dummyIntervalId); + spyOn(window, 'clearInterval').and.stub(); + vm = mountComponent(Component, { + mr: { + mergeError: 'Merge error happened.', + }, + }); }); afterEach(() => { vm.$destroy(); }); + it('sets interval to refresh', () => { + expect(window.setInterval).toHaveBeenCalledWith(vm.updateTimer, 1000); + expect(vm.intervalId).toBe(dummyIntervalId); + }); + + it('clears interval when destroying ', () => { + vm.$destroy(); + + expect(window.clearInterval).toHaveBeenCalledWith(dummyIntervalId); + }); + describe('computed', () => { describe('timerText', () => { it('should return correct timer text', () => { @@ -65,11 +81,13 @@ describe('MRWidgetFailedToMerge', () => { }); describe('while it is refreshing', () => { - it('renders Refresing now', (done) => { + it('renders Refresing now', done => { vm.isRefreshing = true; Vue.nextTick(() => { - expect(vm.$el.querySelector('.js-refresh-label').textContent.trim()).toEqual('Refreshing now'); + expect(vm.$el.querySelector('.js-refresh-label').textContent.trim()).toEqual( + 'Refreshing now', + ); done(); }); }); @@ -78,11 +96,15 @@ describe('MRWidgetFailedToMerge', () => { describe('while it is not regresing', () => { it('renders warning icon and disabled merge button', () => { expect(vm.$el.querySelector('.js-ci-status-icon-warning')).not.toBeNull(); - expect(vm.$el.querySelector('.js-disabled-merge-button').getAttribute('disabled')).toEqual('disabled'); + expect(vm.$el.querySelector('.js-disabled-merge-button').getAttribute('disabled')).toEqual( + 'disabled', + ); }); it('renders given error', () => { - expect(vm.$el.querySelector('.has-error-message').textContent.trim()).toEqual('Merge error happened..'); + expect(vm.$el.querySelector('.has-error-message').textContent.trim()).toEqual( + 'Merge error happened..', + ); }); it('renders refresh button', () => { @@ -90,13 +112,13 @@ describe('MRWidgetFailedToMerge', () => { }); it('renders remaining time', () => { - expect( - vm.$el.querySelector('.has-custom-error').textContent.trim(), - ).toEqual('Refreshing in 10 seconds to show the updated status...'); + expect(vm.$el.querySelector('.has-custom-error').textContent.trim()).toEqual( + 'Refreshing in 10 seconds to show the updated status...', + ); }); }); - it('should just generic merge failed message if merge_error is not available', (done) => { + it('should just generic merge failed message if merge_error is not available', done => { vm.mr.mergeError = null; Vue.nextTick(() => { @@ -106,7 +128,7 @@ describe('MRWidgetFailedToMerge', () => { }); }); - it('should show refresh label when refresh requested', (done) => { + it('should show refresh label when refresh requested', done => { vm.refresh(); Vue.nextTick(() => { expect(vm.$el.innerText).not.toContain('Merge failed. Refreshing');