@cnamts/synapse 1.0.12 → 1.0.13
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/{DateFilter-DoCcOfDW.js → DateFilter-_EFzsvvM.js} +1 -1
- package/dist/{NumberFilter-9uR8uo6p.js → NumberFilter-CUxEbKJh.js} +1 -1
- package/dist/{PeriodFilter-CxN5ini7.js → PeriodFilter-D5ueqtKy.js} +1 -1
- package/dist/{SelectFilter-bfxipgvt.js → SelectFilter-BciBNydy.js} +1 -1
- package/dist/{TextFilter-yCnWcmW2.js → TextFilter-DMN_WAQB.js} +1 -1
- package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordion.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAccordion/AmeliproAccordionTemplate/AmeliproAccordionTemplate.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResult.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAccordionResult/AmeliproAccordionResultTemplate/AmeliproAccordionResultTemplate.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproAutoCompleteField/AmeliproAutoCompleteField.d.ts +44 -62
- package/dist/components/Amelipro/AmeliproCard/AmeliproCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIcon/AmeliproIcon.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproIconBtn/AmeliproIconBtn.d.ts +5 -5
- package/dist/components/Amelipro/AmeliproMultipleFoldingCard/AmeliproMultipleFoldingCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproNumberedCard/AmeliproNumberedCard.d.ts +1 -1
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressCityRow/AmeliproPostalAddressCityRow.d.ts +24 -32
- package/dist/components/Amelipro/AmeliproPostalAddressField/AmeliproPostalAddressField.d.ts +36 -48
- package/dist/components/Amelipro/AmeliproSelect/AmeliproSelect.d.ts +44 -62
- package/dist/components/Amelipro/AmeliproTabs/AmeliproTabs.d.ts +44 -62
- package/dist/components/Amelipro/AmeliproTextArea/AmeliproTextArea.d.ts +0 -4
- package/dist/components/Amelipro/AmeliproTextField/AmeliproTextField.d.ts +12 -16
- package/dist/components/Captcha/Captcha.d.ts +68 -0
- package/dist/components/Captcha/CaptchaAlert.d.ts +13 -0
- package/dist/components/Captcha/CaptchaBase.d.ts +55 -0
- package/dist/components/Captcha/CaptchaBtn.d.ts +12 -0
- package/dist/components/Captcha/CaptchaForm.d.ts +16 -0
- package/dist/components/Captcha/CaptchaImg.d.ts +12 -0
- package/dist/components/Captcha/CaptchaInformation.d.ts +20 -0
- package/dist/components/Captcha/captchaApi.d.ts +41 -0
- package/dist/components/Captcha/icons/volumeUp.d.ts +2 -0
- package/dist/components/Captcha/locales.d.ts +35 -0
- package/dist/components/Captcha/types.d.ts +2 -0
- package/dist/components/ChipList/ChipList.d.ts +2 -2
- package/dist/components/Customs/Selects/SySelect/SySelect.d.ts +2 -2
- package/dist/components/Customs/SyForm/SyForm.d.ts +6 -3
- package/dist/components/Customs/SyTextField/SyTextField.d.ts +13 -17
- package/dist/components/DatePicker/CalendarMode/DatePicker.d.ts +56 -64
- package/dist/components/DatePicker/ComplexDatePicker/ComplexDatePicker.d.ts +47 -64
- package/dist/components/DatePicker/DateTextInput/DateTextInput.d.ts +18 -17
- package/dist/components/DatePicker/tests/setup.d.ts +448 -512
- package/dist/components/HeaderToolbar/HeaderToolbar.d.ts +4 -4
- package/dist/components/NirField/NirField.d.ts +29 -34
- package/dist/components/NirField/locales.d.ts +1 -3
- package/dist/components/PasswordField/PasswordField.d.ts +2 -0
- package/dist/components/PeriodField/PeriodField.d.ts +112 -128
- package/dist/components/PhoneField/PhoneField.d.ts +13 -17
- package/dist/components/SearchListField/SearchListField.d.ts +2 -2
- package/dist/components/SyTextArea/SyTextArea.d.ts +0 -4
- package/dist/components/Tables/common/SyTablePagination.d.ts +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/composables/validation/useFormValidation.d.ts +10 -0
- package/dist/composables/validation/useValidatable.d.ts +10 -2
- package/dist/design-system-v3.js +126 -125
- package/dist/design-system-v3.umd.cjs +155 -155
- package/dist/main-DISHlqcd.js +34217 -0
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/Amelipro/AmeliproFooter/AmeliproFooter.vue +6 -7
- package/src/components/Amelipro/AmeliproFooter/__tests__/AmeliproFooter.spec.ts +787 -0
- package/src/components/Amelipro/AmeliproFooter/__tests__/__snapshots__/AmeliproFooter.spec.ts.snap +318 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/AmeliproHeaderBrandSection.spec.ts +167 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/__tests__/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +100 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/AmeliproHeaderBar.spec.ts +312 -0
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/__tests__/__snapshots__/AmeliproHeaderBar.spec.ts.snap +98 -0
- package/src/components/Amelipro/AmeliproHeader/__tests__/AmeliproHeader.spec.ts +361 -0
- package/src/components/Amelipro/AmeliproHeader/__tests__/__snapshots__/AmeliproHeader.spec.ts.snap +22 -0
- package/src/components/Amelipro/AmeliproMenu/__tests__/AmeliproMenu.spec.ts +168 -0
- package/src/components/Amelipro/AmeliproMenu/__tests__/__snapshots__/AmeliproMenu.spec.ts.snap +295 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/AmeliproDropdownMenuBtn.spec.ts +128 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/__tests__/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +67 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/AmeliproDropdownMenu.spec.ts +266 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/__tests__/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +134 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/AmeliproMessagingMenuBtn.spec.ts +72 -0
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/__tests__/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +71 -0
- package/src/components/Amelipro/AmeliproPageLayout/tests/__snapshots__/AmeliproPageLayout.spec.ts.snap +12 -0
- package/src/components/Captcha/Captcha.mdx +72 -0
- package/src/components/Captcha/Captcha.stories.ts +276 -0
- package/src/components/Captcha/Captcha.vue +325 -0
- package/src/components/Captcha/CaptchaAlert.vue +60 -0
- package/src/components/Captcha/CaptchaBase.vue +219 -0
- package/src/components/Captcha/CaptchaBtn.vue +35 -0
- package/src/components/Captcha/CaptchaForm.vue +58 -0
- package/src/components/Captcha/CaptchaImg.vue +41 -0
- package/src/components/Captcha/CaptchaInformation.vue +64 -0
- package/src/components/Captcha/captchaApi.ts +111 -0
- package/src/components/Captcha/icons/volumeUp.vue +11 -0
- package/src/components/Captcha/locales.ts +35 -0
- package/src/components/Captcha/readme.md +5 -0
- package/src/components/Captcha/tests/Captcha.spec.ts +298 -0
- package/src/components/Captcha/tests/__snapshots__/Captcha.spec.ts.snap +716 -0
- package/src/components/Captcha/types.ts +2 -0
- package/src/components/Customs/Selects/SySelect/SySelect.vue +2 -2
- package/src/components/Customs/SyCheckbox/SyCheckbox.vue +4 -0
- package/src/components/Customs/SyForm/SyForm.stories.ts +133 -23
- package/src/components/Customs/SyForm/SyForm.vue +17 -1
- package/src/components/Customs/SyTextField/SyTextField.vue +2 -2
- package/src/components/DatePicker/CalendarMode/DatePicker.vue +1 -1
- package/src/components/DatePicker/ComplexDatePicker/ComplexDatePicker.vue +110 -6
- package/src/components/DatePicker/DateTextInput/DateTextInput.vue +28 -3
- package/src/components/NirField/NirField.stories.ts +74 -0
- package/src/components/NirField/NirField.vue +34 -9
- package/src/components/NirField/locales.ts +1 -3
- package/src/components/PasswordField/PasswordField.vue +39 -7
- package/src/components/PhoneField/PhoneField.vue +43 -10
- package/src/components/index.ts +1 -0
- package/src/composables/validation/useFormValidation.ts +46 -8
- package/src/composables/validation/useValidatable.ts +19 -8
- package/dist/main-DMXtXK3y.js +0 -33458
- package/src/components/Amelipro/AmeliproFooter/tests/AmeliproFooter.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproFooter/tests/__snapshots__/AmeliproFooter.spec.ts.snap +0 -432
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/AmeliproHeaderBrandSection.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/AmeliproHeaderBrandSection/tests/__snapshots__/AmeliproHeaderBrandSection.spec.ts.snap +0 -131
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/AmeliproHeaderBar.spec.ts +0 -15
- package/src/components/Amelipro/AmeliproHeader/AmeliproHeaderBar/tests/__snapshots__/AmeliproHeaderBar.spec.ts.snap +0 -172
- package/src/components/Amelipro/AmeliproHeader/tests/AmeliproHeader.spec.ts +0 -159
- package/src/components/Amelipro/AmeliproHeader/tests/__snapshots__/AmeliproHeader.spec.ts.snap +0 -841
- package/src/components/Amelipro/AmeliproMenu/tests/AmeliproMenu.spec.ts +0 -85
- package/src/components/Amelipro/AmeliproMenu/tests/__snapshots__/AmeliproMenu.spec.ts.snap +0 -537
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/AmeliproDropdownMenuBtn.spec.ts +0 -16
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/AmeliproDropdownMenuBtn/tests/__snapshots__/AmeliproDropdownMenuBtn.spec.ts.snap +0 -56
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/AmeliproDropdownMenu.spec.ts +0 -28
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproDropdownMenu/tests/__snapshots__/AmeliproDropdownMenu.spec.ts.snap +0 -300
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/AmeliproMessagingMenuBtn.spec.ts +0 -16
- package/src/components/Amelipro/AmeliproMessagingLayout/AmeliproMessagingMenuBtn/tests/__snapshots__/AmeliproMessagingMenuBtn.spec.ts.snap +0 -89
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { VueWrapper, mount, shallowMount } from '@vue/test-utils'
|
|
2
|
+
import { beforeEach, describe, expect, it } from 'vitest'
|
|
3
|
+
import { AmeliproBtn } from '@/components'
|
|
4
|
+
import AmeliproDropdownMenu from '../AmeliproDropdownMenu.vue'
|
|
5
|
+
import type { ComponentProps } from 'vue-component-type-helpers'
|
|
6
|
+
import type { DropdownItem } from '../types'
|
|
7
|
+
import type { ExpectedPropOptions } from '@tests/types'
|
|
8
|
+
import type { PropType } from 'vue'
|
|
9
|
+
import TestHelper from '@tests/helpers/TestHelper'
|
|
10
|
+
import { attachToApp } from '@tests/helpers/utils'
|
|
11
|
+
|
|
12
|
+
const expectedPropOptions: ExpectedPropOptions<typeof AmeliproDropdownMenu> = {
|
|
13
|
+
items: {
|
|
14
|
+
type: Array as PropType<DropdownItem[]>,
|
|
15
|
+
required: true,
|
|
16
|
+
},
|
|
17
|
+
label: {
|
|
18
|
+
type: String,
|
|
19
|
+
required: true,
|
|
20
|
+
},
|
|
21
|
+
menuWidth: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: '100%',
|
|
24
|
+
},
|
|
25
|
+
uniqueId: {
|
|
26
|
+
type: String,
|
|
27
|
+
required: true,
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Values pour les props "required"
|
|
32
|
+
const requiredPropValues = (): ComponentProps<typeof AmeliproDropdownMenu> => ({
|
|
33
|
+
items: [],
|
|
34
|
+
label: 'Required label',
|
|
35
|
+
uniqueId: 'required-unique-id',
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const items = (): DropdownItem[] => ([
|
|
39
|
+
{
|
|
40
|
+
active: false,
|
|
41
|
+
href: '#',
|
|
42
|
+
label: 'Boîte de réception',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
active: true,
|
|
46
|
+
href: '#',
|
|
47
|
+
label: 'Brouillons',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
active: false,
|
|
51
|
+
href: '#',
|
|
52
|
+
label: 'Archives',
|
|
53
|
+
},
|
|
54
|
+
])
|
|
55
|
+
|
|
56
|
+
// Valeurs pour les props "modified"
|
|
57
|
+
const modifiedPropValues = (): ComponentProps<typeof AmeliproDropdownMenu> => ({
|
|
58
|
+
items: items(),
|
|
59
|
+
label: 'Modified label',
|
|
60
|
+
menuWidth: '500px',
|
|
61
|
+
uniqueId: 'modified-unique-id',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const testHelper = new TestHelper(AmeliproDropdownMenu)
|
|
65
|
+
testHelper.setExpectedPropOptions(expectedPropOptions)
|
|
66
|
+
.setRequiredPropValues(requiredPropValues)
|
|
67
|
+
.setModifiedPropValues(modifiedPropValues)
|
|
68
|
+
|
|
69
|
+
describe('AmeliproDropdownMenu', () => {
|
|
70
|
+
describe('Snapshots', () => {
|
|
71
|
+
testHelper.snapshots()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('Properties', () => {
|
|
75
|
+
testHelper.properties()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
describe('Setting props should update attributes of inner tags', () => {
|
|
79
|
+
let vueWrapper: VueWrapper<InstanceType<typeof AmeliproDropdownMenu>>
|
|
80
|
+
|
|
81
|
+
describe('root', () => {
|
|
82
|
+
beforeEach(() => {
|
|
83
|
+
vueWrapper = shallowMount(AmeliproDropdownMenu, { props: requiredPropValues() })
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('prop uniqueId sets attribute id', async () => {
|
|
87
|
+
expect(vueWrapper.attributes('id')).toBe(testHelper.default('uniqueId'))
|
|
88
|
+
|
|
89
|
+
const { uniqueId } = modifiedPropValues()
|
|
90
|
+
await vueWrapper.setProps({ uniqueId })
|
|
91
|
+
expect(vueWrapper.attributes('id')).toBe(testHelper.modified('uniqueId'))
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('prop menuWidth sets attribute style', async () => {
|
|
95
|
+
expect(vueWrapper.attributes('style')).toBe(`width: ${testHelper.default('menuWidth')};`)
|
|
96
|
+
|
|
97
|
+
const { menuWidth } = modifiedPropValues()
|
|
98
|
+
await vueWrapper.setProps({ menuWidth })
|
|
99
|
+
expect(vueWrapper.attributes('style')).toBe(`width: ${testHelper.modified('menuWidth')};`)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe('dropdown menu list', () => {
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
vueWrapper = shallowMount(AmeliproDropdownMenu, { props: requiredPropValues() })
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('prop uniqueId sets attribute id', async () => {
|
|
109
|
+
expect(vueWrapper.find('.dropdown-menu__list').attributes('id')).toBe(`${testHelper.default('uniqueId')}-menu`)
|
|
110
|
+
|
|
111
|
+
const { uniqueId } = modifiedPropValues()
|
|
112
|
+
await vueWrapper.setProps({ uniqueId })
|
|
113
|
+
expect(vueWrapper.find('.dropdown-menu__list').attributes('id')).toBe(`${testHelper.modified('uniqueId')}-menu`)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('prop label sets attribute aria-label', async () => {
|
|
117
|
+
expect(vueWrapper.find('.dropdown-menu__list').attributes('aria-label')).toBe(testHelper.default('label'))
|
|
118
|
+
|
|
119
|
+
const { label } = modifiedPropValues()
|
|
120
|
+
await vueWrapper.setProps({ label })
|
|
121
|
+
expect(vueWrapper.find('.dropdown-menu__list').attributes('aria-label')).toBe(testHelper.modified('label'))
|
|
122
|
+
})
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// describe.todo('dropdown menu item')
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('Setting props should update props or attributes of inner components', () => {
|
|
129
|
+
let vueWrapper: VueWrapper<InstanceType<typeof AmeliproDropdownMenu>>
|
|
130
|
+
|
|
131
|
+
describe('AmeliproBtn', () => {
|
|
132
|
+
beforeEach(() => {
|
|
133
|
+
vueWrapper = shallowMount(AmeliproDropdownMenu, { props: requiredPropValues() })
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it('prop uniqueId sets prop uniqueId', async () => {
|
|
137
|
+
expect(vueWrapper.findComponent(AmeliproBtn).props('uniqueId')).toBe(`${testHelper.default('uniqueId')}-btn`)
|
|
138
|
+
|
|
139
|
+
const { uniqueId } = modifiedPropValues()
|
|
140
|
+
await vueWrapper.setProps({ uniqueId })
|
|
141
|
+
expect(vueWrapper.findComponent(AmeliproBtn).props('uniqueId')).toBe(`${testHelper.modified('uniqueId')}-btn`)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
it('prop uniqueId sets prop aria-controls', async () => {
|
|
145
|
+
expect(vueWrapper.findComponent(AmeliproBtn).attributes('aria-controls')).toBe(`${testHelper.default('uniqueId')}-menu`)
|
|
146
|
+
|
|
147
|
+
const { uniqueId } = modifiedPropValues()
|
|
148
|
+
await vueWrapper.setProps({ uniqueId })
|
|
149
|
+
expect(vueWrapper.findComponent(AmeliproBtn).attributes('aria-controls')).toBe(`${testHelper.modified('uniqueId')}-menu`)
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
// describe.todo('AmeliproDropdownMenuBtn')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
// Apparemment, Vitest ne modifie pas document.activeElement (contrairement à Jest)
|
|
157
|
+
// On ne peut pas se baser sur ça pour identifier l'élément actif...
|
|
158
|
+
// CF : https://stackoverflow.com/questions/78798672/vue-3-and-vitest-focus-input-sets-document-activeelement-to-htmlbodyelement-in-t
|
|
159
|
+
describe.skip('Functions', () => {
|
|
160
|
+
let vueWrapper: VueWrapper<InstanceType<typeof AmeliproDropdownMenu>>
|
|
161
|
+
const wrapperFinder = () => vueWrapper.find('#test-id-btn')
|
|
162
|
+
|
|
163
|
+
beforeEach(() => {
|
|
164
|
+
vueWrapper = mount(AmeliproDropdownMenu, {
|
|
165
|
+
autoAttach: attachToApp(),
|
|
166
|
+
props: modifiedPropValues(),
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
it('test openMenu', async () => {
|
|
171
|
+
expect(wrapperFinder().exists()).toBe(true)
|
|
172
|
+
// open the menu with down key
|
|
173
|
+
await wrapperFinder().trigger('keyup.down')
|
|
174
|
+
await vueWrapper.vm.$nextTick()
|
|
175
|
+
|
|
176
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
177
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
178
|
+
// close the menu
|
|
179
|
+
await wrapperFinder().trigger('click')
|
|
180
|
+
await vueWrapper.vm.$nextTick()
|
|
181
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('false')
|
|
182
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn');
|
|
183
|
+
// open the menu with up key
|
|
184
|
+
await wrapperFinder().trigger('keyup.up')
|
|
185
|
+
await vueWrapper.vm.$nextTick()
|
|
186
|
+
|
|
187
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
188
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-2');
|
|
189
|
+
// close the menu with click
|
|
190
|
+
await wrapperFinder().trigger('click')
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
it('test closeMenu', async () => {
|
|
194
|
+
// open the menu with down key
|
|
195
|
+
await wrapperFinder().trigger('keyup.down')
|
|
196
|
+
await vueWrapper.vm.$nextTick()
|
|
197
|
+
|
|
198
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
199
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
200
|
+
// close the menu with esc
|
|
201
|
+
await vueWrapper.find('#test-id-btn-0').trigger('keyup.esc')
|
|
202
|
+
await vueWrapper.vm.$nextTick()
|
|
203
|
+
|
|
204
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('false')
|
|
205
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn');
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
it('test pressUp', async () => {
|
|
209
|
+
// open the menu with up key
|
|
210
|
+
await wrapperFinder().trigger('keyup.up')
|
|
211
|
+
await vueWrapper.vm.$nextTick()
|
|
212
|
+
|
|
213
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
214
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-2');
|
|
215
|
+
// press up on the focused btn
|
|
216
|
+
await vueWrapper.find('#test-id-btn-2').trigger('keyup.up')
|
|
217
|
+
await vueWrapper.vm.$nextTick()
|
|
218
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-1');
|
|
219
|
+
// press up on the focused btn
|
|
220
|
+
await vueWrapper.find('#test-id-btn-1').trigger('keyup.up')
|
|
221
|
+
await vueWrapper.vm.$nextTick()
|
|
222
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
223
|
+
// press up on the focused btn
|
|
224
|
+
await vueWrapper.find('#test-id-btn-0').trigger('keyup.up')
|
|
225
|
+
await vueWrapper.vm.$nextTick()
|
|
226
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-2');
|
|
227
|
+
// close the menu with click
|
|
228
|
+
await wrapperFinder().trigger('click')
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('test pressDown', async () => {
|
|
232
|
+
// open the menu with down key
|
|
233
|
+
await wrapperFinder().trigger('keyup.down')
|
|
234
|
+
await vueWrapper.vm.$nextTick()
|
|
235
|
+
|
|
236
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
237
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
238
|
+
// expect(vueWrapper.find('#test-id-btn-0').element.matches(':focus')).toBe(true);
|
|
239
|
+
// press down on the focused btn
|
|
240
|
+
await vueWrapper.find('#test-id-btn-0').trigger('keyup.down')
|
|
241
|
+
await vueWrapper.vm.$nextTick()
|
|
242
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-1');
|
|
243
|
+
// press down on the focused btn
|
|
244
|
+
await vueWrapper.find('#test-id-btn-1').trigger('keyup.down')
|
|
245
|
+
await vueWrapper.vm.$nextTick()
|
|
246
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-2');
|
|
247
|
+
// press down on the focused btn
|
|
248
|
+
await vueWrapper.find('#test-id-btn-2').trigger('keyup.down')
|
|
249
|
+
await vueWrapper.vm.$nextTick()
|
|
250
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
251
|
+
// close the menu with click
|
|
252
|
+
await wrapperFinder().trigger('click')
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('test pressCharacter', async () => {
|
|
256
|
+
// open the menu with down key
|
|
257
|
+
await wrapperFinder().trigger('keyup.down')
|
|
258
|
+
await vueWrapper.vm.$nextTick()
|
|
259
|
+
|
|
260
|
+
expect(wrapperFinder().attributes('aria-expanded')).toStrictEqual('true')
|
|
261
|
+
// expect(document.activeElement?.id).toStrictEqual('test-id-btn-0');
|
|
262
|
+
// press A to set focus on item 2
|
|
263
|
+
await vueWrapper.find('#test-id-btn-0').trigger('keyup', { key: 'A' })
|
|
264
|
+
})
|
|
265
|
+
})
|
|
266
|
+
})
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`AmeliproDropdownMenu > Snapshots > renders the component with all properties filled in 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
class="dropdown-menu"
|
|
6
|
+
id="modified-unique-id"
|
|
7
|
+
style="width: 500px;"
|
|
8
|
+
>
|
|
9
|
+
<amelipro-btn-stub
|
|
10
|
+
aria-controls="modified-unique-id-menu"
|
|
11
|
+
aria-expanded="false"
|
|
12
|
+
aria-haspopup="true"
|
|
13
|
+
badge="false"
|
|
14
|
+
badgebgcolor="ap-pink"
|
|
15
|
+
badgecolor="ap-white"
|
|
16
|
+
bordered="false"
|
|
17
|
+
class="
|
|
18
|
+
dropdown-menu__open-btn
|
|
19
|
+
font-weight-bold
|
|
20
|
+
text-h6
|
|
21
|
+
text-none
|
|
22
|
+
w-100
|
|
23
|
+
"
|
|
24
|
+
color="ap-white"
|
|
25
|
+
disabled="false"
|
|
26
|
+
hovercolor="ap-grey-lighten-4"
|
|
27
|
+
hoverunderline="false"
|
|
28
|
+
iconbgcolor="transparent"
|
|
29
|
+
iconbordered="false"
|
|
30
|
+
iconleft="false"
|
|
31
|
+
infoblock="false"
|
|
32
|
+
minheight="2.5rem"
|
|
33
|
+
size="60px"
|
|
34
|
+
text="false"
|
|
35
|
+
textcolor="ap-grey-darken-1"
|
|
36
|
+
type="button"
|
|
37
|
+
underline="false"
|
|
38
|
+
uniqueid="modified-unique-id-btn"
|
|
39
|
+
></amelipro-btn-stub>
|
|
40
|
+
<ul
|
|
41
|
+
aria-label="Modified label"
|
|
42
|
+
class="
|
|
43
|
+
ap-white
|
|
44
|
+
dropdown-menu__list
|
|
45
|
+
list-style-none
|
|
46
|
+
"
|
|
47
|
+
id="modified-unique-id-menu"
|
|
48
|
+
role="menu"
|
|
49
|
+
style="display: none;"
|
|
50
|
+
>
|
|
51
|
+
<li
|
|
52
|
+
class="dropdown-menu__item"
|
|
53
|
+
role="none"
|
|
54
|
+
>
|
|
55
|
+
<amelipro-dropdown-menu-btn-stub
|
|
56
|
+
href="#"
|
|
57
|
+
label="Boîte de réception"
|
|
58
|
+
uniqueid="modified-unique-id-btn-0"
|
|
59
|
+
></amelipro-dropdown-menu-btn-stub>
|
|
60
|
+
</li>
|
|
61
|
+
<li
|
|
62
|
+
class="dropdown-menu__item"
|
|
63
|
+
role="none"
|
|
64
|
+
>
|
|
65
|
+
<amelipro-dropdown-menu-btn-stub
|
|
66
|
+
href="#"
|
|
67
|
+
label="Brouillons"
|
|
68
|
+
uniqueid="modified-unique-id-btn-1"
|
|
69
|
+
></amelipro-dropdown-menu-btn-stub>
|
|
70
|
+
</li>
|
|
71
|
+
<li
|
|
72
|
+
class="dropdown-menu__item"
|
|
73
|
+
role="none"
|
|
74
|
+
>
|
|
75
|
+
<amelipro-dropdown-menu-btn-stub
|
|
76
|
+
href="#"
|
|
77
|
+
label="Archives"
|
|
78
|
+
uniqueid="modified-unique-id-btn-2"
|
|
79
|
+
></amelipro-dropdown-menu-btn-stub>
|
|
80
|
+
</li>
|
|
81
|
+
</ul>
|
|
82
|
+
</div>
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
exports[`AmeliproDropdownMenu > Snapshots > renders the component with only required properties filled in 1`] = `
|
|
86
|
+
<div
|
|
87
|
+
class="dropdown-menu"
|
|
88
|
+
id="required-unique-id"
|
|
89
|
+
style="width: 100%;"
|
|
90
|
+
>
|
|
91
|
+
<amelipro-btn-stub
|
|
92
|
+
aria-controls="required-unique-id-menu"
|
|
93
|
+
aria-expanded="false"
|
|
94
|
+
aria-haspopup="true"
|
|
95
|
+
badge="false"
|
|
96
|
+
badgebgcolor="ap-pink"
|
|
97
|
+
badgecolor="ap-white"
|
|
98
|
+
bordered="false"
|
|
99
|
+
class="
|
|
100
|
+
dropdown-menu__open-btn
|
|
101
|
+
font-weight-bold
|
|
102
|
+
text-h6
|
|
103
|
+
text-none
|
|
104
|
+
w-100
|
|
105
|
+
"
|
|
106
|
+
color="ap-white"
|
|
107
|
+
disabled="false"
|
|
108
|
+
hovercolor="ap-grey-lighten-4"
|
|
109
|
+
hoverunderline="false"
|
|
110
|
+
iconbgcolor="transparent"
|
|
111
|
+
iconbordered="false"
|
|
112
|
+
iconleft="false"
|
|
113
|
+
infoblock="false"
|
|
114
|
+
minheight="2.5rem"
|
|
115
|
+
size="60px"
|
|
116
|
+
text="false"
|
|
117
|
+
textcolor="ap-grey-darken-1"
|
|
118
|
+
type="button"
|
|
119
|
+
underline="false"
|
|
120
|
+
uniqueid="required-unique-id-btn"
|
|
121
|
+
></amelipro-btn-stub>
|
|
122
|
+
<ul
|
|
123
|
+
aria-label="Required label"
|
|
124
|
+
class="
|
|
125
|
+
ap-white
|
|
126
|
+
dropdown-menu__list
|
|
127
|
+
list-style-none
|
|
128
|
+
"
|
|
129
|
+
id="required-unique-id-menu"
|
|
130
|
+
role="menu"
|
|
131
|
+
style="display: none;"
|
|
132
|
+
></ul>
|
|
133
|
+
</div>
|
|
134
|
+
`;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import AmeliproMessagingMenuBtn from '../AmeliproMessagingMenuBtn.vue'
|
|
2
|
+
import type { ComponentProps } from 'vue-component-type-helpers'
|
|
3
|
+
import type { ExpectedPropOptions } from '@tests/types'
|
|
4
|
+
import type { PropType } from 'vue'
|
|
5
|
+
import type { RouteLocationRaw } from 'vue-router'
|
|
6
|
+
import TestHelper from '@tests/helpers/TestHelper'
|
|
7
|
+
import { describe } from 'vitest'
|
|
8
|
+
|
|
9
|
+
const expectedPropOptions: ExpectedPropOptions<typeof AmeliproMessagingMenuBtn> = {
|
|
10
|
+
active: {
|
|
11
|
+
type: Boolean,
|
|
12
|
+
default: false,
|
|
13
|
+
},
|
|
14
|
+
href: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: undefined,
|
|
17
|
+
},
|
|
18
|
+
icon: {
|
|
19
|
+
type: String,
|
|
20
|
+
default: undefined,
|
|
21
|
+
},
|
|
22
|
+
label: {
|
|
23
|
+
type: String,
|
|
24
|
+
default: undefined,
|
|
25
|
+
},
|
|
26
|
+
to: {
|
|
27
|
+
type: [Array, Object, String] as PropType<RouteLocationRaw>,
|
|
28
|
+
default: undefined,
|
|
29
|
+
},
|
|
30
|
+
uniqueId: {
|
|
31
|
+
type: String,
|
|
32
|
+
required: true,
|
|
33
|
+
},
|
|
34
|
+
unreadNumber: {
|
|
35
|
+
type: Number,
|
|
36
|
+
default: undefined,
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Values pour les props "required"
|
|
41
|
+
const requiredPropValues = (): ComponentProps<typeof AmeliproMessagingMenuBtn> => ({ uniqueId: 'required-unique-id' })
|
|
42
|
+
|
|
43
|
+
// Valeurs pour les props "modified"
|
|
44
|
+
const modifiedPropValues = (): ComponentProps<typeof AmeliproMessagingMenuBtn> => ({
|
|
45
|
+
active: true,
|
|
46
|
+
href: '#modified',
|
|
47
|
+
icon: 'modified-plus',
|
|
48
|
+
label: 'Modified label',
|
|
49
|
+
to: '/modified-home',
|
|
50
|
+
uniqueId: 'modified-unique-id',
|
|
51
|
+
unreadNumber: 5,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const testHelper = new TestHelper(AmeliproMessagingMenuBtn)
|
|
55
|
+
testHelper.setExpectedPropOptions(expectedPropOptions)
|
|
56
|
+
.setRequiredPropValues(requiredPropValues)
|
|
57
|
+
.setModifiedPropValues(modifiedPropValues)
|
|
58
|
+
|
|
59
|
+
describe('AmeliproMessagingMenuBtn', () => {
|
|
60
|
+
describe('Snapshots', () => {
|
|
61
|
+
testHelper.snapshots()
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
describe('Properties', () => {
|
|
65
|
+
testHelper.properties()
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
// const wrapper = mount(AmeliproMessagingMenuBtn, {
|
|
69
|
+
// props: modifiedPropValues(),
|
|
70
|
+
// stubs: { AmeliproIcon },
|
|
71
|
+
// });
|
|
72
|
+
})
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`AmeliproMessagingMenuBtn > Snapshots > renders the component with all properties filled in 1`] = `
|
|
4
|
+
<amelipro-btn-stub
|
|
5
|
+
active="true"
|
|
6
|
+
badge="false"
|
|
7
|
+
badgebgcolor="ap-pink"
|
|
8
|
+
badgecolor="ap-white"
|
|
9
|
+
bordered="false"
|
|
10
|
+
class="
|
|
11
|
+
font-weight-bold
|
|
12
|
+
mb-1
|
|
13
|
+
messaging-menu__btn
|
|
14
|
+
text-h6
|
|
15
|
+
text-none
|
|
16
|
+
w-100
|
|
17
|
+
"
|
|
18
|
+
color="ap-blue-darken-2"
|
|
19
|
+
disabled="false"
|
|
20
|
+
hovercolor="ap-blue-darken-2"
|
|
21
|
+
hoverunderline="false"
|
|
22
|
+
href="#modified"
|
|
23
|
+
iconbgcolor="transparent"
|
|
24
|
+
iconbordered="false"
|
|
25
|
+
iconleft="false"
|
|
26
|
+
infoblock="false"
|
|
27
|
+
minheight="2.5rem"
|
|
28
|
+
size="60px"
|
|
29
|
+
style="min-height: 50px;"
|
|
30
|
+
text="false"
|
|
31
|
+
textcolor="ap-white"
|
|
32
|
+
to="/modified-home"
|
|
33
|
+
type="button"
|
|
34
|
+
underline="false"
|
|
35
|
+
uniqueid="modified-unique-id"
|
|
36
|
+
></amelipro-btn-stub>
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
exports[`AmeliproMessagingMenuBtn > Snapshots > renders the component with only required properties filled in 1`] = `
|
|
40
|
+
<amelipro-btn-stub
|
|
41
|
+
active="false"
|
|
42
|
+
badge="false"
|
|
43
|
+
badgebgcolor="ap-pink"
|
|
44
|
+
badgecolor="ap-white"
|
|
45
|
+
bordered="false"
|
|
46
|
+
class="
|
|
47
|
+
font-weight-bold
|
|
48
|
+
mb-1
|
|
49
|
+
messaging-menu__btn
|
|
50
|
+
text-h6
|
|
51
|
+
text-none
|
|
52
|
+
w-100
|
|
53
|
+
"
|
|
54
|
+
color="ap-blue-darken-1"
|
|
55
|
+
disabled="false"
|
|
56
|
+
hovercolor="ap-blue-darken-2"
|
|
57
|
+
hoverunderline="false"
|
|
58
|
+
iconbgcolor="transparent"
|
|
59
|
+
iconbordered="false"
|
|
60
|
+
iconleft="false"
|
|
61
|
+
infoblock="false"
|
|
62
|
+
minheight="2.5rem"
|
|
63
|
+
size="60px"
|
|
64
|
+
style="min-height: 50px;"
|
|
65
|
+
text="false"
|
|
66
|
+
textcolor="ap-white"
|
|
67
|
+
type="button"
|
|
68
|
+
underline="false"
|
|
69
|
+
uniqueid="required-unique-id"
|
|
70
|
+
></amelipro-btn-stub>
|
|
71
|
+
`;
|
|
@@ -1297,6 +1297,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1297
1297
|
<a
|
|
1298
1298
|
class="
|
|
1299
1299
|
amelipro-btn
|
|
1300
|
+
amelipro-footer__site-map-btn
|
|
1301
|
+
amelipro-footer__site-map-btn
|
|
1300
1302
|
elevation-0
|
|
1301
1303
|
text-ap-white
|
|
1302
1304
|
text-none
|
|
@@ -1342,6 +1344,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1342
1344
|
<a
|
|
1343
1345
|
class="
|
|
1344
1346
|
amelipro-btn
|
|
1347
|
+
amelipro-footer__about-btn
|
|
1348
|
+
amelipro-footer__about-btn
|
|
1345
1349
|
elevation-0
|
|
1346
1350
|
text-ap-white
|
|
1347
1351
|
text-none
|
|
@@ -1387,6 +1391,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1387
1391
|
<a
|
|
1388
1392
|
class="
|
|
1389
1393
|
amelipro-btn
|
|
1394
|
+
amelipro-footer__config-btn
|
|
1395
|
+
amelipro-footer__config-btn
|
|
1390
1396
|
elevation-0
|
|
1391
1397
|
text-ap-white
|
|
1392
1398
|
text-none
|
|
@@ -1432,6 +1438,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1432
1438
|
<a
|
|
1433
1439
|
class="
|
|
1434
1440
|
amelipro-btn
|
|
1441
|
+
amelipro-footer__legal-notice-btn
|
|
1442
|
+
amelipro-footer__legal-notice-btn
|
|
1435
1443
|
elevation-0
|
|
1436
1444
|
text-ap-white
|
|
1437
1445
|
text-none
|
|
@@ -1477,6 +1485,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1477
1485
|
<a
|
|
1478
1486
|
class="
|
|
1479
1487
|
amelipro-btn
|
|
1488
|
+
amelipro-footer__cgu-btn
|
|
1489
|
+
amelipro-footer__cgu-btn
|
|
1480
1490
|
elevation-0
|
|
1481
1491
|
text-ap-white
|
|
1482
1492
|
text-none
|
|
@@ -1522,6 +1532,8 @@ exports[`AmeliproPageLayout > render correctly 1`] = `
|
|
|
1522
1532
|
<a
|
|
1523
1533
|
class="
|
|
1524
1534
|
amelipro-btn
|
|
1535
|
+
amelipro-footer__a11y-btn
|
|
1536
|
+
amelipro-footer__a11y-btn
|
|
1525
1537
|
elevation-0
|
|
1526
1538
|
text-ap-white
|
|
1527
1539
|
text-none
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import {Controls, Canvas, Meta, Source, Story} from '@storybook/blocks';
|
|
2
|
+
import * as CaptchaStories from './Captcha.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={CaptchaStories} />
|
|
5
|
+
|
|
6
|
+
<div className="header">
|
|
7
|
+
<h1>Captcha</h1>
|
|
8
|
+
<p>Le composant `Captcha` est utilisé pour afficher un captcha à l’utilisateur. </p>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<Canvas
|
|
12
|
+
of={CaptchaStories.Default}
|
|
13
|
+
source={{
|
|
14
|
+
language: 'html',
|
|
15
|
+
format: 'dedent',
|
|
16
|
+
code: `
|
|
17
|
+
<script lang="ts" setup>
|
|
18
|
+
import { captcha } from '@cnamts/synapse'
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<VCard class="pa-8" width="400">
|
|
23
|
+
<Captcha
|
|
24
|
+
url-create="..."
|
|
25
|
+
url-get-image="..."
|
|
26
|
+
url-get-audio="/..."
|
|
27
|
+
service="(e) => {
|
|
28
|
+
// call the API to verify the captcha and return the response
|
|
29
|
+
}"
|
|
30
|
+
@validation:success="(e) => { ... }"
|
|
31
|
+
@validation:error="(e) => { ... }"
|
|
32
|
+
/>
|
|
33
|
+
</VCard>
|
|
34
|
+
</template>
|
|
35
|
+
`
|
|
36
|
+
}}
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<Story
|
|
40
|
+
of={CaptchaStories.WarningDocProps}
|
|
41
|
+
/>
|
|
42
|
+
|
|
43
|
+
## API
|
|
44
|
+
|
|
45
|
+
<Controls of={CaptchaStories.Default} />
|
|
46
|
+
|
|
47
|
+
## Context d'utilisation
|
|
48
|
+
|
|
49
|
+
Le composant Captcha permet d'intéragir avec l'api d'OBS [Live Identity Captcha](https://www.orange-business.com/fr/solutions/securite/live-identity-captcha) (directement ou indirectement).
|
|
50
|
+
|
|
51
|
+
Pour implementer le composant avec l'api OBS, se referer à la documentation suivante : [la documentation et le postman de l'api d'OBS version 1.16](https://gitlab.cnqd.cnamts.fr/captcha/capt_postman/-/tree/v1.16).
|
|
52
|
+
|
|
53
|
+
### Détails d'implementation
|
|
54
|
+
|
|
55
|
+
Les api Captcha d'OBS sont exposées en https.
|
|
56
|
+
|
|
57
|
+
Pour les appels réalisés depuis un back-end, il est nécessaire d'ajouter le root CA (autorité de certifications racine) au niveau du truststore du serveur hébergeant ce back-end.
|
|
58
|
+
Pour la production et la pré-production, le root CA "DigiCert Global Root CA" est accessible (voir informations de sécurité) depuis le site : [https://captcha.liveidentity.com/documentation](https://captcha.liveidentity.com/documentation).
|
|
59
|
+
|
|
60
|
+
De plus, les api Captcha d'OBS sont externes / non hébergées par la CNAM.
|
|
61
|
+
Il est donc nécessaire :
|
|
62
|
+
- d'autoriser ces appels sortant dans la liste blanche du firewall Cnam pour la production et le hors prod
|
|
63
|
+
- de réaliser l'ouverture des flux depuis la plateforme d'hébergement (ex : csh-dijon.cnamts.fr)
|
|
64
|
+
Logiquement, ces deux points ont été déjà réalisés.
|
|
65
|
+
|
|
66
|
+
## Précautions d'utilisation
|
|
67
|
+
|
|
68
|
+
Pour permettre une bonne expérience utilisateur et éviter de bloquer des utilisateurs légitimes potentiellement en situation de handicap, il est recommandé de suivre les bonnes pratiques suivantes :
|
|
69
|
+
|
|
70
|
+
- Ne pas utiliser de captcha lorsque l'utilisateur est déjà authentifié.
|
|
71
|
+
- Préférer l'utilisation de captcha invisible (API scoring) lorsque c'est possible.
|
|
72
|
+
- Préferer l'utilisation de captcha uniquement lorsqu'un comportement suspect est détecté (ex : trop de tentatives de connexion échouées).
|