diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-14 03:06:24 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-11-14 03:06:24 +0300 |
commit | eed996ac33a60d5fd8315a62fec8beaa8e907e69 (patch) | |
tree | d8077bee50b58a170ae1a950ae76e3011c78a415 /spec/frontend/create_cluster | |
parent | b42f312df5aee0f1b832b69171e9d1cf92eb7416 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/create_cluster')
6 files changed, 563 insertions, 77 deletions
diff --git a/spec/frontend/create_cluster/eks_cluster/components/cluster_form_dropdown_spec.js b/spec/frontend/create_cluster/eks_cluster/components/cluster_form_dropdown_spec.js index 366c2fc7b26..efbe2635fcc 100644 --- a/spec/frontend/create_cluster/eks_cluster/components/cluster_form_dropdown_spec.js +++ b/spec/frontend/create_cluster/eks_cluster/components/cluster_form_dropdown_spec.js @@ -3,7 +3,7 @@ import { shallowMount } from '@vue/test-utils'; import ClusterFormDropdown from '~/create_cluster/eks_cluster/components/cluster_form_dropdown.vue'; import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; import DropdownSearchInput from '~/vue_shared/components/dropdown/dropdown_search_input.vue'; -import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; +import { GlIcon } from '@gitlab/ui'; describe('ClusterFormDropdown', () => { let vm; @@ -41,24 +41,50 @@ describe('ClusterFormDropdown', () => { .trigger('click'); }); - it('displays selected item label', () => { - expect(vm.find(DropdownButton).props('toggleText')).toEqual(secondItem.name); + it('emits input event with selected item', () => { + expect(vm.emitted('input')[0]).toEqual([secondItem.value]); + }); + }); + + describe('when multiple items are selected', () => { + const value = [1]; + + beforeEach(() => { + vm.setProps({ items, multiple: true, value }); + vm.findAll('.js-dropdown-item') + .at(0) + .trigger('click'); + vm.findAll('.js-dropdown-item') + .at(1) + .trigger('click'); + }); + + it('emits input event with an array of selected items', () => { + expect(vm.emitted('input')[1]).toEqual([[firstItem.value, secondItem.value]]); + }); + }); + + describe('when multiple items can be selected', () => { + beforeEach(() => { + vm.setProps({ items, multiple: true, value: firstItem.value }); }); - it('sets selected value to dropdown hidden input', () => { - expect(vm.find(DropdownHiddenInput).props('value')).toEqual(secondItem.value); + it('displays a checked GlIcon next to the item', () => { + expect(vm.find(GlIcon).is('.invisible')).toBe(false); + expect(vm.find(GlIcon).props('name')).toBe('mobile-issue-close'); }); }); describe('when an item is selected and has a custom label property', () => { it('displays selected item custom label', () => { const labelProperty = 'customLabel'; - const selectedItem = { [labelProperty]: 'Name' }; + const label = 'Name'; + const currentValue = 1; + const customLabelItems = [{ [labelProperty]: label, value: currentValue }]; - vm.setProps({ labelProperty }); - vm.setData({ selectedItem }); + vm.setProps({ labelProperty, items: customLabelItems, value: currentValue }); - expect(vm.find(DropdownButton).props('toggleText')).toEqual(selectedItem[labelProperty]); + expect(vm.find(DropdownButton).props('toggleText')).toEqual(label); }); }); diff --git a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js index 69290f6dfa9..25d613d64ed 100644 --- a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js +++ b/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js @@ -4,7 +4,6 @@ import Vue from 'vue'; import { GlFormCheckbox } from '@gitlab/ui'; import EksClusterConfigurationForm from '~/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue'; -import RegionDropdown from '~/create_cluster/eks_cluster/components/region_dropdown.vue'; import eksClusterFormState from '~/create_cluster/eks_cluster/store/state'; import clusterDropdownStoreState from '~/create_cluster/eks_cluster/store/cluster_dropdown/state'; @@ -21,17 +20,21 @@ describe('EksClusterConfigurationForm', () => { let subnetsState; let keyPairsState; let securityGroupsState; + let instanceTypesState; let vpcsActions; let rolesActions; let regionsActions; let subnetsActions; let keyPairsActions; let securityGroupsActions; + let instanceTypesActions; let vm; beforeEach(() => { state = eksClusterFormState(); actions = { + signOut: jest.fn(), + createCluster: jest.fn(), setClusterName: jest.fn(), setEnvironmentScope: jest.fn(), setKubernetesVersion: jest.fn(), @@ -41,6 +44,8 @@ describe('EksClusterConfigurationForm', () => { setRole: jest.fn(), setKeyPair: jest.fn(), setSecurityGroup: jest.fn(), + setInstanceType: jest.fn(), + setNodeCount: jest.fn(), setGitlabManagedCluster: jest.fn(), }; regionsActions = { @@ -61,6 +66,9 @@ describe('EksClusterConfigurationForm', () => { securityGroupsActions = { fetchItems: jest.fn(), }; + instanceTypesActions = { + fetchItems: jest.fn(), + }; rolesState = { ...clusterDropdownStoreState(), }; @@ -79,6 +87,9 @@ describe('EksClusterConfigurationForm', () => { securityGroupsState = { ...clusterDropdownStoreState(), }; + instanceTypesState = { + ...clusterDropdownStoreState(), + }; store = new Vuex.Store({ state, actions, @@ -113,6 +124,11 @@ describe('EksClusterConfigurationForm', () => { state: securityGroupsState, actions: securityGroupsActions, }, + instanceTypes: { + namespaced: true, + state: instanceTypesState, + actions: instanceTypesActions, + }, }, }); }); @@ -124,6 +140,7 @@ describe('EksClusterConfigurationForm', () => { propsData: { gitlabManagedClusterHelpPath: '', kubernetesIntegrationHelpPath: '', + externalLinkIcon: '', }, }); }); @@ -132,15 +149,34 @@ describe('EksClusterConfigurationForm', () => { vm.destroy(); }); + const setAllConfigurationFields = () => { + store.replaceState({ + ...state, + clusterName: 'cluster name', + environmentScope: '*', + selectedRegion: 'region', + selectedRole: 'role', + selectedKeyPair: 'key pair', + selectedVpc: 'vpc', + selectedSubnet: 'subnet', + selectedSecurityGroup: 'group', + selectedInstanceType: 'small-1', + }); + }; + + const findSignOutButton = () => vm.find('.js-sign-out'); + const findCreateClusterButton = () => vm.find('.js-create-cluster'); const findClusterNameInput = () => vm.find('[id=eks-cluster-name]'); const findEnvironmentScopeInput = () => vm.find('[id=eks-environment-scope]'); const findKubernetesVersionDropdown = () => vm.find('[field-id="eks-kubernetes-version"]'); - const findRegionDropdown = () => vm.find(RegionDropdown); + const findRegionDropdown = () => vm.find('[field-id="eks-region"]'); const findKeyPairDropdown = () => vm.find('[field-id="eks-key-pair"]'); const findVpcDropdown = () => vm.find('[field-id="eks-vpc"]'); const findSubnetDropdown = () => vm.find('[field-id="eks-subnet"]'); const findRoleDropdown = () => vm.find('[field-id="eks-role"]'); const findSecurityGroupDropdown = () => vm.find('[field-id="eks-security-group"]'); + const findInstanceTypeDropdown = () => vm.find('[field-id="eks-instance-type"'); + const findNodeCountInput = () => vm.find('[id="eks-node-count"]'); const findGitlabManagedClusterCheckbox = () => vm.find(GlFormCheckbox); describe('when mounted', () => { @@ -151,6 +187,15 @@ describe('EksClusterConfigurationForm', () => { it('fetches available roles', () => { expect(rolesActions.fetchItems).toHaveBeenCalled(); }); + + it('fetches available instance types', () => { + expect(instanceTypesActions.fetchItems).toHaveBeenCalled(); + }); + }); + + it('dispatches signOut action when sign out button is clicked', () => { + findSignOutButton().trigger('click'); + expect(actions.signOut).toHaveBeenCalled(); }); it('sets isLoadingRoles to RoleDropdown loading property', () => { @@ -180,11 +225,13 @@ describe('EksClusterConfigurationForm', () => { }); it('sets regions to RegionDropdown regions property', () => { - expect(findRegionDropdown().props('regions')).toBe(regionsState.items); + expect(findRegionDropdown().props('items')).toBe(regionsState.items); }); it('sets loadingRegionsError to RegionDropdown error property', () => { - expect(findRegionDropdown().props('error')).toBe(regionsState.loadingItemsError); + regionsState.loadingItemsError = new Error(); + + expect(findRegionDropdown().props('hasErrors')).toEqual(true); }); it('disables KeyPairDropdown when no region is selected', () => { @@ -329,6 +376,34 @@ describe('EksClusterConfigurationForm', () => { undefined, ); }); + + it('cleans selected vpc', () => { + expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null }, undefined); + }); + + it('cleans selected key pair', () => { + expect(actions.setKeyPair).toHaveBeenCalledWith( + expect.anything(), + { keyPair: null }, + undefined, + ); + }); + + it('cleans selected subnet', () => { + expect(actions.setSubnet).toHaveBeenCalledWith( + expect.anything(), + { subnet: null }, + undefined, + ); + }); + + it('cleans selected security group', () => { + expect(actions.setSecurityGroup).toHaveBeenCalledWith( + expect.anything(), + { securityGroup: null }, + undefined, + ); + }); }); it('dispatches setClusterName when cluster name input changes', () => { @@ -381,8 +456,10 @@ describe('EksClusterConfigurationForm', () => { describe('when vpc is selected', () => { const vpc = { name: 'vpc-1' }; + const region = 'east-1'; beforeEach(() => { + state.selectedRegion = region; findVpcDropdown().vm.$emit('input', vpc); }); @@ -390,14 +467,34 @@ describe('EksClusterConfigurationForm', () => { expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc }, undefined); }); + it('cleans selected subnet', () => { + expect(actions.setSubnet).toHaveBeenCalledWith( + expect.anything(), + { subnet: null }, + undefined, + ); + }); + + it('cleans selected security group', () => { + expect(actions.setSecurityGroup).toHaveBeenCalledWith( + expect.anything(), + { securityGroup: null }, + undefined, + ); + }); + it('dispatches fetchSubnets action', () => { - expect(subnetsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { vpc }, undefined); + expect(subnetsActions.fetchItems).toHaveBeenCalledWith( + expect.anything(), + { vpc, region }, + undefined, + ); }); it('dispatches fetchSecurityGroups action', () => { expect(securityGroupsActions.fetchItems).toHaveBeenCalledWith( expect.anything(), - { vpc }, + { vpc, region }, undefined, ); }); @@ -454,4 +551,76 @@ describe('EksClusterConfigurationForm', () => { ); }); }); + + describe('when instance type is selected', () => { + const instanceType = 'small-1'; + + beforeEach(() => { + findInstanceTypeDropdown().vm.$emit('input', instanceType); + }); + + it('dispatches setInstanceType action', () => { + expect(actions.setInstanceType).toHaveBeenCalledWith( + expect.anything(), + { instanceType }, + undefined, + ); + }); + }); + + it('dispatches setNodeCount when node count input changes', () => { + const nodeCount = 5; + + findNodeCountInput().vm.$emit('input', nodeCount); + + expect(actions.setNodeCount).toHaveBeenCalledWith(expect.anything(), { nodeCount }, undefined); + }); + + describe('when all cluster configuration fields are set', () => { + beforeEach(() => { + setAllConfigurationFields(); + }); + + it('enables create cluster button', () => { + expect(findCreateClusterButton().props('disabled')).toBe(false); + }); + }); + + describe('when at least one cluster configuration field is not set', () => { + beforeEach(() => { + setAllConfigurationFields(); + store.replaceState({ + ...state, + clusterName: '', + }); + }); + + it('disables create cluster button', () => { + expect(findCreateClusterButton().props('disabled')).toBe(true); + }); + }); + + describe('when isCreatingCluster', () => { + beforeEach(() => { + setAllConfigurationFields(); + store.replaceState({ + ...state, + isCreatingCluster: true, + }); + }); + + it('sets create cluster button as loading', () => { + expect(findCreateClusterButton().props('loading')).toBe(true); + }); + }); + + describe('clicking create cluster button', () => { + beforeEach(() => { + findCreateClusterButton().vm.$emit('click'); + }); + + it('dispatches createCluster action', () => { + expect(actions.createCluster).toHaveBeenCalled(); + }); + }); }); diff --git a/spec/frontend/create_cluster/eks_cluster/components/region_dropdown_spec.js b/spec/frontend/create_cluster/eks_cluster/components/region_dropdown_spec.js deleted file mode 100644 index 0ebb5026a4b..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/components/region_dropdown_spec.js +++ /dev/null @@ -1,55 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; - -import ClusterFormDropdown from '~/create_cluster/eks_cluster/components/cluster_form_dropdown.vue'; -import RegionDropdown from '~/create_cluster/eks_cluster/components/region_dropdown.vue'; - -describe('RegionDropdown', () => { - let vm; - - const getClusterFormDropdown = () => vm.find(ClusterFormDropdown); - - beforeEach(() => { - vm = shallowMount(RegionDropdown); - }); - afterEach(() => vm.destroy()); - - it('renders a cluster-form-dropdown', () => { - expect(getClusterFormDropdown().exists()).toBe(true); - }); - - it('sets regions to cluster-form-dropdown items property', () => { - const regions = [{ name: 'basic' }]; - - vm.setProps({ regions }); - - expect(getClusterFormDropdown().props('items')).toEqual(regions); - }); - - it('sets a loading text', () => { - expect(getClusterFormDropdown().props('loadingText')).toEqual('Loading Regions'); - }); - - it('sets a placeholder', () => { - expect(getClusterFormDropdown().props('placeholder')).toEqual('Select a region'); - }); - - it('sets an empty results text', () => { - expect(getClusterFormDropdown().props('emptyText')).toEqual('No region found'); - }); - - it('sets a search field placeholder', () => { - expect(getClusterFormDropdown().props('searchFieldPlaceholder')).toEqual('Search regions'); - }); - - it('sets hasErrors property', () => { - vm.setProps({ error: {} }); - - expect(getClusterFormDropdown().props('hasErrors')).toEqual(true); - }); - - it('sets an error message', () => { - expect(getClusterFormDropdown().props('errorMessage')).toEqual( - 'Could not load regions from your AWS account', - ); - }); -}); diff --git a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js new file mode 100644 index 00000000000..25be858dcb3 --- /dev/null +++ b/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js @@ -0,0 +1,152 @@ +import awsServicesFacadeFactory from '~/create_cluster/eks_cluster/services/aws_services_facade'; +import axios from '~/lib/utils/axios_utils'; +import AxiosMockAdapter from 'axios-mock-adapter'; + +describe('awsServicesFacade', () => { + let apiPaths; + let axiosMock; + let awsServices; + let region; + let vpc; + + beforeEach(() => { + apiPaths = { + getKeyPairsPath: '/clusters/aws/api/key_pairs', + getRegionsPath: '/clusters/aws/api/regions', + getRolesPath: '/clusters/aws/api/roles', + getSecurityGroupsPath: '/clusters/aws/api/security_groups', + getSubnetsPath: '/clusters/aws/api/subnets', + getVpcsPath: '/clusters/aws/api/vpcs', + getInstanceTypesPath: '/clusters/aws/api/instance_types', + }; + region = 'west-1'; + vpc = 'vpc-2'; + awsServices = awsServicesFacadeFactory(apiPaths); + axiosMock = new AxiosMockAdapter(axios); + }); + + describe('when fetchRegions succeeds', () => { + let regions; + let regionsOutput; + + beforeEach(() => { + regions = [{ region_name: 'east-1' }, { region_name: 'west-2' }]; + regionsOutput = regions.map(({ region_name: name }) => ({ name, value: name })); + axiosMock.onGet(apiPaths.getRegionsPath).reply(200, { regions }); + }); + + it('return list of roles where each item has a name and value', () => { + expect(awsServices.fetchRegions()).resolves.toEqual(regionsOutput); + }); + }); + + describe('when fetchRoles succeeds', () => { + let roles; + let rolesOutput; + + beforeEach(() => { + roles = [ + { role_name: 'admin', arn: 'aws::admin' }, + { role_name: 'read-only', arn: 'aws::read-only' }, + ]; + rolesOutput = roles.map(({ role_name: name, arn: value }) => ({ name, value })); + axiosMock.onGet(apiPaths.getRolesPath).reply(200, { roles }); + }); + + it('return list of regions where each item has a name and value', () => { + expect(awsServices.fetchRoles()).resolves.toEqual(rolesOutput); + }); + }); + + describe('when fetchKeyPairs succeeds', () => { + let keyPairs; + let keyPairsOutput; + + beforeEach(() => { + keyPairs = [{ key_pair: 'key-pair' }, { key_pair: 'key-pair-2' }]; + keyPairsOutput = keyPairs.map(({ key_name: name }) => ({ name, value: name })); + axiosMock + .onGet(apiPaths.getKeyPairsPath, { params: { region } }) + .reply(200, { key_pairs: keyPairs }); + }); + + it('return list of key pairs where each item has a name and value', () => { + expect(awsServices.fetchKeyPairs({ region })).resolves.toEqual(keyPairsOutput); + }); + }); + + describe('when fetchVpcs succeeds', () => { + let vpcs; + let vpcsOutput; + + beforeEach(() => { + vpcs = [{ vpc_id: 'vpc-1' }, { vpc_id: 'vpc-2' }]; + vpcsOutput = vpcs.map(({ vpc_id: name }) => ({ name, value: name })); + axiosMock.onGet(apiPaths.getVpcsPath, { params: { region } }).reply(200, { vpcs }); + }); + + it('return list of vpcs where each item has a name and value', () => { + expect(awsServices.fetchVpcs({ region })).resolves.toEqual(vpcsOutput); + }); + }); + + describe('when fetchSubnets succeeds', () => { + let subnets; + let subnetsOutput; + + beforeEach(() => { + subnets = [{ subnet_id: 'vpc-1' }, { subnet_id: 'vpc-2' }]; + subnetsOutput = subnets.map(({ subnet_id }) => ({ name: subnet_id, value: subnet_id })); + axiosMock + .onGet(apiPaths.getSubnetsPath, { params: { region, vpc_id: vpc } }) + .reply(200, { subnets }); + }); + + it('return list of subnets where each item has a name and value', () => { + expect(awsServices.fetchSubnets({ region, vpc })).resolves.toEqual(subnetsOutput); + }); + }); + + describe('when fetchSecurityGroups succeeds', () => { + let securityGroups; + let securityGroupsOutput; + + beforeEach(() => { + securityGroups = [ + { group_name: 'admin group', group_id: 'group-1' }, + { group_name: 'basic group', group_id: 'group-2' }, + ]; + securityGroupsOutput = securityGroups.map(({ group_id: value, group_name: name }) => ({ + name, + value, + })); + axiosMock + .onGet(apiPaths.getSecurityGroupsPath, { params: { region, vpc_id: vpc } }) + .reply(200, { security_groups: securityGroups }); + }); + + it('return list of security groups where each item has a name and value', () => { + expect(awsServices.fetchSecurityGroups({ region, vpc })).resolves.toEqual( + securityGroupsOutput, + ); + }); + }); + + describe('when fetchInstanceTypes succeeds', () => { + let instanceTypes; + let instanceTypesOutput; + + beforeEach(() => { + instanceTypes = [{ instance_type_name: 't2.small' }, { instance_type_name: 't2.medium' }]; + instanceTypesOutput = instanceTypes.map(({ instance_type_name }) => ({ + name: instance_type_name, + value: instance_type_name, + })); + axiosMock.onGet(apiPaths.getInstanceTypesPath).reply(200, { instance_types: instanceTypes }); + }); + + it('return list of instance types where each item has a name and value', () => { + expect(awsServices.fetchInstanceTypes()).resolves.toEqual(instanceTypesOutput); + }); + }); +}); diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js index 99c8cdba296..cf6c317a2df 100644 --- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js +++ b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js @@ -13,12 +13,20 @@ import { SET_ROLE, SET_SECURITY_GROUP, SET_GITLAB_MANAGED_CLUSTER, + SET_INSTANCE_TYPE, + SET_NODE_COUNT, REQUEST_CREATE_ROLE, CREATE_ROLE_SUCCESS, CREATE_ROLE_ERROR, + REQUEST_CREATE_CLUSTER, + CREATE_CLUSTER_ERROR, + SIGN_OUT, } from '~/create_cluster/eks_cluster/store/mutation_types'; import axios from '~/lib/utils/axios_utils'; import MockAdapter from 'axios-mock-adapter'; +import createFlash from '~/flash'; + +jest.mock('~/flash'); describe('EKS Cluster Store Actions', () => { let clusterName; @@ -30,25 +38,34 @@ describe('EKS Cluster Store Actions', () => { let role; let keyPair; let securityGroup; + let instanceType; + let nodeCount; let gitlabManagedCluster; let mock; let state; + let newClusterUrl; beforeEach(() => { clusterName = 'my cluster'; environmentScope = 'production'; kubernetesVersion = '11.1'; - region = { name: 'regions-1' }; - vpc = { name: 'vpc-1' }; - subnet = { name: 'subnet-1' }; - role = { name: 'role-1' }; - keyPair = { name: 'key-pair-1' }; - securityGroup = { name: 'default group' }; + region = 'regions-1'; + vpc = 'vpc-1'; + subnet = 'subnet-1'; + role = 'role-1'; + keyPair = 'key-pair-1'; + securityGroup = 'default group'; + instanceType = 'small-1'; + nodeCount = '5'; gitlabManagedCluster = true; + newClusterUrl = '/clusters/1'; + state = { ...createState(), createRolePath: '/clusters/roles/', + signOutPath: '/aws/signout', + createClusterPath: '/clusters/', }; }); @@ -71,6 +88,8 @@ describe('EKS Cluster Store Actions', () => { ${'setVpc'} | ${SET_VPC} | ${{ vpc }} | ${'vpc'} ${'setSubnet'} | ${SET_SUBNET} | ${{ subnet }} | ${'subnet'} ${'setSecurityGroup'} | ${SET_SECURITY_GROUP} | ${{ securityGroup }} | ${'securityGroup'} + ${'setInstanceType'} | ${SET_INSTANCE_TYPE} | ${{ instanceType }} | ${'instance type'} + ${'setNodeCount'} | ${SET_NODE_COUNT} | ${{ nodeCount }} | ${'node count'} ${'setGitlabManagedCluster'} | ${SET_GITLAB_MANAGED_CLUSTER} | ${gitlabManagedCluster} | ${'gitlab managed cluster'} `(`$action commits $mutation with $payloadDescription payload`, data => { const { action, mutation, payload } = data; @@ -149,4 +168,127 @@ describe('EKS Cluster Store Actions', () => { testAction(actions.createRoleError, payload, state, [{ type: CREATE_ROLE_ERROR, payload }]); }); }); + + describe('createCluster', () => { + let requestPayload; + + beforeEach(() => { + requestPayload = { + name: clusterName, + environment_scope: environmentScope, + managed: gitlabManagedCluster, + provider_aws_attributes: { + region, + vpc_id: vpc, + subnet_ids: subnet, + role_arn: role, + key_name: keyPair, + security_group_id: securityGroup, + instance_type: instanceType, + num_nodes: nodeCount, + }, + }; + state = Object.assign(createState(), { + clusterName, + environmentScope, + kubernetesVersion, + selectedRegion: region, + selectedVpc: vpc, + selectedSubnet: subnet, + selectedRole: role, + selectedKeyPair: keyPair, + selectedSecurityGroup: securityGroup, + selectedInstanceType: instanceType, + nodeCount, + gitlabManagedCluster, + }); + }); + + describe('when request succeeds', () => { + beforeEach(() => { + mock.onPost(state.createClusterPath, requestPayload).reply(201, null, { + location: '/clusters/1', + }); + }); + + it('dispatches createClusterSuccess action', () => + testAction( + actions.createCluster, + null, + state, + [], + [ + { type: 'requestCreateCluster' }, + { type: 'createClusterSuccess', payload: newClusterUrl }, + ], + )); + }); + + describe('when request fails', () => { + let response; + + beforeEach(() => { + response = 'Request failed with status code 400'; + mock.onPost(state.createClusterPath, requestPayload).reply(400, response); + }); + + it('dispatches createRoleError action', () => + testAction( + actions.createCluster, + null, + state, + [], + [{ type: 'requestCreateCluster' }, { type: 'createClusterError', payload: response }], + )); + }); + }); + + describe('requestCreateCluster', () => { + it('commits requestCreateCluster mutation', () => { + testAction(actions.requestCreateCluster, null, state, [{ type: REQUEST_CREATE_CLUSTER }]); + }); + }); + + describe('createClusterSuccess', () => { + beforeEach(() => { + jest.spyOn(window.location, 'assign').mockImplementation(() => {}); + }); + afterEach(() => { + window.location.assign.mockRestore(); + }); + + it('redirects to the new cluster URL', () => { + actions.createClusterSuccess(null, newClusterUrl); + + expect(window.location.assign).toHaveBeenCalledWith(newClusterUrl); + }); + }); + + describe('createClusterError', () => { + let payload; + + beforeEach(() => { + payload = { name: ['Create cluster failed'] }; + }); + + it('commits createClusterError mutation', () => { + testAction(actions.createClusterError, payload, state, [ + { type: CREATE_CLUSTER_ERROR, payload }, + ]); + }); + + it('creates a flash that displays the create cluster error', () => { + expect(createFlash).toHaveBeenCalledWith(payload.name[0]); + }); + }); + + describe('signOut', () => { + beforeEach(() => { + mock.onDelete(state.signOutPath).reply(200, null); + }); + + it('commits signOut mutation', () => { + testAction(actions.signOut, null, state, [{ type: SIGN_OUT }]); + }); + }); }); diff --git a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js b/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js index 2637b4822a5..0fb392f5eea 100644 --- a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js +++ b/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js @@ -8,10 +8,15 @@ import { SET_SUBNET, SET_ROLE, SET_SECURITY_GROUP, + SET_INSTANCE_TYPE, + SET_NODE_COUNT, SET_GITLAB_MANAGED_CLUSTER, REQUEST_CREATE_ROLE, CREATE_ROLE_SUCCESS, CREATE_ROLE_ERROR, + REQUEST_CREATE_CLUSTER, + CREATE_CLUSTER_ERROR, + SIGN_OUT, } from '~/create_cluster/eks_cluster/store/mutation_types'; import createState from '~/create_cluster/eks_cluster/store/state'; import mutations from '~/create_cluster/eks_cluster/store/mutations'; @@ -27,6 +32,8 @@ describe('Create EKS cluster store mutations', () => { let role; let keyPair; let securityGroup; + let instanceType; + let nodeCount; let gitlabManagedCluster; beforeEach(() => { @@ -39,6 +46,8 @@ describe('Create EKS cluster store mutations', () => { role = { name: 'role-1' }; keyPair = { name: 'key pair' }; securityGroup = { name: 'default group' }; + instanceType = 'small-1'; + nodeCount = '5'; gitlabManagedCluster = false; state = createState(); @@ -53,8 +62,10 @@ describe('Create EKS cluster store mutations', () => { ${SET_REGION} | ${'selectedRegion'} | ${{ region }} | ${region} | ${'selected region payload'} ${SET_KEY_PAIR} | ${'selectedKeyPair'} | ${{ keyPair }} | ${keyPair} | ${'selected key pair payload'} ${SET_VPC} | ${'selectedVpc'} | ${{ vpc }} | ${vpc} | ${'selected vpc payload'} - ${SET_SUBNET} | ${'selectedSubnet'} | ${{ subnet }} | ${subnet} | ${'selected sybnet payload'} + ${SET_SUBNET} | ${'selectedSubnet'} | ${{ subnet }} | ${subnet} | ${'selected subnet payload'} ${SET_SECURITY_GROUP} | ${'selectedSecurityGroup'} | ${{ securityGroup }} | ${securityGroup} | ${'selected security group payload'} + ${SET_INSTANCE_TYPE} | ${'selectedInstanceType'} | ${{ instanceType }} | ${instanceType} | ${'selected instance type payload'} + ${SET_NODE_COUNT} | ${'nodeCount'} | ${{ nodeCount }} | ${nodeCount} | ${'node count payload'} ${SET_GITLAB_MANAGED_CLUSTER} | ${'gitlabManagedCluster'} | ${{ gitlabManagedCluster }} | ${gitlabManagedCluster} | ${'gitlab managed cluster'} `(`$mutation sets $mutatedProperty to $expectedValueDescription`, data => { const { mutation, mutatedProperty, payload, expectedValue } = data; @@ -118,4 +129,45 @@ describe('Create EKS cluster store mutations', () => { expect(state.hasCredentials).toBe(false); }); }); + + describe(`mutation ${REQUEST_CREATE_CLUSTER}`, () => { + beforeEach(() => { + mutations[REQUEST_CREATE_CLUSTER](state); + }); + + it('sets isCreatingCluster to true', () => { + expect(state.isCreatingCluster).toBe(true); + }); + + it('sets createClusterError to null', () => { + expect(state.createClusterError).toBe(null); + }); + }); + + describe(`mutation ${CREATE_CLUSTER_ERROR}`, () => { + const error = new Error(); + + beforeEach(() => { + mutations[CREATE_CLUSTER_ERROR](state, { error }); + }); + + it('sets isCreatingRole to false', () => { + expect(state.isCreatingCluster).toBe(false); + }); + + it('sets createRoleError to the error object', () => { + expect(state.createClusterError).toBe(error); + }); + }); + + describe(`mutation ${SIGN_OUT}`, () => { + beforeEach(() => { + state.hasCredentials = true; + mutations[SIGN_OUT](state); + }); + + it('sets hasCredentials to false', () => { + expect(state.hasCredentials).toBe(false); + }); + }); }); |