feat: Rewrite labels/validationMixin mixin to a helper (#9818)

This commit is contained in:
Sivin Varghese
2024-07-22 21:41:05 +05:30
committed by GitHub
parent 81d7c51a84
commit 10ee773aac
6 changed files with 101 additions and 106 deletions

View File

@@ -1,17 +1,17 @@
<template>
<div class="h-auto overflow-auto flex flex-col">
<div class="flex flex-col h-auto overflow-auto">
<woot-modal-header
:header-title="$t('LABEL_MGMT.ADD.TITLE')"
:header-content="$t('LABEL_MGMT.ADD.DESC')"
/>
<form class="mx-0 flex flex-wrap" @submit.prevent="addLabel">
<form class="flex flex-wrap mx-0" @submit.prevent="addLabel">
<woot-input
v-model.trim="title"
:class="{ error: $v.title.$error }"
class="w-full label-name--input"
:label="$t('LABEL_MGMT.FORM.NAME.LABEL')"
:placeholder="$t('LABEL_MGMT.FORM.NAME.PLACEHOLDER')"
:error="getLabelTitleErrorMessage"
:error="labelTitleErrorMessage"
data-testid="label-title"
@input="$v.title.$touch"
/>
@@ -32,13 +32,13 @@
<woot-color-picker v-model="color" />
</label>
</div>
<div class="w-full flex items-center gap-2">
<div class="flex items-center w-full gap-2">
<input v-model="showOnSidebar" type="checkbox" :value="true" />
<label for="conversation_creation">
{{ $t('LABEL_MGMT.FORM.SHOW_ON_SIDEBAR.LABEL') }}
</label>
</div>
<div class="flex justify-end items-center py-2 px-0 gap-2 w-full">
<div class="flex items-center justify-end w-full gap-2 px-0 py-2">
<woot-button
:is-disabled="$v.title.$invalid || uiFlags.isCreating"
:is-loading="uiFlags.isCreating"
@@ -56,13 +56,12 @@
<script>
import alertMixin from 'shared/mixins/alertMixin';
import validationMixin from './validationMixin';
import { mapGetters } from 'vuex';
import validations from './validations';
import validations, { getLabelTitleErrorMessage } from './validations';
import { getRandomColor } from 'dashboard/helper/labelColor';
export default {
mixins: [alertMixin, validationMixin],
mixins: [alertMixin],
props: {
prefillTitle: {
type: String,
@@ -82,6 +81,10 @@ export default {
...mapGetters({
uiFlags: 'labels/getUIFlags',
}),
labelTitleErrorMessage() {
const errorMessage = getLabelTitleErrorMessage(this.$v);
return this.$t(errorMessage);
},
},
mounted() {
this.color = getRandomColor();

View File

@@ -1,14 +1,14 @@
<template>
<div class="h-auto overflow-auto flex flex-col">
<div class="flex flex-col h-auto overflow-auto">
<woot-modal-header :header-title="pageTitle" />
<form class="mx-0 flex flex-wrap" @submit.prevent="editLabel">
<form class="flex flex-wrap mx-0" @submit.prevent="editLabel">
<woot-input
v-model.trim="title"
:class="{ error: $v.title.$error }"
class="w-full label-name--input"
:label="$t('LABEL_MGMT.FORM.NAME.LABEL')"
:placeholder="$t('LABEL_MGMT.FORM.NAME.PLACEHOLDER')"
:error="getLabelTitleErrorMessage"
:error="labelTitleErrorMessage"
@input="$v.title.$touch"
/>
<woot-input
@@ -26,13 +26,13 @@
<woot-color-picker v-model="color" />
</label>
</div>
<div class="w-full flex items-center gap-2">
<div class="flex items-center w-full gap-2">
<input v-model="showOnSidebar" type="checkbox" :value="true" />
<label for="conversation_creation">
{{ $t('LABEL_MGMT.FORM.SHOW_ON_SIDEBAR.LABEL') }}
</label>
</div>
<div class="flex justify-end items-center py-2 px-0 gap-2 w-full">
<div class="flex items-center justify-end w-full gap-2 px-0 py-2">
<woot-button
:is-disabled="$v.title.$invalid || uiFlags.isUpdating"
:is-loading="uiFlags.isUpdating"
@@ -50,11 +50,10 @@
<script>
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import validationMixin from './validationMixin';
import validations from './validations';
import validations, { getLabelTitleErrorMessage } from './validations';
export default {
mixins: [alertMixin, validationMixin],
mixins: [alertMixin],
props: {
selectedResponse: {
type: Object,
@@ -79,6 +78,10 @@ export default {
this.selectedResponse.title
}`;
},
labelTitleErrorMessage() {
const errorMessage = getLabelTitleErrorMessage(this.$v);
return this.$t(errorMessage);
},
},
mounted() {
this.setFormValues();

View File

@@ -1,72 +0,0 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueI18n from 'vue-i18n';
import Vuelidate from 'vuelidate';
import validationMixin from '../validationMixin';
import validations from '../validations';
import i18n from 'dashboard/i18n';
const localVue = createLocalVue();
localVue.use(VueI18n);
localVue.use(Vuelidate);
const i18nConfig = new VueI18n({
locale: 'en',
messages: i18n,
});
const Component = {
render() {},
title: 'TestComponent',
mixins: [validationMixin],
validations,
};
describe('validationMixin', () => {
it('it should return empty error message if valid label name passed', async () => {
const wrapper = shallowMount(Component, {
i18n: i18nConfig,
localVue,
data() {
return { title: 'sales' };
},
});
wrapper.vm.$v.$touch();
expect(wrapper.vm.getLabelTitleErrorMessage).toBe('');
});
it('it should return label required error message if empty name is passed', async () => {
const wrapper = shallowMount(Component, {
i18n: i18nConfig,
localVue,
data() {
return { title: '' };
},
});
wrapper.vm.$v.$touch();
expect(wrapper.vm.getLabelTitleErrorMessage).toBe('Label name is required');
});
it('it should return label minimum length error message if one charceter label name is passed', async () => {
const wrapper = shallowMount(Component, {
i18n: i18nConfig,
localVue,
data() {
return { title: 's' };
},
});
wrapper.vm.$v.$touch();
expect(wrapper.vm.getLabelTitleErrorMessage).toBe(
'Minimum length 2 is required'
);
});
it('it should return invalid character error message if invalid lable name passed', async () => {
const wrapper = shallowMount(Component, {
i18n: i18nConfig,
localVue,
data() {
return { title: 'sales enquiry' };
},
});
wrapper.vm.$v.$touch();
expect(wrapper.vm.getLabelTitleErrorMessage).toBe(
'Only Alphabets, Numbers, Hyphen and Underscore are allowed'
);
});
});

View File

@@ -1,4 +1,7 @@
import { validLabelCharacters } from '../validations';
import {
validLabelCharacters,
getLabelTitleErrorMessage,
} from '../validations';
describe('#validLabelCharacters', () => {
it('validates the label', () => {
@@ -8,3 +11,64 @@ describe('#validLabelCharacters', () => {
expect(validLabelCharacters('str-str')).toEqual(true);
});
});
describe('#getLabelTitleErrorMessage', () => {
const createValidation = titleValidation => ({
title: {
$error: titleValidation.$error,
required: titleValidation.required,
minLength: titleValidation.minLength,
validLabelCharacters: titleValidation.validLabelCharacters,
},
});
it('returns an empty string when there are no validation errors', () => {
const validation = createValidation({
$error: false,
required: true,
minLength: true,
validLabelCharacters: true,
});
expect(getLabelTitleErrorMessage(validation)).toEqual('');
});
it('returns a required error message when the title is required but not provided', () => {
const validation = createValidation({
$error: true,
required: false,
minLength: true,
validLabelCharacters: true,
});
expect(getLabelTitleErrorMessage(validation)).toEqual(
'LABEL_MGMT.FORM.NAME.REQUIRED_ERROR'
);
});
it('returns a minimum length error message when the title is too short', () => {
const validation = createValidation({
$error: true,
required: true,
minLength: false,
validLabelCharacters: true,
});
expect(getLabelTitleErrorMessage(validation)).toEqual(
'LABEL_MGMT.FORM.NAME.MINIMUM_LENGTH_ERROR'
);
});
it('returns a valid label characters error message when the title has invalid characters', () => {
const validation = createValidation({
$error: true,
required: true,
minLength: true,
validLabelCharacters: false,
});
expect(getLabelTitleErrorMessage(validation)).toEqual(
'LABEL_MGMT.FORM.NAME.VALID_ERROR'
);
});
});

View File

@@ -1,17 +0,0 @@
export default {
computed: {
getLabelTitleErrorMessage() {
let errorMessage = '';
if (!this.$v.title.$error) {
errorMessage = '';
} else if (!this.$v.title.required) {
errorMessage = this.$t('LABEL_MGMT.FORM.NAME.REQUIRED_ERROR');
} else if (!this.$v.title.minLength) {
errorMessage = this.$t('LABEL_MGMT.FORM.NAME.MINIMUM_LENGTH_ERROR');
} else if (!this.$v.title.validLabelCharacters) {
errorMessage = this.$t('LABEL_MGMT.FORM.NAME.VALID_ERROR');
}
return errorMessage;
},
},
};

View File

@@ -2,6 +2,20 @@ import { required, minLength } from 'vuelidate/lib/validators';
export const validLabelCharacters = (str = '') => !!str && !str.includes(' ');
export const getLabelTitleErrorMessage = validation => {
let errorMessage = '';
if (!validation.title.$error) {
errorMessage = '';
} else if (!validation.title.required) {
errorMessage = 'LABEL_MGMT.FORM.NAME.REQUIRED_ERROR';
} else if (!validation.title.minLength) {
errorMessage = 'LABEL_MGMT.FORM.NAME.MINIMUM_LENGTH_ERROR';
} else if (!validation.title.validLabelCharacters) {
errorMessage = 'LABEL_MGMT.FORM.NAME.VALID_ERROR';
}
return errorMessage;
};
export default {
title: {
required,