Commit 0fc93df0 authored by Winnie Hellmann's avatar Winnie Hellmann

Add component tests for scheduled job frontend

parent 4741c07f
......@@ -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}
......
......@@ -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;
......
......@@ -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 || []),
];
},
/**
......
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');
});
});
});
......@@ -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', () => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment