diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-12 03:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-12 03:09:00 +0300 |
commit | b133cb2468b412683dbc5f19492d98b2ffa47d09 (patch) | |
tree | d01f5db9e1a7576fccadd2ea5a2a7c9ea8b25d99 /spec/javascripts | |
parent | 0e9eea40b62fcae67b2bd885dbedd7525fbca3c7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/javascripts')
-rw-r--r-- | spec/javascripts/environments/environments_app_spec.js | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js new file mode 100644 index 00000000000..6c05b609923 --- /dev/null +++ b/spec/javascripts/environments/environments_app_spec.js @@ -0,0 +1,279 @@ +import Vue from 'vue'; +import MockAdapter from 'axios-mock-adapter'; +import mountComponent from 'spec/helpers/vue_mount_component_helper'; +import axios from '~/lib/utils/axios_utils'; +import environmentsComponent from '~/environments/components/environments_app.vue'; +import { environment, folder } from './mock_data'; + +describe('Environment', () => { + const mockData = { + endpoint: 'environments.json', + canCreateEnvironment: true, + canReadEnvironment: true, + newEnvironmentPath: 'environments/new', + helpPagePath: 'help', + canaryDeploymentFeatureId: 'canary_deployment', + showCanaryDeploymentCallout: true, + userCalloutsPath: '/callouts', + lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg', + helpCanaryDeploymentsPath: 'help/canary-deployments', + }; + + let EnvironmentsComponent; + let component; + let mock; + + beforeEach(() => { + mock = new MockAdapter(axios); + + EnvironmentsComponent = Vue.extend(environmentsComponent); + }); + + afterEach(() => { + component.$destroy(); + mock.restore(); + }); + + describe('successful request', () => { + describe('without environments', () => { + beforeEach(done => { + mock.onGet(mockData.endpoint).reply(200, { environments: [] }); + + component = mountComponent(EnvironmentsComponent, mockData); + + setTimeout(() => { + done(); + }, 0); + }); + + it('should render the empty state', () => { + expect(component.$el.querySelector('.js-new-environment-button').textContent).toContain( + 'New environment', + ); + + expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain( + "You don't have any environments right now", + ); + }); + + describe('when it is possible to enable a review app', () => { + beforeEach(done => { + mock + .onGet(mockData.endpoint) + .reply(200, { environments: [], review_app: { can_setup_review_app: true } }); + + component = mountComponent(EnvironmentsComponent, mockData); + + setTimeout(() => { + done(); + }, 0); + }); + + it('should render the enable review app button', () => { + expect(component.$el.querySelector('.js-enable-review-app-button').textContent).toContain( + 'Enable review app', + ); + }); + }); + }); + + describe('with paginated environments', () => { + beforeEach(done => { + mock.onGet(mockData.endpoint).reply( + 200, + { + environments: [environment], + stopped_count: 1, + available_count: 0, + }, + { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }, + ); + + component = mountComponent(EnvironmentsComponent, mockData); + + setTimeout(() => { + done(); + }, 0); + }); + + it('should render a table with environments', () => { + expect(component.$el.querySelectorAll('table')).not.toBeNull(); + expect(component.$el.querySelector('.environment-name').textContent.trim()).toEqual( + environment.name, + ); + }); + + describe('pagination', () => { + it('should render pagination', () => { + expect(component.$el.querySelectorAll('.gl-pagination li').length).toEqual(9); + }); + + it('should make an API request when page is clicked', done => { + spyOn(component, 'updateContent'); + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(3) .page-link').click(); + + expect(component.updateContent).toHaveBeenCalledWith({ scope: 'available', page: '2' }); + done(); + }, 0); + }); + + it('should make an API request when using tabs', done => { + setTimeout(() => { + spyOn(component, 'updateContent'); + component.$el.querySelector('.js-environments-tab-stopped').click(); + + expect(component.updateContent).toHaveBeenCalledWith({ scope: 'stopped', page: '1' }); + done(); + }, 0); + }); + }); + }); + }); + + describe('unsuccessfull request', () => { + beforeEach(done => { + mock.onGet(mockData.endpoint).reply(500, {}); + + component = mountComponent(EnvironmentsComponent, mockData); + + setTimeout(() => { + done(); + }, 0); + }); + + it('should render empty state', () => { + expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain( + "You don't have any environments right now", + ); + }); + }); + + describe('expandable folders', () => { + beforeEach(() => { + mock.onGet(mockData.endpoint).reply( + 200, + { + environments: [folder], + stopped_count: 0, + available_count: 1, + }, + { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }, + ); + + mock.onGet(environment.folder_path).reply(200, { environments: [environment] }); + + component = mountComponent(EnvironmentsComponent, mockData); + }); + + it('should open a closed folder', done => { + setTimeout(() => { + component.$el.querySelector('.folder-name').click(); + + Vue.nextTick(() => { + expect(component.$el.querySelector('.folder-icon.ic-chevron-right')).toBe(null); + done(); + }); + }, 0); + }); + + it('should close an opened folder', done => { + setTimeout(() => { + // open folder + component.$el.querySelector('.folder-name').click(); + + Vue.nextTick(() => { + // close folder + component.$el.querySelector('.folder-name').click(); + + Vue.nextTick(() => { + expect(component.$el.querySelector('.folder-icon.ic-chevron-down')).toBe(null); + done(); + }); + }); + }, 0); + }); + + it('should show children environments and a button to show all environments', done => { + setTimeout(() => { + // open folder + component.$el.querySelector('.folder-name').click(); + + Vue.nextTick(() => { + // wait for next async request + setTimeout(() => { + expect(component.$el.querySelectorAll('.js-child-row').length).toEqual(1); + expect(component.$el.querySelector('.text-center > a.btn').textContent).toContain( + 'Show all', + ); + done(); + }); + }); + }, 0); + }); + }); + + describe('methods', () => { + beforeEach(() => { + mock.onGet(mockData.endpoint).reply( + 200, + { + environments: [], + stopped_count: 0, + available_count: 1, + }, + {}, + ); + + component = mountComponent(EnvironmentsComponent, mockData); + spyOn(window.history, 'pushState').and.stub(); + }); + + describe('updateContent', () => { + it('should set given parameters', done => { + component + .updateContent({ scope: 'stopped', page: '3' }) + .then(() => { + expect(component.page).toEqual('3'); + expect(component.scope).toEqual('stopped'); + expect(component.requestData.scope).toEqual('stopped'); + expect(component.requestData.page).toEqual('3'); + done(); + }) + .catch(done.fail); + }); + }); + + describe('onChangeTab', () => { + it('should set page to 1', () => { + spyOn(component, 'updateContent'); + component.onChangeTab('stopped'); + + expect(component.updateContent).toHaveBeenCalledWith({ scope: 'stopped', page: '1' }); + }); + }); + + describe('onChangePage', () => { + it('should update page and keep scope', () => { + spyOn(component, 'updateContent'); + component.onChangePage(4); + + expect(component.updateContent).toHaveBeenCalledWith({ scope: component.scope, page: '4' }); + }); + }); + }); +}); |