diff options
author | Filipa Lacerda <lacerda.filipa@gmail.com> | 2017-02-16 12:30:18 +0000 |
---|---|---|
committer | Filipa Lacerda <lacerda.filipa@gmail.com> | 2017-02-16 12:30:18 +0000 |
commit | ea7c7769570f2c9a371ace7a655082a95457aa5f (patch) | |
tree | 7912ebf580498a662f5fbba1085faf6d5b0e630f /spec | |
parent | edecab2041c1be24f430bc4ab6615116273b6659 (diff) | |
parent | 13615ef80da5b53c4c605878011e5998daf314f2 (diff) | |
download | gitlab-ce-ea7c7769570f2c9a371ace7a655082a95457aa5f.tar.gz |
Merge branch 'fe-paginated-environments-api' into 'paginate-environments-bundle'
paginate-environments-bundle
Integrate with new environments API
See merge request !8954
Diffstat (limited to 'spec')
16 files changed, 549 insertions, 266 deletions
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 7ac1d62d1b1..84d119f1867 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -3,9 +3,12 @@ require 'spec_helper' describe Projects::EnvironmentsController do include ApiHelpers - let(:environment) { create(:environment) } - let(:project) { environment.project } - let(:user) { create(:user) } + let(:user) { create(:user) } + let(:project) { create(:empty_project) } + + let(:environment) do + create(:environment, name: 'production', project: project) + end before do project.team << [user, :master] @@ -22,14 +25,58 @@ describe Projects::EnvironmentsController do end end - context 'when requesting JSON response' do - it 'responds with correct JSON' do - get :index, environment_params(format: :json) + context 'when requesting JSON response for folders' do + before do + create(:environment, project: project, + name: 'staging/review-1', + state: :available) + + create(:environment, project: project, + name: 'staging/review-2', + state: :available) + + create(:environment, project: project, + name: 'staging/review-3', + state: :stopped) + end + + let(:environments) { json_response['environments'] } + + context 'when requesting available environments scope' do + before do + get :index, environment_params(format: :json, scope: :available) + end + + it 'responds with a payload describing available environments' do + expect(environments.count).to eq 2 + expect(environments.first['name']).to eq 'production' + expect(environments.second['name']).to eq 'staging' + expect(environments.second['size']).to eq 2 + expect(environments.second['latest']['name']).to eq 'staging/review-2' + end - first_environment = json_response.first + it 'contains values describing environment scopes sizes' do + expect(json_response['available_count']).to eq 3 + expect(json_response['stopped_count']).to eq 1 + end + end - expect(first_environment).not_to be_empty - expect(first_environment['name']). to eq environment.name + context 'when requesting stopped environments scope' do + before do + get :index, environment_params(format: :json, scope: :stopped) + end + + it 'responds with a payload describing stopped environments' do + expect(environments.count).to eq 1 + expect(environments.first['name']).to eq 'staging' + expect(environments.first['size']).to eq 1 + expect(environments.first['latest']['name']).to eq 'staging/review-3' + end + + it 'contains values describing environment scopes sizes' do + expect(json_response['available_count']).to eq 3 + expect(json_response['stopped_count']).to eq 1 + end end end end diff --git a/spec/features/projects/builds_spec.rb b/spec/features/projects/builds_spec.rb index f1036b275f7..2116721b224 100644 --- a/spec/features/projects/builds_spec.rb +++ b/spec/features/projects/builds_spec.rb @@ -275,7 +275,7 @@ feature 'Builds', :feature do let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) } let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) } - it 'shows a link to lastest deployment' do + it 'shows a link to latest deployment' do visit namespace_project_build_path(project.namespace, project, build) expect(page).to have_link('latest deployment') diff --git a/spec/javascripts/environments/environment_actions_spec.js.es6 b/spec/javascripts/environments/environment_actions_spec.js.es6 index b1838045a06..850586f9f3a 100644 --- a/spec/javascripts/environments/environment_actions_spec.js.es6 +++ b/spec/javascripts/environments/environment_actions_spec.js.es6 @@ -1,4 +1,4 @@ -require('~/environments/components/environment_actions'); +const ActionsComponent = require('~/environments/components/environment_actions'); describe('Actions Component', () => { preloadFixtures('static/environments/element.html.raw'); @@ -19,7 +19,7 @@ describe('Actions Component', () => { }, ]; - const component = new window.gl.environmentsList.ActionsComponent({ + const component = new ActionsComponent({ el: document.querySelector('.test-dom-element'), propsData: { actions: actionsMock, @@ -47,7 +47,7 @@ describe('Actions Component', () => { }, ]; - const component = new window.gl.environmentsList.ActionsComponent({ + const component = new ActionsComponent({ el: document.querySelector('.test-dom-element'), propsData: { actions: actionsMock, diff --git a/spec/javascripts/environments/environment_external_url_spec.js.es6 b/spec/javascripts/environments/environment_external_url_spec.js.es6 index a6a587e69f5..393dbb5aae0 100644 --- a/spec/javascripts/environments/environment_external_url_spec.js.es6 +++ b/spec/javascripts/environments/environment_external_url_spec.js.es6 @@ -1,4 +1,4 @@ -require('~/environments/components/environment_external_url'); +const ExternalUrlComponent = require('~/environments/components/environment_external_url'); describe('External URL Component', () => { preloadFixtures('static/environments/element.html.raw'); @@ -8,7 +8,7 @@ describe('External URL Component', () => { it('should link to the provided externalUrl prop', () => { const externalURL = 'https://gitlab.com'; - const component = new window.gl.environmentsList.ExternalUrlComponent({ + const component = new ExternalUrlComponent({ el: document.querySelector('.test-dom-element'), propsData: { externalUrl: externalURL, diff --git a/spec/javascripts/environments/environment_item_spec.js.es6 b/spec/javascripts/environments/environment_item_spec.js.es6 index e6fb0d00290..7fea80ed799 100644 --- a/spec/javascripts/environments/environment_item_spec.js.es6 +++ b/spec/javascripts/environments/environment_item_spec.js.es6 @@ -1,5 +1,5 @@ window.timeago = require('timeago.js'); -require('~/environments/components/environment_item'); +const EnvironmentItem = require('~/environments/components/environment_item'); describe('Environment item', () => { preloadFixtures('static/environments/table.html.raw'); @@ -14,33 +14,16 @@ describe('Environment item', () => { beforeEach(() => { mockItem = { name: 'review', - children: [ - { - name: 'review-app', - id: 1, - state: 'available', - external_url: '', - last_deployment: {}, - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-10T15:55:58.778Z', - }, - { - name: 'production', - id: 2, - state: 'available', - external_url: '', - last_deployment: {}, - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-10T15:55:58.778Z', - }, - ], + folderName: 'review', + size: 3, + isFolder: true, + environment_path: 'url', }; - component = new window.gl.environmentsList.EnvironmentItem({ + component = new EnvironmentItem({ el: document.querySelector('tr#environment-row'), propsData: { model: mockItem, - toggleRow: () => {}, canCreateDeployment: false, canReadEnvironment: true, }, @@ -53,7 +36,7 @@ describe('Environment item', () => { }); it('Should render the number of children in a badge', () => { - expect(component.$el.querySelector('.folder-name .badge').textContent).toContain(mockItem.children.length); + expect(component.$el.querySelector('.folder-name .badge').textContent).toContain(mockItem.size); }); }); @@ -63,8 +46,8 @@ describe('Environment item', () => { beforeEach(() => { environment = { - id: 31, name: 'production', + size: 1, state: 'stopped', external_url: 'http://external.com', environment_type: null, @@ -125,11 +108,10 @@ describe('Environment item', () => { updated_at: '2016-11-10T15:55:58.778Z', }; - component = new window.gl.environmentsList.EnvironmentItem({ + component = new EnvironmentItem({ el: document.querySelector('tr#environment-row'), propsData: { model: environment, - toggleRow: () => {}, canCreateDeployment: true, canReadEnvironment: true, }, diff --git a/spec/javascripts/environments/environment_rollback_spec.js.es6 b/spec/javascripts/environments/environment_rollback_spec.js.es6 index 043b8708a6e..4a596baad09 100644 --- a/spec/javascripts/environments/environment_rollback_spec.js.es6 +++ b/spec/javascripts/environments/environment_rollback_spec.js.es6 @@ -1,4 +1,4 @@ -require('~/environments/components/environment_rollback'); +const RollbackComponent = require('~/environments/components/environment_rollback'); describe('Rollback Component', () => { preloadFixtures('static/environments/element.html.raw'); @@ -10,7 +10,7 @@ describe('Rollback Component', () => { }); it('Should link to the provided retryUrl', () => { - const component = new window.gl.environmentsList.RollbackComponent({ + const component = new RollbackComponent({ el: document.querySelector('.test-dom-element'), propsData: { retryUrl: retryURL, @@ -22,7 +22,7 @@ describe('Rollback Component', () => { }); it('Should render Re-deploy label when isLastDeployment is true', () => { - const component = new window.gl.environmentsList.RollbackComponent({ + const component = new RollbackComponent({ el: document.querySelector('.test-dom-element'), propsData: { retryUrl: retryURL, @@ -34,7 +34,7 @@ describe('Rollback Component', () => { }); it('Should render Rollback label when isLastDeployment is false', () => { - const component = new window.gl.environmentsList.RollbackComponent({ + const component = new RollbackComponent({ el: document.querySelector('.test-dom-element'), propsData: { retryUrl: retryURL, diff --git a/spec/javascripts/environments/environment_spec.js.es6 b/spec/javascripts/environments/environment_spec.js.es6 index 87eda136122..edd0cad32d0 100644 --- a/spec/javascripts/environments/environment_spec.js.es6 +++ b/spec/javascripts/environments/environment_spec.js.es6 @@ -1,9 +1,7 @@ -/* global Vue, environment */ - +const Vue = require('vue'); require('~/flash'); -require('~/environments/stores/environments_store'); -require('~/environments/components/environment'); -require('./mock_data'); +const EnvironmentsComponent = require('~/environments/components/environment'); +const { environment } = require('./mock_data'); describe('Environment', () => { preloadFixtures('static/environments/environments.html.raw'); @@ -33,11 +31,8 @@ describe('Environment', () => { }); it('should render the empty state', (done) => { - component = new gl.environmentsList.EnvironmentsComponent({ + component = new EnvironmentsComponent({ el: document.querySelector('#environments-list-view'), - propsData: { - store: gl.environmentsList.EnvironmentsStore.create(), - }, }); setTimeout(() => { @@ -54,15 +49,30 @@ describe('Environment', () => { }); }); - describe('with environments', () => { + describe('with paginated environments', () => { const environmentsResponseInterceptor = (request, next) => { - next(request.respondWith(JSON.stringify([environment]), { + next(request.respondWith(JSON.stringify({ + environments: [environment], + stopped_count: 1, + available_count: 0, + }), { status: 200, + headers: { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }, })); }; beforeEach(() => { Vue.http.interceptors.push(environmentsResponseInterceptor); + component = new EnvironmentsComponent({ + el: document.querySelector('#environments-list-view'), + }); }); afterEach(() => { @@ -72,13 +82,6 @@ describe('Environment', () => { }); it('should render a table with environments', (done) => { - component = new gl.environmentsList.EnvironmentsComponent({ - el: document.querySelector('#environments-list-view'), - propsData: { - store: gl.environmentsList.EnvironmentsStore.create(), - }, - }); - setTimeout(() => { expect( component.$el.querySelectorAll('table tbody tr').length, @@ -86,6 +89,59 @@ describe('Environment', () => { done(); }, 0); }); + + describe('pagination', () => { + it('should render pagination', (done) => { + setTimeout(() => { + expect( + component.$el.querySelectorAll('.gl-pagination li').length, + ).toEqual(5); + done(); + }, 0); + }); + + it('should update url when no search params are present', (done) => { + spyOn(gl.utils, 'visitUrl'); + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2'); + done(); + }, 0); + }); + + it('should update url when page is already present', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?page=1'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2'); + done(); + }, 0); + }); + + it('should update url when page and scope are already present', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?scope=all&page=1'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?scope=all&page=2'); + done(); + }, 0); + }); + + it('should update url when page and scope are already present and page is first param', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?page=1&scope=all'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2&scope=all'); + done(); + }, 0); + }); + }); }); }); @@ -107,11 +163,8 @@ describe('Environment', () => { }); it('should render empty state', (done) => { - component = new gl.environmentsList.EnvironmentsComponent({ + component = new EnvironmentsComponent({ el: document.querySelector('#environments-list-view'), - propsData: { - store: gl.environmentsList.EnvironmentsStore.create(), - }, }); setTimeout(() => { diff --git a/spec/javascripts/environments/environment_stop_spec.js.es6 b/spec/javascripts/environments/environment_stop_spec.js.es6 index 2dfce5ba824..5ca65b1debc 100644 --- a/spec/javascripts/environments/environment_stop_spec.js.es6 +++ b/spec/javascripts/environments/environment_stop_spec.js.es6 @@ -1,4 +1,4 @@ -require('~/environments/components/environment_stop'); +const StopComponent = require('~/environments/components/environment_stop'); describe('Stop Component', () => { preloadFixtures('static/environments/element.html.raw'); @@ -10,7 +10,7 @@ describe('Stop Component', () => { loadFixtures('static/environments/element.html.raw'); stopURL = '/stop'; - component = new window.gl.environmentsList.StopComponent({ + component = new StopComponent({ el: document.querySelector('.test-dom-element'), propsData: { stopUrl: stopURL, diff --git a/spec/javascripts/environments/environment_table_spec.js.es6 b/spec/javascripts/environments/environment_table_spec.js.es6 new file mode 100644 index 00000000000..be4330b5012 --- /dev/null +++ b/spec/javascripts/environments/environment_table_spec.js.es6 @@ -0,0 +1,30 @@ +const EnvironmentTable = require('~/environments/components/environments_table'); + +describe('Environment item', () => { + preloadFixtures('static/environments/element.html.raw'); + beforeEach(() => { + loadFixtures('static/environments/element.html.raw'); + }); + + it('Should render a table', () => { + const mockItem = { + name: 'review', + size: 3, + isFolder: true, + latest: { + environment_path: 'url', + }, + }; + + const component = new EnvironmentTable({ + el: document.querySelector('.test-dom-element'), + propsData: { + environments: [{ mockItem }], + canCreateDeployment: false, + canReadEnvironment: true, + }, + }); + + expect(component.$el.tagName).toEqual('TABLE'); + }); +}); diff --git a/spec/javascripts/environments/environments_store_spec.js.es6 b/spec/javascripts/environments/environments_store_spec.js.es6 index 9a8300d3832..77e182b3830 100644 --- a/spec/javascripts/environments/environments_store_spec.js.es6 +++ b/spec/javascripts/environments/environments_store_spec.js.es6 @@ -1,70 +1,58 @@ -/* global environmentsList */ - -require('~/environments/stores/environments_store'); -require('./mock_data'); +const Store = require('~/environments/stores/environments_store'); +const { environmentsList, serverData } = require('./mock_data'); (() => { describe('Store', () => { + let store; + beforeEach(() => { - gl.environmentsList.EnvironmentsStore.create(); + store = new Store(); }); it('should start with a blank state', () => { - expect(gl.environmentsList.EnvironmentsStore.state.environments.length).toBe(0); - expect(gl.environmentsList.EnvironmentsStore.state.stoppedCounter).toBe(0); - expect(gl.environmentsList.EnvironmentsStore.state.availableCounter).toBe(0); + expect(store.state.environments.length).toEqual(0); + expect(store.state.stoppedCounter).toEqual(0); + expect(store.state.availableCounter).toEqual(0); + expect(store.state.paginationInformation).toEqual({}); }); - describe('store environments', () => { - beforeEach(() => { - gl.environmentsList.EnvironmentsStore.storeEnvironments(environmentsList); - }); - - it('should count stopped environments and save the count in the state', () => { - expect(gl.environmentsList.EnvironmentsStore.state.stoppedCounter).toBe(1); - }); - - it('should count available environments and save the count in the state', () => { - expect(gl.environmentsList.EnvironmentsStore.state.availableCounter).toBe(3); - }); - - it('should store environments with same environment_type as sibilings', () => { - expect(gl.environmentsList.EnvironmentsStore.state.environments.length).toBe(3); - - const parentFolder = gl.environmentsList.EnvironmentsStore.state.environments - .filter(env => env.children && env.children.length > 0); - - expect(parentFolder[0].children.length).toBe(2); - expect(parentFolder[0].children[0].environment_type).toBe('review'); - expect(parentFolder[0].children[1].environment_type).toBe('review'); - expect(parentFolder[0].children[0].name).toBe('test-environment'); - expect(parentFolder[0].children[1].name).toBe('test-environment-1'); - }); - - it('should sort the environments alphabetically', () => { - const { environments } = gl.environmentsList.EnvironmentsStore.state; - - expect(environments[0].name).toBe('production'); - expect(environments[1].name).toBe('review'); - expect(environments[1].children[0].name).toBe('test-environment'); - expect(environments[1].children[1].name).toBe('test-environment-1'); - expect(environments[2].name).toBe('review_app'); - }); + it('should store environments', () => { + store.storeEnvironments(serverData); + expect(store.state.environments.length).toEqual(serverData.length); + expect(store.state.environments[0]).toEqual(environmentsList[0]); }); - describe('toggleFolder', () => { - beforeEach(() => { - gl.environmentsList.EnvironmentsStore.storeEnvironments(environmentsList); - }); - - it('should toggle the open property for the given environment', () => { - gl.environmentsList.EnvironmentsStore.toggleFolder('review'); + it('should store available count', () => { + store.storeAvailableCount(2); + expect(store.state.availableCounter).toEqual(2); + }); - const { environments } = gl.environmentsList.EnvironmentsStore.state; - const environment = environments.filter(env => env['vue-isChildren'] === true && env.name === 'review'); + it('should store stopped count', () => { + store.storeStoppedCount(2); + expect(store.state.stoppedCounter).toEqual(2); + }); - expect(environment[0].isOpen).toBe(true); - }); + it('should store pagination information', () => { + const pagination = { + 'X-nExt-pAge': '2', + 'X-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '2', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }; + + const expectedResult = { + perPage: 1, + page: 1, + total: 37, + totalPages: 2, + nextPage: 2, + previousPage: 2, + }; + + store.setPagination(pagination); + expect(store.state.paginationInformation).toEqual(expectedResult); }); }); })(); diff --git a/spec/javascripts/environments/folder/environments_folder_view_spec.js.es6 b/spec/javascripts/environments/folder/environments_folder_view_spec.js.es6 new file mode 100644 index 00000000000..d1335b5b304 --- /dev/null +++ b/spec/javascripts/environments/folder/environments_folder_view_spec.js.es6 @@ -0,0 +1,202 @@ +const Vue = require('vue'); +require('~/flash'); +const EnvironmentsFolderViewComponent = require('~/environments/folder/environments_folder_view'); +const { environmentsList } = require('../mock_data'); + +describe('Environments Folder View', () => { + preloadFixtures('static/environments/environments_folder_view.html.raw'); + + beforeEach(() => { + loadFixtures('static/environments/environments_folder_view.html.raw'); + window.history.pushState({}, null, 'environments/folders/build'); + }); + + let component; + + describe('successfull request', () => { + const environmentsResponseInterceptor = (request, next) => { + next(request.respondWith(JSON.stringify({ + environments: environmentsList, + stopped_count: 1, + available_count: 0, + }), { + status: 200, + headers: { + 'X-nExt-pAge': '2', + 'x-page': '1', + 'X-Per-Page': '1', + 'X-Prev-Page': '', + 'X-TOTAL': '37', + 'X-Total-Pages': '2', + }, + })); + }; + + beforeEach(() => { + Vue.http.interceptors.push(environmentsResponseInterceptor); + component = new EnvironmentsFolderViewComponent({ + el: document.querySelector('#environments-folder-list-view'), + }); + }); + + afterEach(() => { + Vue.http.interceptors = _.without( + Vue.http.interceptors, environmentsResponseInterceptor, + ); + }); + + it('should render a table with environments', (done) => { + setTimeout(() => { + expect( + component.$el.querySelectorAll('table tbody tr').length, + ).toEqual(2); + done(); + }, 0); + }); + + it('should render available tab with count', (done) => { + setTimeout(() => { + expect( + component.$el.querySelector('.js-available-environments-folder-tab').textContent, + ).toContain('Available'); + + expect( + component.$el.querySelector('.js-available-environments-folder-tab .js-available-environments-count').textContent, + ).toContain('0'); + done(); + }, 0); + }); + + it('should render stopped tab with count', (done) => { + setTimeout(() => { + expect( + component.$el.querySelector('.js-stopped-environments-folder-tab').textContent, + ).toContain('Stopped'); + + expect( + component.$el.querySelector('.js-stopped-environments-folder-tab .js-stopped-environments-count').textContent, + ).toContain('1'); + done(); + }, 0); + }); + + it('should render parent folder name', (done) => { + setTimeout(() => { + expect( + component.$el.querySelector('.js-folder-name').textContent, + ).toContain('Environments / build'); + done(); + }, 0); + }); + + describe('pagination', () => { + it('should render pagination', (done) => { + setTimeout(() => { + expect( + component.$el.querySelectorAll('.gl-pagination li').length, + ).toEqual(5); + done(); + }, 0); + }); + + it('should update url when no search params are present', (done) => { + spyOn(gl.utils, 'visitUrl'); + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2'); + done(); + }, 0); + }); + + it('should update url when page is already present', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?page=1'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2'); + done(); + }, 0); + }); + + it('should update url when page and scope are already present', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?scope=all&page=1'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?scope=all&page=2'); + done(); + }, 0); + }); + + it('should update url when page and scope are already present and page is first param', (done) => { + spyOn(gl.utils, 'visitUrl'); + window.history.pushState({}, null, '?page=1&scope=all'); + + setTimeout(() => { + component.$el.querySelector('.gl-pagination li:nth-child(5) a').click(); + expect(gl.utils.visitUrl).toHaveBeenCalledWith('?page=2&scope=all'); + done(); + }, 0); + }); + }); + }); + + describe('unsuccessfull request', () => { + const environmentsErrorResponseInterceptor = (request, next) => { + next(request.respondWith(JSON.stringify([]), { + status: 500, + })); + }; + + beforeEach(() => { + Vue.http.interceptors.push(environmentsErrorResponseInterceptor); + }); + + afterEach(() => { + Vue.http.interceptors = _.without( + Vue.http.interceptors, environmentsErrorResponseInterceptor, + ); + }); + + it('should not render a table', (done) => { + component = new EnvironmentsFolderViewComponent({ + el: document.querySelector('#environments-folder-list-view'), + }); + + setTimeout(() => { + expect( + component.$el.querySelector('table'), + ).toBe(null); + done(); + }, 0); + }); + + it('should render available tab with count 0', (done) => { + setTimeout(() => { + expect( + component.$el.querySelector('.js-available-environments-folder-tab').textContent, + ).toContain('Available'); + + expect( + component.$el.querySelector('.js-available-environments-folder-tab .js-available-environments-count').textContent, + ).toContain('0'); + done(); + }, 0); + }); + + it('should render stopped tab with count 0', (done) => { + setTimeout(() => { + expect( + component.$el.querySelector('.js-stopped-environments-folder-tab').textContent, + ).toContain('Stopped'); + + expect( + component.$el.querySelector('.js-stopped-environments-folder-tab .js-stopped-environments-count').textContent, + ).toContain('0'); + done(); + }, 0); + }); + }); +}); diff --git a/spec/javascripts/environments/mock_data.js.es6 b/spec/javascripts/environments/mock_data.js.es6 index 80e1cbc6f4d..5c395c6b2d8 100644 --- a/spec/javascripts/environments/mock_data.js.es6 +++ b/spec/javascripts/environments/mock_data.js.es6 @@ -1,153 +1,92 @@ - const environmentsList = [ { - id: 31, - name: 'production', + name: 'DEV', + size: 1, + id: 7, state: 'available', - external_url: 'https://www.gitlab.com', - environment_type: null, - last_deployment: { - id: 64, - iid: 5, - sha: '500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - ref: { - name: 'master', - ref_url: 'http://localhost:3000/root/ci-folders/tree/master', - }, - tag: false, - 'last?': true, - user: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', - web_url: 'http://localhost:3000/root', - }, - commit: { - id: '500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - short_id: '500aabcb', - title: 'Update .gitlab-ci.yml', - author_name: 'Administrator', - author_email: 'admin@example.com', - created_at: '2016-11-07T18:28:13.000+00:00', - message: 'Update .gitlab-ci.yml', - author: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', - web_url: 'http://localhost:3000/root', - }, - commit_path: '/root/ci-folders/tree/500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - }, - deployable: { - id: 1278, - name: 'build', - build_path: '/root/ci-folders/builds/1278', - retry_path: '/root/ci-folders/builds/1278/retry', - }, - manual_actions: [], - }, - 'stop_action?': true, - environment_path: '/root/ci-folders/environments/31', - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-07T11:11:16.525Z', - }, - { - id: 32, - name: 'review_app', - state: 'stopped', - external_url: 'https://www.gitlab.com', + external_url: null, environment_type: null, - last_deployment: { - id: 64, - iid: 5, - sha: '500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - ref: { - name: 'master', - ref_url: 'http://localhost:3000/root/ci-folders/tree/master', - }, - tag: false, - 'last?': true, - user: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', - web_url: 'http://localhost:3000/root', - }, - commit: { - id: '500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - short_id: '500aabcb', - title: 'Update .gitlab-ci.yml', - author_name: 'Administrator', - author_email: 'admin@example.com', - created_at: '2016-11-07T18:28:13.000+00:00', - message: 'Update .gitlab-ci.yml', - author: { - name: 'Administrator', - username: 'root', - id: 1, - state: 'active', - avatar_url: 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', - web_url: 'http://localhost:3000/root', - }, - commit_path: '/root/ci-folders/tree/500aabcb17c97bdcf2d0c410b70cb8556f0362dd', - }, - deployable: { - id: 1278, - name: 'build', - build_path: '/root/ci-folders/builds/1278', - retry_path: '/root/ci-folders/builds/1278/retry', - }, - manual_actions: [], - }, + last_deployment: null, 'stop_action?': false, - environment_path: '/root/ci-folders/environments/31', - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-07T11:11:16.525Z', + environment_path: '/root/review-app/environments/7', + stop_path: '/root/review-app/environments/7/stop', + created_at: '2017-01-31T10:53:46.894Z', + updated_at: '2017-01-31T10:53:46.894Z', }, { - id: 33, - name: 'test-environment', + folderName: 'build', + size: 5, + id: 12, + name: 'build/update-README', state: 'available', - environment_type: 'review', + external_url: null, + environment_type: 'build', last_deployment: null, - 'stop_action?': true, - environment_path: '/root/ci-folders/environments/31', - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-07T11:11:16.525Z', + 'stop_action?': false, + environment_path: '/root/review-app/environments/12', + stop_path: '/root/review-app/environments/12/stop', + created_at: '2017-02-01T19:42:18.400Z', + updated_at: '2017-02-01T19:42:18.400Z', }, +]; + +const serverData = [ { - id: 34, - name: 'test-environment-1', - state: 'available', - environment_type: 'review', - last_deployment: null, - 'stop_action?': true, - environment_path: '/root/ci-folders/environments/31', - created_at: '2016-11-07T11:11:16.525Z', - updated_at: '2016-11-07T11:11:16.525Z', + name: 'DEV', + size: 1, + latest: { + id: 7, + name: 'DEV', + state: 'available', + external_url: null, + environment_type: null, + last_deployment: null, + 'stop_action?': false, + environment_path: '/root/review-app/environments/7', + stop_path: '/root/review-app/environments/7/stop', + created_at: '2017-01-31T10:53:46.894Z', + updated_at: '2017-01-31T10:53:46.894Z', + }, + }, + { + name: 'build', + size: 5, + latest: { + id: 12, + name: 'build/update-README', + state: 'available', + external_url: null, + environment_type: 'build', + last_deployment: null, + 'stop_action?': false, + environment_path: '/root/review-app/environments/12', + stop_path: '/root/review-app/environments/12/stop', + created_at: '2017-02-01T19:42:18.400Z', + updated_at: '2017-02-01T19:42:18.400Z', + }, }, ]; -window.environmentsList = environmentsList; - const environment = { - id: 4, - name: 'production', - state: 'available', - external_url: 'http://production.', - environment_type: null, - last_deployment: {}, - 'stop_action?': false, - environment_path: '/root/review-app/environments/4', - stop_path: '/root/review-app/environments/4/stop', - created_at: '2016-12-16T11:51:04.690Z', - updated_at: '2016-12-16T12:04:51.133Z', + name: 'DEV', + size: 1, + latest: { + id: 7, + name: 'DEV', + state: 'available', + external_url: null, + environment_type: null, + last_deployment: null, + 'stop_action?': false, + environment_path: '/root/review-app/environments/7', + stop_path: '/root/review-app/environments/7/stop', + created_at: '2017-01-31T10:53:46.894Z', + updated_at: '2017-01-31T10:53:46.894Z', + }, }; -window.environment = environment; +module.exports = { + environmentsList, + environment, + serverData, +}; diff --git a/spec/javascripts/fixtures/environments/environments_folder_view.html.haml b/spec/javascripts/fixtures/environments/environments_folder_view.html.haml new file mode 100644 index 00000000000..aceec139730 --- /dev/null +++ b/spec/javascripts/fixtures/environments/environments_folder_view.html.haml @@ -0,0 +1,7 @@ +%div + #environments-folder-list-view{ data: { "can-create-deployment" => "true", + "can-read-environment" => "true", + "css-class" => "", + "commit-icon-svg" => custom_icon("icon_commit"), + "terminal-icon-svg" => custom_icon("icon_terminal"), + "play-icon-svg" => custom_icon("icon_play") } } diff --git a/spec/javascripts/lib/utils/common_utils_spec.js.es6 b/spec/javascripts/lib/utils/common_utils_spec.js.es6 index 006ede21093..f4d3e77e515 100644 --- a/spec/javascripts/lib/utils/common_utils_spec.js.es6 +++ b/spec/javascripts/lib/utils/common_utils_spec.js.es6 @@ -108,6 +108,30 @@ require('~/lib/utils/common_utils'); }); }); + describe('gl.utils.parseIntPagination', () => { + it('should parse to integers all string values and return pagination object', () => { + const pagination = { + 'X-PER-PAGE': 10, + 'X-PAGE': 2, + 'X-TOTAL': 30, + 'X-TOTAL-PAGES': 3, + 'X-NEXT-PAGE': 3, + 'X-PREV-PAGE': 1, + }; + + const expectedPagination = { + perPage: 10, + page: 2, + total: 30, + totalPages: 3, + nextPage: 3, + previousPage: 1, + }; + + expect(gl.utils.parseIntPagination(pagination)).toEqual(expectedPagination); + }); + }); + describe('gl.utils.isMetaClick', () => { it('should identify meta click on Windows/Linux', () => { const e = { diff --git a/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6 b/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6 index e84f0dcfe67..dd495cb43bc 100644 --- a/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6 +++ b/spec/javascripts/vue_shared/components/table_pagination_spec.js.es6 @@ -34,7 +34,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: '1' } }); expect(changeChanges.one).toEqual(1); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); it('should go to the previous page', () => { @@ -55,7 +55,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: 'Prev' } }); expect(changeChanges.one).toEqual(1); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); it('should go to the next page', () => { @@ -76,7 +76,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: 'Next' } }); expect(changeChanges.one).toEqual(5); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); it('should go to the last page', () => { @@ -97,7 +97,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: 'Last >>' } }); expect(changeChanges.one).toEqual(10); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); it('should go to the first page', () => { @@ -118,7 +118,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: '<< First' } }); expect(changeChanges.one).toEqual(1); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); it('should do nothing', () => { @@ -139,7 +139,7 @@ describe('Pagination component', () => { component.changePage({ target: { innerText: '...' } }); expect(changeChanges.one).toEqual(1); - expect(changeChanges.two).toEqual('all'); + expect(changeChanges.two).toEqual(null); }); }); diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb index 1b95f1ff198..6a6df377b35 100644 --- a/spec/serializers/environment_serializer_spec.rb +++ b/spec/serializers/environment_serializer_spec.rb @@ -181,6 +181,17 @@ describe EnvironmentSerializer do expect(subject.first[:name]).to eq 'production' expect(subject.second[:name]).to eq 'staging' end + + it 'appends correct total page count header' do + expect(subject).not_to be_empty + expect(response).to have_received(:[]=).with('X-Total', '3') + end + + it 'appends correct page count headers' do + expect(subject).not_to be_empty + expect(response).to have_received(:[]=).with('X-Total-Pages', '2') + expect(response).to have_received(:[]=).with('X-Per-Page', '2') + end end end end |