diff options
Diffstat (limited to 'spec/frontend')
-rw-r--r-- | spec/frontend/environments/environment_item_spec.js | 131 | ||||
-rw-r--r-- | spec/frontend/environments/environment_table_spec.js | 278 | ||||
-rw-r--r-- | spec/frontend/environments/mock_data.js | 106 |
3 files changed, 515 insertions, 0 deletions
diff --git a/spec/frontend/environments/environment_item_spec.js b/spec/frontend/environments/environment_item_spec.js new file mode 100644 index 00000000000..6184df0fdc2 --- /dev/null +++ b/spec/frontend/environments/environment_item_spec.js @@ -0,0 +1,131 @@ +import { mount } from '@vue/test-utils'; +import { format } from 'timeago.js'; +import EnvironmentItem from '~/environments/components/environment_item.vue'; +import { environment, folder, tableData } from './mock_data'; + +describe('Environment item', () => { + 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(EnvironmentItem, { + ...options, + }); + }; + + beforeEach(() => { + factory({ + propsData: { + model: environment, + canReadEnvironment: true, + tableData, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('when item is not folder', () => { + it('should render environment name', () => { + expect(wrapper.find('.environment-name').text()).toContain(environment.name); + }); + + describe('With deployment', () => { + it('should render deployment internal id', () => { + expect(wrapper.find('.deployment-column span').text()).toContain( + environment.last_deployment.iid, + ); + + expect(wrapper.find('.deployment-column span').text()).toContain('#'); + }); + + it('should render last deployment date', () => { + const formatedDate = format(environment.last_deployment.deployed_at); + + expect(wrapper.find('.environment-created-date-timeago').text()).toContain(formatedDate); + }); + + describe('With user information', () => { + it('should render user avatar with link to profile', () => { + expect(wrapper.find('.js-deploy-user-container').attributes('href')).toEqual( + environment.last_deployment.user.web_url, + ); + }); + }); + + describe('With build url', () => { + it('should link to build url provided', () => { + expect(wrapper.find('.build-link').attributes('href')).toEqual( + environment.last_deployment.deployable.build_path, + ); + }); + + it('should render deployable name and id', () => { + expect(wrapper.find('.build-link').attributes('href')).toEqual( + environment.last_deployment.deployable.build_path, + ); + }); + }); + + describe('With commit information', () => { + it('should render commit component', () => { + expect(wrapper.find('.js-commit-component')).toBeDefined(); + }); + }); + }); + + describe('With manual actions', () => { + it('should render actions component', () => { + expect(wrapper.find('.js-manual-actions-container')).toBeDefined(); + }); + }); + + describe('With external URL', () => { + it('should render external url component', () => { + expect(wrapper.find('.js-external-url-container')).toBeDefined(); + }); + }); + + describe('With stop action', () => { + it('should render stop action component', () => { + expect(wrapper.find('.js-stop-component-container')).toBeDefined(); + }); + }); + + describe('With retry action', () => { + it('should render rollback component', () => { + expect(wrapper.find('.js-rollback-component-container')).toBeDefined(); + }); + }); + }); + + describe('When item is folder', () => { + beforeEach(() => { + factory({ + propsData: { + model: folder, + canReadEnvironment: true, + tableData, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('should render folder icon and name', () => { + expect(wrapper.find('.folder-name').text()).toContain(folder.name); + expect(wrapper.find('.folder-icon')).toBeDefined(); + }); + + it('should render the number of children in a badge', () => { + expect(wrapper.find('.folder-name .badge').text()).toContain(folder.size); + }); + }); +}); diff --git a/spec/frontend/environments/environment_table_spec.js b/spec/frontend/environments/environment_table_spec.js new file mode 100644 index 00000000000..b8ef40e2568 --- /dev/null +++ b/spec/frontend/environments/environment_table_spec.js @@ -0,0 +1,278 @@ +import { mount } from '@vue/test-utils'; +import EnvironmentTable from '~/environments/components/environments_table.vue'; +import { folder } from './mock_data'; + +const eeOnlyProps = { + canaryDeploymentFeatureId: 'canary_deployment', + showCanaryDeploymentCallout: true, + userCalloutsPath: '/callouts', + lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg', + helpCanaryDeploymentsPath: 'help/canary-deployments', +}; + +describe('Environment table', () => { + 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(EnvironmentTable, { + ...options, + }); + }; + + beforeEach(() => { + factory({ + propsData: { + environments: [folder], + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('Should render a table', () => { + expect(wrapper.classes()).toContain('ci-table'); + }); + + describe('sortEnvironments', () => { + it('should sort environments by last updated', () => { + const mockItems = [ + { + name: 'old', + size: 3, + isFolder: false, + last_deployment: { + created_at: new Date(2019, 0, 5).toISOString(), + }, + }, + { + name: 'new', + size: 3, + isFolder: false, + last_deployment: { + created_at: new Date(2019, 1, 5).toISOString(), + }, + }, + { + name: 'older', + size: 3, + isFolder: false, + last_deployment: { + created_at: new Date(2018, 0, 5).toISOString(), + }, + }, + { + name: 'an environment with no deployment', + }, + ]; + + factory({ + propsData: { + environments: mockItems, + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + + const [old, newer, older, noDeploy] = mockItems; + + expect(wrapper.vm.sortEnvironments(mockItems)).toEqual([newer, old, older, noDeploy]); + }); + + it('should push environments with no deployments to the bottom', () => { + const mockItems = [ + { + name: 'production', + size: 1, + id: 2, + state: 'available', + external_url: 'https://google.com/production', + environment_type: null, + last_deployment: null, + has_stop_action: false, + environment_path: '/Commit451/lab-coat/environments/2', + stop_path: '/Commit451/lab-coat/environments/2/stop', + folder_path: '/Commit451/lab-coat/environments/folders/production', + created_at: '2019-01-17T16:26:10.064Z', + updated_at: '2019-01-17T16:27:37.717Z', + can_stop: true, + }, + { + name: 'review/225addcibuildstatus', + size: 2, + isFolder: true, + isLoadingFolderContent: false, + folderName: 'review', + isOpen: false, + children: [], + id: 12, + state: 'available', + external_url: 'https://google.com/review/225addcibuildstatus', + environment_type: 'review', + last_deployment: null, + has_stop_action: false, + environment_path: '/Commit451/lab-coat/environments/12', + stop_path: '/Commit451/lab-coat/environments/12/stop', + folder_path: '/Commit451/lab-coat/environments/folders/review', + created_at: '2019-01-17T16:27:37.877Z', + updated_at: '2019-01-17T16:27:37.883Z', + can_stop: true, + }, + { + name: 'staging', + size: 1, + id: 1, + state: 'available', + external_url: 'https://google.com/staging', + environment_type: null, + last_deployment: { + created_at: '2019-01-17T16:26:15.125Z', + scheduled_actions: [], + }, + }, + ]; + + factory({ + propsData: { + environments: mockItems, + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + + const [prod, review, staging] = mockItems; + + expect(wrapper.vm.sortEnvironments(mockItems)).toEqual([review, staging, prod]); + }); + + it('should sort environments by folder first', () => { + const mockItems = [ + { + name: 'old', + size: 3, + isFolder: false, + last_deployment: { + created_at: new Date(2019, 0, 5).toISOString(), + }, + }, + { + name: 'new', + size: 3, + isFolder: false, + last_deployment: { + created_at: new Date(2019, 1, 5).toISOString(), + }, + }, + { + name: 'older', + size: 3, + isFolder: true, + children: [], + }, + ]; + + factory({ + propsData: { + environments: mockItems, + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + + const [old, newer, older] = mockItems; + + expect(wrapper.vm.sortEnvironments(mockItems)).toEqual([older, newer, old]); + }); + + it('should break ties by name', () => { + const mockItems = [ + { + name: 'old', + isFolder: false, + }, + { + name: 'new', + isFolder: false, + }, + { + folderName: 'older', + isFolder: true, + }, + ]; + + factory({ + propsData: { + environments: mockItems, + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + + const [old, newer, older] = mockItems; + + expect(wrapper.vm.sortEnvironments(mockItems)).toEqual([older, newer, old]); + }); + }); + + describe('sortedEnvironments', () => { + it('it should sort children as well', () => { + const mockItems = [ + { + name: 'production', + last_deployment: null, + }, + { + name: 'review/225addcibuildstatus', + isFolder: true, + folderName: 'review', + isOpen: true, + children: [ + { + name: 'review/225addcibuildstatus', + last_deployment: { + created_at: '2019-01-17T16:26:15.125Z', + }, + }, + { + name: 'review/master', + last_deployment: { + created_at: '2019-02-17T16:26:15.125Z', + }, + }, + ], + }, + { + name: 'staging', + last_deployment: { + created_at: '2019-01-17T16:26:15.125Z', + }, + }, + ]; + const [production, review, staging] = mockItems; + const [addcibuildstatus, master] = mockItems[1].children; + + factory({ + propsData: { + environments: mockItems, + canReadEnvironment: true, + ...eeOnlyProps, + }, + }); + + expect(wrapper.vm.sortedEnvironments.map(env => env.name)).toEqual([ + review.name, + staging.name, + production.name, + ]); + + expect(wrapper.vm.sortedEnvironments[0].children).toEqual([master, addcibuildstatus]); + }); + }); +}); diff --git a/spec/frontend/environments/mock_data.js b/spec/frontend/environments/mock_data.js new file mode 100644 index 00000000000..a014108b898 --- /dev/null +++ b/spec/frontend/environments/mock_data.js @@ -0,0 +1,106 @@ +const environment = { + name: 'production', + size: 1, + state: 'stopped', + external_url: 'http://external.com', + environment_type: null, + last_deployment: { + id: 66, + iid: 6, + sha: '500aabcb17c97bdcf2d0c410b70cb8556f0362dd', + ref: { + name: 'master', + ref_url: 'root/ci-folders/tree/master', + }, + tag: true, + 'last?': true, + user: { + name: 'Administrator', + username: 'root', + id: 1, + state: 'active', + avatar_url: + 'https://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: + 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon', + web_url: 'http://localhost:3000/root', + }, + commit_path: '/root/ci-folders/tree/500aabcb17c97bdcf2d0c410b70cb8556f0362dd', + }, + deployable: { + id: 1279, + name: 'deploy', + build_path: '/root/ci-folders/builds/1279', + retry_path: '/root/ci-folders/builds/1279/retry', + created_at: '2016-11-29T18:11:58.430Z', + updated_at: '2016-11-29T18:11:58.430Z', + }, + manual_actions: [ + { + name: 'action', + play_path: '/play', + }, + ], + deployed_at: '2016-11-29T18:11:58.430Z', + }, + has_stop_action: true, + environment_path: 'root/ci-folders/environments/31', + log_path: 'root/ci-folders/environments/31/logs', + created_at: '2016-11-07T11:11:16.525Z', + updated_at: '2016-11-10T15:55:58.778Z', +}; + +const folder = { + name: 'review', + folderName: 'review', + size: 3, + isFolder: true, + environment_path: 'url', + log_path: 'url', + latest: { + environment_path: 'url', + }, +}; + +const tableData = { + name: { + title: 'Environment', + spacing: 'section-15', + }, + deploy: { + title: 'Deployment', + spacing: 'section-10', + }, + build: { + title: 'Job', + spacing: 'section-15', + }, + commit: { + title: 'Commit', + spacing: 'section-20', + }, + date: { + title: 'Updated', + spacing: 'section-10', + }, + actions: { + spacing: 'section-25', + }, +}; + +export { environment, folder, tableData }; |