Commit 93f5d463 authored by Enrique Alcantara's avatar Enrique Alcantara

Create gke submit button component

Move logic to enable submit button in the GKE
form to a separate component to avoid cluttering
the machine type dropdown component.
parent 9fd594b7
......@@ -16,9 +16,6 @@ export default {
]),
...mapState({ items: 'machineTypes' }),
...mapGetters(['hasZone', 'hasMachineType']),
allDropdownsSelected() {
return this.projectHasBillingEnabled && this.hasZone && this.hasMachineType;
},
isDisabled() {
return (
this.isLoading ||
......@@ -65,22 +62,10 @@ export default {
.catch(this.fetchFailureHandler);
}
},
selectedMachineType() {
this.enableSubmit();
},
},
methods: {
...mapActions(['fetchMachineTypes']),
...mapActions({ setItem: 'setMachineType' }),
enableSubmit() {
if (this.allDropdownsSelected) {
const submitButtonEl = document.querySelector('.js-gke-cluster-creation-submit');
if (submitButtonEl) {
submitButtonEl.removeAttribute('disabled');
}
}
},
},
};
</script>
......
<script>
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters(['hasValidData']),
},
};
</script>
<template>
<button
type="submit"
:disabled="!hasValidData"
class="js-gke-cluster-creation-submit btn btn-success"
>
{{ s__('ClusterIntegration|Create Kubernetes cluster') }}
</button>
</template>
......@@ -4,6 +4,10 @@ import Flash from '~/flash';
import GkeProjectIdDropdown from './components/gke_project_id_dropdown.vue';
import GkeZoneDropdown from './components/gke_zone_dropdown.vue';
import GkeMachineTypeDropdown from './components/gke_machine_type_dropdown.vue';
import GkeSubmitButton from './components/gke_submit_button.vue';
import store from './store';
import * as CONSTANTS from './constants';
const mountComponent = (entryPoint, component, componentName, extraProps = {}) => {
......@@ -14,6 +18,7 @@ const mountComponent = (entryPoint, component, componentName, extraProps = {}) =
return new Vue({
el,
store,
components: {
[componentName]: component,
},
......@@ -50,6 +55,10 @@ const mountGkeMachineTypeDropdown = () => {
);
};
const mountGkeSubmitButton = () => {
mountComponent('.js-gke-cluster-creation-submit-container', GkeSubmitButton, 'gke-submit-button');
};
const gkeDropdownErrorHandler = () => {
Flash(CONSTANTS.GCP_API_ERROR);
};
......@@ -72,6 +81,7 @@ const initializeGapiClient = () => {
mountGkeProjectIdDropdown();
mountGkeZoneDropdown();
mountGkeMachineTypeDropdown();
mountGkeSubmitButton();
})
.catch(gkeDropdownErrorHandler);
};
......
export const hasProject = state => Boolean(state.selectedProject.projectId);
export const hasZone = state => Boolean(state.selectedZone);
export const hasMachineType = state => Boolean(state.selectedMachineType);
export const hasValidData = (state, getters) =>
Boolean(state.projectHasBillingEnabled) && getters.hasZone && getters.hasMachineType;
......@@ -79,6 +79,6 @@
= s_('ClusterIntegration|Allow GitLab to manage namespace and service accounts for this cluster.')
= link_to _('More information'), help_page_path('user/project/clusters/index.md', anchor: 'gitlab-managed-clusters'), target: '_blank'
.form-group
.form-group.js-gke-cluster-creation-submit-container
= field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
class: 'js-gke-cluster-creation-submit btn btn-success', disabled: true
......@@ -14,6 +14,11 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
allow(Projects::ClustersController).to receive(:STATUS_POLLING_INTERVAL) { 100 }
end
def submit_form
execute_script('document.querySelector(".js-gke-cluster-creation-submit").removeAttribute("disabled")')
execute_script('document.querySelector(".js-gke-cluster-creation-submit").click()')
end
context 'when user has signed with Google' do
let(:project_id) { 'test-project-1234' }
......@@ -34,7 +39,7 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
end
context 'when user filled form with valid parameters' do
subject { click_button 'Create Kubernetes cluster' }
subject { submit_form }
before do
allow_any_instance_of(GoogleApi::CloudPlatform::Client)
......@@ -47,8 +52,8 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
allow(WaitForClusterCreationWorker).to receive(:perform_in).and_return(nil)
execute_script('document.querySelector(".js-gke-cluster-creation-submit").removeAttribute("disabled")')
sleep 2 # wait for ajax
expect(page).to have_css('.js-gcp-project-id-dropdown')
execute_script('document.querySelector(".js-gcp-project-id-dropdown input").setAttribute("type", "text")')
execute_script('document.querySelector(".js-gcp-zone-dropdown input").setAttribute("type", "text")')
execute_script('document.querySelector(".js-gcp-machine-type-dropdown input").setAttribute("type", "text")')
......@@ -86,8 +91,7 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
context 'when user filled form with invalid parameters' do
before do
execute_script('document.querySelector(".js-gke-cluster-creation-submit").removeAttribute("disabled")')
click_button 'Create Kubernetes cluster'
submit_form
end
it 'user sees a validation error' do
......
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import GkeSubmitButton from '~/create_cluster/gke_cluster/components/gke_submit_button.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('GkeSubmitButton', () => {
let wrapper;
let store;
let hasValidData;
const buildStore = () =>
new Vuex.Store({
getters: {
hasValidData,
},
});
const buildWrapper = () =>
shallowMount(GkeSubmitButton, {
store,
localVue,
});
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();
});
});
import * as getters from '~/create_cluster/gke_cluster/store/getters';
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', () => {
......@@ -7,6 +12,7 @@ describe('GCP Cluster Dropdown Store Getters', () => {
describe('valid states', () => {
beforeEach(() => {
state = {
projectHasBillingEnabled: true,
selectedProject: selectedProjectMock,
selectedZone: selectedZoneMock,
selectedMachineType: selectedMachineTypeMock,
......@@ -15,19 +21,25 @@ describe('GCP Cluster Dropdown Store Getters', () => {
describe('hasProject', () => {
it('should return true when project is selected', () => {
expect(getters.hasProject(state)).toEqual(true);
expect(hasProject(state)).toEqual(true);
});
});
describe('hasZone', () => {
it('should return true when zone is selected', () => {
expect(getters.hasZone(state)).toEqual(true);
expect(hasZone(state)).toEqual(true);
});
});
describe('hasMachineType', () => {
it('should return true when machine type is selected', () => {
expect(getters.hasMachineType(state)).toEqual(true);
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);
});
});
});
......@@ -46,19 +58,45 @@ describe('GCP Cluster Dropdown Store Getters', () => {
describe('hasProject', () => {
it('should return false when project is not selected', () => {
expect(getters.hasProject(state)).toEqual(false);
expect(hasProject(state)).toEqual(false);
});
});
describe('hasZone', () => {
it('should return false when zone is not selected', () => {
expect(getters.hasZone(state)).toEqual(false);
expect(hasZone(state)).toEqual(false);
});
});
describe('hasMachineType', () => {
it('should return false when machine type is not selected', () => {
expect(getters.hasMachineType(state)).toEqual(false);
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);
});
});
});
......
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