Commit 811342e3 authored by Enrique Alcantara's avatar Enrique Alcantara Committed by Tiger

Implement error handling in auth form

Handle isAuthenticating state
Handle authentication error state
parent 06c996be
<script>
import { mapState } from 'vuex';
import ServiceCredentialsForm from './service_credentials_form.vue';
import EksClusterConfigurationForm from './eks_cluster_configuration_form.vue';
import { mapState } from 'vuex';
export default {
components: {
......
<script>
import { GlFormInput, GlButton } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
import { GlFormInput } from '@gitlab/ui';
import { sprintf, s__, __ } from '~/locale';
import _ from 'underscore';
import { mapState } from 'vuex';
import { mapState, mapActions } from 'vuex';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
export default {
components: {
GlFormInput,
GlButton,
LoadingButton,
ClipboardButton,
},
props: {
......@@ -27,7 +28,15 @@ export default {
};
},
computed: {
...mapState(['accountId', 'externalId']),
...mapState(['accountId', 'externalId', 'isCreatingRole', 'createRoleError']),
submitButtonDisabled() {
return this.isCreatingRole || !this.roleArn;
},
submitButtonLabel() {
return this.isCreatingRole
? __('Authenticating')
: s__('ClusterIntegration|Authenticate with AWS');
},
accountAndExternalIdsHelpText() {
const escapedUrl = _.escape(this.accountAndExternalIdsHelpPath);
......@@ -61,6 +70,14 @@ export default {
);
},
},
methods: {
...mapActions(['createRole']),
handleAuthenticate() {
const { roleArn, externalId } = this;
this.createRole({ roleArn, externalId });
},
},
};
</script>
<template>
......@@ -73,11 +90,14 @@ export default {
)
}}
</p>
<div v-if="createRoleError" class="js-invalid-credentials bs-callout bs-callout-danger">
{{ createRoleError }}
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="gitlab-account-id">{{ __('Account ID') }}</label>
<div class="input-group">
<gl-form-input type="text" readonly :value="accountId" id="gitlab-account-id" />
<gl-form-input id="gitlab-account-id" type="text" readonly :value="accountId" />
<div class="input-group-append">
<clipboard-button
:text="accountId"
......@@ -90,7 +110,7 @@ export default {
<div class="form-group col-md-6">
<label for="eks-external-id">{{ __('External ID') }}</label>
<div class="input-group">
<gl-form-input type="text" readonly :value="externalId" id="eks-external-id" />
<gl-form-input id="eks-external-id" type="text" readonly :value="externalId" />
<div class="input-group-append">
<clipboard-button
:text="externalId"
......@@ -109,8 +129,12 @@ export default {
<gl-form-input id="eks-provision-role-arn" v-model="roleArn" />
<p class="form-text text-muted" v-html="provisionRoleArnHelpText"></p>
</div>
<gl-button class="js-submit-service-credentials" :disabled="!roleArn">
{{ s__('ClusterIntegration|Authenticate with AWS') }}
</gl-button>
<loading-button
class="js-submit-service-credentials"
:disabled="submitButtonDisabled"
:loading="isCreatingRole"
:label="submitButtonLabel"
@click="handleAuthenticate($event)"
/>
</form>
</template>
import { KUBERNETES_VERSIONS } from '../constants';
export default () => ({
isValidatingCredentials: false,
isAuthenticating: false,
hasCredentials: false,
invalidCredentials: false,
invalidCredentialsError: null,
......
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import ServiceCredentialsForm from '~/create_cluster/eks_cluster/components/service_credentials_form.vue';
import LoadingButton from '~/vue_shared/components/loading_button.vue';
import eksClusterState from '~/create_cluster/eks_cluster/store/state';
const localVue = createLocalVue();
localVue.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: {
accountId,
externalId,
accountAndExternalIdsHelpPath: '',
createRoleArnHelpPath: '',
},
localVue,
store,
});
});
afterEach(() => vm.destroy());
......@@ -23,7 +44,8 @@ describe('ServiceCredentialsForm', () => {
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 findSubmitButton = () => vm.find('.js-submit-service-credentials');
const findInvalidCredentials = () => vm.find('.js-invalid-credentials');
const findSubmitButton = () => vm.find(LoadingButton);
it('displays provided account id', () => {
expect(findAccountIdInput().attributes('value')).toBe(accountId);
......@@ -50,4 +72,44 @@ describe('ServiceCredentialsForm', () => {
expect(findSubmitButton().attributes('disabled')).toBeFalsy();
});
it('dispatches authenticate action when submit button is clicked', () => {
findSubmitButton().vm.$emit('click');
expect(createRoleAction).toHaveBeenCalled();
});
describe('when is creating role', () => {
beforeEach(() => {
vm.setData({ roleArn: '123' }); // set role ARN to enable button
state.isCreatingRole = true;
});
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().props('label')).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);
});
});
});
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