@cnamts/synapse 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AutocompleteFilter-DXd4szWO.js → AutocompleteFilter-CGF33skz.js} +1 -1
- package/dist/{DateFilter-BD59Kgwf.js → DateFilter-D7-MsKtx.js} +1 -1
- package/dist/{NumberFilter-BSMZE7uw.js → NumberFilter-bjQPPfsj.js} +1 -1
- package/dist/{PeriodFilter-keUdSSk0.js → PeriodFilter-B3wJpK8-.js} +1 -1
- package/dist/{SelectFilter-Dhvvwazl.js → SelectFilter-BN6DbKAV.js} +1 -1
- package/dist/{TextFilter-CU8FpXz0.js → TextFilter-BffP0J2f.js} +1 -1
- package/dist/{apLightTheme2026-DbS7BPUf.js → apLightTheme2026-C4ygwMHC.js} +11 -11
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +6 -6
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +6 -6
- package/dist/components/Captcha/Captcha.d.ts +27 -16
- package/dist/components/Captcha/CaptchaForm.d.ts +29 -3
- package/dist/components/Captcha/types.d.ts +14 -0
- package/dist/components/Captcha/useCaptchaValidation.d.ts +37 -0
- package/dist/components/Customs/Selects/SelectBtnField/SelectBtnField.d.ts +33 -13
- package/dist/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.d.ts +23 -0
- package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +2 -2
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +2 -2
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +17 -48
- package/dist/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.d.ts +29 -0
- package/dist/components/Customs/SyCheckBoxGroup/types.d.ts +46 -0
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +16 -51
- package/dist/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.d.ts +27 -0
- package/dist/components/Customs/SyCheckbox/types.d.ts +49 -0
- package/dist/components/Customs/SyTextField/FieldState.d.ts +5 -0
- package/dist/components/Customs/SyTextField/useSyTextFieldValidation.d.ts +3 -3
- package/dist/components/DialogBox/DialogBox.d.ts +2 -0
- package/dist/components/DialogBox/locales.d.ts +1 -0
- package/dist/components/FilterSideBar/FilterSideBar.d.ts +4 -0
- package/dist/components/LunarCalendar/LunarCalendar.d.ts +43 -14
- package/dist/components/LunarCalendar/types.d.ts +35 -0
- package/dist/components/LunarCalendar/useLunarCalendarValidation.d.ts +11 -12
- package/dist/components/MonthPicker/MonthPicker.d.ts +72 -1747
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +21 -1733
- package/dist/components/MonthPicker/MonthPickerText/useTextField.d.ts +5 -0
- package/dist/components/MonthPicker/locales.d.ts +1 -0
- package/dist/components/MonthPicker/types.d.ts +11 -0
- package/dist/components/MonthPicker/useMonthPickerValidation.d.ts +37 -24
- package/dist/components/NirField/NirField.d.ts +6 -4
- package/dist/components/NirField/useNirValidation.d.ts +7 -5
- package/dist/components/PageContainer/PageContainer.d.ts +8 -0
- package/dist/components/PasswordField/PasswordField.d.ts +2 -2
- package/dist/components/PasswordField/usePasswordFieldValidation.d.ts +2 -2
- package/dist/components/PhoneField/PhoneField.d.ts +960 -1938
- package/dist/components/PhoneField/indicatifs.d.ts +715 -8
- package/dist/components/PhoneField/locales.d.ts +7 -0
- package/dist/components/PhoneField/types.d.ts +29 -0
- package/dist/components/PhoneField/usePhoneFieldValidation.d.ts +45 -0
- package/dist/components/PhoneField/usePhoneIndicatifs.d.ts +947 -0
- package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +2 -2
- package/dist/composables/unifyValidation/documentationValidationProps.d.ts +1 -1
- package/dist/composables/unifyValidation/useValidation.d.ts +4 -5
- package/dist/design-system-v3.js +2 -2
- package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/baseTokens.d.ts +18 -18
- package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/pa/paLightTheme.d.ts +10 -10
- package/dist/designTokens/tokens/semanticTokens.d.ts +14 -14
- package/dist/{main-D8ryUoS5.js → main-C4wAktOs.js} +13718 -12991
- package/dist/synapse.css +1 -1
- package/dist/vuetifyConfig.js +1 -1
- package/package.json +7 -7
- package/src/assets/compat/_legacy-tokens.scss +91 -0
- package/src/assets/overrides/_utilities.scss +23 -0
- package/src/components/Accordion/Accordion.stories.ts +121 -1
- package/src/components/BackBtn/BackBtn.mdx +1 -1
- package/src/components/BackToTopBtn/BackToTopBtn.mdx +0 -1
- package/src/components/Captcha/Captcha.stories.ts +134 -31
- package/src/components/Captcha/Captcha.vue +95 -28
- package/src/components/Captcha/CaptchaForm.vue +51 -22
- package/src/components/Captcha/tests/Captcha.focus.spec.ts +214 -0
- package/src/components/Captcha/tests/Captcha.spec.ts +233 -24
- package/src/components/Captcha/tests/CaptchaForm.spec.ts +82 -0
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +16 -42
- package/src/components/Captcha/types.ts +15 -0
- package/src/components/Captcha/useCaptchaValidation.ts +87 -0
- package/src/components/Captcha/validation/validation.stories.ts +1194 -0
- package/src/components/ChipList/ChipList.mdx +0 -1
- package/src/components/CollapsibleList/CollapsibleList.mdx +0 -1
- package/src/components/CookieBanner/CookieBanner.mdx +0 -1
- package/src/components/CopyBtn/CopyBtn.mdx +0 -1
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +123 -439
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +147 -41
- package/src/components/Customs/Selects/SelectBtnField/Validation/Validation.stories.ts +600 -0
- package/src/components/Customs/Selects/SelectBtnField/composables/useSelectBtnFieldValidation.ts +87 -0
- package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +402 -33
- package/src/components/Customs/Selects/SelectBtnField/tests/__snapshots__/SelectBtnField.spec.ts.snap +52 -38
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +342 -162
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +77 -129
- package/src/components/Customs/SyCheckBoxGroup/Validation/Validation.stories.ts +1008 -0
- package/src/components/Customs/SyCheckBoxGroup/composables/useSyCheckBoxGroupValidation.ts +107 -0
- package/src/components/Customs/SyCheckBoxGroup/tests/SyCheckBoxGroup.spec.ts +180 -7
- package/src/components/Customs/SyCheckBoxGroup/types.ts +49 -0
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +41 -161
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +71 -148
- package/src/components/Customs/SyCheckbox/Validation/Validation.stories.ts +654 -0
- package/src/components/Customs/SyCheckbox/composables/useSyCheckboxValidation.ts +105 -0
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +106 -0
- package/src/components/Customs/SyCheckbox/tests/useSyCheckboxValidation.spec.ts +98 -0
- package/src/components/Customs/SyCheckbox/types.ts +51 -0
- package/src/components/Customs/SyTextField/FieldState.vue +50 -0
- package/src/components/Customs/SyTextField/SyTextField.vue +12 -9
- package/src/components/Customs/SyTextField/useSyTextFieldValidation.ts +2 -11
- package/src/components/DataList/DataList.mdx +0 -1
- package/src/components/DataListGroup/DataListGroup.mdx +0 -1
- package/src/components/DiacriticPicker/DiacriticPicker.mdx +0 -1
- package/src/components/DialogBox/DialogBox.mdx +0 -1
- package/src/components/DialogBox/DialogBox.stories.ts +399 -4
- package/src/components/DialogBox/DialogBox.vue +20 -0
- package/src/components/DialogBox/locales.ts +1 -0
- package/src/components/DialogBox/tests/DialogBox.spec.ts +73 -0
- package/src/components/DialogBox/tests/DialogBox.visual.cy.ts +24 -0
- package/src/components/ErrorPage/ErrorPage.mdx +1 -1
- package/src/components/ExternalLinks/ExternalLinks.mdx +0 -1
- package/src/components/FileList/FileList.mdx +0 -1
- package/src/components/FilterInline/FilterInline.mdx +0 -1
- package/src/components/FilterSideBar/FilterSideBar.mdx +8 -1
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +133 -1
- package/src/components/FilterSideBar/FilterSideBar.vue +19 -2
- package/src/components/FilterSideBar/tests/FilterSideBar.spec.ts +55 -0
- package/src/components/FooterBar/FooterBar.mdx +0 -1
- package/src/components/FranceConnectBtn/FranceConnectBtn.mdx +0 -1
- package/src/components/HeaderBar/HeaderBar.mdx +0 -1
- package/src/components/HeaderLoading/HeaderLoading.mdx +0 -1
- package/src/components/LangBtn/LangBtn.mdx +0 -1
- package/src/components/Logo/Logo.mdx +1 -1
- package/src/components/LunarCalendar/LunarCalendar.mdx +6 -9
- package/src/components/LunarCalendar/LunarCalendar.stories.ts +243 -46
- package/src/components/LunarCalendar/LunarCalendar.vue +61 -26
- package/src/components/LunarCalendar/Validation/Validation.stories.ts +717 -0
- package/src/components/LunarCalendar/tests/LunarCalendar.a11y.spec.ts +1 -1
- package/src/components/LunarCalendar/tests/LunarCalendar.spec.ts +197 -6
- package/src/components/LunarCalendar/tests/useLunarCalendarValidation.spec.ts +287 -0
- package/src/components/LunarCalendar/types.ts +39 -0
- package/src/components/LunarCalendar/useLunarCalendarValidation.ts +115 -39
- package/src/components/MonthPicker/MonthPicker.stories.ts +38 -281
- package/src/components/MonthPicker/MonthPicker.vue +66 -17
- package/src/components/MonthPicker/MonthPickerText/MonthPickerInput.vue +44 -20
- package/src/components/MonthPicker/MonthPickerText/useTextField.ts +5 -0
- package/src/components/MonthPicker/Validation/Validation.stories.ts +1117 -0
- package/src/components/MonthPicker/locales.ts +1 -0
- package/src/components/MonthPicker/tests/MonthPicker.spec.ts +353 -2
- package/src/components/MonthPicker/tests/__snapshots__/MonthPicker.spec.ts.snap +12 -8
- package/src/components/MonthPicker/types.ts +16 -0
- package/src/components/MonthPicker/useMonthPickerValidation.ts +64 -27
- package/src/components/NirField/NirField.mdx +120 -66
- package/src/components/NirField/NirField.stories.ts +216 -0
- package/src/components/NirField/useNirValidation.ts +16 -17
- package/src/components/NotFoundPage/tests/__snapshots__/NotFoundPage.spec.ts.snap +263 -245
- package/src/components/NotificationBar/NotificationBar.mdx +0 -1
- package/src/components/PageContainer/PageContainer.mdx +0 -1
- package/src/components/PageContainer/PageContainer.stories.ts +170 -2
- package/src/components/PageContainer/PageContainer.vue +63 -8
- package/src/components/PageContainer/tests/__snapshots__/PageContainer.spec.ts.snap +19 -11
- package/src/components/PaginatedTable/PaginatedTable.mdx +0 -1
- package/src/components/PeriodField/PeriodField.mdx +0 -1
- package/src/components/PhoneField/PhoneField.mdx +2 -3
- package/src/components/PhoneField/PhoneField.stories.ts +227 -410
- package/src/components/PhoneField/PhoneField.vue +204 -438
- package/src/components/PhoneField/indicatifs.ts +1 -1
- package/src/components/PhoneField/locales.ts +7 -0
- package/src/components/PhoneField/tests/PhoneField.a11y.spec.ts +0 -1
- package/src/components/PhoneField/tests/PhoneField.spec.ts +517 -220
- package/src/components/PhoneField/types.ts +30 -0
- package/src/components/PhoneField/usePhoneFieldValidation.ts +119 -0
- package/src/components/PhoneField/usePhoneIndicatifs.ts +89 -0
- package/src/components/PhoneField/validation/validation.stories.ts +717 -0
- package/src/components/RangeField/RangeField.mdx +0 -1
- package/src/components/RatingPicker/RatingPicker.mdx +0 -1
- package/src/components/SocialMediaLinks/SocialMediaLinks.mdx +0 -1
- package/src/components/StatusPage/StatusPage.vue +1 -0
- package/src/components/StatusPage/tests/__snapshots__/StatusPage.spec.ts.snap +248 -230
- package/src/components/SubHeader/SubHeader.mdx +5 -6
- package/src/components/Tables/common/tests/SyTableFilter.spec.ts +11 -12
- package/src/components/UploadWorkflow/UploadWorkflow.mdx +0 -1
- package/src/components/UserMenuBtn/UserMenuBtn.mdx +0 -1
- package/src/components/UserMenuBtn/UserMenuBtn.stories.ts +177 -0
- package/src/composables/unifyValidation/documentationValidationProps.ts +1 -1
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +13 -1
- package/src/composables/unifyValidation/useValidation.ts +37 -33
- package/src/composantsVuetify/VCard/VCard.mdx +4 -0
- package/src/composantsVuetify/VCard/v-card.stories.ts +93 -1
- package/src/composantsVuetify/VCarousel/VCarousel.mdx +74 -0
- package/src/composantsVuetify/VCarousel/v-carousel.stories.ts +531 -0
- package/src/composantsVuetify/VNavigationDrawer/VNavgationDrawer.mdx +53 -0
- package/src/composantsVuetify/VNavigationDrawer/v-navigation-drawer.stories.ts +310 -0
- package/src/composantsVuetify/VSlideGroup/VSlideGroup.mdx +105 -0
- package/src/composantsVuetify/VSlideGroup/v-slide-group.stories.ts +463 -0
- package/src/designTokens/tokens/baseColors.ts +1 -1
- package/src/designTokens/tokens/baseTokens.ts +18 -18
- package/src/stories/Components/Components.stories.ts +34 -1
- package/src/stories/Demarrer/Releases.stories.ts +16 -2
- package/src/stories/DesignTokens/Arrondis.mdx +1 -1
- package/src/stories/DesignTokens/Correspondances.mdx +219 -0
- package/src/stories/DesignTokens/UtiliserLesTokens.mdx +235 -0
- package/src/stories/DesignTokens/colors.stories.ts +569 -569
- package/src/stories/GuideDuDev/Amelipro.stories.ts +335 -267
- package/dist/components/LunarCalendar/useLunarCalendarRules.d.ts +0 -5
- package/dist/components/PhoneField/tests/types.d.ts +0 -18
- package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +0 -184
- package/src/components/LunarCalendar/useLunarCalendarRules.ts +0 -96
- package/src/components/PhoneField/tests/types.d.ts +0 -19
|
@@ -1,7 +1,41 @@
|
|
|
1
|
-
import { mount, VueWrapper } from '@vue/test-utils'
|
|
1
|
+
import { mount as baseMount, VueWrapper } from '@vue/test-utils'
|
|
2
2
|
import PhoneField from '../PhoneField.vue'
|
|
3
3
|
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest'
|
|
4
4
|
import { indicatifs } from '../indicatifs'
|
|
5
|
+
import type { ComponentPublicInstance } from 'vue'
|
|
6
|
+
import { locales } from '../locales'
|
|
7
|
+
import SyForm from '@/components/Customs/SyForm/SyForm.vue'
|
|
8
|
+
|
|
9
|
+
interface PhoneFieldInstance extends ComponentPublicInstance {
|
|
10
|
+
phoneNumber: string
|
|
11
|
+
internalDialCode: { code: string, country: string, abbreviation: string, phoneLength: number, mask: string, displayText?: string }
|
|
12
|
+
dialCodeList: unknown[]
|
|
13
|
+
hasError: boolean
|
|
14
|
+
errors: string[]
|
|
15
|
+
validation: {
|
|
16
|
+
clearValidation: () => void
|
|
17
|
+
errors: string[]
|
|
18
|
+
warnings: string[]
|
|
19
|
+
successes: string[]
|
|
20
|
+
hasError: boolean
|
|
21
|
+
hasWarning: boolean
|
|
22
|
+
hasSuccess: boolean
|
|
23
|
+
}
|
|
24
|
+
validateOnSubmit: () => Promise<boolean>
|
|
25
|
+
phoneMask: string
|
|
26
|
+
clearValidation: () => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type IndicatifLike = {
|
|
30
|
+
code: string
|
|
31
|
+
country: string
|
|
32
|
+
abbreviation: string
|
|
33
|
+
phoneLength: number
|
|
34
|
+
mask: string
|
|
35
|
+
displayText?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const mount = (component: unknown, options?: Record<string, unknown>) => baseMount(component as never, options as never) as unknown as VueWrapper<PhoneFieldInstance>
|
|
5
39
|
|
|
6
40
|
describe('PhoneField', () => {
|
|
7
41
|
afterEach(() => {
|
|
@@ -18,7 +52,6 @@ describe('PhoneField', () => {
|
|
|
18
52
|
const input = wrapper.find('input')
|
|
19
53
|
await input.setValue('1234567890')
|
|
20
54
|
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
21
|
-
// change est émis au blur, pas à chaque frappe
|
|
22
55
|
await input.trigger('blur')
|
|
23
56
|
expect(wrapper.emitted('change')).toBeTruthy()
|
|
24
57
|
})
|
|
@@ -28,7 +61,7 @@ describe('PhoneField', () => {
|
|
|
28
61
|
props: {
|
|
29
62
|
required: true,
|
|
30
63
|
modelValue: '01 23 45 67 89',
|
|
31
|
-
|
|
64
|
+
isValidateOnBlur: true,
|
|
32
65
|
},
|
|
33
66
|
})
|
|
34
67
|
|
|
@@ -42,11 +75,13 @@ describe('PhoneField', () => {
|
|
|
42
75
|
props: {
|
|
43
76
|
required: true,
|
|
44
77
|
modelValue: '',
|
|
45
|
-
|
|
78
|
+
isValidateOnBlur: true,
|
|
79
|
+
showSuccessMessages: true,
|
|
46
80
|
},
|
|
47
81
|
})
|
|
48
82
|
|
|
49
83
|
const input = wrapper.find('input')
|
|
84
|
+
await input.trigger('focus')
|
|
50
85
|
await input.setValue('123456')
|
|
51
86
|
await input.trigger('blur')
|
|
52
87
|
|
|
@@ -59,7 +94,7 @@ describe('PhoneField', () => {
|
|
|
59
94
|
const wrapper = mount(PhoneField, {
|
|
60
95
|
props: {
|
|
61
96
|
withCountryCode: true,
|
|
62
|
-
|
|
97
|
+
isValidateOnBlur: false,
|
|
63
98
|
showSuccessMessages: true,
|
|
64
99
|
modelValue: '',
|
|
65
100
|
},
|
|
@@ -91,8 +126,7 @@ describe('PhoneField', () => {
|
|
|
91
126
|
},
|
|
92
127
|
})
|
|
93
128
|
|
|
94
|
-
wrapper.
|
|
95
|
-
await wrapper.vm.$nextTick()
|
|
129
|
+
await wrapper.setProps({ dialCodeModel: '+27' })
|
|
96
130
|
|
|
97
131
|
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
98
132
|
const input = textField.find('input')
|
|
@@ -112,8 +146,7 @@ describe('PhoneField', () => {
|
|
|
112
146
|
},
|
|
113
147
|
})
|
|
114
148
|
|
|
115
|
-
wrapper.
|
|
116
|
-
await wrapper.vm.$nextTick()
|
|
149
|
+
await wrapper.setProps({ dialCodeModel: '+27' })
|
|
117
150
|
|
|
118
151
|
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
119
152
|
expect(textField.props('counter')).toBe(9)
|
|
@@ -123,7 +156,8 @@ describe('PhoneField', () => {
|
|
|
123
156
|
const wrapper = mount(PhoneField, {
|
|
124
157
|
props: { modelValue: '0619123456' },
|
|
125
158
|
})
|
|
126
|
-
|
|
159
|
+
await wrapper.vm.$nextTick()
|
|
160
|
+
expect(wrapper.find('input').element.value).toBe('06 19 12 34 56')
|
|
127
161
|
})
|
|
128
162
|
|
|
129
163
|
it('renders SySelect when withCountryCode is true', () => {
|
|
@@ -133,61 +167,18 @@ describe('PhoneField', () => {
|
|
|
133
167
|
expect(wrapper.findComponent({ name: 'SySelect' }).exists()).toBe(true)
|
|
134
168
|
})
|
|
135
169
|
|
|
136
|
-
it('validates country code when countryCodeRequired is true', async () => {
|
|
137
|
-
const wrapper = mount(PhoneField, {
|
|
138
|
-
props: {
|
|
139
|
-
withCountryCode: true,
|
|
140
|
-
countryCodeRequired: true,
|
|
141
|
-
modelValue: '0123456789',
|
|
142
|
-
},
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
// Vider le code pays manuellement (France est sélectionnée par défaut)
|
|
146
|
-
wrapper.vm.dialCode = ''
|
|
147
|
-
await wrapper.vm.$nextTick()
|
|
148
|
-
|
|
149
|
-
const result = await wrapper.vm.validateOnSubmit()
|
|
150
|
-
|
|
151
|
-
expect(result).toBe(false)
|
|
152
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Nécessaire pour accéder à errors
|
|
153
|
-
expect((wrapper.vm as any).errors.length).toBeGreaterThan(0)
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Nécessaire pour accéder à errors
|
|
155
|
-
expect((wrapper.vm as any).errors[0]).toContain('est requis')
|
|
156
|
-
})
|
|
157
|
-
|
|
158
170
|
it('updates phone mask and counter when dialCode changes', async () => {
|
|
159
171
|
const wrapper = mount(PhoneField, {
|
|
160
172
|
props: { withCountryCode: true },
|
|
161
173
|
})
|
|
162
|
-
wrapper.
|
|
163
|
-
await wrapper.vm.$nextTick()
|
|
174
|
+
await wrapper.setProps({ dialCodeModel: '+1' })
|
|
164
175
|
// dialCode is normalized against the canonical indicatifs list by code
|
|
165
176
|
expect(wrapper.vm.phoneMask).toBe('### ### ####')
|
|
166
|
-
expect(wrapper.
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
it('validates phone number with country code on blur', async () => {
|
|
170
|
-
const wrapper = mount(PhoneField, {
|
|
171
|
-
props: {
|
|
172
|
-
required: true,
|
|
173
|
-
countryCodeRequired: true,
|
|
174
|
-
modelValue: '1234567890',
|
|
175
|
-
withCountryCode: true,
|
|
176
|
-
isValidatedOnBlur: true,
|
|
177
|
-
},
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
wrapper.vm.dialCode = { code: '+1', phoneLength: 10, mask: '###-###-####' }
|
|
181
|
-
await wrapper.vm.$nextTick()
|
|
182
|
-
|
|
183
|
-
const input = wrapper.find('input')
|
|
184
|
-
await input.trigger('blur')
|
|
185
|
-
|
|
186
|
-
expect(wrapper.vm.hasError).toBe(false)
|
|
177
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(10)
|
|
187
178
|
})
|
|
188
179
|
|
|
189
|
-
it('uses only custom indicatifs when useCustomIndicatifsOnly is true', () => {
|
|
190
|
-
const customIndicatifs = [{ code: '+99', abbreviation: 'XX', country: 'Testland', phoneLength: 10 }]
|
|
180
|
+
it('uses only custom indicatifs when useCustomIndicatifsOnly is true', async () => {
|
|
181
|
+
const customIndicatifs = [{ code: '+99', abbreviation: 'XX', country: 'Testland', phoneLength: 10, displayText: '+99' }]
|
|
191
182
|
const wrapper = mount(PhoneField, {
|
|
192
183
|
props: {
|
|
193
184
|
useCustomIndicatifsOnly: true,
|
|
@@ -195,27 +186,7 @@ describe('PhoneField', () => {
|
|
|
195
186
|
},
|
|
196
187
|
})
|
|
197
188
|
|
|
198
|
-
expect(wrapper.vm.
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
it('validates phone number with valid country code on blur', async () => {
|
|
202
|
-
const wrapper = mount(PhoneField, {
|
|
203
|
-
props: {
|
|
204
|
-
required: true,
|
|
205
|
-
countryCodeRequired: true,
|
|
206
|
-
modelValue: '1234567890',
|
|
207
|
-
withCountryCode: true,
|
|
208
|
-
isValidatedOnBlur: true,
|
|
209
|
-
},
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
wrapper.vm.dialCode = { code: '+1', phoneLength: 10, mask: '###-###-####' }
|
|
213
|
-
await wrapper.vm.$nextTick()
|
|
214
|
-
|
|
215
|
-
const input = wrapper.find('input')
|
|
216
|
-
await input.trigger('blur')
|
|
217
|
-
|
|
218
|
-
expect(wrapper.vm.hasError).toBe(false)
|
|
189
|
+
expect(wrapper.vm.dialCodeList).toEqual(customIndicatifs.map(ind => expect.objectContaining(ind)))
|
|
219
190
|
})
|
|
220
191
|
|
|
221
192
|
it('renders VTextField with outlined variant when outlined prop is true', () => {
|
|
@@ -252,8 +223,9 @@ describe('PhoneField', () => {
|
|
|
252
223
|
|
|
253
224
|
await wrapper.vm.$nextTick()
|
|
254
225
|
|
|
255
|
-
|
|
256
|
-
expect(
|
|
226
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
227
|
+
expect(select.exists()).toBe(true)
|
|
228
|
+
expect(typeof select.props('modelValue')).toBe('object')
|
|
257
229
|
|
|
258
230
|
type Indicatif = {
|
|
259
231
|
code: string
|
|
@@ -263,7 +235,7 @@ describe('PhoneField', () => {
|
|
|
263
235
|
mask: string
|
|
264
236
|
displayText?: string
|
|
265
237
|
}
|
|
266
|
-
const dialCode =
|
|
238
|
+
const dialCode = select.props('modelValue') as Indicatif
|
|
267
239
|
|
|
268
240
|
expect(dialCode.code).toBe('+33')
|
|
269
241
|
expect(dialCode.country).toBe('France')
|
|
@@ -275,74 +247,37 @@ describe('PhoneField', () => {
|
|
|
275
247
|
expect(typeof dialCode.displayText).toBe('string')
|
|
276
248
|
})
|
|
277
249
|
|
|
278
|
-
it('formats phone number correctly', () => {
|
|
250
|
+
it('formats phone number correctly', async () => {
|
|
279
251
|
const wrapper = mount(PhoneField, {
|
|
280
252
|
props: {
|
|
281
253
|
modelValue: '0123456789',
|
|
282
254
|
},
|
|
283
255
|
})
|
|
284
|
-
|
|
285
|
-
|
|
256
|
+
await wrapper.vm.$nextTick()
|
|
257
|
+
const input = wrapper.find('input')
|
|
258
|
+
expect(input.element.value).toBe('01 23 45 67 89')
|
|
286
259
|
})
|
|
287
260
|
|
|
288
|
-
it('emits update:
|
|
261
|
+
it('emits update:dialCodeModel when dialCode changes', async () => {
|
|
289
262
|
const wrapper = mount(PhoneField, {
|
|
290
263
|
props: {
|
|
291
264
|
withCountryCode: true,
|
|
292
265
|
},
|
|
293
266
|
})
|
|
294
267
|
|
|
295
|
-
|
|
296
|
-
wrapper.vm.dialCode = dialCodeValue
|
|
297
|
-
await wrapper.vm.$nextTick()
|
|
268
|
+
await wrapper.setProps({ dialCodeModel: '+34' })
|
|
298
269
|
|
|
299
|
-
expect(wrapper.emitted('update:
|
|
300
|
-
const emittedEvents = wrapper.emitted('update:
|
|
270
|
+
expect(wrapper.emitted('update:dialCodeModel')).toBeTruthy()
|
|
271
|
+
const emittedEvents = wrapper.emitted('update:dialCodeModel')
|
|
301
272
|
const lastEmitted = emittedEvents && emittedEvents[emittedEvents.length - 1]?.[0]
|
|
302
|
-
expect(lastEmitted).toHaveProperty('code',
|
|
303
|
-
})
|
|
304
|
-
|
|
305
|
-
it('validates phone number on submit', async () => {
|
|
306
|
-
const wrapper = mount(PhoneField, {
|
|
307
|
-
props: {
|
|
308
|
-
required: true,
|
|
309
|
-
modelValue: '',
|
|
310
|
-
},
|
|
311
|
-
})
|
|
312
|
-
|
|
313
|
-
const result = await wrapper.vm.validateOnSubmit()
|
|
314
|
-
console.log('Validation result:', result)
|
|
315
|
-
|
|
316
|
-
expect(result).toBe(false)
|
|
317
|
-
expect(wrapper.vm.hasError).toBe(true)
|
|
318
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Nécessaire pour accéder à errors
|
|
319
|
-
expect((wrapper.vm as any).errors.length).toBeGreaterThan(0)
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
it('validates phone number successfully on submit with valid input', async () => {
|
|
323
|
-
const wrapper = mount(PhoneField, {
|
|
324
|
-
props: {
|
|
325
|
-
required: true,
|
|
326
|
-
modelValue: '0123456789',
|
|
327
|
-
},
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
const result = await wrapper.vm.validateOnSubmit()
|
|
331
|
-
|
|
332
|
-
expect(result).toBe(true)
|
|
333
|
-
expect(wrapper.vm.hasError).toBe(false)
|
|
273
|
+
expect(lastEmitted).toHaveProperty('code', '+34')
|
|
334
274
|
})
|
|
335
275
|
|
|
336
276
|
it('exposes necessary properties and methods', () => {
|
|
337
277
|
const wrapper = mount(PhoneField)
|
|
338
278
|
|
|
339
|
-
expect(wrapper.vm.computedValue).toBeDefined()
|
|
340
|
-
expect(wrapper.vm.dialCode).toBeDefined()
|
|
341
279
|
expect(wrapper.vm.phoneMask).toBeDefined()
|
|
342
|
-
expect(wrapper.vm.
|
|
343
|
-
expect(wrapper.vm.hasError).toBeDefined()
|
|
344
|
-
expect(wrapper.vm.phoneNumber).toBeDefined()
|
|
345
|
-
expect(wrapper.vm.mergedDialCodes).toBeDefined()
|
|
280
|
+
expect(wrapper.vm.dialCodeList).toBeDefined()
|
|
346
281
|
expect(wrapper.vm.validation).toBeDefined()
|
|
347
282
|
expect(wrapper.vm.validateOnSubmit).toBeDefined()
|
|
348
283
|
})
|
|
@@ -355,13 +290,14 @@ describe('PhoneField', () => {
|
|
|
355
290
|
},
|
|
356
291
|
})
|
|
357
292
|
|
|
358
|
-
expect(wrapper.
|
|
359
|
-
|
|
360
|
-
|
|
293
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(10)
|
|
294
|
+
await wrapper.setProps({
|
|
295
|
+
dialCodeModel: { code: '+44', abbreviation: 'UK', country: 'United Kingdom', phoneLength: 11, mask: '### ### #####' },
|
|
296
|
+
})
|
|
361
297
|
await wrapper.vm.$nextTick()
|
|
362
298
|
|
|
363
|
-
//
|
|
364
|
-
expect(wrapper.
|
|
299
|
+
// In the indicatifs list, +44 is associed with phoneLength 10
|
|
300
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(10)
|
|
365
301
|
})
|
|
366
302
|
|
|
367
303
|
it('handles disabled state correctly', async () => {
|
|
@@ -394,27 +330,62 @@ describe('PhoneField', () => {
|
|
|
394
330
|
expect(select.props('readonly')).toBe(true)
|
|
395
331
|
})
|
|
396
332
|
|
|
397
|
-
it('
|
|
333
|
+
it('forwards hideDetails prop to SyTextField', () => {
|
|
398
334
|
const wrapper = mount(PhoneField, {
|
|
399
335
|
props: {
|
|
400
|
-
|
|
401
|
-
|
|
336
|
+
hideDetails: true,
|
|
337
|
+
},
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
341
|
+
expect(textField.props('hideDetails')).toBe(true)
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
it('shows and handles clear button when isClearable is true', async () => {
|
|
345
|
+
const wrapper = mount(PhoneField, {
|
|
346
|
+
props: {
|
|
347
|
+
isClearable: true,
|
|
348
|
+
modelValue: '0123456789',
|
|
402
349
|
},
|
|
403
350
|
})
|
|
404
351
|
|
|
405
352
|
await wrapper.vm.$nextTick()
|
|
406
353
|
|
|
407
|
-
|
|
408
|
-
expect(
|
|
354
|
+
const clearButton = wrapper.find(`button[aria-label="${locales.clearButtonAriaLabel}"]`)
|
|
355
|
+
expect(clearButton.exists()).toBe(true)
|
|
356
|
+
|
|
357
|
+
await clearButton.trigger('click')
|
|
358
|
+
await wrapper.vm.$nextTick()
|
|
359
|
+
|
|
360
|
+
expect(wrapper.vm.phoneNumber).toBe('')
|
|
361
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
362
|
+
expect(wrapper.emitted('update:modelValue')?.at(-1)?.[0]).toBe('')
|
|
363
|
+
|
|
364
|
+
await wrapper.setProps({ isClearable: false, modelValue: '0123456789' })
|
|
365
|
+
await wrapper.vm.$nextTick()
|
|
366
|
+
expect(wrapper.find(`button[aria-label="${locales.clearButtonAriaLabel}"]`).exists()).toBe(false)
|
|
367
|
+
})
|
|
409
368
|
|
|
369
|
+
it('verifies SyTextField and SySelect props are correctly passed', async () => {
|
|
370
|
+
const wrapper = mount(PhoneField, {
|
|
371
|
+
props: {
|
|
372
|
+
withCountryCode: true,
|
|
373
|
+
dialCodeModel: { code: '+33', abbreviation: 'FR', country: 'France', phoneLength: 10, mask: '## ## ## ## ##' },
|
|
374
|
+
},
|
|
375
|
+
})
|
|
376
|
+
|
|
377
|
+
const phoneInput = wrapper.find<HTMLInputElement>('input[type="tel"]')
|
|
378
|
+
await phoneInput.setValue('0123456789')
|
|
379
|
+
expect(phoneInput.element.value).toBe('01 23 45 67 89')
|
|
410
380
|
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
381
|
+
|
|
411
382
|
expect(textField.exists()).toBe(true)
|
|
412
383
|
expect(textField.props('counter')).toBe(10)
|
|
413
384
|
|
|
414
385
|
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
415
386
|
expect(select.exists()).toBe(true)
|
|
416
387
|
expect(select.props('returnObject')).toBe(true)
|
|
417
|
-
expect(select.props('modelValue')).
|
|
388
|
+
expect((select.props('modelValue') as IndicatifLike).code).toBe('+33')
|
|
418
389
|
})
|
|
419
390
|
|
|
420
391
|
it('updates dialCode when dialCodeModel changes after mount', async () => {
|
|
@@ -425,7 +396,7 @@ describe('PhoneField', () => {
|
|
|
425
396
|
})
|
|
426
397
|
|
|
427
398
|
// France est sélectionnée par défaut quand withCountryCode=true
|
|
428
|
-
expect(wrapper.
|
|
399
|
+
expect((wrapper.findComponent({ name: 'SySelect' }).props('modelValue') as IndicatifLike).code).toBe('+33')
|
|
429
400
|
|
|
430
401
|
await wrapper.setProps({
|
|
431
402
|
dialCodeModel: { code: '+1', country: 'USA', abbreviation: 'US', phoneLength: 10, mask: '###-###-####' },
|
|
@@ -433,8 +404,9 @@ describe('PhoneField', () => {
|
|
|
433
404
|
|
|
434
405
|
await wrapper.vm.$nextTick()
|
|
435
406
|
|
|
436
|
-
|
|
437
|
-
expect(
|
|
407
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
408
|
+
expect(select.exists()).toBe(true)
|
|
409
|
+
expect(typeof select.props('modelValue')).toBe('object')
|
|
438
410
|
|
|
439
411
|
type Indicatif = {
|
|
440
412
|
code: string
|
|
@@ -444,12 +416,12 @@ describe('PhoneField', () => {
|
|
|
444
416
|
mask: string
|
|
445
417
|
displayText?: string
|
|
446
418
|
}
|
|
447
|
-
const dialCode =
|
|
419
|
+
const dialCode = select.props('modelValue') as Indicatif
|
|
448
420
|
|
|
449
421
|
expect(dialCode.code).toBe('+1')
|
|
450
422
|
expect(dialCode.country).toBe('USA/Canada')
|
|
451
423
|
expect(wrapper.vm.phoneMask).toBe('### ### ####')
|
|
452
|
-
expect(wrapper.
|
|
424
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(10)
|
|
453
425
|
})
|
|
454
426
|
|
|
455
427
|
it('handles dialCodeModel objects without displayText property', async () => {
|
|
@@ -470,7 +442,8 @@ describe('PhoneField', () => {
|
|
|
470
442
|
|
|
471
443
|
await wrapper.vm.$nextTick()
|
|
472
444
|
|
|
473
|
-
|
|
445
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
446
|
+
expect(select.exists()).toBe(true)
|
|
474
447
|
|
|
475
448
|
type Indicatif = {
|
|
476
449
|
code: string
|
|
@@ -480,7 +453,7 @@ describe('PhoneField', () => {
|
|
|
480
453
|
mask: string
|
|
481
454
|
displayText?: string
|
|
482
455
|
}
|
|
483
|
-
const dialCode =
|
|
456
|
+
const dialCode = select.props('modelValue') as Indicatif
|
|
484
457
|
|
|
485
458
|
expect(dialCode.code).toBe('+44')
|
|
486
459
|
expect(dialCode.country).toBe('United Kingdom')
|
|
@@ -559,7 +532,7 @@ describe('PhoneField', () => {
|
|
|
559
532
|
expect(phoneInput.attributes('autocomplete')).toBe('tel-national')
|
|
560
533
|
|
|
561
534
|
// Check that country code select has default tel-country-code autocomplete
|
|
562
|
-
const selectInput = wrapper.find('.
|
|
535
|
+
const selectInput = wrapper.find('.dial-code-select input')
|
|
563
536
|
expect(selectInput.attributes('autocomplete')).toBe('tel-country-code')
|
|
564
537
|
})
|
|
565
538
|
|
|
@@ -580,7 +553,7 @@ describe('PhoneField', () => {
|
|
|
580
553
|
expect(phoneInput.attributes('autocomplete')).toBe('tel-extension')
|
|
581
554
|
|
|
582
555
|
// Check that country code select has custom autocomplete
|
|
583
|
-
const selectInput = wrapper.find('.
|
|
556
|
+
const selectInput = wrapper.find('.dial-code-select input')
|
|
584
557
|
expect(selectInput.attributes('autocomplete')).toBe('tel-country-code')
|
|
585
558
|
})
|
|
586
559
|
|
|
@@ -603,7 +576,7 @@ describe('PhoneField', () => {
|
|
|
603
576
|
expect(telAutocomplete).toBe('tel-national')
|
|
604
577
|
|
|
605
578
|
// Verify country select input has correct autocomplete
|
|
606
|
-
const selectInput = wrapper.find('.
|
|
579
|
+
const selectInput = wrapper.find('.dial-code-select input')
|
|
607
580
|
expect(selectInput.exists()).toBe(true)
|
|
608
581
|
const selectAutocomplete = selectInput.attributes('autocomplete')
|
|
609
582
|
expect(selectAutocomplete).toBe('tel-country-code')
|
|
@@ -625,7 +598,7 @@ describe('PhoneField', () => {
|
|
|
625
598
|
expect(phoneInput.attributes('autocomplete')).toBe('tel')
|
|
626
599
|
|
|
627
600
|
// Check that country code select doesn't exist
|
|
628
|
-
const selectInput = wrapper.find('.
|
|
601
|
+
const selectInput = wrapper.find('.dial-code-select input')
|
|
629
602
|
expect(selectInput.exists()).toBe(false)
|
|
630
603
|
})
|
|
631
604
|
|
|
@@ -642,7 +615,8 @@ describe('PhoneField', () => {
|
|
|
642
615
|
|
|
643
616
|
await wrapper.vm.$nextTick()
|
|
644
617
|
|
|
645
|
-
|
|
618
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
619
|
+
expect(select.exists()).toBe(true)
|
|
646
620
|
|
|
647
621
|
type Indicatif = {
|
|
648
622
|
code: string
|
|
@@ -652,50 +626,17 @@ describe('PhoneField', () => {
|
|
|
652
626
|
mask: string
|
|
653
627
|
displayText?: string
|
|
654
628
|
}
|
|
655
|
-
const dialCode =
|
|
629
|
+
const dialCode = select.props('modelValue') as Indicatif
|
|
656
630
|
|
|
657
631
|
expect(dialCode.code).toBe('+33')
|
|
658
632
|
expect(dialCode.country).toBe('France')
|
|
659
633
|
|
|
660
|
-
|
|
661
|
-
expect(select.exists()).toBe(true)
|
|
662
|
-
expect(select.props('modelValue')).toEqual(wrapper.vm.dialCode)
|
|
663
|
-
})
|
|
664
|
-
|
|
665
|
-
it('disables error handling when readonly is true', async () => {
|
|
666
|
-
const wrapper = mount(PhoneField, {
|
|
667
|
-
props: {
|
|
668
|
-
required: true,
|
|
669
|
-
modelValue: '',
|
|
670
|
-
readonly: true,
|
|
671
|
-
},
|
|
672
|
-
})
|
|
673
|
-
|
|
674
|
-
expect(wrapper.props('readonly')).toBe(true)
|
|
675
|
-
|
|
676
|
-
const isValid = await wrapper.vm.validateOnSubmit()
|
|
677
|
-
|
|
678
|
-
expect(isValid).toBe(true)
|
|
679
|
-
|
|
680
|
-
expect(wrapper.vm.hasError).toBe(false)
|
|
681
|
-
const wrapperNotReadonly = mount(PhoneField, {
|
|
682
|
-
props: {
|
|
683
|
-
required: true,
|
|
684
|
-
modelValue: '',
|
|
685
|
-
readonly: false,
|
|
686
|
-
},
|
|
687
|
-
})
|
|
688
|
-
|
|
689
|
-
const isValidNotReadonly = await wrapperNotReadonly.vm.validateOnSubmit()
|
|
690
|
-
|
|
691
|
-
expect(isValidNotReadonly).toBe(false)
|
|
692
|
-
|
|
693
|
-
expect(wrapperNotReadonly.vm.hasError).toBe(true)
|
|
634
|
+
expect(select.props('modelValue')).toEqual(expect.objectContaining({ code: '+33' }))
|
|
694
635
|
})
|
|
695
636
|
|
|
696
637
|
// Tests pour les formats d'affichage avec abréviations encapsulées
|
|
697
638
|
describe('Display formats with abbreviations', () => {
|
|
698
|
-
let wrapper: VueWrapper<
|
|
639
|
+
let wrapper: VueWrapper<PhoneFieldInstance>
|
|
699
640
|
|
|
700
641
|
beforeEach(() => {
|
|
701
642
|
wrapper = mount(PhoneField, {
|
|
@@ -743,6 +684,72 @@ describe('PhoneField', () => {
|
|
|
743
684
|
const expectedCountry = firstItem.countryFr || firstItem.country
|
|
744
685
|
expect(firstItem.displayText).toBe(`<abbr title="${expectedCountry}">${firstItem.abbreviation}</abbr>`)
|
|
745
686
|
})
|
|
687
|
+
|
|
688
|
+
it('escapes HTML special characters in country name and abbreviation for code-abbreviation format', async () => {
|
|
689
|
+
const maliciousIndicatif = {
|
|
690
|
+
code: '+99',
|
|
691
|
+
country: 'Bad"Country<script>',
|
|
692
|
+
abbreviation: 'B&D',
|
|
693
|
+
phoneLength: 10,
|
|
694
|
+
mask: '## ## ## ##',
|
|
695
|
+
}
|
|
696
|
+
await wrapper.setProps({
|
|
697
|
+
displayFormat: 'code-abbreviation',
|
|
698
|
+
customIndicatifs: [maliciousIndicatif],
|
|
699
|
+
useCustomIndicatifsOnly: true,
|
|
700
|
+
})
|
|
701
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
702
|
+
const item = select.props('items')[0]
|
|
703
|
+
expect(item.displayText).not.toContain('<script>')
|
|
704
|
+
expect(item.displayText).not.toContain('"Country')
|
|
705
|
+
expect(item.displayText).toContain('"Country')
|
|
706
|
+
expect(item.displayText).toContain('<')
|
|
707
|
+
expect(item.displayText).toContain('&')
|
|
708
|
+
expect(item.plainDisplayText).toBe(`${maliciousIndicatif.code} (${maliciousIndicatif.abbreviation})`)
|
|
709
|
+
})
|
|
710
|
+
|
|
711
|
+
it('escapes HTML special characters in country name and abbreviation for abbreviation format', async () => {
|
|
712
|
+
const maliciousIndicatif = {
|
|
713
|
+
code: '+99',
|
|
714
|
+
country: 'Evil<img src=x onerror=alert(1)>',
|
|
715
|
+
abbreviation: '<XSS>',
|
|
716
|
+
phoneLength: 10,
|
|
717
|
+
mask: '## ## ## ##',
|
|
718
|
+
}
|
|
719
|
+
await wrapper.setProps({
|
|
720
|
+
displayFormat: 'abbreviation',
|
|
721
|
+
customIndicatifs: [maliciousIndicatif],
|
|
722
|
+
useCustomIndicatifsOnly: true,
|
|
723
|
+
})
|
|
724
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
725
|
+
const item = select.props('items')[0]
|
|
726
|
+
expect(item.displayText).not.toContain('<img')
|
|
727
|
+
expect(item.displayText).not.toContain('<XSS>')
|
|
728
|
+
expect(item.displayText).toContain('<XSS>')
|
|
729
|
+
expect(item.displayText).toContain('<img')
|
|
730
|
+
expect(item.plainDisplayText).toBe(maliciousIndicatif.abbreviation)
|
|
731
|
+
})
|
|
732
|
+
|
|
733
|
+
it('escapes HTML in country name for non-abbreviation formats (code-country, country)', async () => {
|
|
734
|
+
const maliciousIndicatif = {
|
|
735
|
+
code: '+99',
|
|
736
|
+
country: '<img src=x onerror=alert(1)>',
|
|
737
|
+
abbreviation: 'XX',
|
|
738
|
+
phoneLength: 10,
|
|
739
|
+
mask: '## ## ## ##',
|
|
740
|
+
}
|
|
741
|
+
for (const format of ['code-country', 'country'] as const) {
|
|
742
|
+
await wrapper.setProps({
|
|
743
|
+
displayFormat: format,
|
|
744
|
+
customIndicatifs: [maliciousIndicatif],
|
|
745
|
+
useCustomIndicatifsOnly: true,
|
|
746
|
+
})
|
|
747
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
748
|
+
const item = select.props('items')[0]
|
|
749
|
+
expect(item.displayText).not.toContain('<img')
|
|
750
|
+
expect(item.displayText).toContain('<img')
|
|
751
|
+
}
|
|
752
|
+
})
|
|
746
753
|
})
|
|
747
754
|
|
|
748
755
|
// Tests pour l'initialisation avec un dialCode par défaut
|
|
@@ -757,15 +764,16 @@ describe('PhoneField', () => {
|
|
|
757
764
|
})
|
|
758
765
|
|
|
759
766
|
await wrapper.vm.$nextTick()
|
|
767
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
760
768
|
|
|
761
769
|
// Vérifier que le dialCode est correctement initialisé
|
|
762
|
-
expect(
|
|
770
|
+
expect(select.exists()).toBe(true)
|
|
763
771
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
764
|
-
expect((
|
|
772
|
+
expect((select.props('modelValue') as any).code).toBe('+44')
|
|
765
773
|
// Vérifier que le masque est appliqué (le format exact peut varier)
|
|
766
774
|
expect(wrapper.vm.phoneMask).toBeDefined()
|
|
767
775
|
// Vérifier que le counter est défini selon la phoneLength
|
|
768
|
-
expect(wrapper.
|
|
776
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBeDefined()
|
|
769
777
|
})
|
|
770
778
|
|
|
771
779
|
it('initializes with a default dialCode string', async () => {
|
|
@@ -777,32 +785,162 @@ describe('PhoneField', () => {
|
|
|
777
785
|
})
|
|
778
786
|
|
|
779
787
|
await wrapper.vm.$nextTick()
|
|
788
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
780
789
|
|
|
781
790
|
// Vérifier que le dialCode est correctement initialisé
|
|
782
|
-
expect(
|
|
791
|
+
expect(select.props('modelValue')).toEqual(expect.objectContaining({ code: '+33' }))
|
|
783
792
|
})
|
|
784
793
|
})
|
|
785
794
|
|
|
786
|
-
// Tests
|
|
787
|
-
describe('
|
|
795
|
+
// Tests de validation
|
|
796
|
+
describe('Validation', () => {
|
|
797
|
+
it('cleans spaces from phone number before validation', async () => {
|
|
798
|
+
const wrapper = mount(PhoneField, {
|
|
799
|
+
props: {
|
|
800
|
+
required: true,
|
|
801
|
+
modelValue: '01 23 45 67 89',
|
|
802
|
+
},
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
const isValid = await wrapper.vm.validateOnSubmit()
|
|
806
|
+
expect(isValid).toBe(true)
|
|
807
|
+
expect(wrapper.vm.hasError).toBe(false)
|
|
808
|
+
})
|
|
809
|
+
|
|
810
|
+
it('validates phone number and country code on blur', async () => {
|
|
811
|
+
const wrapper = mount(PhoneField, {
|
|
812
|
+
props: {
|
|
813
|
+
required: true,
|
|
814
|
+
modelValue: '12345',
|
|
815
|
+
isValidateOnBlur: true,
|
|
816
|
+
},
|
|
817
|
+
})
|
|
818
|
+
|
|
819
|
+
const input = wrapper.find('input')
|
|
820
|
+
await input.trigger('focus')
|
|
821
|
+
await input.trigger('blur')
|
|
822
|
+
await wrapper.vm.$nextTick()
|
|
823
|
+
|
|
824
|
+
expect(wrapper.vm.hasError).toBe(true)
|
|
825
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required to access errors
|
|
826
|
+
expect((wrapper.vm as any).errors[0]).toContain(locales.errorLength(10))
|
|
827
|
+
})
|
|
828
|
+
|
|
829
|
+
it('keeps a consistent success message before and after blur when withCountryCode is true', async () => {
|
|
830
|
+
const wrapper = mount(PhoneField, {
|
|
831
|
+
props: {
|
|
832
|
+
withCountryCode: true,
|
|
833
|
+
isValidateOnBlur: false,
|
|
834
|
+
modelValue: '',
|
|
835
|
+
showSuccessMessages: true,
|
|
836
|
+
},
|
|
837
|
+
})
|
|
838
|
+
|
|
839
|
+
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
840
|
+
const input = textField.find('input')
|
|
841
|
+
await input.setValue('0123456789')
|
|
842
|
+
await wrapper.vm.$nextTick()
|
|
843
|
+
|
|
844
|
+
const messageBeforeBlur = textField.find('.v-messages__message')
|
|
845
|
+
expect(messageBeforeBlur.exists()).toBe(true)
|
|
846
|
+
expect(messageBeforeBlur.text()).toBe('Le champ Numéro de téléphone sans indicatif est valide.')
|
|
847
|
+
expect(messageBeforeBlur.text()).not.toBe('Le champ Numéro de téléphone est valide.')
|
|
848
|
+
|
|
849
|
+
await input.trigger('blur')
|
|
850
|
+
await wrapper.vm.$nextTick()
|
|
851
|
+
|
|
852
|
+
const messageAfterBlur = textField.find('.v-messages__message')
|
|
853
|
+
expect(messageAfterBlur.exists()).toBe(true)
|
|
854
|
+
expect(messageAfterBlur.text()).toBe('Le champ Numéro de téléphone sans indicatif est valide.')
|
|
855
|
+
})
|
|
856
|
+
|
|
857
|
+
it('falls back to default country code when provided code is invalid', async () => {
|
|
858
|
+
const wrapper = mount(PhoneField, {
|
|
859
|
+
props: {
|
|
860
|
+
withCountryCode: true,
|
|
861
|
+
modelValue: '0123456789',
|
|
862
|
+
dialCodeModel: '+9999',
|
|
863
|
+
},
|
|
864
|
+
})
|
|
865
|
+
|
|
866
|
+
const result = await wrapper.vm.validateOnSubmit()
|
|
867
|
+
|
|
868
|
+
expect(result).toBe(true)
|
|
869
|
+
expect((wrapper.findComponent({ name: 'SySelect' }).props('modelValue') as IndicatifLike).code).toBe('+33')
|
|
870
|
+
})
|
|
871
|
+
|
|
872
|
+
it('validates phone number on submit', async () => {
|
|
873
|
+
const wrapper = mount(PhoneField, {
|
|
874
|
+
props: {
|
|
875
|
+
required: true,
|
|
876
|
+
modelValue: '',
|
|
877
|
+
},
|
|
878
|
+
})
|
|
879
|
+
|
|
880
|
+
const result = await wrapper.vm.validateOnSubmit()
|
|
881
|
+
|
|
882
|
+
expect(result).toBe(false)
|
|
883
|
+
expect(wrapper.vm.hasError).toBe(true)
|
|
884
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required to access errors
|
|
885
|
+
expect((wrapper.vm as any).errors.length).toBeGreaterThan(0)
|
|
886
|
+
})
|
|
887
|
+
|
|
888
|
+
it('validates phone number successfully on submit with valid input', async () => {
|
|
889
|
+
const wrapper = mount(PhoneField, {
|
|
890
|
+
props: {
|
|
891
|
+
required: true,
|
|
892
|
+
modelValue: '0123456789',
|
|
893
|
+
},
|
|
894
|
+
})
|
|
895
|
+
|
|
896
|
+
const result = await wrapper.vm.validateOnSubmit()
|
|
897
|
+
|
|
898
|
+
expect(result).toBe(true)
|
|
899
|
+
expect(wrapper.vm.hasError).toBe(false)
|
|
900
|
+
})
|
|
901
|
+
|
|
902
|
+
it('disables error handling when readonly is true', async () => {
|
|
903
|
+
const wrapper = mount(PhoneField, {
|
|
904
|
+
props: {
|
|
905
|
+
required: true,
|
|
906
|
+
modelValue: '',
|
|
907
|
+
readonly: true,
|
|
908
|
+
},
|
|
909
|
+
})
|
|
910
|
+
|
|
911
|
+
const isValid = await wrapper.vm.validateOnSubmit()
|
|
912
|
+
|
|
913
|
+
expect(isValid).toBe(true)
|
|
914
|
+
expect(wrapper.vm.hasError).toBe(false)
|
|
915
|
+
|
|
916
|
+
const wrapperNotReadonly = mount(PhoneField, {
|
|
917
|
+
props: {
|
|
918
|
+
required: true,
|
|
919
|
+
modelValue: '',
|
|
920
|
+
readonly: false,
|
|
921
|
+
},
|
|
922
|
+
})
|
|
923
|
+
|
|
924
|
+
const isValidNotReadonly = await wrapperNotReadonly.vm.validateOnSubmit()
|
|
925
|
+
expect(isValidNotReadonly).toBe(false)
|
|
926
|
+
expect(wrapperNotReadonly.vm.hasError).toBe(true)
|
|
927
|
+
})
|
|
928
|
+
|
|
788
929
|
it('displays error messages by default when validation fails', async () => {
|
|
789
930
|
const wrapper = mount(PhoneField, {
|
|
790
931
|
props: {
|
|
791
932
|
required: true,
|
|
792
933
|
modelValue: '',
|
|
793
|
-
|
|
934
|
+
isValidateOnBlur: true,
|
|
794
935
|
},
|
|
795
936
|
})
|
|
796
937
|
|
|
797
|
-
// Déclencher la validation
|
|
798
938
|
await wrapper.vm.validateOnSubmit()
|
|
799
939
|
|
|
800
|
-
// Vérifier que les erreurs sont affichées
|
|
801
940
|
expect(wrapper.vm.hasError).toBe(true)
|
|
802
941
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- This is a generic type
|
|
803
942
|
expect((wrapper.vm as any).errors.length).toBeGreaterThan(0)
|
|
804
943
|
|
|
805
|
-
// Vérifier que les erreurs sont passées au composant SyTextField
|
|
806
944
|
const textField = wrapper.findComponent({ name: 'SyTextField' })
|
|
807
945
|
expect(textField.props('errorMessages')).toBeTruthy()
|
|
808
946
|
})
|
|
@@ -812,19 +950,14 @@ describe('PhoneField', () => {
|
|
|
812
950
|
props: {
|
|
813
951
|
required: true,
|
|
814
952
|
modelValue: '',
|
|
815
|
-
|
|
953
|
+
isValidateOnBlur: true,
|
|
816
954
|
disableErrorHandling: true,
|
|
817
955
|
},
|
|
818
956
|
})
|
|
819
957
|
|
|
820
|
-
// Vérifier que la propriété disableErrorHandling est bien prise en compte
|
|
821
|
-
// en vérifiant qu'elle est passée lors de l'initialisation du composable useValidation
|
|
822
958
|
expect(wrapper.vm.validation).toBeDefined()
|
|
823
959
|
})
|
|
824
|
-
})
|
|
825
960
|
|
|
826
|
-
// Tests pour la validation dans un contexte de formulaire
|
|
827
|
-
describe('Form validation', () => {
|
|
828
961
|
it('validates as part of a form submission', async () => {
|
|
829
962
|
const wrapper = mount(PhoneField, {
|
|
830
963
|
props: {
|
|
@@ -833,11 +966,9 @@ describe('PhoneField', () => {
|
|
|
833
966
|
},
|
|
834
967
|
})
|
|
835
968
|
|
|
836
|
-
// Simuler une soumission de formulaire avec un champ vide
|
|
837
969
|
const isValid = await wrapper.vm.validateOnSubmit()
|
|
838
970
|
expect(isValid).toBe(false)
|
|
839
971
|
|
|
840
|
-
// Mettre à jour la valeur et valider à nouveau
|
|
841
972
|
await wrapper.setProps({ modelValue: '0123456789' })
|
|
842
973
|
const isValidAfterUpdate = await wrapper.vm.validateOnSubmit()
|
|
843
974
|
expect(isValidAfterUpdate).toBe(true)
|
|
@@ -847,27 +978,129 @@ describe('PhoneField', () => {
|
|
|
847
978
|
const wrapper = mount(PhoneField, {
|
|
848
979
|
props: {
|
|
849
980
|
required: true,
|
|
850
|
-
modelValue: '
|
|
981
|
+
modelValue: '012',
|
|
982
|
+
dialCodeModel: { code: 'test', abbreviation: 'TEST', country: 'Test', phoneLength: 3, mask: '###' },
|
|
983
|
+
customIndicatifs: [{ code: 'test', abbreviation: 'TEST', country: 'Test', phoneLength: 3, mask: '###' }],
|
|
851
984
|
withCountryCode: true,
|
|
852
|
-
countryCodeRequired: true,
|
|
853
985
|
},
|
|
854
986
|
})
|
|
855
987
|
|
|
856
|
-
// Vider le code pays manuellement (France est sélectionnée par défaut)
|
|
857
|
-
wrapper.vm.dialCode = ''
|
|
858
988
|
await wrapper.vm.$nextTick()
|
|
859
989
|
|
|
860
|
-
// Sans code pays, la validation échoue
|
|
861
990
|
const isValidWithoutCountry = await wrapper.vm.validateOnSubmit()
|
|
862
|
-
expect(isValidWithoutCountry).toBe(
|
|
991
|
+
expect(isValidWithoutCountry).toBe(true)
|
|
863
992
|
|
|
864
|
-
// Ajouter un code pays et valider à nouveau
|
|
865
|
-
wrapper.vm.dialCode = { code: '+33', abbreviation: 'FR', country: 'France', phoneLength: 10, mask: '## ## ## ## ##' }
|
|
866
993
|
await wrapper.vm.$nextTick()
|
|
867
994
|
|
|
868
995
|
const isValidWithCountry = await wrapper.vm.validateOnSubmit()
|
|
869
996
|
expect(isValidWithCountry).toBe(true)
|
|
870
997
|
})
|
|
998
|
+
|
|
999
|
+
describe('Validation with SyForm', () => {
|
|
1000
|
+
it('validates as part of SyForm submission', async () => {
|
|
1001
|
+
const wrapper = baseMount({
|
|
1002
|
+
components: { PhoneField, SyForm },
|
|
1003
|
+
template: `
|
|
1004
|
+
<SyForm>
|
|
1005
|
+
<PhoneField with-country-code required />
|
|
1006
|
+
<button type="submit">Submit</button>
|
|
1007
|
+
</SyForm>
|
|
1008
|
+
`,
|
|
1009
|
+
})
|
|
1010
|
+
|
|
1011
|
+
const syForm = wrapper.findComponent(SyForm)
|
|
1012
|
+
const form = syForm.vm as unknown as { validate: () => Promise<boolean> }
|
|
1013
|
+
const isValidWithoutPhone = await form.validate()
|
|
1014
|
+
await wrapper.vm.$nextTick()
|
|
1015
|
+
|
|
1016
|
+
const phoneField = wrapper.find('.phone-field')
|
|
1017
|
+
expect(syForm.exists()).toBe(true)
|
|
1018
|
+
expect(isValidWithoutPhone).toBe(false)
|
|
1019
|
+
expect(phoneField.classes()).toContain('error-field')
|
|
1020
|
+
|
|
1021
|
+
const input = wrapper.find('input[type="tel"]')
|
|
1022
|
+
await input.setValue('0123456789')
|
|
1023
|
+
await wrapper.vm.$nextTick()
|
|
1024
|
+
|
|
1025
|
+
const isValidWithPhone = await form.validate()
|
|
1026
|
+
await wrapper.vm.$nextTick()
|
|
1027
|
+
|
|
1028
|
+
expect(isValidWithPhone).toBe(true)
|
|
1029
|
+
expect(phoneField.classes()).not.toContain('error-field')
|
|
1030
|
+
})
|
|
1031
|
+
|
|
1032
|
+
it('blocks SyForm submission when a Vuetify custom rule fails', async () => {
|
|
1033
|
+
const wrapper = baseMount({
|
|
1034
|
+
components: { PhoneField, SyForm },
|
|
1035
|
+
setup() {
|
|
1036
|
+
const rules = [(v: unknown) => String(v ?? '').replace(/\D/g, '').startsWith('06') || 'Le numéro doit commencer par 06']
|
|
1037
|
+
return { rules }
|
|
1038
|
+
},
|
|
1039
|
+
template: `
|
|
1040
|
+
<SyForm>
|
|
1041
|
+
<PhoneField :rules="rules" use-vuetify-validation />
|
|
1042
|
+
<button type="submit">Submit</button>
|
|
1043
|
+
</SyForm>
|
|
1044
|
+
`,
|
|
1045
|
+
})
|
|
1046
|
+
|
|
1047
|
+
const syForm = wrapper.findComponent(SyForm)
|
|
1048
|
+
const form = syForm.vm as unknown as { validate: () => Promise<boolean> }
|
|
1049
|
+
|
|
1050
|
+
// A number that does not start with 06 — the Vuetify rule rejects it
|
|
1051
|
+
const input = wrapper.find('input[type="tel"]')
|
|
1052
|
+
await input.setValue('0123456789')
|
|
1053
|
+
await wrapper.vm.$nextTick()
|
|
1054
|
+
|
|
1055
|
+
const isInvalid = await form.validate()
|
|
1056
|
+
await wrapper.vm.$nextTick()
|
|
1057
|
+
|
|
1058
|
+
expect(isInvalid).toBe(false)
|
|
1059
|
+
expect(wrapper.find('.phone-field').classes()).toContain('error-field')
|
|
1060
|
+
|
|
1061
|
+
// Fix the value so the Vuetify rule passes
|
|
1062
|
+
await input.setValue('0612345678')
|
|
1063
|
+
await wrapper.vm.$nextTick()
|
|
1064
|
+
|
|
1065
|
+
const isValid = await form.validate()
|
|
1066
|
+
await wrapper.vm.$nextTick()
|
|
1067
|
+
|
|
1068
|
+
expect(isValid).toBe(true)
|
|
1069
|
+
expect(wrapper.find('.phone-field').classes()).not.toContain('error-field')
|
|
1070
|
+
})
|
|
1071
|
+
|
|
1072
|
+
it('passes SyForm submission when all Vuetify rules are satisfied', async () => {
|
|
1073
|
+
const wrapper = baseMount({
|
|
1074
|
+
components: { PhoneField, SyForm },
|
|
1075
|
+
setup() {
|
|
1076
|
+
const rules = [
|
|
1077
|
+
(v: unknown) => !!v || 'Champ requis',
|
|
1078
|
+
(v: unknown) => String(v ?? '').replace(/\D/g, '').length === 10 || 'Le numéro doit contenir 10 chiffres',
|
|
1079
|
+
]
|
|
1080
|
+
return { rules }
|
|
1081
|
+
},
|
|
1082
|
+
template: `
|
|
1083
|
+
<SyForm>
|
|
1084
|
+
<PhoneField :rules="rules" use-vuetify-validation />
|
|
1085
|
+
<button type="submit">Submit</button>
|
|
1086
|
+
</SyForm>
|
|
1087
|
+
`,
|
|
1088
|
+
})
|
|
1089
|
+
|
|
1090
|
+
const syForm = wrapper.findComponent(SyForm)
|
|
1091
|
+
const form = syForm.vm as unknown as { validate: () => Promise<boolean> }
|
|
1092
|
+
|
|
1093
|
+
const input = wrapper.find('input[type="tel"]')
|
|
1094
|
+
await input.setValue('0612345678')
|
|
1095
|
+
await wrapper.vm.$nextTick()
|
|
1096
|
+
|
|
1097
|
+
const isValid = await form.validate()
|
|
1098
|
+
await wrapper.vm.$nextTick()
|
|
1099
|
+
|
|
1100
|
+
expect(isValid).toBe(true)
|
|
1101
|
+
expect(wrapper.find('.phone-field').classes()).not.toContain('error-field')
|
|
1102
|
+
})
|
|
1103
|
+
})
|
|
871
1104
|
})
|
|
872
1105
|
|
|
873
1106
|
// Tests pour la gestion des indicatifs personnalisés
|
|
@@ -882,8 +1115,8 @@ describe('PhoneField', () => {
|
|
|
882
1115
|
})
|
|
883
1116
|
|
|
884
1117
|
// Vérifier que les indicatifs personnalisés sont ajoutés aux indicatifs standards
|
|
885
|
-
expect(wrapper.vm.
|
|
886
|
-
expect(wrapper.vm.
|
|
1118
|
+
expect(wrapper.vm.dialCodeList.length).toBe(indicatifs.length + customIndicatifs.length)
|
|
1119
|
+
expect(wrapper.vm.dialCodeList).toContainEqual(expect.objectContaining(customIndicatifs[0]))
|
|
887
1120
|
})
|
|
888
1121
|
|
|
889
1122
|
it('uses only custom indicatifs when useCustomIndicatifsOnly is true', () => {
|
|
@@ -897,8 +1130,8 @@ describe('PhoneField', () => {
|
|
|
897
1130
|
})
|
|
898
1131
|
|
|
899
1132
|
// Vérifier que seuls les indicatifs personnalisés sont utilisés
|
|
900
|
-
expect(wrapper.vm.
|
|
901
|
-
expect(wrapper.vm.
|
|
1133
|
+
expect(wrapper.vm.dialCodeList.length).toBe(customIndicatifs.length)
|
|
1134
|
+
expect(wrapper.vm.dialCodeList).toEqual(expect.arrayContaining(customIndicatifs.map(ind => expect.objectContaining(ind))))
|
|
902
1135
|
})
|
|
903
1136
|
|
|
904
1137
|
it('updates phone mask and counter based on selected custom indicatif', async () => {
|
|
@@ -911,13 +1144,77 @@ describe('PhoneField', () => {
|
|
|
911
1144
|
})
|
|
912
1145
|
|
|
913
1146
|
// Sélectionner l'indicatif personnalisé
|
|
914
|
-
wrapper.
|
|
915
|
-
await wrapper.vm.$nextTick()
|
|
1147
|
+
await wrapper.setProps({ dialCodeModel: '+999' })
|
|
916
1148
|
|
|
917
1149
|
// Vérifier que le masque et le counter sont mis à jour
|
|
918
|
-
expect(wrapper.
|
|
1150
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(8)
|
|
919
1151
|
expect(wrapper.vm.phoneMask).toBe('## ## ## ##')
|
|
920
1152
|
})
|
|
1153
|
+
|
|
1154
|
+
it('updates the dialCode when customIndicatifs prop changes', async () => {
|
|
1155
|
+
const initialCustomIndicatifs = [{ code: '+999', abbreviation: 'XX', country: 'Test Country', phoneLength: 8, mask: '## ## ## ##' }]
|
|
1156
|
+
const wrapper = mount(PhoneField, {
|
|
1157
|
+
props: {
|
|
1158
|
+
customIndicatifs: initialCustomIndicatifs,
|
|
1159
|
+
useCustomIndicatifsOnly: true,
|
|
1160
|
+
withCountryCode: true,
|
|
1161
|
+
},
|
|
1162
|
+
})
|
|
1163
|
+
|
|
1164
|
+
// Vérifier que le dialCode est initialisé avec l'indicatif personnalisé
|
|
1165
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
1166
|
+
expect(select.props('modelValue')).toEqual(expect.objectContaining(initialCustomIndicatifs[0]))
|
|
1167
|
+
|
|
1168
|
+
const newCustomIndicatifs = [{ code: '+998', abbreviation: 'YY', country: 'New Test Country', phoneLength: 9, mask: '### ### ###' }]
|
|
1169
|
+
await wrapper.setProps({ customIndicatifs: newCustomIndicatifs })
|
|
1170
|
+
await wrapper.vm.$nextTick()
|
|
1171
|
+
|
|
1172
|
+
// Vérifier que le dialCode est mis à jour avec le nouvel indicatif personnalisé
|
|
1173
|
+
expect(select.props('modelValue')).toEqual(expect.objectContaining(newCustomIndicatifs[0]))
|
|
1174
|
+
|
|
1175
|
+
// Vérifier que le masque et le counter sont mis à jour avec le nouvel indicatif personnalisé
|
|
1176
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(9)
|
|
1177
|
+
expect(wrapper.vm.phoneMask).toBe('### ### ###')
|
|
1178
|
+
|
|
1179
|
+
// Vérifier que les indicatifs affichés dans le select sont mis à jour avec les nouveaux indicatifs personnalisés
|
|
1180
|
+
const items = select.props('items')
|
|
1181
|
+
expect(items).toEqual(expect.arrayContaining(newCustomIndicatifs.map(ind => expect.objectContaining(ind))))
|
|
1182
|
+
|
|
1183
|
+
// Vérifier que les anciens indicatifs personnalisés ne sont plus présents
|
|
1184
|
+
expect(items).not.toEqual(expect.arrayContaining(initialCustomIndicatifs.map(ind => expect.objectContaining(ind))))
|
|
1185
|
+
|
|
1186
|
+
// Vérifier que l'indicatif sélectionné est mis à jour
|
|
1187
|
+
expect(select.props('modelValue')).toEqual(expect.objectContaining(newCustomIndicatifs[0]))
|
|
1188
|
+
})
|
|
1189
|
+
|
|
1190
|
+
it('does not keep selected dial code when it is no longer available', async () => {
|
|
1191
|
+
const initialCustomIndicatifs = [
|
|
1192
|
+
{ code: '+999', abbreviation: 'XX', country: 'Test Country', phoneLength: 8, mask: '## ## ## ##' },
|
|
1193
|
+
{ code: '+998', abbreviation: 'YY', country: 'Fallback Country', phoneLength: 9, mask: '### ### ###' },
|
|
1194
|
+
]
|
|
1195
|
+
|
|
1196
|
+
const wrapper = mount(PhoneField, {
|
|
1197
|
+
props: {
|
|
1198
|
+
customIndicatifs: initialCustomIndicatifs,
|
|
1199
|
+
useCustomIndicatifsOnly: true,
|
|
1200
|
+
withCountryCode: true,
|
|
1201
|
+
dialCodeModel: '+999',
|
|
1202
|
+
},
|
|
1203
|
+
})
|
|
1204
|
+
|
|
1205
|
+
const select = wrapper.findComponent({ name: 'SySelect' })
|
|
1206
|
+
expect((select.props('modelValue') as IndicatifLike).code).toBe('+999')
|
|
1207
|
+
|
|
1208
|
+
await wrapper.setProps({
|
|
1209
|
+
customIndicatifs: [{ code: '+998', abbreviation: 'YY', country: 'Fallback Country', phoneLength: 9, mask: '### ### ###' }],
|
|
1210
|
+
})
|
|
1211
|
+
await wrapper.vm.$nextTick()
|
|
1212
|
+
|
|
1213
|
+
const currentDialCode = select.props('modelValue') as IndicatifLike
|
|
1214
|
+
expect(currentDialCode.code).toBe('+998')
|
|
1215
|
+
expect(currentDialCode.code).not.toBe('+999')
|
|
1216
|
+
expect(wrapper.findComponent({ name: 'SyTextField' }).props('counter')).toBe(9)
|
|
1217
|
+
})
|
|
921
1218
|
})
|
|
922
1219
|
|
|
923
1220
|
describe('Fieldset rendering', () => {
|