summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinnie Hellmann <winnie@gitlab.com>2018-10-04 14:53:15 +0200
committerWinnie Hellmann <winnie@gitlab.com>2018-10-04 14:54:22 +0200
commit0fc93df02b7d1be4ec243298ff17045cbd4f049a (patch)
tree33d9a3287f7cffad7074921f794d071bc583b655
parent4741c07f3fa61326665c36d4b9974025bf9dd9e9 (diff)
downloadgitlab-ce-0fc93df02b7d1be4ec243298ff17045cbd4f049a.tar.gz
Add component tests for scheduled job frontend
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js1
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_actions.vue2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_table_row.vue6
-rw-r--r--spec/javascripts/pipelines/pipelines_actions_spec.js89
-rw-r--r--spec/javascripts/pipelines/pipelines_table_row_spec.js7
5 files changed, 75 insertions, 30 deletions
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index abfcf1eaf3f..833dbefd3dc 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -373,6 +373,7 @@ window.gl.utils = {
/**
* Formats milliseconds as timestamp (e.g. 01:02:03).
+ * This takes durations longer than a day into account (e.g. two days would be 48:00:00).
*
* @param milliseconds
* @returns {string}
diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
index f0e845d0773..743d241ee7a 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue
@@ -27,7 +27,7 @@ export default {
onClickAction(action) {
if (action.scheduled_at) {
const confirmationMessage = sprintf(s__("DelayedJobs|Are you sure you want to run %{jobName} immediately? This job will run automatically after it's timer finishes."), { jobName: action.name });
- // https://gitlab.com/gitlab-org/gitlab-ce/issues/52099
+ // https://gitlab.com/gitlab-org/gitlab-ce/issues/52156
// eslint-disable-next-line no-alert
if (!window.confirm(confirmationMessage)) {
return;
diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
index 88957554d12..09ee190b8ca 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue
@@ -63,10 +63,10 @@ export default {
if (!this.pipeline || !this.pipeline.details) {
return [];
}
- const { details: pipelineDetails } = this.pipeline;
+ const { details } = this.pipeline;
return [
- ...(pipelineDetails.manual_actions || []),
- ...(pipelineDetails.scheduled_actions || []),
+ ...(details.manual_actions || []),
+ ...(details.scheduled_actions || []),
];
},
/**
diff --git a/spec/javascripts/pipelines/pipelines_actions_spec.js b/spec/javascripts/pipelines/pipelines_actions_spec.js
index 72fb0a8f9ef..fe60a883f77 100644
--- a/spec/javascripts/pipelines/pipelines_actions_spec.js
+++ b/spec/javascripts/pipelines/pipelines_actions_spec.js
@@ -1,46 +1,83 @@
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 findDropdownItem = () => vm.$el.querySelector('.dropdown-menu li button');
+
+ beforeEach(() => {
+ spyOn(Date, 'now').and.callFake(() => new Date('2063-04-04T00:42:00Z').getTime());
+ vm = mountComponent(Component, { actions: [scheduledJobAction] });
+ });
+
+ it('emits postAction event after confirming', () => {
+ const emitSpy = jasmine.createSpy('emit');
+ eventHub.$on('postAction', emitSpy);
+ spyOn(window, 'confirm').and.callFake(() => true);
+
+ findDropdownItem().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().click();
+
+ expect(window.confirm).toHaveBeenCalled();
+ expect(emitSpy).not.toHaveBeenCalled();
+ });
- expect(
- component.$el.querySelector('.dropdown-menu li:last-child button').classList.contains('disabled'),
- ).toEqual(true);
+ it('displays the remaining time in the dropdown', () => {
+ expect(findDropdownItem()).toContainText('24: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', () => {