@cnamts/synapse 1.0.26 → 1.0.27
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-BPR-a55G.js → AutocompleteFilter-C9eLKyW8.js} +3 -3
- package/dist/{DateFilter-CknrJWs2.js → DateFilter-y-GLkAkn.js} +8 -8
- package/dist/{NumberFilter-DJ-yNlzv.js → NumberFilter-DN6hIBS7.js} +1 -1
- package/dist/{PeriodFilter-CiB5Oa9Z.js → PeriodFilter-MoUUp9qS.js} +1 -1
- package/dist/{SelectFilter-EiafX97M.js → SelectFilter-bCbrdLmu.js} +1 -1
- package/dist/{TextFilter-BzOmpdxj.js → TextFilter-CvjgEaoM.js} +4 -4
- package/dist/apLightTheme2026-ug4Y23ns.js +611 -0
- package/dist/components/Customs/Selects/SyAutocomplete/SyAutocomplete.d.ts +2369 -353
- package/dist/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.d.ts +18 -0
- package/dist/components/Customs/Selects/SyAutocomplete/utils/ariaManager.d.ts +1 -1
- package/dist/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.d.ts +3 -1
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +9 -10
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.d.ts +1 -0
- package/dist/components/Customs/Selects/SySelect/composables/useSySelectValidation.d.ts +15 -0
- package/dist/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.d.ts +3 -3
- package/dist/components/Customs/SyCheckbox/SyCheckbox.d.ts +3 -3
- package/dist/components/Customs/SyIconButton/SyIconButton.d.ts +18 -0
- package/dist/components/Customs/SyRadioGroup/SyRadioGroup.d.ts +20 -38
- package/dist/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.d.ts +50 -0
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +6 -6
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +147 -136
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +62 -54
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +27 -24
- package/dist/components/DatePicker/composables/index.d.ts +1 -0
- package/dist/components/DatePicker/composables/useDatePickerValidationBridge.d.ts +51 -0
- package/dist/components/MonthPicker/MonthPicker.d.ts +23 -23
- package/dist/components/MonthPicker/MonthPickerText/MonthPickerInput.d.ts +23 -23
- package/dist/components/NirField/NirField.d.ts +56 -56
- package/dist/components/PasswordField/PasswordField.d.ts +3 -3
- package/dist/components/PeriodField/PeriodField.d.ts +236 -212
- package/dist/components/PhoneField/PhoneField.d.ts +23 -23
- package/dist/components/SyTextArea/SyTextArea.d.ts +25 -15
- package/dist/components/SyTextArea/composables/useSyTextAreaValidation.d.ts +20 -0
- package/dist/components/SyTextArea/locales.d.ts +1 -0
- package/dist/components/Tables/SyServerTable/SyServerTable.d.ts +1 -0
- package/dist/components/Tables/SyTable/SyTable.d.ts +1 -0
- package/dist/components/Tables/common/SyTablePagination.d.ts +25 -25
- package/dist/components/Tables/common/types.d.ts +2 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/composables/unifyValidation/documentationValidationProps.d.ts +160 -160
- package/dist/composables/unifyValidation/useValidation.d.ts +16 -14
- package/dist/design-system-v3.js +81 -80
- package/dist/designTokens/tokens/amelipro/apContextual.d.ts +6 -6
- package/dist/designTokens/tokens/amelipro/apDarkTheme.d.ts +3 -1
- package/dist/designTokens/tokens/amelipro/apLightTheme.d.ts +53 -100
- package/dist/designTokens/tokens/baseContextualTokens.d.ts +0 -6
- package/dist/designTokens/tokens/baseTokens.d.ts +232 -0
- package/dist/designTokens/tokens/cnam/cnamContextual.d.ts +6 -6
- package/dist/designTokens/tokens/cnam/cnamDarkTheme.d.ts +1 -1
- package/dist/designTokens/tokens/cnam/cnamLightTheme.d.ts +57 -101
- package/dist/designTokens/tokens/pa/paContextual.d.ts +0 -6
- package/dist/designTokens/tokens/pa/paDarkTheme.d.ts +1 -1
- package/dist/designTokens/tokens/pa/paLightTheme.d.ts +53 -97
- package/dist/designTokens/tokens/pa/paSemantic.d.ts +1 -0
- package/dist/designTokens/tokens/semanticTokens.d.ts +112 -0
- package/dist/main-CI6Q9nmO.js +39234 -0
- package/dist/synapse.css +1 -1
- package/dist/vuetifyConfig.js +208 -72
- package/package.json +4 -2
- package/src/assets/overrides/_icons.scss +5 -4
- package/src/assets/overrides/_otp.scss +4 -4
- package/src/assets/overrides/_typography.scss +2 -1
- package/src/assets/overrides/_utilities.scss +1 -42
- package/src/components/ChipList/ChipList.vue +30 -18
- package/src/components/ChipList/tests/chipList.spec.ts +4 -4
- package/src/components/CopyBtn/CopyBtn.vue +2 -2
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.stories.ts +4 -0
- package/src/components/Customs/Selects/SelectBtnField/SelectBtnField.vue +7 -6
- package/src/components/Customs/Selects/SelectBtnField/tests/SelectBtnField.spec.ts +223 -0
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.stories.ts +283 -351
- package/src/components/Customs/Selects/SyAutocomplete/SyAutocomplete.vue +182 -218
- package/src/components/Customs/Selects/SyAutocomplete/composables/useSyAutocompleteValidation.ts +101 -0
- package/src/components/Customs/Selects/SyAutocomplete/tests/SyAutocomplete.spec.ts +761 -1
- package/src/components/Customs/Selects/SyAutocomplete/utils/ariaManager.ts +3 -1
- package/src/components/Customs/Selects/SyAutocomplete/utils/useKeyboardHandler.ts +79 -5
- package/src/components/Customs/Selects/SyAutocomplete/validation/Validation.stories.ts +1029 -0
- package/src/components/Customs/Selects/SySelect/SySelect.stories.ts +9 -491
- package/src/components/Customs/Selects/SySelect/SySelect.vue +46 -79
- package/src/components/Customs/Selects/SySelect/composables/useSySelectKeyboard.ts +3 -0
- package/src/components/Customs/Selects/SySelect/composables/useSySelectValidation.ts +64 -0
- package/src/components/Customs/Selects/SySelect/tests/SySelect.spec.ts +196 -0
- package/src/components/Customs/Selects/SySelect/validation/Validation.stories.ts +1026 -0
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.stories.ts +18 -7
- package/src/components/Customs/SyCheckBoxGroup/SyCheckBoxGroup.vue +2 -2
- package/src/components/Customs/SyCheckbox/SyCheckbox.stories.ts +8 -8
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +8 -8
- package/src/components/Customs/SyCheckbox/tests/SyCheckbox.spec.ts +1 -1
- package/src/components/Customs/SyIcon/accessibilite/Accessibility.mdx +0 -6
- package/src/components/Customs/SyIcon/utils/tests/iconUtils.spec.ts +107 -0
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.mdx +2 -2
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.stories.ts +395 -200
- package/src/components/Customs/SyRadioGroup/SyRadioGroup.vue +82 -127
- package/src/components/Customs/SyRadioGroup/composables/useSyRadioGroupValidation.ts +127 -0
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.a11y.spec.ts +93 -1
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.spec.ts +146 -9
- package/src/components/Customs/SyRadioGroup/tests/SyRadioGroup.visual.cy.ts +165 -0
- package/src/components/Customs/SyRadioGroup/validation/Validation.stories.ts +773 -0
- package/src/components/Customs/SyTabs/config.ts +3 -3
- package/src/components/Customs/SyTabs/tests/SyTabs.spec.ts +265 -0
- package/src/components/Customs/SyTabs/tests/useTabTransition.spec.ts +188 -0
- package/src/components/Customs/SyTextField/SyTextField.stories.ts +10 -29
- package/src/components/Customs/SyTextField/SyTextField.vue +23 -15
- package/src/components/DataList/DataList.stories.ts +1 -1
- package/src/components/DataListItem/tests/DataListItem.spec.ts +3 -1
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +37 -142
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.coverage.spec.ts +156 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.spec.ts +495 -4
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +47 -66
- package/src/components/DatePicker/ComplexDatePicker/tests/ComplexDatePicker.spec.ts +206 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/bridge-integration.regression.spec.ts +210 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/calendar-navigation.regression.spec.ts +214 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/validation-cross.regression.spec.ts +194 -0
- package/src/components/DatePicker/ComplexDatePicker/tests/validation-success-messages.regression.spec.ts +83 -0
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +129 -54
- package/src/components/DatePicker/DateTextInput/tests/DateTextInput.spec.ts +320 -0
- package/src/components/DatePicker/composables/index.ts +1 -0
- package/src/components/DatePicker/composables/tests/useCalendarKeyboardNavigation.spec.ts +360 -0
- package/src/components/DatePicker/composables/tests/useDatePickerValidationBridge.spec.ts +129 -0
- package/src/components/DatePicker/composables/useDatePickerValidationBridge.ts +205 -0
- package/src/components/DatePicker/docExamples/BidirectionalComplexValidation.vue +1 -1
- package/src/components/DatePicker/docExamples/DatePickerBidirectionalValidation.vue +1 -1
- package/src/components/DatePicker/tests/exposed-methods.coverage.spec.ts +75 -0
- package/src/components/DialogBox/DialogBox.vue +1 -1
- package/src/components/FileList/UploadItem/UploadItem.vue +4 -4
- package/src/components/FileUpload/FileUpload.vue +2 -2
- package/src/components/FileUpload/FileUploadContent.vue +1 -1
- package/src/components/FilterInline/FilterInline.mdx +2 -2
- package/src/components/FilterSideBar/FilterSideBar.stories.ts +1 -1
- package/src/components/FilterSideBar/FilterSideBar.vue +2 -2
- package/src/components/FooterBar/FooterBar.vue +7 -7
- package/src/components/FranceConnectBtn/FranceConnectBtn.vue +1 -1
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderMenuItem/HeaderMenuItem.vue +2 -2
- package/src/components/HeaderBar/HeaderBurgerMenu/HeaderSubMenu/HeaderSubMenu.vue +7 -7
- package/src/components/HeaderBar/HeaderMenuBtn/HeaderMenuBtn.vue +2 -2
- package/src/components/HeaderLoading/tests/HeaderLoading.spec.ts +87 -8
- package/src/components/HeaderNavigationBar/HorizontalNavbar/HorizontalNavbar.vue +3 -3
- package/src/components/HeaderNavigationBar/HorizontalNavbar/tests/HorizontalNavbar.spec.ts +589 -0
- package/src/components/HeaderToolbar/tests/HeaderToolBar.spec.ts +153 -1
- package/src/components/HeaderToolbar/tests/useMobileRightMenu.spec.ts +258 -0
- package/src/components/LogoBrandSection/tests/LogoBrandSection.spec.ts +2 -2
- package/src/components/LogoBrandSection/tests/__snapshots__/LogoBrandSection.spec.ts.snap +1 -1
- package/src/components/LunarCalendar/tests/useLunarCalendarRules.spec.ts +184 -0
- package/src/components/MonthPicker/MonthPickerVisual/MonthSelector.vue +3 -3
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerFooter.vue +1 -1
- package/src/components/MonthPicker/MonthPickerVisual/VisualPickerHeader.vue +2 -2
- package/src/components/MonthPicker/MonthPickerVisual/YearSelector.vue +1 -1
- package/src/components/NirField/NirField.vue +3 -3
- package/src/components/NotificationBar/Notification/Notification.vue +12 -12
- package/src/components/NotificationBar/NotificationBar.stories.ts +8 -8
- package/src/components/PaginatedTable/Pagination.vue +2 -2
- package/src/components/PasswordField/PasswordField.vue +8 -8
- package/src/components/PasswordField/tests/PasswordField.spec.ts +3 -3
- package/src/components/RangeField/RangeSlider/RangeSlider.vue +2 -2
- package/src/components/RangeField/RangeSlider/Tooltip/Tooltip.vue +1 -1
- package/src/components/StatusPage/tests/StatusPage.spec.ts +149 -0
- package/src/components/SubHeader/SubHeader.vue +1 -1
- package/src/components/SyAlert/SyAlert.vue +23 -23
- package/src/components/SyTextArea/SyTextArea.stories.ts +177 -131
- package/src/components/SyTextArea/SyTextArea.vue +235 -83
- package/src/components/SyTextArea/composables/useSyTextAreaValidation.ts +81 -0
- package/src/components/SyTextArea/locales.ts +1 -0
- package/src/components/SyTextArea/tests/SyTextArea.spec.ts +449 -1
- package/src/components/SyTextArea/useDefaultValidationRules.ts +2 -7
- package/src/components/SyTextArea/validation/Validation.stories.ts +856 -0
- package/src/components/TableToolbar/TableToolbar.vue +6 -6
- package/src/components/TableToolbar/accessibilite/Accessibility.mdx +81 -7
- package/src/components/Tables/SyServerTable/SyServerTable.stories.ts +163 -0
- package/src/components/Tables/SyServerTable/SyServerTable.vue +2 -1
- package/src/components/Tables/SyServerTable/tests/SyServerTable.spec.ts +67 -0
- package/src/components/Tables/SyTable/SyTable.stories.ts +94 -0
- package/src/components/Tables/SyTable/SyTable.vue +2 -1
- package/src/components/Tables/SyTable/tests/SyTable.spec.ts +64 -0
- package/src/components/Tables/common/TableHeader.vue +2 -2
- package/src/components/Tables/common/filters/logics/tests/NumberFilterLogic.spec.ts +176 -0
- package/src/components/Tables/common/filters/logics/tests/SelectFilterLogic.spec.ts +111 -0
- package/src/components/Tables/common/tableStyles.scss +6 -6
- package/src/components/Tables/common/types.ts +2 -0
- package/src/components/UploadWorkflow/tests/UploadWorkflow.spec.ts +2 -0
- package/src/components/index.ts +1 -0
- package/src/composables/date/tests/useDateFormatDayjs.spec.ts +31 -0
- package/src/composables/date/tests/useHolidayDay.spec.ts +109 -0
- package/src/composables/rules/tests/useFieldValidation.spec.ts +374 -0
- package/src/composables/tests/useError.spec.ts +30 -0
- package/src/composables/tests/useFormFieldErrorHandling.spec.ts +234 -0
- package/src/composables/unifyValidation/documentationValidationProps.ts +5 -5
- package/src/composables/unifyValidation/tests/documentationValidationProps.spec.ts +177 -0
- package/src/composables/unifyValidation/tests/useCustomValidation.spec.ts +30 -0
- package/src/composables/unifyValidation/tests/useValidation.spec.ts +6 -2
- package/src/composables/unifyValidation/useCustomValidation.ts +19 -9
- package/src/composables/unifyValidation/useValidation.ts +18 -21
- package/src/composables/useFilterable/useFilterable.spec.ts +42 -0
- package/src/composables/useFilterable/useFilterable.ts +11 -7
- package/src/composables/useFormFieldErrorHandling.ts +2 -2
- package/src/composantsVuetify/VBtn/VBtn.mdx +9 -39
- package/src/composantsVuetify/VBtn/v-btn.stories.ts +26 -86
- package/src/designTokens/tokens/amelipro/apContextual.ts +6 -0
- package/src/designTokens/tokens/amelipro/apDarkTheme.ts +2 -2
- package/src/designTokens/tokens/amelipro/apLightTheme.ts +72 -103
- package/src/designTokens/tokens/amelipro/apSemantic.ts +1 -1
- package/src/designTokens/tokens/baseContextualTokens.ts +1 -6
- package/src/designTokens/tokens/baseTokens.ts +232 -0
- package/src/designTokens/tokens/cnam/cnamContextual.ts +6 -0
- package/src/designTokens/tokens/cnam/cnamDarkTheme.ts +2 -2
- package/src/designTokens/tokens/cnam/cnamLightTheme.ts +76 -104
- package/src/designTokens/tokens/pa/paDarkTheme.ts +2 -2
- package/src/designTokens/tokens/pa/paLightTheme.ts +73 -99
- package/src/designTokens/tokens/pa/paSemantic.ts +2 -0
- package/src/designTokens/tokens/semanticTokens.ts +114 -0
- package/src/stories/Components/Components.stories.ts +7 -3
- package/src/stories/DesignTokens/ColorIntegrationExample.vue +2 -3
- package/src/stories/DesignTokens/Colors.mdx +6 -8
- package/src/stories/DesignTokens/colors.stories.ts +244 -1081
- package/src/utils/amelipro/toKebabCase/tests/toKebabCase.spec.ts +52 -0
- package/src/utils/formatNir/tests/formatNir.spec.ts +34 -0
- package/src/utils/tests/insertAt.spec.ts +44 -0
- package/dist/apLightTheme-DS0Uy44H.js +0 -954
- package/dist/components/RatingPicker/tests/RatingPicker.a11y.spect.d.ts +0 -1
- package/dist/main-BsJ9ec3i.js +0 -38954
- package/src/components/BackBtn/tests/__snapshots__/back-btn-custom-bg.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-dark-mode.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-default.snap.png +0 -0
- package/src/components/BackBtn/tests/__snapshots__/back-btn-no-icon.snap.png +0 -0
- package/src/components/DatePicker/CalendarMode/tests/DatePicker.events.spec.ts +0 -178
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-custom-texts.snap.png +0 -0
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-default.snap.png +0 -0
- package/src/components/DialogBox/tests/__snapshots__/dialog-box-no-actions.snap.png +0 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated-submenu-open.snap.png +0 -0
- package/src/components/HeaderBar/HeaderBurgerMenu/tests/__snapshots__/header-burger-menu-generated.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-custom-width.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-default.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-no-sticky.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-prepend.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-side.snap.png +0 -0
- package/src/components/HeaderBar/tests/__snapshots__/header-bar-with-subtitle.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-avatar.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-dark.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-default.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-no-organism.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-no-signature.snap.png +0 -0
- package/src/components/Logo/tests/__snapshots__/logo-risque-pro.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-custom-bg.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-custom-range.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-default.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-step.snap.png +0 -0
- package/src/components/RangeField/tests/__snapshots__/range-field-with-label.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-closable.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-error.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-info.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-success.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-outlined.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-variant-tonal.snap.png +0 -0
- package/src/components/SyAlert/tests/__snapshots__/sy-alert-warning.snap.png +0 -0
- /package/src/components/RatingPicker/tests/{RatingPicker.a11y.spect.ts → RatingPicker.a11y.spec.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils'
|
|
2
|
-
import { expect, describe, it } from 'vitest'
|
|
2
|
+
import { expect, describe, it, vi, afterEach } from 'vitest'
|
|
3
3
|
import HeaderToolbar from '../HeaderToolbar.vue'
|
|
4
4
|
|
|
5
5
|
describe('HeaderToolbar', () => {
|
|
@@ -183,4 +183,156 @@ describe('HeaderToolbar', () => {
|
|
|
183
183
|
await wrapper.vm.handleLink(1)
|
|
184
184
|
expect(wrapper.vm.highlightMenu).toBe(false)
|
|
185
185
|
})
|
|
186
|
+
|
|
187
|
+
describe('getLinkComponent', () => {
|
|
188
|
+
it('retourne "a" pour un item avec href', () => {
|
|
189
|
+
const wrapper = mount(HeaderToolbar)
|
|
190
|
+
const result = wrapper.vm.getLinkComponent({ title: 'Test', href: 'https://example.com' })
|
|
191
|
+
expect(result).toBe('a')
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it('retourne "RouterLink" pour un item avec to', () => {
|
|
195
|
+
const wrapper = mount(HeaderToolbar)
|
|
196
|
+
const result = wrapper.vm.getLinkComponent({ title: 'Test', to: '/home' } as unknown as Parameters<typeof wrapper.vm.getLinkComponent>[0])
|
|
197
|
+
expect(result).toBe('RouterLink')
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('retourne "a" pour un item sans href ni to', () => {
|
|
201
|
+
const wrapper = mount(HeaderToolbar)
|
|
202
|
+
const result = wrapper.vm.getLinkComponent({ title: 'Test' })
|
|
203
|
+
expect(result).toBe('a')
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
describe('getCurrentPageIndex', () => {
|
|
208
|
+
it('retourne currentPageIndex si défini', async () => {
|
|
209
|
+
const wrapper = mount(HeaderToolbar, {
|
|
210
|
+
props: { currentPageIndex: 2 },
|
|
211
|
+
})
|
|
212
|
+
expect(wrapper.vm.activeIndex).toBeNull()
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
it('retourne activeIndex si currentPageIndex est null', async () => {
|
|
216
|
+
const wrapper = mount(HeaderToolbar)
|
|
217
|
+
await wrapper.vm.checkActiveLink(1)
|
|
218
|
+
expect(wrapper.vm.activeIndex).toBe(1)
|
|
219
|
+
})
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
describe('handleKeyboardEnter', () => {
|
|
223
|
+
it('appelle checkActiveLink et hideOverlay pour un item avec href', async () => {
|
|
224
|
+
const wrapper = mount(HeaderToolbar)
|
|
225
|
+
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
|
|
226
|
+
const item = { title: 'Test', href: 'https://example.com', openInNewTab: true }
|
|
227
|
+
wrapper.vm.handleKeyboardEnter(item, 0)
|
|
228
|
+
expect(openSpy).toHaveBeenCalledWith('https://example.com', '_blank', 'noopener,noreferrer')
|
|
229
|
+
openSpy.mockRestore()
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('appelle checkActiveLink pour un item avec to', async () => {
|
|
233
|
+
const wrapper = mount(HeaderToolbar)
|
|
234
|
+
const item = { title: 'Test', to: '/home' } as unknown as Parameters<typeof wrapper.vm.handleKeyboardEnter>[0]
|
|
235
|
+
wrapper.vm.handleKeyboardEnter(item, 0)
|
|
236
|
+
expect(wrapper.vm.showOverlay).toBe(false)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('ouvre le menu pour index=1', async () => {
|
|
240
|
+
const wrapper = mount(HeaderToolbar)
|
|
241
|
+
const item = { title: 'Professionnel de santé' }
|
|
242
|
+
wrapper.vm.handleKeyboardEnter(item, 1)
|
|
243
|
+
await wrapper.vm.$nextTick()
|
|
244
|
+
expect(wrapper.vm.showOverlay).toBe(true)
|
|
245
|
+
})
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
describe('handleSubMenuItemClick', () => {
|
|
249
|
+
it('met à jour dropdownMenuTitle et ferme l\'overlay', async () => {
|
|
250
|
+
const wrapper = mount(HeaderToolbar, {
|
|
251
|
+
props: {
|
|
252
|
+
itemsSelectMenu: [{ text: 'Médecin', value: 'medecin' }],
|
|
253
|
+
},
|
|
254
|
+
})
|
|
255
|
+
const subItem = { text: 'Médecin', value: 'medecin' }
|
|
256
|
+
wrapper.vm.handleSubMenuItemClick(subItem)
|
|
257
|
+
await wrapper.vm.$nextTick()
|
|
258
|
+
expect(wrapper.vm.showOverlay).toBe(false)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it('ouvre dans un nouvel onglet si openInNewTab=true', async () => {
|
|
262
|
+
const wrapper = mount(HeaderToolbar)
|
|
263
|
+
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
|
|
264
|
+
const subItem = { text: 'Médecin', value: 'medecin', href: 'https://example.com', openInNewTab: true }
|
|
265
|
+
wrapper.vm.handleSubMenuItemClick(subItem)
|
|
266
|
+
expect(openSpy).toHaveBeenCalledWith('https://example.com', '_blank', 'noopener,noreferrer')
|
|
267
|
+
openSpy.mockRestore()
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
describe('handleMenuKeydown', () => {
|
|
272
|
+
function makeMenuContainer(count: number): HTMLElement {
|
|
273
|
+
const container = document.createElement('div')
|
|
274
|
+
for (let i = 0; i < count; i++) {
|
|
275
|
+
const item = document.createElement('div')
|
|
276
|
+
item.setAttribute('role', 'menuitem')
|
|
277
|
+
item.id = `menu-item-${i}`
|
|
278
|
+
container.appendChild(item)
|
|
279
|
+
}
|
|
280
|
+
document.body.appendChild(container)
|
|
281
|
+
return container
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
afterEach(() => {
|
|
285
|
+
document.body.innerHTML = ''
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
it('ArrowDown ne plante pas avec des items dans le conteneur', async () => {
|
|
289
|
+
const wrapper = mount(HeaderToolbar)
|
|
290
|
+
const container = makeMenuContainer(3)
|
|
291
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true, cancelable: true })
|
|
292
|
+
Object.defineProperty(event, 'currentTarget', { value: container, writable: false })
|
|
293
|
+
expect(() => wrapper.vm.handleMenuKeydown(event)).not.toThrow()
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('Escape ferme le menu et l\'overlay', async () => {
|
|
297
|
+
const wrapper = mount(HeaderToolbar)
|
|
298
|
+
const container = makeMenuContainer(2)
|
|
299
|
+
wrapper.vm.showOverlay = true
|
|
300
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true })
|
|
301
|
+
Object.defineProperty(event, 'currentTarget', { value: container, writable: false })
|
|
302
|
+
wrapper.vm.handleMenuKeydown(event)
|
|
303
|
+
expect(wrapper.vm.showOverlay).toBe(false)
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
it('Home ne plante pas avec des items dans le conteneur', async () => {
|
|
307
|
+
const wrapper = mount(HeaderToolbar)
|
|
308
|
+
const container = makeMenuContainer(3)
|
|
309
|
+
const event = new KeyboardEvent('keydown', { key: 'Home', bubbles: true, cancelable: true })
|
|
310
|
+
Object.defineProperty(event, 'currentTarget', { value: container, writable: false })
|
|
311
|
+
expect(() => wrapper.vm.handleMenuKeydown(event)).not.toThrow()
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
it('End ne plante pas avec des items dans le conteneur', async () => {
|
|
315
|
+
const wrapper = mount(HeaderToolbar)
|
|
316
|
+
const container = makeMenuContainer(3)
|
|
317
|
+
const event = new KeyboardEvent('keydown', { key: 'End', bubbles: true, cancelable: true })
|
|
318
|
+
Object.defineProperty(event, 'currentTarget', { value: container, writable: false })
|
|
319
|
+
expect(() => wrapper.vm.handleMenuKeydown(event)).not.toThrow()
|
|
320
|
+
})
|
|
321
|
+
|
|
322
|
+
it('Enter ne plante pas sans item actif', () => {
|
|
323
|
+
const wrapper = mount(HeaderToolbar)
|
|
324
|
+
const container = makeMenuContainer(2)
|
|
325
|
+
const event = new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })
|
|
326
|
+
Object.defineProperty(event, 'currentTarget', { value: container, writable: false })
|
|
327
|
+
expect(() => wrapper.vm.handleMenuKeydown(event)).not.toThrow()
|
|
328
|
+
})
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
describe('openMenuWithKeyboard', () => {
|
|
332
|
+
it('ouvre le menu et l\'overlay', async () => {
|
|
333
|
+
const wrapper = mount(HeaderToolbar)
|
|
334
|
+
wrapper.vm.openMenuWithKeyboard()
|
|
335
|
+
expect(wrapper.vm.showOverlay).toBe(true)
|
|
336
|
+
})
|
|
337
|
+
})
|
|
186
338
|
})
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from 'vitest'
|
|
2
|
+
import { nextTick } from 'vue'
|
|
3
|
+
import { useMobileRightMenu } from '../useMobileRightMenu'
|
|
4
|
+
|
|
5
|
+
function makeContainerWithItems(count: number): { container: HTMLElement, items: HTMLElement[] } {
|
|
6
|
+
const container = document.createElement('div')
|
|
7
|
+
const items = Array.from({ length: count }, (_, i) => {
|
|
8
|
+
const el = document.createElement('button')
|
|
9
|
+
el.setAttribute('role', 'menuitem')
|
|
10
|
+
el.id = `mobile-item-${i}`
|
|
11
|
+
container.appendChild(el)
|
|
12
|
+
return el
|
|
13
|
+
})
|
|
14
|
+
document.body.appendChild(container)
|
|
15
|
+
return { container, items }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('useMobileRightMenu', () => {
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
document.body.innerHTML = ''
|
|
21
|
+
vi.useRealTimers()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
describe('état initial', () => {
|
|
25
|
+
it('mobileMenuOpen est false par défaut', () => {
|
|
26
|
+
const { mobileMenuOpen } = useMobileRightMenu()
|
|
27
|
+
expect(mobileMenuOpen.value).toBe(false)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('mobileActiveIndex est null par défaut', () => {
|
|
31
|
+
const { mobileActiveIndex } = useMobileRightMenu()
|
|
32
|
+
expect(mobileActiveIndex.value).toBeNull()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('mobileActiveDescendantId est null par défaut', () => {
|
|
36
|
+
const { mobileActiveDescendantId } = useMobileRightMenu()
|
|
37
|
+
expect(mobileActiveDescendantId.value).toBeNull()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('mobileBurgerButtonRef est null par défaut', () => {
|
|
41
|
+
const { mobileBurgerButtonRef } = useMobileRightMenu()
|
|
42
|
+
expect(mobileBurgerButtonRef.value).toBeNull()
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
describe('openMobileMenuAndFocus', () => {
|
|
47
|
+
it('ouvre le menu', async () => {
|
|
48
|
+
vi.useFakeTimers()
|
|
49
|
+
const { mobileMenuOpen, openMobileMenuAndFocus } = useMobileRightMenu()
|
|
50
|
+
openMobileMenuAndFocus()
|
|
51
|
+
expect(mobileMenuOpen.value).toBe(true)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('définit mobileActiveIndex à 0', () => {
|
|
55
|
+
vi.useFakeTimers()
|
|
56
|
+
const { mobileActiveIndex, openMobileMenuAndFocus } = useMobileRightMenu()
|
|
57
|
+
openMobileMenuAndFocus()
|
|
58
|
+
expect(mobileActiveIndex.value).toBe(0)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it('définit mobileActiveDescendantId à "mobile-item-0"', () => {
|
|
62
|
+
vi.useFakeTimers()
|
|
63
|
+
const { mobileActiveDescendantId, openMobileMenuAndFocus } = useMobileRightMenu()
|
|
64
|
+
openMobileMenuAndFocus()
|
|
65
|
+
expect(mobileActiveDescendantId.value).toBe('mobile-item-0')
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe('onMobileMenuModel', () => {
|
|
70
|
+
it('quand val=true, définit activeIndex=0 et activeDescendantId="mobile-item-0"', async () => {
|
|
71
|
+
vi.useFakeTimers()
|
|
72
|
+
const { mobileActiveIndex, mobileActiveDescendantId, onMobileMenuModel } = useMobileRightMenu()
|
|
73
|
+
onMobileMenuModel(true)
|
|
74
|
+
expect(mobileActiveIndex.value).toBe(0)
|
|
75
|
+
expect(mobileActiveDescendantId.value).toBe('mobile-item-0')
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('quand val=false, tente de focus le burger button', async () => {
|
|
79
|
+
const { mobileBurgerButtonRef, onMobileMenuModel } = useMobileRightMenu()
|
|
80
|
+
const btn = document.createElement('button')
|
|
81
|
+
btn.id = 'burger-btn'
|
|
82
|
+
document.body.appendChild(btn)
|
|
83
|
+
mobileBurgerButtonRef.value = btn
|
|
84
|
+
const focusSpy = vi.spyOn(btn, 'focus')
|
|
85
|
+
|
|
86
|
+
onMobileMenuModel(false)
|
|
87
|
+
await nextTick()
|
|
88
|
+
|
|
89
|
+
expect(focusSpy).toHaveBeenCalled()
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe('handleMobileMenuKeydown', () => {
|
|
94
|
+
it('ne fait rien si aucun item [role="menuitem"] dans le conteneur', () => {
|
|
95
|
+
const { mobileRightMenuRef, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
96
|
+
const container = document.createElement('div')
|
|
97
|
+
document.body.appendChild(container)
|
|
98
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
99
|
+
|
|
100
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true })
|
|
101
|
+
vi.spyOn(event, 'preventDefault')
|
|
102
|
+
handleMobileMenuKeydown(event)
|
|
103
|
+
|
|
104
|
+
expect(mobileActiveIndex.value).toBeNull()
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('ArrowDown navigue vers l\'élément suivant', () => {
|
|
108
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
109
|
+
const { container, items } = makeContainerWithItems(3)
|
|
110
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
111
|
+
|
|
112
|
+
mobileActiveDescendantId.value = items[0]!.id
|
|
113
|
+
|
|
114
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true, cancelable: true })
|
|
115
|
+
handleMobileMenuKeydown(event)
|
|
116
|
+
|
|
117
|
+
expect(mobileActiveIndex.value).toBe(1)
|
|
118
|
+
expect(mobileActiveDescendantId.value).toBe(items[1]!.id)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('ArrowDown sur le dernier item revient au premier (wrap)', () => {
|
|
122
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
123
|
+
const { container, items } = makeContainerWithItems(3)
|
|
124
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
125
|
+
|
|
126
|
+
mobileActiveDescendantId.value = items[2]!.id
|
|
127
|
+
|
|
128
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true, cancelable: true })
|
|
129
|
+
handleMobileMenuKeydown(event)
|
|
130
|
+
|
|
131
|
+
expect(mobileActiveIndex.value).toBe(0)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('ArrowUp navigue vers l\'élément précédent', () => {
|
|
135
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
136
|
+
const { container, items } = makeContainerWithItems(3)
|
|
137
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
138
|
+
|
|
139
|
+
mobileActiveDescendantId.value = items[2]!.id
|
|
140
|
+
|
|
141
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true, cancelable: true })
|
|
142
|
+
handleMobileMenuKeydown(event)
|
|
143
|
+
|
|
144
|
+
expect(mobileActiveIndex.value).toBe(1)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('ArrowUp sur le premier item revient au dernier (wrap)', () => {
|
|
148
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
149
|
+
const { container, items } = makeContainerWithItems(3)
|
|
150
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
151
|
+
|
|
152
|
+
mobileActiveDescendantId.value = items[0]!.id
|
|
153
|
+
|
|
154
|
+
const event = new KeyboardEvent('keydown', { key: 'ArrowUp', bubbles: true, cancelable: true })
|
|
155
|
+
handleMobileMenuKeydown(event)
|
|
156
|
+
|
|
157
|
+
expect(mobileActiveIndex.value).toBe(2)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('Home navigue vers le premier item', () => {
|
|
161
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
162
|
+
const { container, items } = makeContainerWithItems(3)
|
|
163
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
164
|
+
|
|
165
|
+
mobileActiveDescendantId.value = items[2]!.id
|
|
166
|
+
|
|
167
|
+
const event = new KeyboardEvent('keydown', { key: 'Home', bubbles: true, cancelable: true })
|
|
168
|
+
handleMobileMenuKeydown(event)
|
|
169
|
+
|
|
170
|
+
expect(mobileActiveIndex.value).toBe(0)
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('End navigue vers le dernier item', () => {
|
|
174
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
175
|
+
const { container, items } = makeContainerWithItems(3)
|
|
176
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
177
|
+
|
|
178
|
+
mobileActiveDescendantId.value = items[0]!.id
|
|
179
|
+
|
|
180
|
+
const event = new KeyboardEvent('keydown', { key: 'End', bubbles: true, cancelable: true })
|
|
181
|
+
handleMobileMenuKeydown(event)
|
|
182
|
+
|
|
183
|
+
expect(mobileActiveIndex.value).toBe(2)
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('Escape ferme le menu', async () => {
|
|
187
|
+
const { mobileRightMenuRef, mobileMenuOpen, handleMobileMenuKeydown } = useMobileRightMenu()
|
|
188
|
+
const { container } = makeContainerWithItems(2)
|
|
189
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
190
|
+
|
|
191
|
+
mobileMenuOpen.value = true
|
|
192
|
+
|
|
193
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true })
|
|
194
|
+
handleMobileMenuKeydown(event)
|
|
195
|
+
|
|
196
|
+
expect(mobileMenuOpen.value).toBe(false)
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
it('Escape focus le burger button', async () => {
|
|
200
|
+
const { mobileRightMenuRef, mobileBurgerButtonRef, handleMobileMenuKeydown } = useMobileRightMenu()
|
|
201
|
+
const { container } = makeContainerWithItems(2)
|
|
202
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
203
|
+
|
|
204
|
+
const btn = document.createElement('button')
|
|
205
|
+
document.body.appendChild(btn)
|
|
206
|
+
mobileBurgerButtonRef.value = btn
|
|
207
|
+
const focusSpy = vi.spyOn(btn, 'focus')
|
|
208
|
+
|
|
209
|
+
const event = new KeyboardEvent('keydown', { key: 'Escape', bubbles: true, cancelable: true })
|
|
210
|
+
handleMobileMenuKeydown(event)
|
|
211
|
+
await nextTick()
|
|
212
|
+
|
|
213
|
+
expect(focusSpy).toHaveBeenCalled()
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
it('Enter clique sur l\'item actif', () => {
|
|
217
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown } = useMobileRightMenu()
|
|
218
|
+
const { container, items } = makeContainerWithItems(2)
|
|
219
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
220
|
+
|
|
221
|
+
mobileActiveDescendantId.value = items[0]!.id
|
|
222
|
+
const clickSpy = vi.spyOn(items[0]!, 'click')
|
|
223
|
+
|
|
224
|
+
const event = new KeyboardEvent('keydown', { key: 'Enter', bubbles: true, cancelable: true })
|
|
225
|
+
handleMobileMenuKeydown(event)
|
|
226
|
+
|
|
227
|
+
expect(clickSpy).toHaveBeenCalled()
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
it('Space clique sur l\'item actif', () => {
|
|
231
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown } = useMobileRightMenu()
|
|
232
|
+
const { container, items } = makeContainerWithItems(2)
|
|
233
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
234
|
+
|
|
235
|
+
mobileActiveDescendantId.value = items[1]!.id
|
|
236
|
+
const clickSpy = vi.spyOn(items[1]!, 'click')
|
|
237
|
+
|
|
238
|
+
const event = new KeyboardEvent('keydown', { key: ' ', bubbles: true, cancelable: true })
|
|
239
|
+
handleMobileMenuKeydown(event)
|
|
240
|
+
|
|
241
|
+
expect(clickSpy).toHaveBeenCalled()
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
it('une touche non gérée ne modifie pas l\'état', () => {
|
|
245
|
+
const { mobileRightMenuRef, mobileActiveDescendantId, handleMobileMenuKeydown, mobileActiveIndex } = useMobileRightMenu()
|
|
246
|
+
const { container, items } = makeContainerWithItems(2)
|
|
247
|
+
;(mobileRightMenuRef as unknown as { value: unknown }).value = { $el: container }
|
|
248
|
+
|
|
249
|
+
mobileActiveDescendantId.value = items[0]!.id
|
|
250
|
+
mobileActiveIndex.value = 0
|
|
251
|
+
|
|
252
|
+
const event = new KeyboardEvent('keydown', { key: 'Tab', bubbles: true })
|
|
253
|
+
handleMobileMenuKeydown(event)
|
|
254
|
+
|
|
255
|
+
expect(mobileActiveIndex.value).toBe(0)
|
|
256
|
+
})
|
|
257
|
+
})
|
|
258
|
+
})
|
|
@@ -122,7 +122,7 @@ describe('LogoBrandSection', () => {
|
|
|
122
122
|
})
|
|
123
123
|
|
|
124
124
|
const divider = wrapper.find('.vd-divider')
|
|
125
|
-
expect(divider.attributes('fill')).toBe('#
|
|
125
|
+
expect(divider.attributes('fill')).toBe('#0C419A')
|
|
126
126
|
})
|
|
127
127
|
|
|
128
128
|
it('renders correctly with cnam theme', () => {
|
|
@@ -156,7 +156,7 @@ describe('LogoBrandSection', () => {
|
|
|
156
156
|
})
|
|
157
157
|
|
|
158
158
|
const divider = wrapper.find('.vd-divider')
|
|
159
|
-
expect(divider.attributes('fill')).toBe('#
|
|
159
|
+
expect(divider.attributes('fill')).toBe('#CD545B')
|
|
160
160
|
})
|
|
161
161
|
|
|
162
162
|
it('renders correctly with risquePro if no reduceLogo', () => {
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { useLunarCalendarRules } from '../useLunarCalendarRules'
|
|
4
|
+
|
|
5
|
+
function getRules(opts: {
|
|
6
|
+
successMessage?: string
|
|
7
|
+
required?: boolean
|
|
8
|
+
minYear?: number
|
|
9
|
+
maxYear?: number
|
|
10
|
+
}) {
|
|
11
|
+
const { rules } = useLunarCalendarRules(
|
|
12
|
+
ref(opts.successMessage),
|
|
13
|
+
ref(opts.required),
|
|
14
|
+
ref(opts.minYear),
|
|
15
|
+
ref(opts.maxYear),
|
|
16
|
+
)
|
|
17
|
+
return rules.value
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type CustomRule = { type: 'custom', options: { validate: (v: string) => boolean, message: string } }
|
|
21
|
+
|
|
22
|
+
describe('useLunarCalendarRules', () => {
|
|
23
|
+
describe('règle required', () => {
|
|
24
|
+
it('n\'ajoute pas de règle required si required est false', () => {
|
|
25
|
+
const rules = getRules({ required: false })
|
|
26
|
+
expect(rules.some(r => r.type === 'required')).toBe(false)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('ajoute une règle required si required est true', () => {
|
|
30
|
+
const rules = getRules({ required: true })
|
|
31
|
+
expect(rules.some(r => r.type === 'required')).toBe(true)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('la règle required contient le bon message', () => {
|
|
35
|
+
const rules = getRules({ required: true })
|
|
36
|
+
const req = rules.find(r => r.type === 'required')
|
|
37
|
+
expect(req?.options.message).toBe('Ce champ est requis.')
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it('la règle required contient le successMessage si fourni', () => {
|
|
41
|
+
const rules = getRules({ required: true, successMessage: 'Bravo' })
|
|
42
|
+
const req = rules.find(r => r.type === 'required')
|
|
43
|
+
expect(req?.options.successMessage).toBe('Bravo')
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
describe('règle format DD/MM/YYYY', () => {
|
|
48
|
+
it('valide une date au format DD/MM/YYYY', () => {
|
|
49
|
+
const rules = getRules({})
|
|
50
|
+
const fmt = rules.find(r => r.type === 'custom') as CustomRule
|
|
51
|
+
expect(fmt.options.validate('25/12/2000')).toBe(true)
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
it('rejette une date sans slashs', () => {
|
|
55
|
+
const rules = getRules({})
|
|
56
|
+
const fmt = rules.find(r => r.type === 'custom') as CustomRule
|
|
57
|
+
expect(fmt.options.validate('25122000')).toBe(false)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('rejette une date incomplète', () => {
|
|
61
|
+
const rules = getRules({})
|
|
62
|
+
const fmt = rules.find(r => r.type === 'custom') as CustomRule
|
|
63
|
+
expect(fmt.options.validate('25/12/200')).toBe(false)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
it('rejette une chaîne vide', () => {
|
|
67
|
+
const rules = getRules({})
|
|
68
|
+
const fmt = rules.find(r => r.type === 'custom') as CustomRule
|
|
69
|
+
expect(fmt.options.validate('')).toBe(false)
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
describe('règle minYear seulement', () => {
|
|
74
|
+
it('retourne true si le format est invalide (year null)', () => {
|
|
75
|
+
const rules = getRules({ minYear: 2000 })
|
|
76
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
77
|
+
expect(minRule.options.validate('invalid')).toBe(true)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('retourne true si l\'année >= minYear', () => {
|
|
81
|
+
const rules = getRules({ minYear: 2000 })
|
|
82
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
83
|
+
expect(minRule.options.validate('25/12/2000')).toBe(true)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('retourne false si l\'année < minYear', () => {
|
|
87
|
+
const rules = getRules({ minYear: 2000 })
|
|
88
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
89
|
+
expect(minRule.options.validate('25/12/1999')).toBe(false)
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('contient le bon message', () => {
|
|
93
|
+
const rules = getRules({ minYear: 2000 })
|
|
94
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
95
|
+
expect(minRule.options.message).toBe('L\'année doit être supérieure ou égale à 2000.')
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
describe('règle maxYear seulement', () => {
|
|
100
|
+
it('retourne true si le format est invalide (year null)', () => {
|
|
101
|
+
const rules = getRules({ maxYear: 2020 })
|
|
102
|
+
const maxRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
103
|
+
expect(maxRule.options.validate('invalid')).toBe(true)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it('retourne true si l\'année <= maxYear', () => {
|
|
107
|
+
const rules = getRules({ maxYear: 2020 })
|
|
108
|
+
const maxRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
109
|
+
expect(maxRule.options.validate('25/12/2020')).toBe(true)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
it('retourne false si l\'année > maxYear', () => {
|
|
113
|
+
const rules = getRules({ maxYear: 2020 })
|
|
114
|
+
const maxRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
115
|
+
expect(maxRule.options.validate('25/12/2021')).toBe(false)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('contient le bon message', () => {
|
|
119
|
+
const rules = getRules({ maxYear: 2020 })
|
|
120
|
+
const maxRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
121
|
+
expect(maxRule.options.message).toBe('L\'année doit être inférieure ou égale à 2020.')
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
describe('règle minYear ET maxYear', () => {
|
|
126
|
+
it('retourne true si le format est invalide (year null)', () => {
|
|
127
|
+
const rules = getRules({ minYear: 2000, maxYear: 2020 })
|
|
128
|
+
const rangeRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
129
|
+
expect(rangeRule.options.validate('invalid')).toBe(true)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('retourne true si l\'année est dans la plage', () => {
|
|
133
|
+
const rules = getRules({ minYear: 2000, maxYear: 2020 })
|
|
134
|
+
const rangeRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
135
|
+
expect(rangeRule.options.validate('25/12/2010')).toBe(true)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('retourne false si l\'année est avant minYear', () => {
|
|
139
|
+
const rules = getRules({ minYear: 2000, maxYear: 2020 })
|
|
140
|
+
const rangeRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
141
|
+
expect(rangeRule.options.validate('25/12/1999')).toBe(false)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('retourne false si l\'année est après maxYear', () => {
|
|
145
|
+
const rules = getRules({ minYear: 2000, maxYear: 2020 })
|
|
146
|
+
const rangeRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
147
|
+
expect(rangeRule.options.validate('25/12/2021')).toBe(false)
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
it('contient le bon message', () => {
|
|
151
|
+
const rules = getRules({ minYear: 2000, maxYear: 2020 })
|
|
152
|
+
const rangeRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
153
|
+
expect(rangeRule.options.message).toBe('L\'année doit être comprise entre 2000 et 2020.')
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
describe('getYearFromModel (via les règles)', () => {
|
|
158
|
+
it('retourne null si le modèle n\'a pas 3 parties', () => {
|
|
159
|
+
const rules = getRules({ minYear: 2000 })
|
|
160
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
161
|
+
expect(minRule.options.validate('25/12')).toBe(true)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
it('retourne null si l\'année n\'a pas 4 chiffres', () => {
|
|
165
|
+
const rules = getRules({ minYear: 2000 })
|
|
166
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
167
|
+
expect(minRule.options.validate('25/12/200')).toBe(true)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
it('retourne null si l\'année n\'est pas un nombre', () => {
|
|
171
|
+
const rules = getRules({ minYear: 2000 })
|
|
172
|
+
const minRule = rules.filter(r => r.type === 'custom')[1] as CustomRule
|
|
173
|
+
expect(minRule.options.validate('25/12/abcd')).toBe(true)
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('aucune règle year si minYear et maxYear sont undefined', () => {
|
|
178
|
+
it('ne génère que 1 règle custom (format) sans min/max', () => {
|
|
179
|
+
const rules = getRules({})
|
|
180
|
+
const customRules = rules.filter(r => r.type === 'custom')
|
|
181
|
+
expect(customRules.length).toBe(1)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
})
|
|
@@ -121,17 +121,17 @@
|
|
|
121
121
|
|
|
122
122
|
.month-selector__month--selected {
|
|
123
123
|
/* stylelint-disable-next-line custom-property-pattern */
|
|
124
|
-
background-color: rgb(var(--v-theme-
|
|
124
|
+
background-color: rgb(var(--v-theme-primary, 12, 65, 154));
|
|
125
125
|
color: white;
|
|
126
126
|
|
|
127
127
|
&:hover {
|
|
128
128
|
/* stylelint-disable-next-line custom-property-pattern */
|
|
129
|
-
background-color: rgb(var(--v-theme-
|
|
129
|
+
background-color: rgb(var(--v-theme-primaryVariant, 7, 39, 92));
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
.month-selector__month--active:focus {
|
|
134
134
|
/* stylelint-disable-next-line custom-property-pattern */
|
|
135
|
-
outline: 2px solid rgb(var(--v-theme-
|
|
135
|
+
outline: 2px solid rgb(var(--v-theme-primary, 12, 65, 154));
|
|
136
136
|
}
|
|
137
137
|
</style>
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
.visual-picker-header {
|
|
104
104
|
padding-block: 16px;
|
|
105
105
|
background-color: rgb(var(--v-theme-primary, '12, 65, 154'));
|
|
106
|
-
color: rgb(var(--v-theme-
|
|
106
|
+
color: rgb(var(--v-theme-onPrimary));
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
.visual-picker-header__title {
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
|
|
144
144
|
&:focus-visible {
|
|
145
145
|
/* stylelint-disable-next-line custom-property-pattern */
|
|
146
|
-
outline: 2px solid rgb(var(--v-theme-
|
|
146
|
+
outline: 2px solid rgb(var(--v-theme-primary, 12, 65, 154));
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
</style>
|