Commit 2ecbc885 authored by Enrique Alcantara's avatar Enrique Alcantara

Add subnets field to cluster form

parent c6b7bff6
...@@ -5,11 +5,10 @@ import ClusterFormDropdown from './cluster_form_dropdown.vue'; ...@@ -5,11 +5,10 @@ import ClusterFormDropdown from './cluster_form_dropdown.vue';
import RegionDropdown from './region_dropdown.vue'; import RegionDropdown from './region_dropdown.vue';
import RoleNameDropdown from './role_name_dropdown.vue'; import RoleNameDropdown from './role_name_dropdown.vue';
import SecurityGroupDropdown from './security_group_dropdown.vue'; import SecurityGroupDropdown from './security_group_dropdown.vue';
import SubnetDropdown from './subnet_dropdown.vue';
const { mapState: mapRegionsState, mapActions: mapRegionsActions } = createNamespacedHelpers( const { mapState: mapRegionsState } = createNamespacedHelpers('regions');
'regions', const { mapState: mapVpcsState } = createNamespacedHelpers('vpcs');
); const { mapState: mapSubnetsState } = createNamespacedHelpers('subnets');
export default { export default {
components: { components: {
...@@ -17,22 +16,29 @@ export default { ...@@ -17,22 +16,29 @@ export default {
RegionDropdown, RegionDropdown,
RoleNameDropdown, RoleNameDropdown,
SecurityGroupDropdown, SecurityGroupDropdown,
SubnetDropdown,
}, },
computed: { computed: {
...mapState(['selectedRegion']), ...mapState(['selectedRegion', 'selectedVpc', 'selectedSubnet']),
...mapRegionsState({ ...mapRegionsState({
regions: 'items', regions: 'items',
isLoadingRegions: 'isLoadingItems', isLoadingRegions: 'isLoadingItems',
loadingRegionsError: 'loadingItemsError', loadingRegionsError: 'loadingItemsError',
}), }),
...mapState('vpcs', { ...mapVpcsState({
vpcs: ({ items }) => items, vpcs: 'items',
isLoadingVpcs: ({ isLoadingItems }) => isLoadingItems, isLoadingVpcs: 'isLoadingItems',
loadingVpcsError: ({ loadingItemsError }) => loadingItemsError, loadingVpcsError: 'loadingItemsError',
}),
...mapSubnetsState({
subnets: 'items',
isLoadingSubnets: 'isLoadingItems',
loadingSubnetsError: 'loadingItemsError',
}), }),
vpcDropdownDisabled() { vpcDropdownDisabled() {
return !Boolean(this.selectedRegion); return !this.selectedRegion;
},
subnetDropdownDisabled() {
return !this.selectedVpc;
}, },
vpcDropdownHelpText() { vpcDropdownHelpText() {
return sprintf( return sprintf(
...@@ -56,11 +62,16 @@ export default { ...@@ -56,11 +62,16 @@ export default {
...mapActions({ ...mapActions({
fetchRegions: 'regions/fetchItems', fetchRegions: 'regions/fetchItems',
fetchVpcs: 'vpcs/fetchItems', fetchVpcs: 'vpcs/fetchItems',
fetchSubnets: 'subnets/fetchItems',
}), }),
setRegionAndFetchVpcs(region) { setRegionAndFetchVpcs(region) {
this.setRegion({ region }); this.setRegion({ region });
this.fetchVpcs({ region }); this.fetchVpcs({ region });
}, },
setVpcAndFetchSubnets(vpc) {
this.setVpc({ vpc });
this.fetchSubnets({ vpc });
},
}, },
}; };
</script> </script>
...@@ -102,7 +113,29 @@ export default { ...@@ -102,7 +113,29 @@ export default {
:empty-text="s__('ClusterIntegration|No VPCs found')" :empty-text="s__('ClusterIntegration|No VPCs found')"
:has-errors="loadingVpcsError" :has-errors="loadingVpcsError"
:error-message="s__('ClusterIntegration|Could not load VPCs for the selected region')" :error-message="s__('ClusterIntegration|Could not load VPCs for the selected region')"
@input="setVpc({ vpc: $event })" @input="setVpcAndFetchSubnets($event)"
/>
<p class="form-text text-muted" v-html="vpcDropdownHelpText"></p>
</div>
<div class="form-group">
<label class="label-bold" name="role" for="eks-role">{{
s__('ClusterIntegration|Subnet')
}}</label>
<cluster-form-dropdown
field-id="eks-subnet"
field-name="eks-subnet"
:input="selectedSubnet"
:items="subnets"
:loading="isLoadingSubnets"
:disabled="subnetDropdownDisabled"
:disabled-text="s__('ClusterIntegration|Select a VPC to choose a subnet')"
:loading-text="s__('ClusterIntegration|Loading subnets')"
:placeholder="s__('ClusterIntergation|Select a subnet')"
:search-field-placeholder="s__('ClusterIntegration|Search subnets')"
:empty-text="s__('ClusterIntegration|No subnet found')"
:has-errors="loadingSubnetsError"
:error-message="s__('ClusterIntegration|Could not load subnets for the selected VPC')"
@input="setVpcAndFetchSubnets($event)"
/> />
<p class="form-text text-muted" v-html="vpcDropdownHelpText"></p> <p class="form-text text-muted" v-html="vpcDropdownHelpText"></p>
</div> </div>
......
...@@ -4,6 +4,7 @@ import Vue from 'vue'; ...@@ -4,6 +4,7 @@ import Vue from 'vue';
import EksClusterConfigurationForm from '~/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue'; import EksClusterConfigurationForm from '~/create_cluster/eks_cluster/components/eks_cluster_configuration_form.vue';
import RegionDropdown from '~/create_cluster/eks_cluster/components/region_dropdown.vue'; import RegionDropdown from '~/create_cluster/eks_cluster/components/region_dropdown.vue';
import eksClusterFormState from '~/create_cluster/eks_cluster/store/state';
import clusterDropdownStoreState from '~/create_cluster/eks_cluster/store/cluster_dropdown/state'; import clusterDropdownStoreState from '~/create_cluster/eks_cluster/store/cluster_dropdown/state';
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -12,13 +13,17 @@ localVue.use(Vuex); ...@@ -12,13 +13,17 @@ localVue.use(Vuex);
describe('EksClusterConfigurationForm', () => { describe('EksClusterConfigurationForm', () => {
let store; let store;
let actions; let actions;
let state;
let regionsState; let regionsState;
let vpcsState; let vpcsState;
let subnetsState;
let vpcsActions; let vpcsActions;
let regionsActions; let regionsActions;
let subnetsActions;
let vm; let vm;
beforeEach(() => { beforeEach(() => {
state = eksClusterFormState();
actions = { actions = {
setRegion: jest.fn(), setRegion: jest.fn(),
setVpc: jest.fn(), setVpc: jest.fn(),
...@@ -29,13 +34,20 @@ describe('EksClusterConfigurationForm', () => { ...@@ -29,13 +34,20 @@ describe('EksClusterConfigurationForm', () => {
vpcsActions = { vpcsActions = {
fetchItems: jest.fn(), fetchItems: jest.fn(),
}; };
subnetsActions = {
fetchItems: jest.fn(),
};
regionsState = { regionsState = {
...clusterDropdownStoreState(), ...clusterDropdownStoreState(),
}; };
vpcsState = { vpcsState = {
...clusterDropdownStoreState(), ...clusterDropdownStoreState(),
}; };
subnetsState = {
...clusterDropdownStoreState(),
};
store = new Vuex.Store({ store = new Vuex.Store({
state,
actions, actions,
modules: { modules: {
vpcs: { vpcs: {
...@@ -48,6 +60,11 @@ describe('EksClusterConfigurationForm', () => { ...@@ -48,6 +60,11 @@ describe('EksClusterConfigurationForm', () => {
state: regionsState, state: regionsState,
actions: regionsActions, actions: regionsActions,
}, },
subnets: {
namespaced: true,
state: subnetsState,
actions: subnetsActions,
},
}, },
}); });
}); });
...@@ -65,6 +82,7 @@ describe('EksClusterConfigurationForm', () => { ...@@ -65,6 +82,7 @@ describe('EksClusterConfigurationForm', () => {
const findRegionDropdown = () => vm.find(RegionDropdown); const findRegionDropdown = () => vm.find(RegionDropdown);
const findVpcDropdown = () => vm.find('[field-id="eks-vpc"]'); const findVpcDropdown = () => vm.find('[field-id="eks-vpc"]');
const findSubnetDropdown = () => vm.find('[field-id="eks-subnet"]');
describe('when mounted', () => { describe('when mounted', () => {
it('fetches available regions', () => { it('fetches available regions', () => {
...@@ -76,59 +94,103 @@ describe('EksClusterConfigurationForm', () => { ...@@ -76,59 +94,103 @@ describe('EksClusterConfigurationForm', () => {
regionsState.isLoadingItems = true; regionsState.isLoadingItems = true;
return Vue.nextTick().then(() => { return Vue.nextTick().then(() => {
expect(findRegionDropdown().props('loading')).toEqual(regionsState.isLoadingItems); expect(findRegionDropdown().props('loading')).toBe(regionsState.isLoadingItems);
}); });
}); });
it('sets regions to RegionDropdown regions property', () => { it('sets regions to RegionDropdown regions property', () => {
expect(findRegionDropdown().props('regions')).toEqual(regionsState.items); expect(findRegionDropdown().props('regions')).toBe(regionsState.items);
}); });
it('sets loadingRegionsError to RegionDropdown error property', () => { it('sets loadingRegionsError to RegionDropdown error property', () => {
expect(findRegionDropdown().props('error')).toEqual(regionsState.loadingItemsError); expect(findRegionDropdown().props('error')).toBe(regionsState.loadingItemsError);
}); });
describe('when region is selected', () => { it('disables VpcDropdown when no region is selected', () => {
const region = { name: 'us-west-2' }; expect(findVpcDropdown().props('disabled')).toBe(true);
beforeEach(() => {
findRegionDropdown().vm.$emit('input', region);
}); });
it('dispatches setRegion action', () => { it('enables VpcDropdown when no region is selected', () => {
expect(actions.setRegion).toHaveBeenCalledWith(expect.anything(), { region }, undefined); state.selectedRegion = { name: 'west-1 ' };
});
it('fetches available vpcs', () => { return Vue.nextTick().then(() => {
expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }, undefined); expect(findVpcDropdown().props('disabled')).toBe(false);
}); });
}); });
it('disables VpcDropdown when no region is selected', () => {
expect(findVpcDropdown().props('disabled')).toEqual(true);
});
it('sets isLoadingVpcs to VpcDropdown loading property', () => { it('sets isLoadingVpcs to VpcDropdown loading property', () => {
vpcsState.isLoadingItems = true; vpcsState.isLoadingItems = true;
return Vue.nextTick().then(() => { return Vue.nextTick().then(() => {
expect(findVpcDropdown().props('loading')).toEqual(vpcsState.isLoadingItems); expect(findVpcDropdown().props('loading')).toBe(vpcsState.isLoadingItems);
}); });
}); });
it('sets vpcs to VpcDropdown items property', () => { it('sets vpcs to VpcDropdown items property', () => {
expect(findVpcDropdown().props('items')).toEqual(vpcsState.items); expect(findVpcDropdown().props('items')).toBe(vpcsState.items);
}); });
it('sets loadingVpcsError to VpcDropdown hasErrors property', () => { it('sets loadingVpcsError to VpcDropdown hasErrors property', () => {
expect(findVpcDropdown().props('hasErrors')).toEqual(vpcsState.loadingItemsError); expect(findVpcDropdown().props('hasErrors')).toBe(vpcsState.loadingItemsError);
});
it('disables SubnetDropdown when no vpc is selected', () => {
expect(findSubnetDropdown().props('disabled')).toBe(true);
});
it('enables SubnetDropdown when a vpc is selected', () => {
state.selectedVpc = { name: 'vpc-1 ' };
return Vue.nextTick().then(() => {
expect(findSubnetDropdown().props('disabled')).toBe(false);
});
});
it('sets isLoadingSubnets to SubnetDropdown loading property', () => {
subnetsState.isLoadingItems = true;
return Vue.nextTick().then(() => {
expect(findSubnetDropdown().props('loading')).toBe(subnetsState.isLoadingItems);
});
});
it('sets subnets to SubnetDropdown items property', () => {
expect(findSubnetDropdown().props('items')).toBe(subnetsState.items);
});
it('sets loadingSubnetsError to SubnetDropdown hasErrors property', () => {
expect(findSubnetDropdown().props('hasErrors')).toBe(subnetsState.loadingItemsError);
});
describe('when region is selected', () => {
const region = { name: 'us-west-2' };
beforeEach(() => {
findRegionDropdown().vm.$emit('input', region);
}); });
it('dispatches setVpc action when vpc is selected', () => { it('dispatches setRegion action', () => {
expect(actions.setRegion).toHaveBeenCalledWith(expect.anything(), { region }, undefined);
});
it('fetches available vpcs', () => {
expect(vpcsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { region }, undefined);
});
});
describe('when vpc is selected', () => {
const vpc = { name: 'vpc-1' }; const vpc = { name: 'vpc-1' };
beforeEach(() => {
findVpcDropdown().vm.$emit('input', vpc); findVpcDropdown().vm.$emit('input', vpc);
});
it('dispatches setVpc action', () => {
expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc }, undefined); expect(actions.setVpc).toHaveBeenCalledWith(expect.anything(), { vpc }, undefined);
}); });
it('dispatches fetchSubnets action', () => {
expect(subnetsActions.fetchItems).toHaveBeenCalledWith(expect.anything(), { vpc }, undefined);
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment