diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2018-10-05 16:30:33 +0000 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2018-10-05 16:30:33 +0000 |
commit | 059da9bc8eb9355a760031ef8e73b0aa6285012f (patch) | |
tree | b6057c99d0c53951a650122d624dc37405194551 /spec/javascripts | |
parent | 7f86172f806558d2b614abcb06cef0ea516c5900 (diff) | |
parent | 7542a5d102bc48f5f7b8104fda22f0975b2dd931 (diff) | |
download | gitlab-ce-059da9bc8eb9355a760031ef8e73b0aa6285012f.tar.gz |
Merge branch 'scheduled-manual-jobs' into 'master'
Delayed jobs
Closes #51352
See merge request gitlab-org/gitlab-ce!21767
Diffstat (limited to 'spec/javascripts')
-rw-r--r-- | spec/javascripts/datetime_utility_spec.js | 25 | ||||
-rw-r--r-- | spec/javascripts/pipelines/pipelines_actions_spec.js | 104 | ||||
-rw-r--r-- | spec/javascripts/pipelines/pipelines_table_row_spec.js | 7 |
3 files changed, 104 insertions, 32 deletions
diff --git a/spec/javascripts/datetime_utility_spec.js b/spec/javascripts/datetime_utility_spec.js index 492171684dc..6c3e73f134e 100644 --- a/spec/javascripts/datetime_utility_spec.js +++ b/spec/javascripts/datetime_utility_spec.js @@ -6,9 +6,7 @@ describe('Date time utils', () => { const date = new Date(); date.setFullYear(date.getFullYear() - 1); - expect( - datetimeUtility.timeFor(date), - ).toBe('Past due'); + expect(datetimeUtility.timeFor(date)).toBe('Past due'); }); it('returns remaining time when in the future', () => { @@ -19,9 +17,7 @@ describe('Date time utils', () => { // short of a full year, timeFor will return '11 months remaining' date.setDate(date.getDate() + 1); - expect( - datetimeUtility.timeFor(date), - ).toBe('1 year remaining'); + expect(datetimeUtility.timeFor(date)).toBe('1 year remaining'); }); }); @@ -168,3 +164,20 @@ describe('getTimeframeWindowFrom', () => { }); }); }); + +describe('formatTime', () => { + const expectedTimestamps = [ + [0, '00:00:00'], + [1000, '00:00:01'], + [42000, '00:00:42'], + [121000, '00:02:01'], + [10921000, '03:02:01'], + [108000000, '30:00:00'], + ]; + + expectedTimestamps.forEach(([milliseconds, expectedTimestamp]) => { + it(`formats ${milliseconds}ms as ${expectedTimestamp}`, () => { + expect(datetimeUtility.formatTime(milliseconds)).toBe(expectedTimestamp); + }); + }); +}); diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js index 72fb0a8f9ef..0566bc55693 100644 --- a/spec/javascripts/pipelines/pipelines_actions_spec.js +++ b/spec/javascripts/pipelines/pipelines_actions_spec.js @@ -1,46 +1,98 @@ import Vue from 'vue'; -import pipelinesActionsComp from '~/pipelines/components/pipelines_actions.vue'; +import eventHub from '~/pipelines/event_hub'; +import PipelinesActions from '~/pipelines/components/pipelines_actions.vue'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import { TEST_HOST } from 'spec/test_constants'; describe('Pipelines Actions dropdown', () => { - let component; - let actions; - let ActionsComponent; + const Component = Vue.extend(PipelinesActions); + let vm; - beforeEach(() => { - ActionsComponent = Vue.extend(pipelinesActionsComp); + afterEach(() => { + vm.$destroy(); + }); - actions = [ + describe('manual actions', () => { + const actions = [ { name: 'stop_review', - path: '/root/review-app/builds/1893/play', + path: `${TEST_HOST}/root/review-app/builds/1893/play`, }, { name: 'foo', - path: '#', + path: `${TEST_HOST}/disabled/pipeline/action`, playable: false, }, ]; - component = new ActionsComponent({ - propsData: { - actions, - }, - }).$mount(); - }); + beforeEach(() => { + vm = mountComponent(Component, { actions }); + }); - it('should render a dropdown with the provided actions', () => { - expect( - component.$el.querySelectorAll('.dropdown-menu li').length, - ).toEqual(actions.length); + it('renders a dropdown with the provided actions', () => { + const dropdownItems = vm.$el.querySelectorAll('.dropdown-menu li'); + expect(dropdownItems.length).toEqual(actions.length); + }); + + it("renders a disabled action when it's not playable", () => { + const dropdownItem = vm.$el.querySelector('.dropdown-menu li:last-child button'); + expect(dropdownItem).toBeDisabled(); + }); }); - it('should render a disabled action when it\'s not playable', () => { - expect( - component.$el.querySelector('.dropdown-menu li:last-child button').getAttribute('disabled'), - ).toEqual('disabled'); + describe('scheduled jobs', () => { + const scheduledJobAction = { + name: 'scheduled action', + path: `${TEST_HOST}/scheduled/job/action`, + playable: true, + scheduled_at: '2063-04-05T00:42:00Z', + }; + const expiredJobAction = { + name: 'expired action', + path: `${TEST_HOST}/expired/job/action`, + playable: true, + scheduled_at: '2018-10-05T08:23:00Z', + }; + const findDropdownItem = action => { + const buttons = vm.$el.querySelectorAll('.dropdown-menu li button'); + return Array.prototype.find.call(buttons, element => + element.innerText.trim().startsWith(action.name), + ); + }; + + beforeEach(() => { + spyOn(Date, 'now').and.callFake(() => new Date('2063-04-04T00:42:00Z').getTime()); + vm = mountComponent(Component, { actions: [scheduledJobAction, expiredJobAction] }); + }); + + it('emits postAction event after confirming', () => { + const emitSpy = jasmine.createSpy('emit'); + eventHub.$on('postAction', emitSpy); + spyOn(window, 'confirm').and.callFake(() => true); + + findDropdownItem(scheduledJobAction).click(); + + expect(window.confirm).toHaveBeenCalled(); + expect(emitSpy).toHaveBeenCalledWith(scheduledJobAction.path); + }); + + it('does not emit postAction event if confirmation is cancelled', () => { + const emitSpy = jasmine.createSpy('emit'); + eventHub.$on('postAction', emitSpy); + spyOn(window, 'confirm').and.callFake(() => false); + + findDropdownItem(scheduledJobAction).click(); + + expect(window.confirm).toHaveBeenCalled(); + expect(emitSpy).not.toHaveBeenCalled(); + }); + + it('displays the remaining time in the dropdown', () => { + expect(findDropdownItem(scheduledJobAction)).toContainText('24:00:00'); + }); - expect( - component.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'), - ).toEqual(true); + it('displays 00:00:00 for expired jobs in the dropdown', () => { + expect(findDropdownItem(expiredJobAction)).toContainText('00:00:00'); + }); }); }); diff --git a/spec/javascripts/pipelines/pipelines_table_row_spec.js b/spec/javascripts/pipelines/pipelines_table_row_spec.js index 03ffc122795..42795f5c134 100644 --- a/spec/javascripts/pipelines/pipelines_table_row_spec.js +++ b/spec/javascripts/pipelines/pipelines_table_row_spec.js @@ -158,8 +158,13 @@ describe('Pipelines Table Row', () => { }); describe('actions column', () => { + const scheduledJobAction = { + name: 'some scheduled job', + }; + beforeEach(() => { const withActions = Object.assign({}, pipeline); + withActions.details.scheduled_actions = [scheduledJobAction]; withActions.flags.cancelable = true; withActions.flags.retryable = true; withActions.cancel_path = '/cancel'; @@ -171,6 +176,8 @@ describe('Pipelines Table Row', () => { it('should render the provided actions', () => { expect(component.$el.querySelector('.js-pipelines-retry-button')).not.toBeNull(); expect(component.$el.querySelector('.js-pipelines-cancel-button')).not.toBeNull(); + const dropdownMenu = component.$el.querySelectorAll('.dropdown-menu'); + expect(dropdownMenu).toContainText(scheduledJobAction.name); }); it('emits `retryPipeline` event when retry button is clicked and toggles loading', () => { |