diff options
Diffstat (limited to 'spec/frontend/create_cluster')
24 files changed, 0 insertions, 3115 deletions
diff --git a/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js b/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js deleted file mode 100644 index 2f835867f5f..00000000000 --- a/spec/frontend/create_cluster/components/cluster_form_dropdown_spec.js +++ /dev/null @@ -1,214 +0,0 @@ -import { GlIcon } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import $ from 'jquery'; - -import { nextTick } from 'vue'; -import ClusterFormDropdown from '~/create_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'; - -describe('ClusterFormDropdown', () => { - let wrapper; - const firstItem = { name: 'item 1', value: '1' }; - const secondItem = { name: 'item 2', value: '2' }; - const items = [firstItem, secondItem, { name: 'item 3', value: '3' }]; - - beforeEach(() => { - wrapper = shallowMount(ClusterFormDropdown); - }); - afterEach(() => wrapper.destroy()); - - describe('when initial value is provided', () => { - it('sets selectedItem to initial value', async () => { - wrapper.setProps({ items, value: secondItem.value }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(secondItem.name); - }); - }); - - describe('when no item is selected', () => { - it('displays placeholder text', async () => { - const placeholder = 'placeholder'; - - wrapper.setProps({ placeholder }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(placeholder); - }); - }); - - describe('when an item is selected', () => { - beforeEach(async () => { - wrapper.setProps({ items }); - await nextTick(); - wrapper.findAll('.js-dropdown-item').at(1).trigger('click'); - await nextTick(); - }); - - it('emits input event with selected item', () => { - expect(wrapper.emitted('input')[0]).toEqual([secondItem.value]); - }); - }); - - describe('when multiple items are selected', () => { - const value = ['1']; - - beforeEach(async () => { - wrapper.setProps({ items, multiple: true, value }); - - await nextTick(); - wrapper.findAll('.js-dropdown-item').at(0).trigger('click'); - - await nextTick(); - wrapper.findAll('.js-dropdown-item').at(1).trigger('click'); - - await nextTick(); - }); - - it('emits input event with an array of selected items', () => { - expect(wrapper.emitted('input')[1]).toEqual([[firstItem.value, secondItem.value]]); - }); - }); - - describe('when multiple items can be selected', () => { - beforeEach(async () => { - wrapper.setProps({ items, multiple: true, value: firstItem.value }); - await nextTick(); - }); - - it('displays a checked GlIcon next to the item', () => { - expect(wrapper.find(GlIcon).classes()).not.toContain('invisible'); - expect(wrapper.find(GlIcon).props('name')).toBe('mobile-issue-close'); - }); - }); - - describe('when multiple values can be selected and initial value is null', () => { - it('emits input event with an array of a single selected item', async () => { - wrapper.setProps({ items, multiple: true, value: null }); - - await nextTick(); - wrapper.findAll('.js-dropdown-item').at(0).trigger('click'); - - expect(wrapper.emitted('input')[0]).toEqual([[firstItem.value]]); - }); - }); - - describe('when an item is selected and has a custom label property', () => { - it('displays selected item custom label', async () => { - const labelProperty = 'customLabel'; - const label = 'Name'; - const currentValue = '1'; - const customLabelItems = [{ [labelProperty]: label, value: currentValue }]; - - wrapper.setProps({ labelProperty, items: customLabelItems, value: currentValue }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(label); - }); - }); - - describe('when loading', () => { - it('dropdown button isLoading', async () => { - await wrapper.setProps({ loading: true }); - expect(wrapper.find(DropdownButton).props('isLoading')).toBe(true); - }); - }); - - describe('when loading and loadingText is provided', () => { - it('uses loading text as toggle button text', async () => { - const loadingText = 'loading text'; - - wrapper.setProps({ loading: true, loadingText }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('toggleText')).toEqual(loadingText); - }); - }); - - describe('when disabled', () => { - it('dropdown button isDisabled', async () => { - wrapper.setProps({ disabled: true }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('isDisabled')).toBe(true); - }); - }); - - describe('when disabled and disabledText is provided', () => { - it('uses disabled text as toggle button text', async () => { - const disabledText = 'disabled text'; - - wrapper.setProps({ disabled: true, disabledText }); - - await nextTick(); - expect(wrapper.find(DropdownButton).props('toggleText')).toBe(disabledText); - }); - }); - - describe('when has errors', () => { - it('sets border-danger class selector to dropdown toggle', async () => { - wrapper.setProps({ hasErrors: true }); - - await nextTick(); - expect(wrapper.find(DropdownButton).classes('border-danger')).toBe(true); - }); - }); - - describe('when has errors and an error message', () => { - it('displays error message', async () => { - const errorMessage = 'error message'; - - wrapper.setProps({ hasErrors: true, errorMessage }); - - await nextTick(); - expect(wrapper.find('.js-eks-dropdown-error-message').text()).toEqual(errorMessage); - }); - }); - - describe('when no results are available', () => { - it('displays empty text', async () => { - const emptyText = 'error message'; - - wrapper.setProps({ items: [], emptyText }); - - await nextTick(); - expect(wrapper.find('.js-empty-text').text()).toEqual(emptyText); - }); - }); - - it('displays search field placeholder', async () => { - const searchFieldPlaceholder = 'Placeholder'; - - wrapper.setProps({ searchFieldPlaceholder }); - - await nextTick(); - expect(wrapper.find(DropdownSearchInput).props('placeholderText')).toEqual( - searchFieldPlaceholder, - ); - }); - - it('it filters results by search query', async () => { - const searchQuery = secondItem.name; - - wrapper.setProps({ items }); - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ searchQuery }); - - await nextTick(); - expect(wrapper.findAll('.js-dropdown-item').length).toEqual(1); - expect(wrapper.find('.js-dropdown-item').text()).toEqual(secondItem.name); - }); - - it('focuses dropdown search input when dropdown is displayed', async () => { - const dropdownEl = wrapper.find('.dropdown').element; - - expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(false); - - $(dropdownEl).trigger('shown.bs.dropdown'); - - await nextTick(); - expect(wrapper.find(DropdownSearchInput).props('focused')).toBe(true); - }); -}); diff --git a/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js b/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js deleted file mode 100644 index c8020cf8308..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/components/create_eks_cluster_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; - -import CreateEksCluster from '~/create_cluster/eks_cluster/components/create_eks_cluster.vue'; -import EksClusterConfigurationForm from '~/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue'; -import ServiceCredentialsForm from '~/create_cluster/eks_cluster/components/service_credentials_form.vue'; - -Vue.use(Vuex); - -describe('CreateEksCluster', () => { - let vm; - let state; - const gitlabManagedClusterHelpPath = 'gitlab-managed-cluster-help-path'; - const namespacePerEnvironmentHelpPath = 'namespace-per-environment-help-path'; - const accountAndExternalIdsHelpPath = 'account-and-external-id-help-path'; - const createRoleArnHelpPath = 'role-arn-help-path'; - const kubernetesIntegrationHelpPath = 'kubernetes-integration'; - const externalLinkIcon = 'external-link'; - - beforeEach(() => { - state = { hasCredentials: false }; - const store = new Vuex.Store({ - state, - }); - - vm = shallowMount(CreateEksCluster, { - propsData: { - gitlabManagedClusterHelpPath, - namespacePerEnvironmentHelpPath, - accountAndExternalIdsHelpPath, - createRoleArnHelpPath, - externalLinkIcon, - kubernetesIntegrationHelpPath, - }, - store, - }); - }); - afterEach(() => vm.destroy()); - - describe('when credentials are provided', () => { - beforeEach(() => { - state.hasCredentials = true; - }); - - it('displays eks cluster configuration form when credentials are valid', () => { - expect(vm.find(EksClusterConfigurationForm).exists()).toBe(true); - }); - - describe('passes to the cluster configuration form', () => { - it('help url for kubernetes integration documentation', () => { - expect(vm.find(EksClusterConfigurationForm).props('gitlabManagedClusterHelpPath')).toBe( - gitlabManagedClusterHelpPath, - ); - }); - - it('help url for namespace per environment cluster documentation', () => { - expect(vm.find(EksClusterConfigurationForm).props('namespacePerEnvironmentHelpPath')).toBe( - namespacePerEnvironmentHelpPath, - ); - }); - - it('help url for gitlab managed cluster documentation', () => { - expect(vm.find(EksClusterConfigurationForm).props('kubernetesIntegrationHelpPath')).toBe( - kubernetesIntegrationHelpPath, - ); - }); - }); - }); - - describe('when credentials are invalid', () => { - beforeEach(() => { - state.hasCredentials = false; - }); - - it('displays service credentials form', () => { - expect(vm.find(ServiceCredentialsForm).exists()).toBe(true); - }); - - describe('passes to the service credentials form', () => { - it('help url for account and external ids', () => { - expect(vm.find(ServiceCredentialsForm).props('accountAndExternalIdsHelpPath')).toBe( - accountAndExternalIdsHelpPath, - ); - }); - - it('external link icon', () => { - expect(vm.find(ServiceCredentialsForm).props('externalLinkIcon')).toBe(externalLinkIcon); - }); - - it('help url to create a role ARN', () => { - expect(vm.find(ServiceCredentialsForm).props('createRoleArnHelpPath')).toBe( - createRoleArnHelpPath, - ); - }); - }); - }); -}); 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 deleted file mode 100644 index 1509d26c99d..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/components/eks_cluster_configuration_form_spec.js +++ /dev/null @@ -1,562 +0,0 @@ -import { GlFormCheckbox } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; -import Vuex from 'vuex'; - -import EksClusterConfigurationForm from '~/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue'; -import eksClusterFormState from '~/create_cluster/eks_cluster/store/state'; -import clusterDropdownStoreState from '~/create_cluster/store/cluster_dropdown/state'; - -Vue.use(Vuex); - -describe('EksClusterConfigurationForm', () => { - let store; - let actions; - let getters; - let state; - let rolesState; - let vpcsState; - let subnetsState; - let keyPairsState; - let securityGroupsState; - let instanceTypesState; - let vpcsActions; - let rolesActions; - let subnetsActions; - let keyPairsActions; - let securityGroupsActions; - let vm; - - const createStore = (config = {}) => { - actions = { - createCluster: jest.fn(), - setClusterName: jest.fn(), - setEnvironmentScope: jest.fn(), - setKubernetesVersion: jest.fn(), - setRegion: jest.fn(), - setVpc: jest.fn(), - setSubnet: jest.fn(), - setRole: jest.fn(), - setKeyPair: jest.fn(), - setSecurityGroup: jest.fn(), - setInstanceType: jest.fn(), - setNodeCount: jest.fn(), - setGitlabManagedCluster: jest.fn(), - }; - keyPairsActions = { - fetchItems: jest.fn(), - }; - vpcsActions = { - fetchItems: jest.fn(), - }; - subnetsActions = { - fetchItems: jest.fn(), - }; - rolesActions = { - fetchItems: jest.fn(), - }; - securityGroupsActions = { - fetchItems: jest.fn(), - }; - state = { - ...eksClusterFormState(), - ...config.initialState, - }; - rolesState = { - ...clusterDropdownStoreState(), - ...config.rolesState, - }; - vpcsState = { - ...clusterDropdownStoreState(), - ...config.vpcsState, - }; - subnetsState = { - ...clusterDropdownStoreState(), - ...config.subnetsState, - }; - keyPairsState = { - ...clusterDropdownStoreState(), - ...config.keyPairsState, - }; - securityGroupsState = { - ...clusterDropdownStoreState(), - ...config.securityGroupsState, - }; - instanceTypesState = { - ...clusterDropdownStoreState(), - ...config.instanceTypesState, - }; - getters = { - subnetValid: config?.getters?.subnetValid || (() => false), - }; - store = new Vuex.Store({ - state, - getters, - actions, - modules: { - vpcs: { - namespaced: true, - state: vpcsState, - actions: vpcsActions, - }, - subnets: { - namespaced: true, - state: subnetsState, - actions: subnetsActions, - }, - roles: { - namespaced: true, - state: rolesState, - actions: rolesActions, - }, - keyPairs: { - namespaced: true, - state: keyPairsState, - actions: keyPairsActions, - }, - securityGroups: { - namespaced: true, - state: securityGroupsState, - actions: securityGroupsActions, - }, - instanceTypes: { - namespaced: true, - state: instanceTypesState, - }, - }, - }); - }; - - const createValidStateStore = (initialState) => { - createStore({ - initialState: { - clusterName: 'cluster name', - environmentScope: '*', - kubernetesVersion: '1.16', - selectedRegion: 'region', - selectedRole: 'role', - selectedKeyPair: 'key pair', - selectedVpc: 'vpc', - selectedSubnet: ['subnet 1', 'subnet 2'], - selectedSecurityGroup: 'group', - selectedInstanceType: 'small-1', - ...initialState, - }, - getters: { - subnetValid: () => true, - }, - }); - }; - - const buildWrapper = () => { - vm = shallowMount(EksClusterConfigurationForm, { - store, - propsData: { - gitlabManagedClusterHelpPath: '', - namespacePerEnvironmentHelpPath: '', - kubernetesIntegrationHelpPath: '', - externalLinkIcon: '', - }, - }); - }; - - beforeEach(() => { - createStore(); - buildWrapper(); - }); - - afterEach(() => { - vm.destroy(); - }); - - 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 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', () => { - it('fetches available roles', () => { - expect(rolesActions.fetchItems).toHaveBeenCalled(); - }); - - describe('when fetching vpcs and key pairs', () => { - const region = 'us-west-2'; - - beforeEach(() => { - createValidStateStore({ selectedRegion: region }); - buildWrapper(); - }); - - it('fetches available vpcs', () => { - expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); - }); - - it('fetches available key pairs', () => { - expect(keyPairsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }); - }); - - it('cleans selected vpc', () => { - expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc: null }); - }); - - it('cleans selected key pair', () => { - expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair: null }); - }); - - it('cleans selected subnet', () => { - expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] }); - }); - - it('cleans selected security group', () => { - expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), { - securityGroup: null, - }); - }); - }); - }); - - it('sets isLoadingRoles to RoleDropdown loading property', async () => { - rolesState.isLoadingItems = true; - - await nextTick(); - expect(findRoleDropdown().props('loading')).toBe(rolesState.isLoadingItems); - }); - - it('sets roles to RoleDropdown items property', () => { - expect(findRoleDropdown().props('items')).toBe(rolesState.items); - }); - - it('sets RoleDropdown hasErrors to true when loading roles failed', async () => { - rolesState.loadingItemsError = new Error(); - - await nextTick(); - expect(findRoleDropdown().props('hasErrors')).toEqual(true); - }); - - it('disables KeyPairDropdown when no region is selected', () => { - expect(findKeyPairDropdown().props('disabled')).toBe(true); - }); - - it('enables KeyPairDropdown when no region is selected', async () => { - state.selectedRegion = { name: 'west-1 ' }; - - await nextTick(); - expect(findKeyPairDropdown().props('disabled')).toBe(false); - }); - - it('sets isLoadingKeyPairs to KeyPairDropdown loading property', async () => { - keyPairsState.isLoadingItems = true; - - await nextTick(); - expect(findKeyPairDropdown().props('loading')).toBe(keyPairsState.isLoadingItems); - }); - - it('sets keyPairs to KeyPairDropdown items property', () => { - expect(findKeyPairDropdown().props('items')).toBe(keyPairsState.items); - }); - - it('sets KeyPairDropdown hasErrors to true when loading key pairs fails', async () => { - keyPairsState.loadingItemsError = new Error(); - - await nextTick(); - expect(findKeyPairDropdown().props('hasErrors')).toEqual(true); - }); - - it('disables VpcDropdown when no region is selected', () => { - expect(findVpcDropdown().props('disabled')).toBe(true); - }); - - it('enables VpcDropdown when no region is selected', async () => { - state.selectedRegion = { name: 'west-1 ' }; - - await nextTick(); - expect(findVpcDropdown().props('disabled')).toBe(false); - }); - - it('sets isLoadingVpcs to VpcDropdown loading property', async () => { - vpcsState.isLoadingItems = true; - - await nextTick(); - expect(findVpcDropdown().props('loading')).toBe(vpcsState.isLoadingItems); - }); - - it('sets vpcs to VpcDropdown items property', () => { - expect(findVpcDropdown().props('items')).toBe(vpcsState.items); - }); - - it('sets VpcDropdown hasErrors to true when loading vpcs fails', async () => { - vpcsState.loadingItemsError = new Error(); - - await nextTick(); - expect(findVpcDropdown().props('hasErrors')).toEqual(true); - }); - - it('disables SubnetDropdown when no vpc is selected', () => { - expect(findSubnetDropdown().props('disabled')).toBe(true); - }); - - it('enables SubnetDropdown when a vpc is selected', async () => { - state.selectedVpc = { name: 'vpc-1 ' }; - - await nextTick(); - expect(findSubnetDropdown().props('disabled')).toBe(false); - }); - - it('sets isLoadingSubnets to SubnetDropdown loading property', async () => { - subnetsState.isLoadingItems = true; - - await nextTick(); - expect(findSubnetDropdown().props('loading')).toBe(subnetsState.isLoadingItems); - }); - - it('sets subnets to SubnetDropdown items property', () => { - expect(findSubnetDropdown().props('items')).toBe(subnetsState.items); - }); - - it('displays a validation error in the subnet dropdown when loading subnets fails', () => { - createStore({ - subnetsState: { - loadingItemsError: new Error(), - }, - }); - buildWrapper(); - - expect(findSubnetDropdown().props('hasErrors')).toEqual(true); - }); - - it('displays a validation error in the subnet dropdown when a single subnet is selected', () => { - createStore({ - initialState: { - selectedSubnet: ['subnet 1'], - }, - }); - buildWrapper(); - - expect(findSubnetDropdown().props('hasErrors')).toEqual(true); - expect(findSubnetDropdown().props('errorMessage')).toEqual( - 'You should select at least two subnets', - ); - }); - - it('disables SecurityGroupDropdown when no vpc is selected', () => { - expect(findSecurityGroupDropdown().props('disabled')).toBe(true); - }); - - it('enables SecurityGroupDropdown when a vpc is selected', async () => { - state.selectedVpc = { name: 'vpc-1 ' }; - - await nextTick(); - expect(findSecurityGroupDropdown().props('disabled')).toBe(false); - }); - - it('sets isLoadingSecurityGroups to SecurityGroupDropdown loading property', async () => { - securityGroupsState.isLoadingItems = true; - - await nextTick(); - expect(findSecurityGroupDropdown().props('loading')).toBe(securityGroupsState.isLoadingItems); - }); - - it('sets securityGroups to SecurityGroupDropdown items property', () => { - expect(findSecurityGroupDropdown().props('items')).toBe(securityGroupsState.items); - }); - - it('sets SecurityGroupDropdown hasErrors to true when loading security groups fails', async () => { - securityGroupsState.loadingItemsError = new Error(); - - await nextTick(); - expect(findSecurityGroupDropdown().props('hasErrors')).toEqual(true); - }); - - it('dispatches setClusterName when cluster name input changes', () => { - const clusterName = 'name'; - - findClusterNameInput().vm.$emit('input', clusterName); - - expect(actions.setClusterName).toHaveBeenCalledWith(expect.anything(), { clusterName }); - }); - - it('dispatches setEnvironmentScope when environment scope input changes', () => { - const environmentScope = 'production'; - - findEnvironmentScopeInput().vm.$emit('input', environmentScope); - - expect(actions.setEnvironmentScope).toHaveBeenCalledWith(expect.anything(), { - environmentScope, - }); - }); - - it('dispatches setKubernetesVersion when kubernetes version dropdown changes', () => { - const kubernetesVersion = { name: '1.11' }; - - findKubernetesVersionDropdown().vm.$emit('input', kubernetesVersion); - - expect(actions.setKubernetesVersion).toHaveBeenCalledWith(expect.anything(), { - kubernetesVersion, - }); - }); - - it('dispatches setGitlabManagedCluster when gitlab managed cluster input changes', () => { - const gitlabManagedCluster = false; - - findGitlabManagedClusterCheckbox().vm.$emit('input', gitlabManagedCluster); - - expect(actions.setGitlabManagedCluster).toHaveBeenCalledWith(expect.anything(), { - gitlabManagedCluster, - }); - }); - - describe('when vpc is selected', () => { - const vpc = { name: 'vpc-1' }; - const region = 'east-1'; - - beforeEach(() => { - state.selectedRegion = region; - findVpcDropdown().vm.$emit('input', vpc); - }); - - it('dispatches setVpc action', () => { - expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc }); - }); - - it('cleans selected subnet', () => { - expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet: [] }); - }); - - it('cleans selected security group', () => { - expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), { - securityGroup: null, - }); - }); - - it('dispatches fetchSubnets action', () => { - expect(subnetsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { vpc, region }); - }); - - it('dispatches fetchSecurityGroups action', () => { - expect(securityGroupsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { - vpc, - region, - }); - }); - }); - - describe('when a subnet is selected', () => { - const subnet = { name: 'subnet-1' }; - - beforeEach(() => { - findSubnetDropdown().vm.$emit('input', subnet); - }); - - it('dispatches setSubnet action', () => { - expect(actions.setSubnet).toHaveBeenCalledWith(expect.anything(), { subnet }); - }); - }); - - describe('when role is selected', () => { - const role = { name: 'admin' }; - - beforeEach(() => { - findRoleDropdown().vm.$emit('input', role); - }); - - it('dispatches setRole action', () => { - expect(actions.setRole).toHaveBeenCalledWith(expect.anything(), { role }); - }); - }); - - describe('when key pair is selected', () => { - const keyPair = { name: 'key pair' }; - - beforeEach(() => { - findKeyPairDropdown().vm.$emit('input', keyPair); - }); - - it('dispatches setKeyPair action', () => { - expect(actions.setKeyPair).toHaveBeenCalledWith(expect.anything(), { keyPair }); - }); - }); - - describe('when security group is selected', () => { - const securityGroup = { name: 'default group' }; - - beforeEach(() => { - findSecurityGroupDropdown().vm.$emit('input', securityGroup); - }); - - it('dispatches setSecurityGroup action', () => { - expect(actions.setSecurityGroup).toHaveBeenCalledWith(expect.anything(), { securityGroup }); - }); - }); - - 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 }); - }); - }); - - it('dispatches setNodeCount when node count input changes', () => { - const nodeCount = 5; - - findNodeCountInput().vm.$emit('input', nodeCount); - - expect(actions.setNodeCount).toHaveBeenCalledWith(expect.anything(), { nodeCount }); - }); - - describe('when all cluster configuration fields are set', () => { - it('enables create cluster button', () => { - createValidStateStore(); - buildWrapper(); - expect(findCreateClusterButton().props('disabled')).toBe(false); - }); - }); - - describe('when at least one cluster configuration field is not set', () => { - beforeEach(() => { - createValidStateStore({ - clusterName: null, - }); - buildWrapper(); - }); - - it('disables create cluster button', () => { - expect(findCreateClusterButton().props('disabled')).toBe(true); - }); - }); - - describe('when is creating cluster', () => { - beforeEach(() => { - createValidStateStore({ - isCreatingCluster: true, - }); - buildWrapper(); - }); - - 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/service_credentials_form_spec.js b/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js deleted file mode 100644 index 0d823a18012..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/components/service_credentials_form_spec.js +++ /dev/null @@ -1,124 +0,0 @@ -import { GlButton } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; -import Vuex from 'vuex'; -import ServiceCredentialsForm from '~/create_cluster/eks_cluster/components/service_credentials_form.vue'; -import eksClusterState from '~/create_cluster/eks_cluster/store/state'; - -Vue.use(Vuex); - -describe('ServiceCredentialsForm', () => { - let vm; - let state; - let createRoleAction; - const accountId = 'accountId'; - const externalId = 'externalId'; - - beforeEach(() => { - state = Object.assign(eksClusterState(), { - accountId, - externalId, - }); - createRoleAction = jest.fn(); - - const store = new Vuex.Store({ - state, - actions: { - createRole: createRoleAction, - }, - }); - vm = shallowMount(ServiceCredentialsForm, { - propsData: { - accountAndExternalIdsHelpPath: '', - createRoleArnHelpPath: '', - externalLinkIcon: '', - }, - store, - }); - }); - afterEach(() => vm.destroy()); - - const findAccountIdInput = () => vm.find('#gitlab-account-id'); - const findCopyAccountIdButton = () => vm.find('.js-copy-account-id-button'); - const findExternalIdInput = () => vm.find('#eks-external-id'); - const findCopyExternalIdButton = () => vm.find('.js-copy-external-id-button'); - const findInvalidCredentials = () => vm.find('.js-invalid-credentials'); - const findSubmitButton = () => vm.find(GlButton); - - it('displays provided account id', () => { - expect(findAccountIdInput().attributes('value')).toBe(accountId); - }); - - it('allows to copy account id', () => { - expect(findCopyAccountIdButton().props('text')).toBe(accountId); - }); - - it('displays provided external id', () => { - expect(findExternalIdInput().attributes('value')).toBe(externalId); - }); - - it('allows to copy external id', () => { - expect(findCopyExternalIdButton().props('text')).toBe(externalId); - }); - - it('disables submit button when role ARN is not provided', () => { - expect(findSubmitButton().attributes('disabled')).toBeTruthy(); - }); - - it('enables submit button when role ARN is not provided', async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - vm.setData({ roleArn: '123' }); - - await nextTick(); - expect(findSubmitButton().attributes('disabled')).toBeFalsy(); - }); - - it('dispatches createRole action when submit button is clicked', () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - vm.setData({ roleArn: '123' }); // set role ARN to enable button - - findSubmitButton().vm.$emit('click', new Event('click')); - - expect(createRoleAction).toHaveBeenCalled(); - }); - - describe('when is creating role', () => { - beforeEach(async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - vm.setData({ roleArn: '123' }); // set role ARN to enable button - - state.isCreatingRole = true; - - await nextTick(); - }); - - it('disables submit button', () => { - expect(findSubmitButton().props('disabled')).toBe(true); - }); - - it('sets submit button as loading', () => { - expect(findSubmitButton().props('loading')).toBe(true); - }); - - it('displays Authenticating label on submit button', () => { - expect(findSubmitButton().text()).toBe('Authenticating'); - }); - }); - - describe('when role can’t be created', () => { - beforeEach(() => { - state.createRoleError = 'Invalid credentials'; - }); - - it('displays invalid role warning banner', () => { - expect(findInvalidCredentials().exists()).toBe(true); - }); - - it('displays invalid role error message', () => { - expect(findInvalidCredentials().text()).toContain(state.createRoleError); - }); - }); -}); 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 deleted file mode 100644 index 7b93b6d0a09..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/services/aws_services_facade_spec.js +++ /dev/null @@ -1,178 +0,0 @@ -import EC2 from 'aws-sdk/clients/ec2'; -import AWS from 'aws-sdk/global'; -import { - setAWSConfig, - fetchRoles, - fetchKeyPairs, - fetchVpcs, - fetchSubnets, - fetchSecurityGroups, -} from '~/create_cluster/eks_cluster/services/aws_services_facade'; - -const mockListRolesPromise = jest.fn(); -const mockDescribeRegionsPromise = jest.fn(); -const mockDescribeKeyPairsPromise = jest.fn(); -const mockDescribeVpcsPromise = jest.fn(); -const mockDescribeSubnetsPromise = jest.fn(); -const mockDescribeSecurityGroupsPromise = jest.fn(); - -jest.mock('aws-sdk/clients/iam', () => - jest.fn().mockImplementation(() => ({ - listRoles: jest.fn().mockReturnValue({ promise: mockListRolesPromise }), - })), -); - -jest.mock('aws-sdk/clients/ec2', () => - jest.fn().mockImplementation(() => ({ - describeRegions: jest.fn().mockReturnValue({ promise: mockDescribeRegionsPromise }), - describeKeyPairs: jest.fn().mockReturnValue({ promise: mockDescribeKeyPairsPromise }), - describeVpcs: jest.fn().mockReturnValue({ promise: mockDescribeVpcsPromise }), - describeSubnets: jest.fn().mockReturnValue({ promise: mockDescribeSubnetsPromise }), - describeSecurityGroups: jest - .fn() - .mockReturnValue({ promise: mockDescribeSecurityGroupsPromise }), - })), -); - -describe('awsServicesFacade', () => { - let region; - let vpc; - - beforeEach(() => { - region = 'west-1'; - vpc = 'vpc-2'; - }); - - it('setAWSConfig configures AWS SDK with provided credentials', () => { - const awsCredentials = { - accessKeyId: 'access-key', - secretAccessKey: 'secret-key', - sessionToken: 'session-token', - region, - }; - - setAWSConfig({ awsCredentials }); - - expect(AWS.config).toEqual(awsCredentials); - }); - - describe('when fetchRoles succeeds', () => { - let roles; - let rolesOutput; - - beforeEach(() => { - roles = [ - { RoleName: 'admin', Arn: 'aws::admin' }, - { RoleName: 'read-only', Arn: 'aws::read-only' }, - ]; - rolesOutput = roles.map(({ RoleName: name, Arn: value }) => ({ name, value })); - - mockListRolesPromise.mockResolvedValueOnce({ Roles: roles }); - }); - - it('return list of regions where each item has a name and value', () => { - return expect(fetchRoles()).resolves.toEqual(rolesOutput); - }); - }); - - describe('when fetchKeyPairs succeeds', () => { - let keyPairs; - let keyPairsOutput; - - beforeEach(() => { - keyPairs = [{ KeyName: 'key-pair' }, { KeyName: 'key-pair-2' }]; - keyPairsOutput = keyPairs.map(({ KeyName: name }) => ({ name, value: name })); - - mockDescribeKeyPairsPromise.mockResolvedValueOnce({ KeyPairs: keyPairs }); - }); - - it('instantatiates ec2 service with provided region', () => { - fetchKeyPairs({ region }); - expect(EC2).toHaveBeenCalledWith({ region }); - }); - - it('return list of key pairs where each item has a name and value', () => { - return expect(fetchKeyPairs({ region })).resolves.toEqual(keyPairsOutput); - }); - }); - - describe('when fetchVpcs succeeds', () => { - let vpcs; - let vpcsOutput; - - beforeEach(() => { - vpcs = [ - { VpcId: 'vpc-1', Tags: [] }, - { VpcId: 'vpc-2', Tags: [] }, - ]; - vpcsOutput = vpcs.map(({ VpcId: vpcId }) => ({ name: vpcId, value: vpcId })); - - mockDescribeVpcsPromise.mockResolvedValueOnce({ Vpcs: vpcs }); - }); - - it('instantatiates ec2 service with provided region', () => { - fetchVpcs({ region }); - expect(EC2).toHaveBeenCalledWith({ region }); - }); - - it('return list of vpcs where each item has a name and value', () => { - return expect(fetchVpcs({ region })).resolves.toEqual(vpcsOutput); - }); - }); - - describe('when vpcs has a Name tag', () => { - const vpcName = 'vpc name'; - const vpcId = 'vpc id'; - let vpcs; - let vpcsOutput; - - beforeEach(() => { - vpcs = [{ VpcId: vpcId, Tags: [{ Key: 'Name', Value: vpcName }] }]; - vpcsOutput = [{ name: vpcName, value: vpcId }]; - - mockDescribeVpcsPromise.mockResolvedValueOnce({ Vpcs: vpcs }); - }); - - it('uses name tag value as the vpc name', () => { - return expect(fetchVpcs({ region })).resolves.toEqual(vpcsOutput); - }); - }); - - describe('when fetchSubnets succeeds', () => { - let subnets; - let subnetsOutput; - - beforeEach(() => { - subnets = [{ SubnetId: 'subnet-1' }, { SubnetId: 'subnet-2' }]; - subnetsOutput = subnets.map(({ SubnetId }) => ({ name: SubnetId, value: SubnetId })); - - mockDescribeSubnetsPromise.mockResolvedValueOnce({ Subnets: subnets }); - }); - - it('return list of subnets where each item has a name and value', () => { - return expect(fetchSubnets({ region, vpc })).resolves.toEqual(subnetsOutput); - }); - }); - - describe('when fetchSecurityGroups succeeds', () => { - let securityGroups; - let securityGroupsOutput; - - beforeEach(() => { - securityGroups = [ - { GroupName: 'admin group', GroupId: 'group-1' }, - { GroupName: 'basic group', GroupId: 'group-2' }, - ]; - securityGroupsOutput = securityGroups.map(({ GroupId: value, GroupName: name }) => ({ - name, - value, - })); - - mockDescribeSecurityGroupsPromise.mockResolvedValueOnce({ SecurityGroups: securityGroups }); - }); - - it('return list of security groups where each item has a name and value', () => { - return expect(fetchSecurityGroups({ region, vpc })).resolves.toEqual(securityGroupsOutput); - }); - }); -}); diff --git a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js b/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js deleted file mode 100644 index 8d7b22fe4ff..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/store/actions_spec.js +++ /dev/null @@ -1,366 +0,0 @@ -import MockAdapter from 'axios-mock-adapter'; -import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; -import testAction from 'helpers/vuex_action_helper'; -import { DEFAULT_REGION } from '~/create_cluster/eks_cluster/constants'; -import * as actions from '~/create_cluster/eks_cluster/store/actions'; -import { - SET_CLUSTER_NAME, - SET_ENVIRONMENT_SCOPE, - SET_KUBERNETES_VERSION, - SET_REGION, - SET_VPC, - SET_KEY_PAIR, - SET_SUBNET, - SET_ROLE, - SET_SECURITY_GROUP, - SET_GITLAB_MANAGED_CLUSTER, - SET_NAMESPACE_PER_ENVIRONMENT, - SET_INSTANCE_TYPE, - SET_NODE_COUNT, - REQUEST_CREATE_ROLE, - CREATE_ROLE_SUCCESS, - CREATE_ROLE_ERROR, - REQUEST_CREATE_CLUSTER, - CREATE_CLUSTER_ERROR, -} from '~/create_cluster/eks_cluster/store/mutation_types'; -import createState from '~/create_cluster/eks_cluster/store/state'; -import createFlash from '~/flash'; -import axios from '~/lib/utils/axios_utils'; - -jest.mock('~/flash'); - -describe('EKS Cluster Store Actions', () => { - let clusterName; - let environmentScope; - let kubernetesVersion; - let region; - let vpc; - let subnet; - let role; - let keyPair; - let securityGroup; - let instanceType; - let nodeCount; - let gitlabManagedCluster; - let namespacePerEnvironment; - let mock; - let state; - let newClusterUrl; - - beforeEach(() => { - clusterName = 'my cluster'; - environmentScope = 'production'; - kubernetesVersion = '1.16'; - 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; - namespacePerEnvironment = true; - - newClusterUrl = '/clusters/1'; - - state = { - ...createState(), - createRolePath: '/clusters/roles/', - createClusterPath: '/clusters/', - }; - }); - - beforeEach(() => { - mock = new MockAdapter(axios); - }); - - afterEach(() => { - mock.restore(); - }); - - it.each` - action | mutation | payload | payloadDescription - ${'setClusterName'} | ${SET_CLUSTER_NAME} | ${{ clusterName }} | ${'cluster name'} - ${'setEnvironmentScope'} | ${SET_ENVIRONMENT_SCOPE} | ${{ environmentScope }} | ${'environment scope'} - ${'setKubernetesVersion'} | ${SET_KUBERNETES_VERSION} | ${{ kubernetesVersion }} | ${'kubernetes version'} - ${'setRole'} | ${SET_ROLE} | ${{ role }} | ${'role'} - ${'setRegion'} | ${SET_REGION} | ${{ region }} | ${'region'} - ${'setKeyPair'} | ${SET_KEY_PAIR} | ${{ keyPair }} | ${'key pair'} - ${'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'} - ${'setNamespacePerEnvironment'} | ${SET_NAMESPACE_PER_ENVIRONMENT} | ${namespacePerEnvironment} | ${'namespace per environment'} - `(`$action commits $mutation with $payloadDescription payload`, (data) => { - const { action, mutation, payload } = data; - - testAction(actions[action], payload, state, [{ type: mutation, payload }]); - }); - - describe('createRole', () => { - const payload = { - roleArn: 'role_arn', - externalId: 'externalId', - }; - const response = { - accessKeyId: 'access-key-id', - secretAccessKey: 'secret-key-id', - }; - - describe('when request succeeds with default region', () => { - beforeEach(() => { - mock - .onPost(state.createRolePath, { - role_arn: payload.roleArn, - role_external_id: payload.externalId, - region: DEFAULT_REGION, - }) - .reply(201, response); - }); - - it('dispatches createRoleSuccess action', () => - testAction( - actions.createRole, - payload, - state, - [], - [ - { type: 'requestCreateRole' }, - { - type: 'createRoleSuccess', - payload: { - region: DEFAULT_REGION, - ...response, - }, - }, - ], - )); - }); - - describe('when request succeeds with custom region', () => { - const customRegion = 'custom-region'; - - beforeEach(() => { - mock - .onPost(state.createRolePath, { - role_arn: payload.roleArn, - role_external_id: payload.externalId, - region: customRegion, - }) - .reply(201, response); - }); - - it('dispatches createRoleSuccess action', () => - testAction( - actions.createRole, - { - selectedRegion: customRegion, - ...payload, - }, - state, - [], - [ - { type: 'requestCreateRole' }, - { - type: 'createRoleSuccess', - payload: { - region: customRegion, - ...response, - }, - }, - ], - )); - }); - - describe('when request fails', () => { - let error; - - beforeEach(() => { - error = new Error('Request failed with status code 400'); - mock - .onPost(state.createRolePath, { - role_arn: payload.roleArn, - role_external_id: payload.externalId, - region: DEFAULT_REGION, - }) - .reply(400, null); - }); - - it('dispatches createRoleError action', () => - testAction( - actions.createRole, - payload, - state, - [], - [{ type: 'requestCreateRole' }, { type: 'createRoleError', payload: { error } }], - )); - }); - - describe('when request fails with a message', () => { - beforeEach(() => { - const errResp = { message: 'Something failed' }; - - mock - .onPost(state.createRolePath, { - role_arn: payload.roleArn, - role_external_id: payload.externalId, - region: DEFAULT_REGION, - }) - .reply(4, errResp); - }); - - it('dispatches createRoleError action', () => - testAction( - actions.createRole, - payload, - state, - [], - [ - { type: 'requestCreateRole' }, - { type: 'createRoleError', payload: { error: 'Something failed' } }, - ], - )); - }); - }); - - describe('requestCreateRole', () => { - it('commits requestCreaterole mutation', () => { - testAction(actions.requestCreateRole, null, state, [{ type: REQUEST_CREATE_ROLE }]); - }); - }); - - describe('createRoleSuccess', () => { - it('sets region and commits createRoleSuccess mutation', () => { - testAction( - actions.createRoleSuccess, - { region }, - state, - [{ type: CREATE_ROLE_SUCCESS }], - [{ type: 'setRegion', payload: { region } }], - ); - }); - }); - - describe('createRoleError', () => { - it('commits createRoleError mutation', () => { - const payload = { - error: new Error(), - }; - - testAction(actions.createRoleError, payload, state, [{ type: CREATE_ROLE_ERROR, payload }]); - }); - }); - - describe('createCluster', () => { - let requestPayload; - - beforeEach(() => { - requestPayload = { - name: clusterName, - environment_scope: environmentScope, - managed: gitlabManagedCluster, - namespace_per_environment: namespacePerEnvironment, - provider_aws_attributes: { - kubernetes_version: kubernetesVersion, - 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, - namespacePerEnvironment, - }); - }); - - 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', () => { - useMockLocationHelper(); - - 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 and displays flash message', () => - testAction(actions.createClusterError, payload, state, [ - { type: CREATE_CLUSTER_ERROR, payload }, - ]).then(() => { - expect(createFlash).toHaveBeenCalledWith({ - message: payload.name[0], - }); - })); - }); -}); diff --git a/spec/frontend/create_cluster/eks_cluster/store/getters_spec.js b/spec/frontend/create_cluster/eks_cluster/store/getters_spec.js deleted file mode 100644 index 46c37961dd3..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/store/getters_spec.js +++ /dev/null @@ -1,13 +0,0 @@ -import { subnetValid } from '~/create_cluster/eks_cluster/store/getters'; - -describe('EKS Cluster Store Getters', () => { - describe('subnetValid', () => { - it('returns true if there are 2 or more selected subnets', () => { - expect(subnetValid({ selectedSubnet: [1, 2] })).toBe(true); - }); - - it.each([[[], [1]]])('returns false if there are 1 or less selected subnets', (subnets) => { - expect(subnetValid({ selectedSubnet: subnets })).toBe(false); - }); - }); -}); diff --git a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js b/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js deleted file mode 100644 index 54d66e79be7..00000000000 --- a/spec/frontend/create_cluster/eks_cluster/store/mutations_spec.js +++ /dev/null @@ -1,161 +0,0 @@ -import { - SET_CLUSTER_NAME, - SET_ENVIRONMENT_SCOPE, - SET_KUBERNETES_VERSION, - SET_REGION, - SET_VPC, - SET_KEY_PAIR, - 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, -} from '~/create_cluster/eks_cluster/store/mutation_types'; -import mutations from '~/create_cluster/eks_cluster/store/mutations'; -import createState from '~/create_cluster/eks_cluster/store/state'; - -describe('Create EKS cluster store mutations', () => { - let clusterName; - let environmentScope; - let kubernetesVersion; - let state; - let region; - let vpc; - let subnet; - let role; - let keyPair; - let securityGroup; - let instanceType; - let nodeCount; - let gitlabManagedCluster; - - 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' }; - securityGroup = { name: 'default group' }; - instanceType = 'small-1'; - nodeCount = '5'; - gitlabManagedCluster = false; - - state = createState(); - }); - - it.each` - mutation | mutatedProperty | payload | expectedValue | expectedValueDescription - ${SET_CLUSTER_NAME} | ${'clusterName'} | ${{ clusterName }} | ${clusterName} | ${'cluster name'} - ${SET_ENVIRONMENT_SCOPE} | ${'environmentScope'} | ${{ environmentScope }} | ${environmentScope} | ${'environment scope'} - ${SET_KUBERNETES_VERSION} | ${'kubernetesVersion'} | ${{ kubernetesVersion }} | ${kubernetesVersion} | ${'kubernetes version'} - ${SET_ROLE} | ${'selectedRole'} | ${{ role }} | ${role} | ${'selected role payload'} - ${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 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; - - mutations[mutation](state, payload); - expect(state[mutatedProperty]).toBe(expectedValue); - }); - - describe(`mutation ${REQUEST_CREATE_ROLE}`, () => { - beforeEach(() => { - mutations[REQUEST_CREATE_ROLE](state); - }); - - it('sets isCreatingRole to true', () => { - expect(state.isCreatingRole).toBe(true); - }); - - it('sets createRoleError to null', () => { - expect(state.createRoleError).toBe(null); - }); - - it('sets hasCredentials to false', () => { - expect(state.hasCredentials).toBe(false); - }); - }); - - describe(`mutation ${CREATE_ROLE_SUCCESS}`, () => { - beforeEach(() => { - mutations[CREATE_ROLE_SUCCESS](state); - }); - - it('sets isCreatingRole to false', () => { - expect(state.isCreatingRole).toBe(false); - }); - - it('sets createRoleError to null', () => { - expect(state.createRoleError).toBe(null); - }); - - it('sets hasCredentials to false', () => { - expect(state.hasCredentials).toBe(true); - }); - }); - - describe(`mutation ${CREATE_ROLE_ERROR}`, () => { - const error = new Error(); - - beforeEach(() => { - mutations[CREATE_ROLE_ERROR](state, { error }); - }); - - it('sets isCreatingRole to false', () => { - expect(state.isCreatingRole).toBe(false); - }); - - it('sets createRoleError to the error object', () => { - expect(state.createRoleError).toBe(error); - }); - - it('sets hasCredentials to false', () => { - 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); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js deleted file mode 100644 index f46b84da939..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_machine_type_dropdown_spec.js +++ /dev/null @@ -1,129 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; -import Vuex from 'vuex'; -import GkeMachineTypeDropdown from '~/create_cluster/gke_cluster/components/gke_machine_type_dropdown.vue'; -import createState from '~/create_cluster/gke_cluster/store/state'; -import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; -import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; -import { selectedMachineTypeMock, gapiMachineTypesResponseMock } from '../mock_data'; - -const componentConfig = { - fieldId: 'cluster_provider_gcp_attributes_gcp_machine_type', - fieldName: 'cluster[provider_gcp_attributes][gcp_machine_type]', -}; -const setMachineType = jest.fn(); - -const LABELS = { - LOADING: 'Fetching machine types', - DISABLED_NO_PROJECT: 'Select project and zone to choose machine type', - DISABLED_NO_ZONE: 'Select zone to choose machine type', - DEFAULT: 'Select machine type', -}; - -Vue.use(Vuex); - -const createComponent = (store, propsData = componentConfig) => - shallowMount(GkeMachineTypeDropdown, { - propsData, - store, - }); - -const createStore = (initialState = {}, getters = {}) => - new Vuex.Store({ - state: { - ...createState(), - ...initialState, - }, - getters: { - hasZone: () => false, - ...getters, - }, - actions: { - setMachineType, - }, - }); - -describe('GkeMachineTypeDropdown', () => { - let wrapper; - let store; - - afterEach(() => { - wrapper.destroy(); - }); - - const dropdownButtonLabel = () => wrapper.find(DropdownButton).props('toggleText'); - const dropdownHiddenInputValue = () => wrapper.find(DropdownHiddenInput).props('value'); - - describe('shows various toggle text depending on state', () => { - it('returns disabled state toggle text when no project and zone are selected', () => { - store = createStore({ - projectHasBillingEnabled: false, - }); - wrapper = createComponent(store); - - expect(dropdownButtonLabel()).toBe(LABELS.DISABLED_NO_PROJECT); - }); - - it('returns disabled state toggle text when no zone is selected', () => { - store = createStore({ - projectHasBillingEnabled: true, - }); - wrapper = createComponent(store); - - expect(dropdownButtonLabel()).toBe(LABELS.DISABLED_NO_ZONE); - }); - - it('returns loading toggle text', async () => { - store = createStore(); - wrapper = createComponent(store); - - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ isLoading: true }); - - await nextTick(); - expect(dropdownButtonLabel()).toBe(LABELS.LOADING); - }); - - it('returns default toggle text', () => { - store = createStore( - { - projectHasBillingEnabled: true, - }, - { hasZone: () => true }, - ); - wrapper = createComponent(store); - - expect(dropdownButtonLabel()).toBe(LABELS.DEFAULT); - }); - - it('returns machine type name if machine type selected', () => { - store = createStore( - { - projectHasBillingEnabled: true, - selectedMachineType: selectedMachineTypeMock, - }, - { hasZone: () => true }, - ); - wrapper = createComponent(store); - - expect(dropdownButtonLabel()).toBe(selectedMachineTypeMock); - }); - }); - - describe('form input', () => { - it('reflects new value when dropdown item is clicked', async () => { - store = createStore({ - machineTypes: gapiMachineTypesResponseMock.items, - }); - wrapper = createComponent(store); - - expect(dropdownHiddenInputValue()).toBe(''); - - wrapper.find('.dropdown-content button').trigger('click'); - - await nextTick(); - expect(setMachineType).toHaveBeenCalledWith(expect.anything(), selectedMachineTypeMock); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_network_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_network_dropdown_spec.js deleted file mode 100644 index addb0ef72a0..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_network_dropdown_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import ClusterFormDropdown from '~/create_cluster/components/cluster_form_dropdown.vue'; -import GkeNetworkDropdown from '~/create_cluster/gke_cluster/components/gke_network_dropdown.vue'; -import createClusterDropdownState from '~/create_cluster/store/cluster_dropdown/state'; - -Vue.use(Vuex); - -describe('GkeNetworkDropdown', () => { - let wrapper; - let store; - const defaultProps = { fieldName: 'field-name' }; - const selectedNetwork = { selfLink: '123456' }; - const projectId = '6789'; - const region = 'east-1'; - const setNetwork = jest.fn(); - const setSubnetwork = jest.fn(); - const fetchSubnetworks = jest.fn(); - - const buildStore = ({ clusterDropdownState } = {}) => - new Vuex.Store({ - state: { - selectedNetwork, - }, - actions: { - setNetwork, - setSubnetwork, - }, - getters: { - hasZone: () => false, - region: () => region, - projectId: () => projectId, - }, - modules: { - networks: { - namespaced: true, - state: { - ...createClusterDropdownState(), - ...(clusterDropdownState || {}), - }, - }, - subnetworks: { - namespaced: true, - actions: { - fetchItems: fetchSubnetworks, - }, - }, - }, - }); - - const buildWrapper = (propsData = defaultProps) => - shallowMount(GkeNetworkDropdown, { - propsData, - store, - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('sets correct field-name', () => { - const fieldName = 'field-name'; - - store = buildStore(); - wrapper = buildWrapper({ fieldName }); - - expect(wrapper.find(ClusterFormDropdown).props('fieldName')).toBe(fieldName); - }); - - it('sets selected network as the dropdown value', () => { - store = buildStore(); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('value')).toBe(selectedNetwork); - }); - - it('maps networks store items to the dropdown items property', () => { - const items = [{ name: 'network' }]; - - store = buildStore({ clusterDropdownState: { items } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('items')).toBe(items); - }); - - describe('when network dropdown store is loading items', () => { - it('sets network dropdown as loading', () => { - store = buildStore({ clusterDropdownState: { isLoadingItems: true } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('loading')).toBe(true); - }); - }); - - describe('when there is no selected zone', () => { - it('disables the network dropdown', () => { - store = buildStore(); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('disabled')).toBe(true); - }); - }); - - describe('when an error occurs while loading networks', () => { - it('sets the network dropdown as having errors', () => { - store = buildStore({ clusterDropdownState: { loadingItemsError: new Error() } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('hasErrors')).toBe(true); - }); - }); - - describe('when dropdown emits input event', () => { - beforeEach(() => { - store = buildStore(); - wrapper = buildWrapper(); - wrapper.find(ClusterFormDropdown).vm.$emit('input', selectedNetwork); - }); - - it('cleans selected subnetwork', () => { - expect(setSubnetwork).toHaveBeenCalledWith(expect.anything(), ''); - }); - - it('dispatches the setNetwork action', () => { - expect(setNetwork).toHaveBeenCalledWith(expect.anything(), selectedNetwork); - }); - - it('fetches subnetworks for the selected project, region, and network', () => { - expect(fetchSubnetworks).toHaveBeenCalledWith(expect.anything(), { - project: projectId, - region, - network: selectedNetwork.selfLink, - }); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js deleted file mode 100644 index 36f8d4bd1e8..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_project_id_dropdown_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; -import Vuex from 'vuex'; -import GkeProjectIdDropdown from '~/create_cluster/gke_cluster/components/gke_project_id_dropdown.vue'; -import createState from '~/create_cluster/gke_cluster/store/state'; -import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; -import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; -import { selectedProjectMock, gapiProjectsResponseMock } from '../mock_data'; - -const componentConfig = { - docsUrl: 'https://console.cloud.google.com/home/dashboard', - fieldId: 'cluster_provider_gcp_attributes_gcp_project_id', - fieldName: 'cluster[provider_gcp_attributes][gcp_project_id]', -}; - -const LABELS = { - LOADING: 'Fetching projects', - VALIDATING_PROJECT_BILLING: 'Validating project billing status', - DEFAULT: 'Select project', - EMPTY: 'No projects found', -}; - -Vue.use(Vuex); - -describe('GkeProjectIdDropdown', () => { - let wrapper; - let vuexStore; - let setProject; - - beforeEach(() => { - setProject = jest.fn(); - }); - - const createStore = (initialState = {}, getters = {}) => - new Vuex.Store({ - state: { - ...createState(), - ...initialState, - }, - actions: { - fetchProjects: jest.fn().mockResolvedValueOnce([]), - setProject, - }, - getters: { - hasProject: () => false, - ...getters, - }, - }); - - const createComponent = (store, propsData = componentConfig) => - shallowMount(GkeProjectIdDropdown, { - propsData, - store, - }); - - const bootstrap = (initialState, getters) => { - vuexStore = createStore(initialState, getters); - wrapper = createComponent(vuexStore); - }; - - const dropdownButtonLabel = () => wrapper.find(DropdownButton).props('toggleText'); - const dropdownHiddenInputValue = () => wrapper.find(DropdownHiddenInput).props('value'); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('toggleText', () => { - it('returns loading toggle text', () => { - bootstrap(); - - expect(dropdownButtonLabel()).toBe(LABELS.LOADING); - }); - - it('returns project billing validation text', () => { - bootstrap({ isValidatingProjectBilling: true }); - - expect(dropdownButtonLabel()).toBe(LABELS.VALIDATING_PROJECT_BILLING); - }); - - it('returns default toggle text', async () => { - bootstrap(); - - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ isLoading: false }); - - await nextTick(); - expect(dropdownButtonLabel()).toBe(LABELS.DEFAULT); - }); - - it('returns project name if project selected', async () => { - bootstrap( - { - selectedProject: selectedProjectMock, - }, - { - hasProject: () => true, - }, - ); - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ isLoading: false }); - - await nextTick(); - expect(dropdownButtonLabel()).toBe(selectedProjectMock.name); - }); - - it('returns empty toggle text', async () => { - bootstrap({ - projects: null, - }); - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ isLoading: false }); - - await nextTick(); - expect(dropdownButtonLabel()).toBe(LABELS.EMPTY); - }); - }); - - describe('selectItem', () => { - it('reflects new value when dropdown item is clicked', async () => { - bootstrap({ projects: gapiProjectsResponseMock.projects }); - - expect(dropdownHiddenInputValue()).toBe(''); - - wrapper.find('.dropdown-content button').trigger('click'); - - await nextTick(); - expect(setProject).toHaveBeenCalledWith( - expect.anything(), - gapiProjectsResponseMock.projects[0], - ); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_submit_button_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_submit_button_spec.js deleted file mode 100644 index 2bf9158628c..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_submit_button_spec.js +++ /dev/null @@ -1,51 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import GkeSubmitButton from '~/create_cluster/gke_cluster/components/gke_submit_button.vue'; - -Vue.use(Vuex); - -describe('GkeSubmitButton', () => { - let wrapper; - let store; - let hasValidData; - - const buildStore = () => - new Vuex.Store({ - getters: { - hasValidData, - }, - }); - - const buildWrapper = () => - shallowMount(GkeSubmitButton, { - store, - }); - - const bootstrap = () => { - store = buildStore(); - wrapper = buildWrapper(); - }; - - beforeEach(() => { - hasValidData = jest.fn(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('is disabled when hasValidData is false', () => { - hasValidData.mockReturnValueOnce(false); - bootstrap(); - - expect(wrapper.attributes('disabled')).toBe('disabled'); - }); - - it('is not disabled when hasValidData is true', () => { - hasValidData.mockReturnValueOnce(true); - bootstrap(); - - expect(wrapper.attributes('disabled')).toBeFalsy(); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_subnetwork_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_subnetwork_dropdown_spec.js deleted file mode 100644 index 9df680d94b5..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_subnetwork_dropdown_spec.js +++ /dev/null @@ -1,111 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; -import ClusterFormDropdown from '~/create_cluster/components/cluster_form_dropdown.vue'; -import GkeSubnetworkDropdown from '~/create_cluster/gke_cluster/components/gke_subnetwork_dropdown.vue'; -import createClusterDropdownState from '~/create_cluster/store/cluster_dropdown/state'; - -Vue.use(Vuex); - -describe('GkeSubnetworkDropdown', () => { - let wrapper; - let store; - const defaultProps = { fieldName: 'field-name' }; - const selectedSubnetwork = '123456'; - const setSubnetwork = jest.fn(); - - const buildStore = ({ clusterDropdownState } = {}) => - new Vuex.Store({ - state: { - selectedSubnetwork, - }, - actions: { - setSubnetwork, - }, - getters: { - hasNetwork: () => false, - }, - modules: { - subnetworks: { - namespaced: true, - state: { - ...createClusterDropdownState(), - ...(clusterDropdownState || {}), - }, - }, - }, - }); - - const buildWrapper = (propsData = defaultProps) => - shallowMount(GkeSubnetworkDropdown, { - propsData, - store, - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('sets correct field-name', () => { - const fieldName = 'field-name'; - - store = buildStore(); - wrapper = buildWrapper({ fieldName }); - - expect(wrapper.find(ClusterFormDropdown).props('fieldName')).toBe(fieldName); - }); - - it('sets selected subnetwork as the dropdown value', () => { - store = buildStore(); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('value')).toBe(selectedSubnetwork); - }); - - it('maps subnetworks store items to the dropdown items property', () => { - const items = [{ name: 'subnetwork' }]; - - store = buildStore({ clusterDropdownState: { items } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('items')).toBe(items); - }); - - describe('when subnetwork dropdown store is loading items', () => { - it('sets subnetwork dropdown as loading', () => { - store = buildStore({ clusterDropdownState: { isLoadingItems: true } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('loading')).toBe(true); - }); - }); - - describe('when there is no selected network', () => { - it('disables the subnetwork dropdown', () => { - store = buildStore(); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('disabled')).toBe(true); - }); - }); - - describe('when an error occurs while loading subnetworks', () => { - it('sets the subnetwork dropdown as having errors', () => { - store = buildStore({ clusterDropdownState: { loadingItemsError: new Error() } }); - wrapper = buildWrapper(); - - expect(wrapper.find(ClusterFormDropdown).props('hasErrors')).toBe(true); - }); - }); - - describe('when dropdown emits input event', () => { - it('dispatches the setSubnetwork action', () => { - store = buildStore(); - wrapper = buildWrapper(); - - wrapper.find(ClusterFormDropdown).vm.$emit('input', selectedSubnetwork); - - expect(setSubnetwork).toHaveBeenCalledWith(expect.anything(), selectedSubnetwork); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js b/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js deleted file mode 100644 index 7b4c228b879..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/components/gke_zone_dropdown_spec.js +++ /dev/null @@ -1,103 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import { nextTick } from 'vue'; -import GkeZoneDropdown from '~/create_cluster/gke_cluster/components/gke_zone_dropdown.vue'; -import { createStore } from '~/create_cluster/gke_cluster/store'; -import { - SET_PROJECT, - SET_ZONES, - SET_PROJECT_BILLING_STATUS, -} from '~/create_cluster/gke_cluster/store/mutation_types'; -import DropdownButton from '~/vue_shared/components/dropdown/dropdown_button.vue'; -import DropdownHiddenInput from '~/vue_shared/components/dropdown/dropdown_hidden_input.vue'; -import { selectedZoneMock, selectedProjectMock, gapiZonesResponseMock } from '../mock_data'; - -const propsData = { - fieldId: 'cluster_provider_gcp_attributes_gcp_zone', - fieldName: 'cluster[provider_gcp_attributes][gcp_zone]', -}; - -const LABELS = { - LOADING: 'Fetching zones', - DISABLED: 'Select project to choose zone', - DEFAULT: 'Select zone', -}; - -describe('GkeZoneDropdown', () => { - let store; - let wrapper; - - beforeEach(() => { - store = createStore(); - wrapper = shallowMount(GkeZoneDropdown, { propsData, store }); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('toggleText', () => { - let dropdownButton; - - beforeEach(() => { - dropdownButton = wrapper.find(DropdownButton); - }); - - it('returns disabled state toggle text', () => { - expect(dropdownButton.props('toggleText')).toBe(LABELS.DISABLED); - }); - - describe('isLoading', () => { - beforeEach(async () => { - // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details - // eslint-disable-next-line no-restricted-syntax - wrapper.setData({ isLoading: true }); - await nextTick(); - }); - - it('returns loading toggle text', () => { - expect(dropdownButton.props('toggleText')).toBe(LABELS.LOADING); - }); - }); - - describe('project is set', () => { - beforeEach(async () => { - wrapper.vm.$store.commit(SET_PROJECT, selectedProjectMock); - wrapper.vm.$store.commit(SET_PROJECT_BILLING_STATUS, true); - await nextTick(); - }); - - it('returns default toggle text', () => { - expect(dropdownButton.props('toggleText')).toBe(LABELS.DEFAULT); - }); - }); - - describe('project is selected', () => { - beforeEach(async () => { - wrapper.vm.setItem(selectedZoneMock); - await nextTick(); - }); - - it('returns project name if project selected', () => { - expect(dropdownButton.props('toggleText')).toBe(selectedZoneMock); - }); - }); - }); - - describe('selectItem', () => { - beforeEach(async () => { - wrapper.vm.$store.commit(SET_ZONES, gapiZonesResponseMock.items); - await nextTick(); - }); - - it('reflects new value when dropdown item is clicked', async () => { - const dropdown = wrapper.find(DropdownHiddenInput); - - expect(dropdown.attributes('value')).toBe(''); - - wrapper.find('.dropdown-content button').trigger('click'); - - await nextTick(); - expect(dropdown.attributes('value')).toBe(selectedZoneMock); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/gapi_loader_spec.js b/spec/frontend/create_cluster/gke_cluster/gapi_loader_spec.js deleted file mode 100644 index 9e4d6996340..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/gapi_loader_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import gapiLoader from '~/create_cluster/gke_cluster/gapi_loader'; - -describe('gapiLoader', () => { - // A mock for document.head.appendChild to intercept the script tag injection. - let mockDOMHeadAppendChild; - - beforeEach(() => { - mockDOMHeadAppendChild = jest.spyOn(document.head, 'appendChild'); - }); - - afterEach(() => { - mockDOMHeadAppendChild.mockRestore(); - delete window.gapi; - delete window.gapiPromise; - delete window.onGapiLoad; - }); - - it('returns a promise', () => { - expect(gapiLoader()).toBeInstanceOf(Promise); - }); - - it('returns the same promise when already loading', () => { - const first = gapiLoader(); - const second = gapiLoader(); - expect(first).toBe(second); - }); - - it('resolves the promise when the script loads correctly', async () => { - mockDOMHeadAppendChild.mockImplementationOnce((script) => { - script.removeAttribute('src'); - script.appendChild( - document.createTextNode(`window.gapi = 'hello gapi'; window.onGapiLoad()`), - ); - document.head.appendChild(script); - }); - await expect(gapiLoader()).resolves.toBe('hello gapi'); - expect(mockDOMHeadAppendChild).toHaveBeenCalled(); - }); - - it('rejects the promise when the script fails loading', async () => { - mockDOMHeadAppendChild.mockImplementationOnce((script) => { - script.onerror(new Error('hello error')); - }); - await expect(gapiLoader()).rejects.toThrow('hello error'); - expect(mockDOMHeadAppendChild).toHaveBeenCalled(); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/helpers.js b/spec/frontend/create_cluster/gke_cluster/helpers.js deleted file mode 100644 index 026e99fa8f4..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/helpers.js +++ /dev/null @@ -1,64 +0,0 @@ -import { - gapiProjectsResponseMock, - gapiZonesResponseMock, - gapiMachineTypesResponseMock, -} from './mock_data'; - -const cloudbilling = { - projects: { - getBillingInfo: jest.fn( - () => - new Promise((resolve) => { - resolve({ - result: { billingEnabled: true }, - }); - }), - ), - }, -}; - -const cloudresourcemanager = { - projects: { - list: jest.fn( - () => - new Promise((resolve) => { - resolve({ - result: { ...gapiProjectsResponseMock }, - }); - }), - ), - }, -}; - -const compute = { - zones: { - list: jest.fn( - () => - new Promise((resolve) => { - resolve({ - result: { ...gapiZonesResponseMock }, - }); - }), - ), - }, - machineTypes: { - list: jest.fn( - () => - new Promise((resolve) => { - resolve({ - result: { ...gapiMachineTypesResponseMock }, - }); - }), - ), - }, -}; - -const gapi = { - client: { - cloudbilling, - cloudresourcemanager, - compute, - }, -}; - -export { gapi as default }; diff --git a/spec/frontend/create_cluster/gke_cluster/mock_data.js b/spec/frontend/create_cluster/gke_cluster/mock_data.js deleted file mode 100644 index d9f5dbc636f..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/mock_data.js +++ /dev/null @@ -1,75 +0,0 @@ -export const emptyProjectMock = { - projectId: '', - name: '', -}; - -export const selectedProjectMock = { - projectId: 'gcp-project-123', - name: 'gcp-project', -}; - -export const selectedZoneMock = 'us-central1-a'; - -export const selectedMachineTypeMock = 'n1-standard-2'; - -export const gapiProjectsResponseMock = { - projects: [ - { - projectNumber: '1234', - projectId: 'gcp-project-123', - lifecycleState: 'ACTIVE', - name: 'gcp-project', - createTime: '2017-12-16T01:48:29.129Z', - parent: { - type: 'organization', - id: '12345', - }, - }, - ], -}; - -export const gapiZonesResponseMock = { - kind: 'compute#zoneList', - id: 'projects/gitlab-internal-153318/zones', - items: [ - { - kind: 'compute#zone', - id: '2000', - creationTimestamp: '1969-12-31T16:00:00.000-08:00', - name: 'us-central1-a', - description: 'us-central1-a', - status: 'UP', - region: - 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/regions/us-central1', - selfLink: - 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a', - availableCpuPlatforms: ['Intel Skylake', 'Intel Broadwell', 'Intel Sandy Bridge'], - }, - ], - selfLink: 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones', -}; - -export const gapiMachineTypesResponseMock = { - kind: 'compute#machineTypeList', - id: 'projects/gitlab-internal-153318/zones/us-central1-a/machineTypes', - items: [ - { - kind: 'compute#machineType', - id: '3002', - creationTimestamp: '1969-12-31T16:00:00.000-08:00', - name: 'n1-standard-2', - description: '2 vCPUs, 7.5 GB RAM', - guestCpus: 2, - memoryMb: 7680, - imageSpaceGb: 10, - maximumPersistentDisks: 64, - maximumPersistentDisksSizeGb: '65536', - zone: 'us-central1-a', - selfLink: - 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a/machineTypes/n1-standard-2', - isSharedCpu: false, - }, - ], - selfLink: - 'https://www.googleapis.com/compute/v1/projects/gitlab-internal-153318/zones/us-central1-a/machineTypes', -}; diff --git a/spec/frontend/create_cluster/gke_cluster/stores/actions_spec.js b/spec/frontend/create_cluster/gke_cluster/stores/actions_spec.js deleted file mode 100644 index c365cb6a9f4..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/stores/actions_spec.js +++ /dev/null @@ -1,141 +0,0 @@ -import testAction from 'helpers/vuex_action_helper'; -import * as actions from '~/create_cluster/gke_cluster/store/actions'; -import * as types from '~/create_cluster/gke_cluster/store/mutation_types'; -import createState from '~/create_cluster/gke_cluster/store/state'; -import gapi from '../helpers'; -import { - selectedProjectMock, - selectedZoneMock, - selectedMachineTypeMock, - gapiProjectsResponseMock, - gapiZonesResponseMock, - gapiMachineTypesResponseMock, -} from '../mock_data'; - -describe('GCP Cluster Dropdown Store Actions', () => { - describe('setProject', () => { - it('should set project', () => { - return testAction( - actions.setProject, - selectedProjectMock, - { selectedProject: {} }, - [{ type: 'SET_PROJECT', payload: selectedProjectMock }], - [], - ); - }); - }); - - describe('setZone', () => { - it('should set zone', () => { - return testAction( - actions.setZone, - selectedZoneMock, - { selectedZone: '' }, - [{ type: 'SET_ZONE', payload: selectedZoneMock }], - [], - ); - }); - }); - - describe('setMachineType', () => { - it('should set machine type', () => { - return testAction( - actions.setMachineType, - selectedMachineTypeMock, - { selectedMachineType: '' }, - [{ type: 'SET_MACHINE_TYPE', payload: selectedMachineTypeMock }], - [], - ); - }); - }); - - describe('setIsValidatingProjectBilling', () => { - it('should set machine type', () => { - return testAction( - actions.setIsValidatingProjectBilling, - true, - { isValidatingProjectBilling: null }, - [{ type: 'SET_IS_VALIDATING_PROJECT_BILLING', payload: true }], - [], - ); - }); - }); - - describe('async fetch methods', () => { - let originalGapi; - - beforeAll(() => { - originalGapi = window.gapi; - window.gapi = gapi; - window.gapiPromise = Promise.resolve(gapi); - }); - - afterAll(() => { - window.gapi = originalGapi; - delete window.gapiPromise; - }); - - describe('fetchProjects', () => { - it('fetches projects from Google API', () => { - const state = createState(); - - return testAction( - actions.fetchProjects, - null, - state, - [{ type: types.SET_PROJECTS, payload: gapiProjectsResponseMock.projects }], - [], - ); - }); - }); - - describe('validateProjectBilling', () => { - it('checks project billing status from Google API', () => { - return testAction( - actions.validateProjectBilling, - true, - { - selectedProject: selectedProjectMock, - selectedZone: '', - selectedMachineType: '', - projectHasBillingEnabled: null, - }, - [ - { type: 'SET_ZONE', payload: '' }, - { type: 'SET_MACHINE_TYPE', payload: '' }, - { type: 'SET_PROJECT_BILLING_STATUS', payload: true }, - ], - [{ type: 'setIsValidatingProjectBilling', payload: false }], - ); - }); - }); - - describe('fetchZones', () => { - it('fetches zones from Google API', () => { - const state = createState(); - - return testAction( - actions.fetchZones, - null, - state, - [{ type: types.SET_ZONES, payload: gapiZonesResponseMock.items }], - [], - ); - }); - }); - - describe('fetchMachineTypes', () => { - it('fetches machine types from Google API', () => { - const state = createState(); - - return testAction( - actions.fetchMachineTypes, - null, - state, - [{ type: types.SET_MACHINE_TYPES, payload: gapiMachineTypesResponseMock.items }], - [], - ); - }); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/stores/getters_spec.js b/spec/frontend/create_cluster/gke_cluster/stores/getters_spec.js deleted file mode 100644 index 39106c3f6ca..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/stores/getters_spec.js +++ /dev/null @@ -1,103 +0,0 @@ -import { - hasProject, - hasZone, - hasMachineType, - hasValidData, -} from '~/create_cluster/gke_cluster/store/getters'; -import { selectedProjectMock, selectedZoneMock, selectedMachineTypeMock } from '../mock_data'; - -describe('GCP Cluster Dropdown Store Getters', () => { - let state; - - describe('valid states', () => { - beforeEach(() => { - state = { - projectHasBillingEnabled: true, - selectedProject: selectedProjectMock, - selectedZone: selectedZoneMock, - selectedMachineType: selectedMachineTypeMock, - }; - }); - - describe('hasProject', () => { - it('should return true when project is selected', () => { - expect(hasProject(state)).toEqual(true); - }); - }); - - describe('hasZone', () => { - it('should return true when zone is selected', () => { - expect(hasZone(state)).toEqual(true); - }); - }); - - describe('hasMachineType', () => { - it('should return true when machine type is selected', () => { - expect(hasMachineType(state)).toEqual(true); - }); - }); - - describe('hasValidData', () => { - it('should return true when a project, zone and machine type are selected', () => { - expect(hasValidData(state, { hasZone: true, hasMachineType: true })).toEqual(true); - }); - }); - }); - - describe('invalid states', () => { - beforeEach(() => { - state = { - selectedProject: { - projectId: '', - name: '', - }, - selectedZone: '', - selectedMachineType: '', - }; - }); - - describe('hasProject', () => { - it('should return false when project is not selected', () => { - expect(hasProject(state)).toEqual(false); - }); - }); - - describe('hasZone', () => { - it('should return false when zone is not selected', () => { - expect(hasZone(state)).toEqual(false); - }); - }); - - describe('hasMachineType', () => { - it('should return false when machine type is not selected', () => { - expect(hasMachineType(state)).toEqual(false); - }); - }); - - describe('hasValidData', () => { - let getters; - - beforeEach(() => { - getters = { hasZone: true, hasMachineType: true }; - }); - - it('should return false when project is not billable', () => { - state.projectHasBillingEnabled = false; - - expect(hasValidData(state, getters)).toEqual(false); - }); - - it('should return false when zone is not selected', () => { - getters.hasZone = false; - - expect(hasValidData(state, getters)).toEqual(false); - }); - - it('should return false when machine type is not selected', () => { - getters.hasMachineType = false; - - expect(hasValidData(state, getters)).toEqual(false); - }); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster/stores/mutations_spec.js b/spec/frontend/create_cluster/gke_cluster/stores/mutations_spec.js deleted file mode 100644 index 4493d49af43..00000000000 --- a/spec/frontend/create_cluster/gke_cluster/stores/mutations_spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import * as types from '~/create_cluster/gke_cluster/store/mutation_types'; -import mutations from '~/create_cluster/gke_cluster/store/mutations'; -import createState from '~/create_cluster/gke_cluster/store/state'; -import { - gapiProjectsResponseMock, - gapiZonesResponseMock, - gapiMachineTypesResponseMock, -} from '../mock_data'; - -describe('GCP Cluster Dropdown Store Mutations', () => { - describe.each` - mutation | stateProperty | mockData - ${types.SET_PROJECTS} | ${'projects'} | ${gapiProjectsResponseMock.projects} - ${types.SET_ZONES} | ${'zones'} | ${gapiZonesResponseMock.items} - ${types.SET_MACHINE_TYPES} | ${'machineTypes'} | ${gapiMachineTypesResponseMock.items} - ${types.SET_MACHINE_TYPE} | ${'selectedMachineType'} | ${gapiMachineTypesResponseMock.items[0].name} - ${types.SET_ZONE} | ${'selectedZone'} | ${gapiZonesResponseMock.items[0].name} - ${types.SET_PROJECT} | ${'selectedProject'} | ${gapiProjectsResponseMock.projects[0]} - ${types.SET_PROJECT_BILLING_STATUS} | ${'projectHasBillingEnabled'} | ${true} - ${types.SET_IS_VALIDATING_PROJECT_BILLING} | ${'isValidatingProjectBilling'} | ${true} - `('$mutation', ({ mutation, stateProperty, mockData }) => { - it(`should set the mutation payload to the ${stateProperty} state property`, () => { - const state = createState(); - - expect(state[stateProperty]).not.toBe(mockData); - - mutations[mutation](state, mockData); - - expect(state[stateProperty]).toBe(mockData); - }); - }); -}); diff --git a/spec/frontend/create_cluster/gke_cluster_namespace/gke_cluster_namespace_spec.js b/spec/frontend/create_cluster/gke_cluster_namespace/gke_cluster_namespace_spec.js deleted file mode 100644 index c22167a078c..00000000000 --- a/spec/frontend/create_cluster/gke_cluster_namespace/gke_cluster_namespace_spec.js +++ /dev/null @@ -1,61 +0,0 @@ -import initGkeNamespace from '~/create_cluster/gke_cluster_namespace'; - -describe('GKE cluster namespace', () => { - const changeEvent = new Event('change'); - const isHidden = (el) => el.classList.contains('hidden'); - const hasDisabledInput = (el) => el.querySelector('input').disabled; - - let glManagedCheckbox; - let selfManaged; - let glManaged; - - beforeEach(() => { - setFixtures(` - <input class="js-gl-managed" type="checkbox" value="1" checked /> - <div class="js-namespace"> - <input type="text" /> - </div> - <div class="js-namespace-prefixed"> - <input type="text" /> - </div> - `); - - glManagedCheckbox = document.querySelector('.js-gl-managed'); - selfManaged = document.querySelector('.js-namespace'); - glManaged = document.querySelector('.js-namespace-prefixed'); - - initGkeNamespace(); - }); - - describe('GKE cluster namespace toggles', () => { - it('initially displays the GitLab-managed label and input', () => { - expect(isHidden(glManaged)).toEqual(false); - expect(hasDisabledInput(glManaged)).toEqual(false); - - expect(isHidden(selfManaged)).toEqual(true); - expect(hasDisabledInput(selfManaged)).toEqual(true); - }); - - it('displays the self-managed label and input when the Gitlab-managed checkbox is unchecked', () => { - glManagedCheckbox.checked = false; - glManagedCheckbox.dispatchEvent(changeEvent); - - expect(isHidden(glManaged)).toEqual(true); - expect(hasDisabledInput(glManaged)).toEqual(true); - - expect(isHidden(selfManaged)).toEqual(false); - expect(hasDisabledInput(selfManaged)).toEqual(false); - }); - - it('displays the GitLab-managed label and input when the Gitlab-managed checkbox is checked', () => { - glManagedCheckbox.checked = true; - glManagedCheckbox.dispatchEvent(changeEvent); - - expect(isHidden(glManaged)).toEqual(false); - expect(hasDisabledInput(glManaged)).toEqual(false); - - expect(isHidden(selfManaged)).toEqual(true); - expect(hasDisabledInput(selfManaged)).toEqual(true); - }); - }); -}); diff --git a/spec/frontend/create_cluster/init_create_cluster_spec.js b/spec/frontend/create_cluster/init_create_cluster_spec.js deleted file mode 100644 index 42d1ceed864..00000000000 --- a/spec/frontend/create_cluster/init_create_cluster_spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import initGkeDropdowns from '~/create_cluster/gke_cluster'; -import initGkeNamespace from '~/create_cluster/gke_cluster_namespace'; -import initCreateCluster from '~/create_cluster/init_create_cluster'; -import PersistentUserCallout from '~/persistent_user_callout'; - -// This import is loaded dynamically in `init_create_cluster`. -// Let's eager import it here so that the first spec doesn't timeout. -// https://gitlab.com/gitlab-org/gitlab/issues/118499 -import '~/create_cluster/eks_cluster'; - -jest.mock('~/create_cluster/gke_cluster', () => jest.fn()); -jest.mock('~/create_cluster/gke_cluster_namespace', () => jest.fn()); -jest.mock('~/persistent_user_callout', () => ({ - factory: jest.fn(), -})); - -describe('initCreateCluster', () => { - let document; - let gon; - - beforeEach(() => { - document = { - body: { dataset: {} }, - querySelector: jest.fn(), - }; - gon = { features: {} }; - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - describe.each` - pageSuffix | page - ${':clusters:new'} | ${'project:clusters:new'} - ${':clusters:create_gcp'} | ${'groups:clusters:create_gcp'} - ${':clusters:create_user'} | ${'admin:clusters:create_user'} - `('when cluster page ends in $pageSuffix', ({ page }) => { - beforeEach(() => { - document.body.dataset = { page }; - - initCreateCluster(document, gon); - }); - - it('initializes create GKE cluster app', () => { - expect(initGkeDropdowns).toHaveBeenCalled(); - }); - - it('initializes gcp signup offer banner', () => { - expect(PersistentUserCallout.factory).toHaveBeenCalled(); - }); - }); - - describe('when creating a project level cluster', () => { - it('initializes gke namespace app', () => { - document.body.dataset.page = 'project:clusters:new'; - - initCreateCluster(document, gon); - - expect(initGkeNamespace).toHaveBeenCalled(); - }); - }); - - describe.each` - clusterLevel | page - ${'group level'} | ${'groups:clusters:new'} - ${'instance level'} | ${'admin:clusters:create_gcp'} - `('when creating a $clusterLevel cluster', ({ page }) => { - it('does not initialize gke namespace app', () => { - document.body.dataset = { page }; - - initCreateCluster(document, gon); - - expect(initGkeNamespace).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/spec/frontend/create_cluster/store/cluster_dropdown/actions_spec.js b/spec/frontend/create_cluster/store/cluster_dropdown/actions_spec.js deleted file mode 100644 index c0e8b11cf1e..00000000000 --- a/spec/frontend/create_cluster/store/cluster_dropdown/actions_spec.js +++ /dev/null @@ -1,95 +0,0 @@ -import testAction from 'helpers/vuex_action_helper'; - -import actionsFactory from '~/create_cluster/store/cluster_dropdown/actions'; -import * as types from '~/create_cluster/store/cluster_dropdown/mutation_types'; -import createState from '~/create_cluster/store/cluster_dropdown/state'; - -describe('Cluster dropdown Store Actions', () => { - const items = [{ name: 'item 1' }]; - let fetchFn; - let actions; - - beforeEach(() => { - fetchFn = jest.fn(); - actions = actionsFactory(fetchFn); - }); - - describe('fetchItems', () => { - describe('on success', () => { - beforeEach(() => { - fetchFn.mockResolvedValueOnce(items); - actions = actionsFactory(fetchFn); - }); - - it('dispatches success with received items', () => - testAction( - actions.fetchItems, - null, - createState(), - [], - [ - { type: 'requestItems' }, - { - type: 'receiveItemsSuccess', - payload: { items }, - }, - ], - )); - }); - - describe('on failure', () => { - const error = new Error('Could not fetch items'); - - beforeEach(() => { - fetchFn.mockRejectedValueOnce(error); - }); - - it('dispatches success with received items', () => - testAction( - actions.fetchItems, - null, - createState(), - [], - [ - { type: 'requestItems' }, - { - type: 'receiveItemsError', - payload: { error }, - }, - ], - )); - }); - }); - - describe('requestItems', () => { - it(`commits ${types.REQUEST_ITEMS} mutation`, () => - testAction(actions.requestItems, null, createState(), [{ type: types.REQUEST_ITEMS }])); - }); - - describe('receiveItemsSuccess', () => { - it(`commits ${types.RECEIVE_ITEMS_SUCCESS} mutation`, () => - testAction(actions.receiveItemsSuccess, { items }, createState(), [ - { - type: types.RECEIVE_ITEMS_SUCCESS, - payload: { - items, - }, - }, - ])); - }); - - describe('receiveItemsError', () => { - it(`commits ${types.RECEIVE_ITEMS_ERROR} mutation`, () => { - const error = new Error('Error fetching items'); - - testAction(actions.receiveItemsError, { error }, createState(), [ - { - type: types.RECEIVE_ITEMS_ERROR, - payload: { - error, - }, - }, - ]); - }); - }); -}); diff --git a/spec/frontend/create_cluster/store/cluster_dropdown/mutations_spec.js b/spec/frontend/create_cluster/store/cluster_dropdown/mutations_spec.js deleted file mode 100644 index 197fcfc2600..00000000000 --- a/spec/frontend/create_cluster/store/cluster_dropdown/mutations_spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import { - REQUEST_ITEMS, - RECEIVE_ITEMS_SUCCESS, - RECEIVE_ITEMS_ERROR, -} from '~/create_cluster/store/cluster_dropdown/mutation_types'; -import mutations from '~/create_cluster/store/cluster_dropdown/mutations'; -import createState from '~/create_cluster/store/cluster_dropdown/state'; - -describe('Cluster dropdown store mutations', () => { - let state; - let emptyPayload; - let items; - let error; - - beforeEach(() => { - emptyPayload = {}; - items = [{ name: 'item 1' }]; - error = new Error('could not load error'); - state = createState(); - }); - - it.each` - mutation | mutatedProperty | payload | expectedValue | expectedValueDescription - ${REQUEST_ITEMS} | ${'isLoadingItems'} | ${emptyPayload} | ${true} | ${true} - ${REQUEST_ITEMS} | ${'loadingItemsError'} | ${emptyPayload} | ${null} | ${null} - ${RECEIVE_ITEMS_SUCCESS} | ${'isLoadingItems'} | ${{ items }} | ${false} | ${false} - ${RECEIVE_ITEMS_SUCCESS} | ${'items'} | ${{ items }} | ${items} | ${'items payload'} - ${RECEIVE_ITEMS_ERROR} | ${'isLoadingItems'} | ${{ error }} | ${false} | ${false} - ${RECEIVE_ITEMS_ERROR} | ${'error'} | ${{ error }} | ${error} | ${'received error object'} - `(`$mutation sets $mutatedProperty to $expectedValueDescription`, (data) => { - const { mutation, mutatedProperty, payload, expectedValue } = data; - - mutations[mutation](state, payload); - expect(state[mutatedProperty]).toBe(expectedValue); - }); -}); |