diff options
author | Filipa Lacerda <filipa@gitlab.com> | 2018-03-14 12:06:28 +0000 |
---|---|---|
committer | Filipa Lacerda <filipa@gitlab.com> | 2018-03-14 12:06:28 +0000 |
commit | 1b48285801735c95083d265d18ae5bd3555809ca (patch) | |
tree | f534dbf5716c8518bee4636bb8c46c191f1cfa3d | |
parent | 9673458edc607b75662a2e53b14de5fe40012fdd (diff) | |
parent | a4a893eaa80665076a26a22903bbae1652c62edf (diff) | |
download | gitlab-ce-1b48285801735c95083d265d18ae5bd3555809ca.tar.gz |
Merge branch 'mr-widget-deployment-styling' into 'master'
Fix styling of multiple environments in merge request widget
Closes #40610
See merge request gitlab-org/gitlab-ce!17663
9 files changed, 393 insertions, 345 deletions
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue new file mode 100644 index 00000000000..7bef2e97349 --- /dev/null +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment.vue @@ -0,0 +1,144 @@ +<script> +import timeagoMixin from '../../vue_shared/mixins/timeago'; +import tooltip from '../../vue_shared/directives/tooltip'; +import LoadingButton from '../../vue_shared/components/loading_button.vue'; +import { visitUrl } from '../../lib/utils/url_utility'; +import createFlash from '../../flash'; +import MemoryUsage from './memory_usage.vue'; +import StatusIcon from './mr_widget_status_icon.vue'; +import MRWidgetService from '../services/mr_widget_service'; + +export default { + name: 'Deployment', + components: { + LoadingButton, + MemoryUsage, + StatusIcon, + }, + directives: { + tooltip, + }, + mixins: [ + timeagoMixin, + ], + props: { + deployment: { + type: Object, + required: true, + }, + }, + data() { + return { + isStopping: false, + }; + }, + computed: { + deployTimeago() { + return this.timeFormated(this.deployment.deployed_at); + }, + hasExternalUrls() { + return !!(this.deployment.external_url && this.deployment.external_url_formatted); + }, + hasDeploymentTime() { + return !!(this.deployment.deployed_at && this.deployment.deployed_at_formatted); + }, + hasDeploymentMeta() { + return !!(this.deployment.url && this.deployment.name); + }, + hasMetrics() { + return !!(this.deployment.metrics_url); + }, + }, + methods: { + stopEnvironment() { + const msg = 'Are you sure you want to stop this environment?'; + const isConfirmed = confirm(msg); // eslint-disable-line + + if (isConfirmed) { + this.isStopping = true; + + MRWidgetService.stopEnvironment(this.deployment.stop_url) + .then(res => res.data) + .then((data) => { + if (data.redirect_url) { + visitUrl(data.redirect_url); + } + + this.isStopping = false; + }) + .catch(() => { + createFlash('Something went wrong while stopping this environment. Please try again.'); + this.isStopping = false; + }); + } + }, + }, +}; +</script> + +<template> + <div class="mr-widget-heading deploy-heading"> + <div class="ci-widget media"> + <div class="ci-status-icon ci-status-icon-success"> + <span class="js-icon-link icon-link"> + <status-icon status="success" /> + </span> + </div> + <div class="media-body"> + <div class="deploy-body"> + <template v-if="hasDeploymentMeta"> + <span> + Deployed to + </span> + <a + :href="deployment.url" + target="_blank" + rel="noopener noreferrer nofollow" + class="deploy-link js-deploy-meta" + > + {{ deployment.name }} + </a> + </template> + <template v-if="hasExternalUrls"> + <span> + on + </span> + <a + :href="deployment.external_url" + target="_blank" + rel="noopener noreferrer nofollow" + class="deploy-link js-deploy-url" + > + <i + class="fa fa-external-link" + aria-hidden="true" + > + </i> + {{ deployment.external_url_formatted }} + </a> + </template> + <span + v-if="hasDeploymentTime" + v-tooltip + :title="deployment.deployed_at_formatted" + class="js-deploy-time" + > + {{ deployTimeago }} + </span> + <loading-button + v-if="deployment.stop_url" + container-class="btn btn-default btn-xs prepend-left-default" + label="Stop environment" + :loading="isStopping" + @click="stopEnvironment" + /> + </div> + <memory-usage + v-if="hasMetrics" + :metrics-url="deployment.metrics_url" + :metrics-monitoring-url="deployment.metrics_monitoring_url" + /> + </div> + </div> + </div> +</template> diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js deleted file mode 100644 index c7f992384c8..00000000000 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_deployment.js +++ /dev/null @@ -1,113 +0,0 @@ -import { getTimeago } from '~/lib/utils/datetime_utility'; -import { visitUrl } from '../../lib/utils/url_utility'; -import Flash from '../../flash'; -import MemoryUsage from './memory_usage.vue'; -import StatusIcon from './mr_widget_status_icon.vue'; -import MRWidgetService from '../services/mr_widget_service'; - -export default { - name: 'MRWidgetDeployment', - props: { - mr: { type: Object, required: true }, - service: { type: Object, required: true }, - }, - components: { - MemoryUsage, - StatusIcon, - }, - methods: { - formatDate(date) { - return getTimeago().format(date); - }, - hasExternalUrls(deployment = {}) { - return deployment.external_url && deployment.external_url_formatted; - }, - hasDeploymentTime(deployment = {}) { - return deployment.deployed_at && deployment.deployed_at_formatted; - }, - hasDeploymentMeta(deployment = {}) { - return deployment.url && deployment.name; - }, - stopEnvironment(deployment) { - const msg = 'Are you sure you want to stop this environment?'; - const isConfirmed = confirm(msg); // eslint-disable-line - - if (isConfirmed) { - MRWidgetService.stopEnvironment(deployment.stop_url) - .then(res => res.data) - .then((data) => { - if (data.redirect_url) { - visitUrl(data.redirect_url); - } - }) - .catch(() => { - new Flash('Something went wrong while stopping this environment. Please try again.'); // eslint-disable-line - }); - } - }, - }, - template: ` - <div class="mr-widget-heading deploy-heading"> - <div v-for="deployment in mr.deployments"> - <div class="ci-widget media"> - <div class="ci-status-icon ci-status-icon-success"> - <span class="js-icon-link icon-link"> - <status-icon status="success" /> - </span> - </div> - <div class="media-body space-children"> - <span> - <span - v-if="hasDeploymentMeta(deployment)"> - Deployed to - </span> - <a - v-if="hasDeploymentMeta(deployment)" - :href="deployment.url" - target="_blank" - rel="noopener noreferrer nofollow" - class="js-deploy-meta inline"> - {{deployment.name}} - </a> - <span - v-if="hasExternalUrls(deployment)"> - on - </span> - <a - v-if="hasExternalUrls(deployment)" - :href="deployment.external_url" - target="_blank" - rel="noopener noreferrer nofollow" - class="js-deploy-url inline"> - <i - class="fa fa-external-link" - aria-hidden="true" /> - {{deployment.external_url_formatted}} - </a> - <span - v-if="hasDeploymentTime(deployment)" - :data-title="deployment.deployed_at_formatted" - class="js-deploy-time" - data-toggle="tooltip" - data-placement="top"> - {{formatDate(deployment.deployed_at)}} - </span> - </span> - <button - type="button" - v-if="deployment.stop_url" - @click="stopEnvironment(deployment)" - class="btn btn-default btn-xs"> - Stop environment - </button> - <memory-usage - v-if="deployment.metrics_url" - :metrics-url="deployment.metrics_url" - :metrics-monitoring-url="deployment.metrics_monitoring_url" - /> - </div> - </div> - </div> - </div> - `, -}; diff --git a/app/assets/javascripts/vue_merge_request_widget/dependencies.js b/app/assets/javascripts/vue_merge_request_widget/dependencies.js index 20624aad0ad..efbe1c96d1c 100644 --- a/app/assets/javascripts/vue_merge_request_widget/dependencies.js +++ b/app/assets/javascripts/vue_merge_request_widget/dependencies.js @@ -14,7 +14,7 @@ export { default as SmartInterval } from '~/smart_interval'; export { default as WidgetHeader } from './components/mr_widget_header.vue'; export { default as WidgetMergeHelp } from './components/mr_widget_merge_help.vue'; export { default as WidgetPipeline } from './components/mr_widget_pipeline.vue'; -export { default as WidgetDeployment } from './components/mr_widget_deployment'; +export { default as Deployment } from './components/deployment.vue'; export { default as WidgetMaintainerEdit } from './components/mr_widget_maintainer_edit.vue'; export { default as WidgetRelatedLinks } from './components/mr_widget_related_links.vue'; export { default as MergedState } from './components/states/mr_widget_merged.vue'; diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js index cc8bc6af1e1..169adfe0a1d 100644 --- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js +++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.js @@ -5,7 +5,7 @@ import { WidgetHeader, WidgetMergeHelp, WidgetPipeline, - WidgetDeployment, + Deployment, WidgetMaintainerEdit, WidgetRelatedLinks, MergedState, @@ -67,9 +67,6 @@ export default { shouldRenderRelatedLinks() { return !!this.mr.relatedLinks && !this.mr.isNothingToMergeState; }, - shouldRenderDeployments() { - return this.mr.deployments.length; - }, shouldRenderSourceBranchRemovalStatus() { return !this.mr.canRemoveSourceBranch && this.mr.shouldRemoveSourceBranch && (!this.mr.isNothingToMergeState && !this.mr.isMergedState); @@ -216,7 +213,7 @@ export default { 'mr-widget-header': WidgetHeader, 'mr-widget-merge-help': WidgetMergeHelp, 'mr-widget-pipeline': WidgetPipeline, - 'mr-widget-deployment': WidgetDeployment, + Deployment, 'mr-widget-maintainer-edit': WidgetMaintainerEdit, 'mr-widget-related-links': WidgetRelatedLinks, 'mr-widget-merged': MergedState, @@ -250,10 +247,11 @@ export default { :ci-status="mr.ciStatus" :has-ci="mr.hasCI" /> - <mr-widget-deployment - v-if="shouldRenderDeployments" - :mr="mr" - :service="service" /> + <deployment + v-for="deployment in mr.deployments" + :key="deployment.id" + :deployment="deployment" + /> <div class="mr-widget-section"> <component :is="componentName" diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss index f887a11004f..4692d0fb873 100644 --- a/app/assets/stylesheets/pages/merge_requests.scss +++ b/app/assets/stylesheets/pages/merge_requests.scss @@ -718,6 +718,8 @@ } .mr-memory-usage { + width: 100%; + p.usage-info-loading .usage-info-load-spinner { margin-right: 10px; font-size: 16px; @@ -727,3 +729,36 @@ .fork-sprite { margin-right: -5px; } + +.deploy-heading { + .media-body { + min-width: 0; + } +} + +.deploy-body { + display: flex; + flex-wrap: wrap; + + @media (min-width: $screen-xs) { + flex-wrap: nowrap; + white-space: nowrap; + } + + > *:not(:last-child) { + margin-right: .3em; + } +} + +.deploy-link { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + min-width: 100px; + max-width: 150px; + + @media (min-width: $screen-xs) { + min-width: 0; + max-width: 100%; + } +} diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb index 3abe363d523..f744d7941f5 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -22,7 +22,7 @@ describe 'Merge request > User sees deployment widget', :js do wait_for_requests expect(page).to have_content("Deployed to #{environment.name}") - expect(find('.js-deploy-time')['data-title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium)) + expect(find('.js-deploy-time')['data-original-title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium)) end context 'with stop action' do diff --git a/spec/javascripts/vue_mr_widget/components/deployment_spec.js b/spec/javascripts/vue_mr_widget/components/deployment_spec.js new file mode 100644 index 00000000000..ff8d54c029f --- /dev/null +++ b/spec/javascripts/vue_mr_widget/components/deployment_spec.js @@ -0,0 +1,172 @@ +import Vue from 'vue'; +import * as urlUtils from '~/lib/utils/url_utility'; +import deploymentComponent from '~/vue_merge_request_widget/components/deployment.vue'; +import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service'; +import { getTimeago } from '~/lib/utils/datetime_utility'; + +const deploymentMockData = { + id: 15, + name: 'review/diplo', + url: '/root/acets-review-apps/environments/15', + stop_url: '/root/acets-review-apps/environments/15/stop', + metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', + metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', + external_url: 'http://diplo.', + external_url_formatted: 'diplo.', + deployed_at: '2017-03-22T22:44:42.258Z', + deployed_at_formatted: 'Mar 22, 2017 10:44pm', +}; +const createComponent = () => { + const Component = Vue.extend(deploymentComponent); + + return new Component({ + el: document.createElement('div'), + propsData: { deployment: { ...deploymentMockData } }, + }); +}; + +describe('Deployment component', () => { + let vm; + + beforeEach(() => { + vm = createComponent(); + }); + + afterEach(() => { + vm.$destroy(); + }); + + describe('computed', () => { + describe('deployTimeago', () => { + it('return formatted date', () => { + const readable = getTimeago().format(deploymentMockData.deployed_at); + expect(vm.deployTimeago).toEqual(readable); + }); + }); + + describe('hasExternalUrls', () => { + it('should return true', () => { + expect(vm.hasExternalUrls).toEqual(true); + }); + + it('should return false when deployment has no external_url_formatted', () => { + vm.deployment.external_url_formatted = null; + + expect(vm.hasExternalUrls).toEqual(false); + }); + + it('should return false when deployment has no external_url', () => { + vm.deployment.external_url = null; + + expect(vm.hasExternalUrls).toEqual(false); + }); + }); + + describe('hasDeploymentTime', () => { + it('should return true', () => { + expect(vm.hasDeploymentTime).toEqual(true); + }); + + it('should return false when deployment has no deployed_at', () => { + vm.deployment.deployed_at = null; + + expect(vm.hasDeploymentTime).toEqual(false); + }); + + it('should return false when deployment has no deployed_at_formatted', () => { + vm.deployment.deployed_at_formatted = null; + + expect(vm.hasDeploymentTime).toEqual(false); + }); + }); + + describe('hasDeploymentMeta', () => { + it('should return true', () => { + expect(vm.hasDeploymentMeta).toEqual(true); + }); + + it('should return false when deployment has no url', () => { + vm.deployment.url = null; + + expect(vm.hasDeploymentMeta).toEqual(false); + }); + + it('should return false when deployment has no name', () => { + vm.deployment.name = null; + + expect(vm.hasDeploymentMeta).toEqual(false); + }); + }); + }); + + describe('methods', () => { + describe('stopEnvironment', () => { + const url = '/foo/bar'; + const returnPromise = () => new Promise((resolve) => { + resolve({ + data: { + redirect_url: url, + }, + }); + }); + const mockStopEnvironment = () => { + vm.stopEnvironment(deploymentMockData); + return vm; + }; + + it('should show a confirm dialog and call service.stopEnvironment when confirmed', (done) => { + spyOn(window, 'confirm').and.returnValue(true); + spyOn(MRWidgetService, 'stopEnvironment').and.returnValue(returnPromise(true)); + spyOn(urlUtils, 'visitUrl').and.returnValue(true); + vm = mockStopEnvironment(); + + expect(window.confirm).toHaveBeenCalled(); + expect(MRWidgetService.stopEnvironment).toHaveBeenCalledWith(deploymentMockData.stop_url); + setTimeout(() => { + expect(urlUtils.visitUrl).toHaveBeenCalledWith(url); + done(); + }, 333); + }); + + it('should show a confirm dialog but should not work if the dialog is rejected', () => { + spyOn(window, 'confirm').and.returnValue(false); + spyOn(MRWidgetService, 'stopEnvironment').and.returnValue(returnPromise(false)); + vm = mockStopEnvironment(); + + expect(window.confirm).toHaveBeenCalled(); + expect(MRWidgetService.stopEnvironment).not.toHaveBeenCalled(); + }); + }); + }); + + describe('template', () => { + let el; + + beforeEach(() => { + vm = createComponent(deploymentMockData); + el = vm.$el; + }); + + it('renders deployment name', () => { + expect(el.querySelector('.js-deploy-meta').getAttribute('href')).toEqual(deploymentMockData.url); + expect(el.querySelector('.js-deploy-meta').innerText).toContain(deploymentMockData.name); + }); + + it('renders external URL', () => { + expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(deploymentMockData.external_url); + expect(el.querySelector('.js-deploy-url').innerText).toContain(deploymentMockData.external_url_formatted); + }); + + it('renders stop button', () => { + expect(el.querySelector('.btn')).not.toBeNull(); + }); + + it('renders deployment time', () => { + expect(el.querySelector('.js-deploy-time').innerText).toContain(vm.deployTimeago); + }); + + it('renders metrics component', () => { + expect(el.querySelector('.js-mr-memory-usage')).not.toBeNull(); + }); + }); +}); diff --git a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js b/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js deleted file mode 100644 index 6a59dc3c87e..00000000000 --- a/spec/javascripts/vue_mr_widget/components/mr_widget_deployment_spec.js +++ /dev/null @@ -1,179 +0,0 @@ -import Vue from 'vue'; -import * as urlUtils from '~/lib/utils/url_utility'; -import deploymentComponent from '~/vue_merge_request_widget/components/mr_widget_deployment'; -import MRWidgetService from '~/vue_merge_request_widget/services/mr_widget_service'; -import { getTimeago } from '~/lib/utils/datetime_utility'; - -const deploymentMockData = [ - { - id: 15, - name: 'review/diplo', - url: '/root/acets-review-apps/environments/15', - stop_url: '/root/acets-review-apps/environments/15/stop', - metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', - metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', - external_url: 'http://diplo.', - external_url_formatted: 'diplo.', - deployed_at: '2017-03-22T22:44:42.258Z', - deployed_at_formatted: 'Mar 22, 2017 10:44pm', - }, -]; -const createComponent = () => { - const Component = Vue.extend(deploymentComponent); - const mr = { - deployments: deploymentMockData, - }; - const service = {}; - - return new Component({ - el: document.createElement('div'), - propsData: { mr, service }, - }); -}; - -describe('MRWidgetDeployment', () => { - describe('props', () => { - it('should have props', () => { - const { mr, service } = deploymentComponent.props; - - expect(mr.type instanceof Object).toBeTruthy(); - expect(mr.required).toBeTruthy(); - - expect(service.type instanceof Object).toBeTruthy(); - expect(service.required).toBeTruthy(); - }); - }); - - describe('methods', () => { - let vm = createComponent(); - const deployment = deploymentMockData[0]; - - describe('formatDate', () => { - it('should work', () => { - const readable = getTimeago().format(deployment.deployed_at); - expect(vm.formatDate(deployment.deployed_at)).toEqual(readable); - }); - }); - - describe('hasExternalUrls', () => { - it('should return true', () => { - expect(vm.hasExternalUrls(deployment)).toBeTruthy(); - }); - - it('should return false when there is not enough information', () => { - expect(vm.hasExternalUrls()).toBeFalsy(); - expect(vm.hasExternalUrls({ external_url: 'Diplo' })).toBeFalsy(); - expect(vm.hasExternalUrls({ external_url_formatted: 'Diplo' })).toBeFalsy(); - }); - }); - - describe('hasDeploymentTime', () => { - it('should return true', () => { - expect(vm.hasDeploymentTime(deployment)).toBeTruthy(); - }); - - it('should return false when there is not enough information', () => { - expect(vm.hasDeploymentTime()).toBeFalsy(); - expect(vm.hasDeploymentTime({ deployed_at: 'Diplo' })).toBeFalsy(); - expect(vm.hasDeploymentTime({ deployed_at_formatted: 'Diplo' })).toBeFalsy(); - }); - }); - - describe('hasDeploymentMeta', () => { - it('should return true', () => { - expect(vm.hasDeploymentMeta(deployment)).toBeTruthy(); - }); - - it('should return false when there is not enough information', () => { - expect(vm.hasDeploymentMeta()).toBeFalsy(); - expect(vm.hasDeploymentMeta({ url: 'Diplo' })).toBeFalsy(); - expect(vm.hasDeploymentMeta({ name: 'Diplo' })).toBeFalsy(); - }); - }); - - describe('stopEnvironment', () => { - const url = '/foo/bar'; - const returnPromise = () => new Promise((resolve) => { - resolve({ - data: { - redirect_url: url, - }, - }); - }); - const mockStopEnvironment = () => { - vm.stopEnvironment(deploymentMockData); - return vm; - }; - - it('should show a confirm dialog and call service.stopEnvironment when confirmed', (done) => { - spyOn(window, 'confirm').and.returnValue(true); - spyOn(MRWidgetService, 'stopEnvironment').and.returnValue(returnPromise(true)); - spyOn(urlUtils, 'visitUrl').and.returnValue(true); - vm = mockStopEnvironment(); - - expect(window.confirm).toHaveBeenCalled(); - expect(MRWidgetService.stopEnvironment).toHaveBeenCalledWith(deploymentMockData.stop_url); - setTimeout(() => { - expect(urlUtils.visitUrl).toHaveBeenCalledWith(url); - done(); - }, 333); - }); - - it('should show a confirm dialog but should not work if the dialog is rejected', () => { - spyOn(window, 'confirm').and.returnValue(false); - spyOn(MRWidgetService, 'stopEnvironment').and.returnValue(returnPromise(false)); - vm = mockStopEnvironment(); - - expect(window.confirm).toHaveBeenCalled(); - expect(MRWidgetService.stopEnvironment).not.toHaveBeenCalled(); - }); - }); - }); - - describe('template', () => { - let vm; - let el; - const [deployment] = deploymentMockData; - - beforeEach(() => { - vm = createComponent(deploymentMockData); - el = vm.$el; - }); - - it('should render template elements correctly', () => { - expect(el.classList.contains('mr-widget-heading')).toBeTruthy(); - expect(el.querySelector('.js-icon-link')).toBeDefined(); - expect(el.querySelector('.js-deploy-meta').getAttribute('href')).toEqual(deployment.url); - expect(el.querySelector('.js-deploy-meta').innerText).toContain(deployment.name); - expect(el.querySelector('.js-deploy-url').getAttribute('href')).toEqual(deployment.external_url); - expect(el.querySelector('.js-deploy-url').innerText).toContain(deployment.external_url_formatted); - expect(el.querySelector('.js-deploy-time').innerText).toContain(vm.formatDate(deployment.deployed_at)); - expect(el.querySelector('.js-mr-memory-usage')).toBeDefined(); - expect(el.querySelector('button')).toBeDefined(); - }); - - it('should list multiple deployments', (done) => { - vm.mr.deployments.push(deployment); - vm.mr.deployments.push(deployment); - - Vue.nextTick(() => { - expect(el.querySelectorAll('.ci-widget').length).toEqual(3); - expect(el.querySelectorAll('.js-mr-memory-usage').length).toEqual(3); - done(); - }); - }); - - it('should not have some elements when there is not enough data', (done) => { - vm.mr.deployments = [{}]; - - Vue.nextTick(() => { - expect(el.querySelectorAll('.js-deploy-meta').length).toEqual(0); - expect(el.querySelectorAll('.js-deploy-url').length).toEqual(0); - expect(el.querySelectorAll('.js-deploy-time').length).toEqual(0); - expect(el.querySelectorAll('.js-mr-memory-usage').length).toEqual(0); - expect(el.querySelectorAll('.button').length).toEqual(0); - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js index 32876ca66ac..e55c7649d40 100644 --- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js +++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js @@ -123,17 +123,6 @@ describe('mrWidgetOptions', () => { expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false); }); }); - - describe('shouldRenderDeployments', () => { - it('should return false for the initial data', () => { - expect(vm.shouldRenderDeployments).toBeFalsy(); - }); - - it('should return true if there is deployments', () => { - vm.mr.deployments.push({}, {}); - expect(vm.shouldRenderDeployments).toBeTruthy(); - }); - }); }); describe('methods', () => { @@ -189,16 +178,16 @@ describe('mrWidgetOptions', () => { describe('fetchDeployments', () => { it('should fetch deployments', (done) => { - spyOn(vm.service, 'fetchDeployments').and.returnValue(returnPromise([{ deployment: 1 }])); + spyOn(vm.service, 'fetchDeployments').and.returnValue(returnPromise([{ id: 1 }])); vm.fetchDeployments(); setTimeout(() => { expect(vm.service.fetchDeployments).toHaveBeenCalled(); expect(vm.mr.deployments.length).toEqual(1); - expect(vm.mr.deployments[0].deployment).toEqual(1); + expect(vm.mr.deployments[0].id).toBe(1); done(); - }, 333); + }); }); }); @@ -368,34 +357,6 @@ describe('mrWidgetOptions', () => { }); }); - describe('components', () => { - it('should register all components', () => { - const comps = mrWidgetOptions.components; - expect(comps['mr-widget-header']).toBeDefined(); - expect(comps['mr-widget-merge-help']).toBeDefined(); - expect(comps['mr-widget-pipeline']).toBeDefined(); - expect(comps['mr-widget-deployment']).toBeDefined(); - expect(comps['mr-widget-related-links']).toBeDefined(); - expect(comps['mr-widget-merged']).toBeDefined(); - expect(comps['mr-widget-closed']).toBeDefined(); - expect(comps['mr-widget-merging']).toBeDefined(); - expect(comps['mr-widget-failed-to-merge']).toBeDefined(); - expect(comps['mr-widget-wip']).toBeDefined(); - expect(comps['mr-widget-archived']).toBeDefined(); - expect(comps['mr-widget-conflicts']).toBeDefined(); - expect(comps['mr-widget-nothing-to-merge']).toBeDefined(); - expect(comps['mr-widget-not-allowed']).toBeDefined(); - expect(comps['mr-widget-missing-branch']).toBeDefined(); - expect(comps['mr-widget-ready-to-merge']).toBeDefined(); - expect(comps['mr-widget-checking']).toBeDefined(); - expect(comps['mr-widget-unresolved-discussions']).toBeDefined(); - expect(comps['mr-widget-pipeline-blocked']).toBeDefined(); - expect(comps['mr-widget-pipeline-failed']).toBeDefined(); - expect(comps['mr-widget-merge-when-pipeline-succeeds']).toBeDefined(); - expect(comps['mr-widget-maintainer-edit']).toBeDefined(); - }); - }); - describe('rendering relatedLinks', () => { beforeEach((done) => { vm.mr.relatedLinks = { @@ -454,4 +415,34 @@ describe('mrWidgetOptions', () => { }); }); }); + + describe('rendering deployments', () => { + const deploymentMockData = { + id: 15, + name: 'review/diplo', + url: '/root/acets-review-apps/environments/15', + stop_url: '/root/acets-review-apps/environments/15/stop', + metrics_url: '/root/acets-review-apps/environments/15/deployments/1/metrics', + metrics_monitoring_url: '/root/acets-review-apps/environments/15/metrics', + external_url: 'http://diplo.', + external_url_formatted: 'diplo.', + deployed_at: '2017-03-22T22:44:42.258Z', + deployed_at_formatted: 'Mar 22, 2017 10:44pm', + }; + + beforeEach((done) => { + vm.mr.deployments.push({ + ...deploymentMockData, + }, { + ...deploymentMockData, + id: deploymentMockData.id + 1, + }); + + vm.$nextTick(done); + }); + + it('renders multiple deployments', () => { + expect(vm.$el.querySelectorAll('.deploy-heading').length).toBe(2); + }); + }); }); |