diff --git a/src/client/components/ui/Select/Select.test.tsx b/src/client/components/ui/Select/Select.test.tsx index 9a9c7e533b..3f15a2359b 100644 --- a/src/client/components/ui/Select/Select.test.tsx +++ b/src/client/components/ui/Select/Select.test.tsx @@ -3,438 +3,326 @@ */ import '@testing-library/jest-dom'; -import { fireEvent, render, screen, waitFor, within } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; import React from 'react'; import { KeyBoard } from '~/client/components/keyboard.fixture'; import { Select } from '~/client/components/ui/Select/Select'; -import { mapTypeDeContratToOffreEmploiCheckboxFiltre } from '~/client/utils/offreEmploi.mapper'; -import { Offre } from '~/server/offres/domain/offre'; -describe('Select', () => { - describe('Select Single', () => { - it('quand on clique sur le select, retourne une liste d‘options', async () => { - //GIVEN - const user = userEvent.setup(); - render( - ', () => { + describe('interaction support', () => { + describe('quand la liste d‘options est fermée', () => { + it('les options sont masquées', () => { + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(, - ); - - //WHEN - const button = screen.getByRole('button', { name: 'Temps de travail' }); - fireEvent.click(button); - const listbox = screen.getByRole('listbox'); - const input = within(listbox).getByRole('radio', { name: 'Temps plein' }); - fireEvent.click(input); - - //THEN - await waitFor(async () => { - const placeholder = await screen.findByTestId('Select-Placeholder'); - expect(placeholder.textContent).toEqual('Temps plein'); + describe('lorsque l‘utilisateur fait "Entrer"', () => { + it('ouvre la liste d‘options', async () => { + const user = userEvent.setup(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(); + + await user.tab(); + await user.keyboard(KeyBoard.SPACE); - it('quand on sélectionne une valeur, on appelle la fonction onChange passée au select', async () => { - //GIVEN - const onChangeSpy = jest.fn(); - render( - , - ); - - // When - const input = await screen.findByTestId('Select-InputHidden'); - - // Then - expect(input).toBeRequired(); - expect(input).toHaveAttribute('aria-invalid', 'false'); + describe('simple select', () => { + it('l‘utilisateur séléctionne une option avec la souris, séléctionne l‘option et ferme la liste d‘option', async () => { + const user = userEvent.setup(); + const onChange = jest.fn(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render( - - , - ); - // When - await userEvent.click(screen.getByText('Mon Select')); - await userEvent.click(screen.getByText('escape')); - - // When - const input = await screen.findByTestId('Select-InputHidden'); - - // Then - expect(input).toBeInvalid(); + describe('quand la liste d‘options est ouverte', () => { + it.todo('lorsque l‘utilisateur fait "Entrer", l‘option qui a le focus visuel est séléctionné et la liste d‘option se ferme'); + + it('lorsque l‘utilisateur fait "Espace", l‘option qui a le focus visuel est séléctionné et la liste d‘option se ferme', async () => { + const user = userEvent.setup(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(); + + await user.tab(); + await user.keyboard(KeyBoard.ENTER); + await user.keyboard(KeyBoard.ARROW_DOWN); + await user.keyboard(KeyBoard.ESCAPE); + + expect(screen.getByRole('textbox', { hidden: true })).toHaveValue(''); + expect(screen.queryByRole('option')).not.toBeInTheDocument(); }); - it('a un message d‘erreur', async () => { - // Given - render( - <> - - , - ); - - //WHEN - const button = screen.getByRole('button', { name: 'Type de contrat' }); - await user.click(button); - screen.getByRole('listbox'); - - //THEN - expect(screen.getByRole('checkbox', { name: 'CDD' })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: 'CDI' })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: 'Intérim' })).toBeInTheDocument(); - expect(screen.getByRole('checkbox', { name: 'Saisonnier' })).toBeInTheDocument(); - }); + describe('choix multiple select', () => { + it('l‘utilisateur séléctionne une option avec la souris, l‘option est ajoutée aux options séléctionnés et la liste d‘option ne se ferme pas', async () => { + const user = userEvent.setup(); + const onChange = jest.fn(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(, - ); - - //WHEN - const button = screen.getByRole('button', { name: 'Type de contrat' }); - fireEvent.click(button); - const listbox = await screen.findByRole('listbox'); - const input = within(listbox).getAllByRole('checkbox'); - fireEvent.click(input[1]); - - //THEN - await waitFor(async () => { - const placeholder = await screen.findByTestId('Select-Placeholder'); - expect(placeholder.textContent).toEqual('1 choix sélectionné'); + await user.click(screen.getByText('options 2')); + expect(inputValue).toHaveValue('1,2'); + + expect(screen.getAllByRole('option').length).toBe(2); }); - const hiddenInput = await screen.findByTestId('Select-InputHidden'); - expect(hiddenInput).toHaveValue('CDI'); - }); + describe('quand la liste d‘options est ouverte', () => { + it.todo('lorsque l‘utilisateur fait "Entrer", l‘option qui a le focus visuel est ajoutée aux options séléctionnés et la liste d‘option se ferme'); - it('quand on sélectionne une valeur, on appelle la fonction onChange passée au select', async () => { - // GIVEN - const user = userEvent.setup(); - const onChangeSpy = jest.fn(); - render( - ); + + await user.tab(); + await user.keyboard(KeyBoard.ENTER); + await user.keyboard(KeyBoard.ARROW_DOWN); + await user.keyboard(KeyBoard.SPACE); + + expect(screen.getByRole('textbox', { hidden: true })).toHaveValue('1,2'); + expect(screen.getAllByRole('option').length).toBe(2); + }); + + it.todo('lorsque l‘utilisateur fait "alt + fleche du haut", l‘option qui a le focus visuel est séléctionné et la liste d‘option se ferme'); + + it.todo('lorsque l‘utilisateur fait "Tab", l‘option qui a le focus visuel est séléctionné, la liste d‘option se ferme et le focus se déplace sur le prochain élément focusable'); + + it('lorsque l‘utilisateur fait "echap", ferme la liste d‘option sans séléctionner l‘option qui a le focus visuel', async () => { + const user = userEvent.setup(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(, - ); - const button = screen.getByRole('button', { name: 'Temps de travail' }); - button.focus(); + const onChange = jest.fn(); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(, - ); - const button = screen.getByRole('button', { name: 'Temps de travail' }); - button.focus(); - await user.keyboard(KeyBoard.SPACE); - const optionList = await screen.findByRole('listbox'); + it('accepte un label et le lie au select', () => { + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + render(); - expect(optionList).not.toBeInTheDocument(); + // TODO (BRUJ 24/04/2024): devrait être un combobox + expect(screen.getByRole('button', { name: 'label complement label' })).toBeVisible(); }); - it('a le focus sur la première option quand on ouvre la liste des options', async () => { + it('accepte une liste d‘options', async () => { const user = userEvent.setup(); - render( - ); - expect(firstOption).toHaveFocus(); - expect(secondOption).not.toHaveFocus(); - }); + await user.tab(); + await user.keyboard(KeyBoard.ENTER); - it('change le focus avec les touches arrow', async () => { - const user = userEvent.setup(); - render( - ); - await user.keyboard(KeyBoard.ARROW_DOWN); + expect(screen.getByRole('textbox', { hidden: true })).toHaveValue('1'); + }); - expect(firstOption).not.toHaveFocus(); - expect(secondOption).toHaveFocus(); + it('lorsque la value change, le select prend la valeur de value mise à jour', () => { + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; + let valueThatCanChange = '1'; - await user.keyboard(KeyBoard.ARROW_UP); + const { rerender } = render(, - ); - const button = screen.getByRole('button', { name: 'Temps de travail' }); - button.focus(); - await user.keyboard(KeyBoard.SPACE); // ouverture de la liste des options - const optionList = await screen.findByRole('listbox'); - const firstOption = within(optionList).getAllByRole('option')[0]; - - expect(firstOption).toHaveFocus(); - - await user.keyboard(KeyBoard.ARROW_DOWN); // focus de la deuxième option - - await user.keyboard(KeyBoard.SPACE); // choix de la deuxième option - - const hiddenInput = await screen.findByTestId('Select-InputHidden'); - expect(hiddenInput).toHaveValue('tempsPartiel'); - - expect(optionList).not.toBeInTheDocument(); + rerender(, - ); - const button = screen.getByRole('button', { name: 'Temps de travail' }); - button.focus(); - await user.keyboard(KeyBoard.SPACE); - const optionList = await screen.findByRole('listbox'); + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; - expect(screen.getByRole('radio', { name: 'Temps plein' })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: 'Temps partiel' })).toBeInTheDocument(); - expect(screen.getByRole('radio', { name: 'Indifférent' })).toBeInTheDocument(); + render(
+ , - ); - - - const button = screen.getByRole('button', { name: 'Type de contrat' }); - button.focus(); - await user.keyboard(KeyBoard.SPACE); - const optionList = await screen.findByRole('listbox'); - const firstOption = within(optionList).getAllByRole('option')[0]; - const secondOption = within(optionList).getAllByRole('option')[1]; + const options = [{ libellé: 'options 1', valeur: '1' }, { libellé: 'options 2', valeur: '2' }]; - expect(firstOption).toHaveFocus(); + render( +