debian-mirror-gitlab/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js
2022-04-04 11:22:00 +05:30

234 lines
8.1 KiB
JavaScript

import { mount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import createFlash from '~/flash';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { visitUrl } from '~/lib/utils/url_utility';
import {
CREATED,
MANUAL_DEPLOY,
FAILED,
DEPLOYING,
REDEPLOYING,
STOPPING,
} from '~/vue_merge_request_widget/components/deployment/constants';
import DeploymentActions from '~/vue_merge_request_widget/components/deployment/deployment_actions.vue';
import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service';
import {
actionButtonMocks,
deploymentMockData,
playDetails,
retryDetails,
} from './deployment_mock_data';
jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility');
jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => {
return {
confirmAction: jest.fn(),
};
});
describe('DeploymentAction component', () => {
let wrapper;
let executeActionSpy;
const factory = (options = {}) => {
// This destroys any wrappers created before a nested call to factory reassigns it
if (wrapper && wrapper.destroy) {
wrapper.destroy();
}
wrapper = mount(DeploymentActions, options);
};
const findStopButton = () => wrapper.find('.js-stop-env');
const findDeployButton = () => wrapper.find('.js-manual-deploy-action');
const findRedeployButton = () => wrapper.find('.js-manual-redeploy-action');
beforeEach(() => {
executeActionSpy = jest.spyOn(MRWidgetService, 'executeInlineAction');
factory({
propsData: {
computedDeploymentStatus: CREATED,
deployment: deploymentMockData,
},
});
});
afterEach(() => {
wrapper.destroy();
confirmAction.mockReset();
});
describe('actions do not appear when conditions are unmet', () => {
describe('when there is no stop_url', () => {
beforeEach(() => {
factory({
propsData: {
computedDeploymentStatus: CREATED,
deployment: {
...deploymentMockData,
stop_url: null,
},
},
});
});
it('the stop button does not appear', () => {
expect(findStopButton().exists()).toBe(false);
});
});
describe('when there is no play_path in details', () => {
it('the manual deploy button does not appear', () => {
expect(findDeployButton().exists()).toBe(false);
});
});
describe('when there is no retry_path in details', () => {
it('the manual redeploy button does not appear', () => {
expect(findRedeployButton().exists()).toBe(false);
});
});
});
describe('when conditions are met', () => {
describe.each`
configConst | computedDeploymentStatus | displayConditionChanges | finderFn | endpoint
${STOPPING} | ${CREATED} | ${{}} | ${findStopButton} | ${deploymentMockData.stop_url}
${DEPLOYING} | ${MANUAL_DEPLOY} | ${playDetails} | ${findDeployButton} | ${playDetails.playable_build.play_path}
${REDEPLOYING} | ${FAILED} | ${retryDetails} | ${findRedeployButton} | ${retryDetails.playable_build.retry_path}
`(
'$configConst action',
({ configConst, computedDeploymentStatus, displayConditionChanges, finderFn, endpoint }) => {
describe(`${configConst} action`, () => {
beforeEach(() => {
factory({
propsData: {
computedDeploymentStatus,
deployment: {
...deploymentMockData,
details: displayConditionChanges,
},
},
});
});
it('the button is rendered', () => {
expect(finderFn().exists()).toBe(true);
});
describe('when clicked', () => {
describe('should show a confirm dialog but not call executeInlineAction when declined', () => {
beforeEach(() => {
executeActionSpy.mockResolvedValueOnce();
confirmAction.mockResolvedValueOnce(false);
finderFn().trigger('click');
});
it('should show the confirm dialog', () => {
expect(confirmAction).toHaveBeenCalled();
expect(confirmAction).toHaveBeenCalledWith(
actionButtonMocks[configConst].confirmMessage,
{
primaryBtnVariant: actionButtonMocks[configConst].buttonVariant,
primaryBtnText: actionButtonMocks[configConst].buttonText,
},
);
});
it('should not execute the action', () => {
expect(MRWidgetService.executeInlineAction).not.toHaveBeenCalled();
});
});
describe('should show a confirm dialog and call executeInlineAction when accepted', () => {
beforeEach(() => {
executeActionSpy.mockResolvedValueOnce();
confirmAction.mockResolvedValueOnce(true);
finderFn().trigger('click');
});
it('should show the confirm dialog', () => {
expect(confirmAction).toHaveBeenCalled();
expect(confirmAction).toHaveBeenCalledWith(
actionButtonMocks[configConst].confirmMessage,
{
primaryBtnVariant: actionButtonMocks[configConst].buttonVariant,
primaryBtnText: actionButtonMocks[configConst].buttonText,
},
);
});
it('should execute the action with expected URL', () => {
expect(MRWidgetService.executeInlineAction).toHaveBeenCalled();
expect(MRWidgetService.executeInlineAction).toHaveBeenCalledWith(endpoint);
});
it('should not throw an error', () => {
expect(createFlash).not.toHaveBeenCalled();
});
describe('response includes redirect_url', () => {
const url = '/root/example';
beforeEach(async () => {
executeActionSpy.mockResolvedValueOnce({
data: { redirect_url: url },
});
await waitForPromises();
confirmAction.mockResolvedValueOnce(true);
finderFn().trigger('click');
});
it('calls visit url with the redirect_url', () => {
expect(visitUrl).toHaveBeenCalled();
expect(visitUrl).toHaveBeenCalledWith(url);
});
});
describe('it should call the executeAction method ', () => {
beforeEach(async () => {
jest.spyOn(wrapper.vm, 'executeAction').mockImplementation();
await waitForPromises();
confirmAction.mockResolvedValueOnce(true);
finderFn().trigger('click');
});
it('calls with the expected arguments', () => {
expect(wrapper.vm.executeAction).toHaveBeenCalled();
expect(wrapper.vm.executeAction).toHaveBeenCalledWith(
endpoint,
actionButtonMocks[configConst],
);
});
});
describe('when executeInlineAction errors', () => {
beforeEach(async () => {
executeActionSpy.mockRejectedValueOnce();
await waitForPromises();
confirmAction.mockResolvedValueOnce(true);
finderFn().trigger('click');
});
it('should call createFlash with error message', () => {
expect(createFlash).toHaveBeenCalled();
expect(createFlash).toHaveBeenCalledWith({
message: actionButtonMocks[configConst].errorMessage,
});
});
});
});
});
});
},
);
});
});