Commit 96df132a authored by Jacques Erasmus's avatar Jacques Erasmus

Merge branch '339949-action-based-dismissable-credit-card-validation-alert' into 'master'

Trigger shared runner credit card validation alert on click, make it always dismissable

See merge request gitlab-org/gitlab!79565
parents a3bdb419 465394d1
import { __ } from '~/locale';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
export const VARIABLE_TYPE = 'env_var';
......@@ -7,5 +8,7 @@ export const CONFIG_VARIABLES_TIMEOUT = 5000;
export const BRANCH_REF_TYPE = 'branch';
export const TAG_REF_TYPE = 'tag';
export const CC_VALIDATION_REQUIRED_ERROR =
'Credit card required to be on file in order to create a pipeline';
// must match pipeline/chain/validate/after_config.rb
export const CC_VALIDATION_REQUIRED_ERROR = __(
'Credit card required to be on file in order to create a pipeline',
);
......@@ -2,6 +2,7 @@
import { GlAlert, GlToggle, GlTooltip } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils';
import { __, s__ } from '~/locale';
import { CC_VALIDATION_REQUIRED_ERROR } from '../constants';
const DEFAULT_ERROR_MESSAGE = __('An error occurred while updating the configuration.');
const REQUIRES_VALIDATION_TEXT = s__(
......@@ -47,11 +48,13 @@ export default {
};
},
computed: {
showCreditCardValidation() {
ccRequiredError() {
return this.errorMessage === CC_VALIDATION_REQUIRED_ERROR && !this.ccAlertDismissed;
},
genericError() {
return (
this.isCreditCardValidationRequired &&
!this.isSharedRunnerEnabled &&
!this.successfulValidation &&
this.errorMessage &&
this.errorMessage !== CC_VALIDATION_REQUIRED_ERROR &&
!this.ccAlertDismissed
);
},
......@@ -62,6 +65,7 @@ export default {
},
toggleSharedRunners() {
this.isLoading = true;
this.ccAlertDismissed = false;
this.errorMessage = null;
axios
......@@ -82,20 +86,19 @@ export default {
<template>
<div>
<section class="gl-mt-5">
<gl-alert v-if="errorMessage" class="gl-mb-3" variant="danger" :dismissible="false">
{{ errorMessage }}
</gl-alert>
<cc-validation-required-alert
v-if="showCreditCardValidation"
v-if="ccRequiredError"
class="gl-pb-5"
:custom-message="$options.i18n.REQUIRES_VALIDATION_TEXT"
@verifiedCreditCard="creditCardValidated"
@dismiss="ccAlertDismissed = true"
/>
<gl-alert v-if="genericError" class="gl-mb-3" variant="danger" :dismissible="false">
{{ errorMessage }}
</gl-alert>
<gl-toggle
v-else
ref="sharedRunnersToggle"
:disabled="isDisabledAndUnoverridable"
:is-loading="isLoading"
......
import { __ } from '~/locale';
export const LEVEL_TYPES = {
ROLE: 'role',
USER: 'user',
......@@ -18,3 +20,8 @@ export const ACCESS_LEVELS = {
};
export const ACCESS_LEVEL_NONE = 0;
// must match shared_runners_setting in update_service.rb
export const CC_VALIDATION_REQUIRED_ERROR = __(
'Shared runners enabled cannot be enabled until a valid credit card is on file',
);
import { GlToggle } from '@gitlab/ui';
import { GlToggle, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAxiosAdapter from 'axios-mock-adapter';
import { nextTick } from 'vue';
......@@ -7,6 +7,7 @@ import { TEST_HOST } from 'helpers/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import SharedRunnersToggleComponent from '~/projects/settings/components/shared_runners_toggle.vue';
import { CC_VALIDATION_REQUIRED_ERROR } from '~/projects/settings/constants';
const TEST_UPDATE_PATH = '/test/update_shared_runners';
......@@ -29,6 +30,7 @@ describe('projects/settings/components/shared_runners', () => {
const findSharedRunnersToggle = () => wrapper.findComponent(GlToggle);
const findCcValidationRequiredAlert = () => wrapper.findComponent(CcValidationRequiredAlert);
const findGenericAlert = () => wrapper.findComponent(GlAlert);
const getToggleValue = () => findSharedRunnersToggle().props('value');
const isToggleDisabled = () => findSharedRunnersToggle().props('disabled');
......@@ -54,36 +56,39 @@ describe('projects/settings/components/shared_runners', () => {
});
});
it('toggle should not be visible', () => {
expect(findSharedRunnersToggle().exists()).toBe(false);
it('should show the toggle button', () => {
expect(findSharedRunnersToggle().exists()).toBe(true);
expect(getToggleValue()).toBe(false);
expect(isToggleDisabled()).toBe(false);
});
it('credit card validation component should exist', () => {
expect(findCcValidationRequiredAlert().exists()).toBe(true);
expect(findCcValidationRequiredAlert().text()).toBe(
SharedRunnersToggleComponent.i18n.REQUIRES_VALIDATION_TEXT,
);
});
describe('when credit card is unvalidated', () => {
beforeEach(() => {
mockAxios.onPost(TEST_UPDATE_PATH).reply(401, { error: CC_VALIDATION_REQUIRED_ERROR });
});
it('credit card alert should be hidden after dismiss', async () => {
findCcValidationRequiredAlert().vm.$emit('dismiss');
it('should show credit card validation error on toggle', async () => {
findSharedRunnersToggle().vm.$emit('change', true);
await waitForPromises();
await nextTick();
expect(findCcValidationRequiredAlert().exists()).toBe(true);
expect(findCcValidationRequiredAlert().text()).toBe(
SharedRunnersToggleComponent.i18n.REQUIRES_VALIDATION_TEXT,
);
});
expect(findCcValidationRequiredAlert().exists()).toBe(false);
});
it('should hide credit card alert on dismiss', async () => {
findSharedRunnersToggle().vm.$emit('change', true);
await waitForPromises();
describe('when credit card is validated', () => {
beforeEach(() => {
findCcValidationRequiredAlert().vm.$emit('verifiedCreditCard');
});
findCcValidationRequiredAlert().vm.$emit('dismiss');
await nextTick();
it('should show the toggle button', () => {
expect(findSharedRunnersToggle().exists()).toBe(true);
expect(getToggleValue()).toBe(false);
expect(isToggleDisabled()).toBe(false);
expect(findCcValidationRequiredAlert().exists()).toBe(false);
});
});
describe('when credit card is validated', () => {
it('should not show credit card alert after toggling on and off', async () => {
findSharedRunnersToggle().vm.$emit('change', true);
await waitForPromises();
......@@ -100,5 +105,22 @@ describe('projects/settings/components/shared_runners', () => {
expect(findCcValidationRequiredAlert().exists()).toBe(false);
});
});
describe('when toggling fails for some other reason', () => {
beforeEach(() => {
mockAxios.onPost(TEST_UPDATE_PATH).reply(500);
});
it('should show a generic alert instead', async () => {
findSharedRunnersToggle().vm.$emit('change', true);
await waitForPromises();
expect(findCcValidationRequiredAlert().exists()).toBe(false);
expect(findGenericAlert().exists()).toBe(true);
expect(findGenericAlert().text()).toBe(
'An error occurred while updating the configuration.',
);
});
});
});
});
......@@ -10470,6 +10470,9 @@ msgstr ""
msgid "CredentialsInventory|SSH Keys"
msgstr ""
msgid "Credit card required to be on file in order to create a pipeline"
msgstr ""
msgid "Credit card:"
msgstr ""
......@@ -33077,6 +33080,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
msgstr ""
msgid "Shared runners help link"
msgstr ""
......
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