diff options
Diffstat (limited to 'spec/frontend/vue_merge_request_widget/deployment/deployment_spec.js')
-rw-r--r-- | spec/frontend/vue_merge_request_widget/deployment/deployment_spec.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/spec/frontend/vue_merge_request_widget/deployment/deployment_spec.js b/spec/frontend/vue_merge_request_widget/deployment/deployment_spec.js new file mode 100644 index 00000000000..c27cbd8b781 --- /dev/null +++ b/spec/frontend/vue_merge_request_widget/deployment/deployment_spec.js @@ -0,0 +1,187 @@ +import { mount } from '@vue/test-utils'; +import { + CREATED, + RUNNING, + SUCCESS, + FAILED, + CANCELED, + SKIPPED, +} from '~/vue_merge_request_widget/components/deployment/constants'; +import DeploymentComponent from '~/vue_merge_request_widget/components/deployment/deployment.vue'; +import DeploymentInfo from '~/vue_merge_request_widget/components/deployment/deployment_info.vue'; +import DeploymentViewButton from '~/vue_merge_request_widget/components/deployment/deployment_view_button.vue'; +import { deploymentMockData, playDetails, retryDetails } from './deployment_mock_data'; + +describe('Deployment component', () => { + let wrapper; + + const factory = (options = {}) => { + // This destroys any wrappers created before a nested call to factory reassigns it + if (wrapper && wrapper.destroy) { + wrapper.destroy(); + } + wrapper = mount(DeploymentComponent, options); + }; + + beforeEach(() => { + factory({ + propsData: { + deployment: deploymentMockData, + showMetrics: false, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('always renders DeploymentInfo', () => { + expect(wrapper.find(DeploymentInfo).exists()).toBe(true); + }); + + describe('status message and buttons', () => { + const noActions = []; + const noDetails = { isManual: false }; + const deployDetail = { + ...playDetails, + isManual: true, + }; + + const retryDetail = { + ...retryDetails, + isManual: true, + }; + const defaultGroup = ['.js-deploy-url', '.js-stop-env']; + const manualDeployGroup = ['.js-manual-deploy-action', ...defaultGroup]; + const manualRedeployGroup = ['.js-manual-redeploy-action', ...defaultGroup]; + + describe.each` + status | previous | deploymentDetails | text | actionButtons + ${CREATED} | ${true} | ${deployDetail} | ${'Can be manually deployed to'} | ${manualDeployGroup} + ${CREATED} | ${true} | ${noDetails} | ${'Will deploy to'} | ${defaultGroup} + ${CREATED} | ${false} | ${deployDetail} | ${'Can be manually deployed to'} | ${noActions} + ${CREATED} | ${false} | ${noDetails} | ${'Will deploy to'} | ${noActions} + ${RUNNING} | ${true} | ${deployDetail} | ${'Deploying to'} | ${defaultGroup} + ${RUNNING} | ${true} | ${noDetails} | ${'Deploying to'} | ${defaultGroup} + ${RUNNING} | ${false} | ${deployDetail} | ${'Deploying to'} | ${noActions} + ${RUNNING} | ${false} | ${noDetails} | ${'Deploying to'} | ${noActions} + ${SUCCESS} | ${true} | ${deployDetail} | ${'Deployed to'} | ${defaultGroup} + ${SUCCESS} | ${true} | ${noDetails} | ${'Deployed to'} | ${defaultGroup} + ${SUCCESS} | ${false} | ${deployDetail} | ${'Deployed to'} | ${defaultGroup} + ${SUCCESS} | ${false} | ${noDetails} | ${'Deployed to'} | ${defaultGroup} + ${FAILED} | ${true} | ${retryDetail} | ${'Failed to deploy to'} | ${manualRedeployGroup} + ${FAILED} | ${true} | ${noDetails} | ${'Failed to deploy to'} | ${defaultGroup} + ${FAILED} | ${false} | ${retryDetail} | ${'Failed to deploy to'} | ${noActions} + ${FAILED} | ${false} | ${noDetails} | ${'Failed to deploy to'} | ${noActions} + ${CANCELED} | ${true} | ${deployDetail} | ${'Canceled deployment to'} | ${defaultGroup} + ${CANCELED} | ${true} | ${noDetails} | ${'Canceled deployment to'} | ${defaultGroup} + ${CANCELED} | ${false} | ${deployDetail} | ${'Canceled deployment to'} | ${noActions} + ${CANCELED} | ${false} | ${noDetails} | ${'Canceled deployment to'} | ${noActions} + ${SKIPPED} | ${true} | ${deployDetail} | ${'Skipped deployment to'} | ${defaultGroup} + ${SKIPPED} | ${true} | ${noDetails} | ${'Skipped deployment to'} | ${defaultGroup} + ${SKIPPED} | ${false} | ${deployDetail} | ${'Skipped deployment to'} | ${noActions} + ${SKIPPED} | ${false} | ${noDetails} | ${'Skipped deployment to'} | ${noActions} + `( + '$status + previous: $previous + manual: $deploymentDetails.isManual', + ({ status, previous, deploymentDetails, text, actionButtons }) => { + beforeEach(() => { + const previousOrSuccess = Boolean(previous || status === SUCCESS); + const updatedDeploymentData = { + status, + deployed_at: previous ? deploymentMockData.deployed_at : null, + deployed_at_formatted: previous ? deploymentMockData.deployed_at_formatted : null, + external_url: previousOrSuccess ? deploymentMockData.external_url : null, + external_url_formatted: previousOrSuccess + ? deploymentMockData.external_url_formatted + : null, + stop_url: previousOrSuccess ? deploymentMockData.stop_url : null, + details: deploymentDetails, + }; + + factory({ + propsData: { + showMetrics: false, + deployment: { + ...deploymentMockData, + ...updatedDeploymentData, + }, + }, + }); + }); + + it(`renders the text: ${text}`, () => { + expect(wrapper.find(DeploymentInfo).text()).toContain(text); + }); + + if (actionButtons.length > 0) { + describe('renders the expected button group', () => { + actionButtons.forEach((button) => { + it(`renders ${button}`, () => { + expect(wrapper.find(button).exists()).toBe(true); + }); + }); + }); + } + + if (actionButtons.length === 0) { + describe('does not render the button group', () => { + defaultGroup.forEach((button) => { + it(`does not render ${button}`, () => { + expect(wrapper.find(button).exists()).toBe(false); + }); + }); + }); + } + + if (actionButtons.includes(DeploymentViewButton)) { + it('renders the View button with expected text', () => { + if (status === SUCCESS) { + expect(wrapper.find(DeploymentViewButton).text()).toContain('View app'); + } else { + expect(wrapper.find(DeploymentViewButton).text()).toContain('View latest app'); + } + }); + } + }, + ); + }); + + describe('hasExternalUrls', () => { + describe('when deployment has both external_url_formatted and external_url', () => { + it('should render the View Button', () => { + expect(wrapper.find(DeploymentViewButton).exists()).toBe(true); + }); + }); + + describe('when deployment has no external_url_formatted', () => { + beforeEach(() => { + factory({ + propsData: { + deployment: { ...deploymentMockData, external_url_formatted: null }, + showMetrics: false, + }, + }); + }); + + it('should not render the View Button', () => { + expect(wrapper.find(DeploymentViewButton).exists()).toBe(false); + }); + }); + + describe('when deployment has no external_url', () => { + beforeEach(() => { + factory({ + propsData: { + deployment: { ...deploymentMockData, external_url: null }, + showMetrics: false, + }, + }); + }); + + it('should not render the View Button', () => { + expect(wrapper.find(DeploymentViewButton).exists()).toBe(false); + }); + }); + }); +}); |