Skip to content

Commit

Permalink
(PC-33528)[PRO] feat: add test to the new component
Browse files Browse the repository at this point in the history
  • Loading branch information
mleroy-pass committed Jan 8, 2025
1 parent c66bf1a commit 90334f3
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 36 deletions.
29 changes: 0 additions & 29 deletions pro/src/ui-kit/MultiSelect/MultiSelect.spec.tsx

This file was deleted.

11 changes: 11 additions & 0 deletions pro/src/ui-kit/MultiSelect/MultiSelect.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,14 @@ export const WithSearchInput: StoryObj<typeof MultiSelect> = {
label: 'Selectionner des départements',
},
}

export const WithSelectAllOption: StoryObj<typeof MultiSelect> = {
args: {
...defaultProps,
hasSelectAllOptions: true,
searchExample: 'Ex : 44 - Nantes',
searchLabel: 'Rechercher des départements',
legend: 'Départements',
label: 'Selectionner des départements',
},
}
10 changes: 3 additions & 7 deletions pro/src/ui-kit/MultiSelect/MultiSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export const MultiSelect = ({
)}

<SelectedValuesTags
disabled={disabled}
disabled={false}
selectedOptions={selectedItems.map((item) => item.id)}
removeOption={handleRemoveItem}
fieldName="tags"
Expand All @@ -137,8 +137,7 @@ export const MultiSelect = ({
)
}

{
/* <fieldset>
/* <fieldset>
<legend><button aria-controls="control-id" aria-expanded=...>Label du bouton</button></legend>
<div id="control-id">
<label class="visually-hidden" for="id-input">Rechercher des ...</label>
Expand Down Expand Up @@ -169,10 +168,8 @@ export const MultiSelect = ({
<div role="option" id="listbox1-6">Pervenche</div>
</div>
*/
}

{
/* <div className={styles.container} role="listbox" aria-label="Liste des départements">
/* <div className={styles.container} role="listbox" aria-label="Liste des départements">
{departments.map(department => (
<label key={department.id} className={styles.item}>
<div className={styles.checkbox}>
Expand All @@ -188,4 +185,3 @@ export const MultiSelect = ({
</label>
))}
</div> */
}
1 change: 1 addition & 0 deletions pro/src/ui-kit/MultiSelect/TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Fonctionnel
Design

- [] corriger la zone de clic sur BaseCheckbox
- [] Passer les selected tag en violet
- [] corriger le curseur de BaseCheckbox
- [] ajuster la hauteur des checkbox
- [] utiliser les fonts du design system
Expand Down
132 changes: 132 additions & 0 deletions pro/src/ui-kit/MultiSelect/__specs__/MultiSelect.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { userEvent } from '@testing-library/user-event'
import { axe } from 'vitest-axe'

import { MultiSelect, Option } from '../MultiSelect'

describe('<MultiSelect />', () => {
const options: Option[] = [
{ id: '1', label: 'Option 1' },
{ id: '2', label: 'Option 2' },
{ id: '3', label: 'Option 3' },
]

const defaultOptions: Option[] = [{ id: '1', label: 'Option 1' }]

it('should render correctly', async () => {
render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
defaultOptions={defaultOptions}
/>
)

expect(await screen.findByText('Select Options')).toBeInTheDocument()
})

it('should not have accessibility violations', async () => {
const { container } = render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
defaultOptions={defaultOptions}
/>
)

expect(await axe(container)).toHaveNoViolations()
})

it('renders the MultiSelect component with the correct initial selected options', () => {
render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
defaultOptions={defaultOptions}
/>
)
// Check that the initial selected options are rendered in the SelectedValuesTags
expect(screen.getByText('Option 1')).toBeInTheDocument()
})

it('toggles the dropdown when the trigger is clicked', async () => {
render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
hasSelectAllOptions={true}
/>
)
const toggleButton = screen.getByText('Select Options')
await userEvent.click(toggleButton) // Open the dropdown
expect(screen.getByText(/Tout sélectionner/i)).toBeInTheDocument()

await userEvent.click(toggleButton) // Close the dropdown
expect(screen.queryByText(/Tout sélectionner/i)).not.toBeInTheDocument()
})

it('selects all options when "Select All" is clicked', async () => {
render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
hasSelectAllOptions={true}
/>
)

const toggleButton = screen.getByText('Select Options')
await userEvent.click(toggleButton) // Open the dropdown

const selectAllCheckbox = screen.getByLabelText(/Tout sélectionner/i)
fireEvent.click(selectAllCheckbox) // Select all options

// Verify that all options are selected
options.forEach((option) => {
expect(screen.getByLabelText(option.label)).toBeChecked()
})
})

it('removes an option from the selected items when clicked in SelectedValuesTags', async () => {
render(
<MultiSelect
options={options}
label="Select Options"
legend="Legend"
defaultOptions={defaultOptions}
/>
)

// Initially, Option 1 is selected
const selectedTag = screen.getByText('Option 1')
await userEvent.click(selectedTag) // Remove Option 1
expect(screen.queryByText('Option 1')).not.toBeInTheDocument()
})

it('closes the dropdown when clicked outside or when Escape key is pressed', async () => {
render(
<MultiSelect options={options} label="Select Options" legend="Legend" />
)

const toggleButton = screen.getByText('Select Options')

fireEvent.click(toggleButton) // Open the dropdown
expect(screen.queryByText('Option 1')).toBeInTheDocument()

// Simulate a click outside the dropdown
fireEvent.click(document.body)
await waitFor(() =>
expect(screen.queryByText('Option 1')).not.toBeInTheDocument()
)

fireEvent.click(toggleButton) // Open the dropdown again
fireEvent.keyDown(toggleButton, { key: 'Escape' }) // Close with Escape key
await waitFor(() =>
expect(screen.queryByText('Option 1')).not.toBeInTheDocument()
)
})
})
99 changes: 99 additions & 0 deletions pro/src/ui-kit/MultiSelect/__specs__/MultiSelectPanel.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { axe } from 'vitest-axe'

import { Option } from '../MultiSelect'
import { MultiSelectPanel } from '../MultiSelectPanel'

describe('<MultiSelectPanel />', () => {
const options: (Option & { checked: boolean })[] = [
{ id: '1', label: 'Option 1', checked: false },
{ id: '2', label: 'Option 2', checked: false },
{ id: '3', label: 'Option 3', checked: false },
]

const defaultOptions: Option[] = [{ id: '1', label: 'Option 1' }]

const onOptionSelect = vi.fn()

it('renders options with checkboxes', () => {
render(
<MultiSelectPanel
options={options}
label={''}
onOptionSelect={function (option: Option | 'all' | undefined): void {
throw new Error('Function not implemented.')
}}
/>
)

expect(screen.getByLabelText('Option 1')).toBeInTheDocument()
expect(screen.getByLabelText('Option 2')).toBeInTheDocument()
expect(screen.getByLabelText('Option 3')).toBeInTheDocument()
})

it('renders the search input if hasSearch is true', () => {
render(
<MultiSelectPanel
options={[]}
label={''}
onOptionSelect={function (option: Option | 'all' | undefined): void {
throw new Error('Function not implemented.')
}}
hasSearch={true}
searchExample="Exemple: Nantes"
/>
)

expect(screen.getByText(/Exemple: Nantes/i)).toBeInTheDocument()
})

it('not renders the search input if hasSearch is false', () => {
render(
<MultiSelectPanel
options={[]}
label={''}
onOptionSelect={function (option: Option | 'all' | undefined): void {
throw new Error('Function not implemented.')
}}
hasSearch={false}
searchExample="Exemple: Nantes"
/>
)

expect(screen.queryByText(/Exemple: Nantes/i)).not.toBeInTheDocument()
})

it('should not have accessibility violations', async () => {
const { container } = render(
<MultiSelectPanel
options={[]}
label={''}
onOptionSelect={function (option: Option | 'all' | undefined): void {
throw new Error('Function not implemented.')
}}
hasSearch={false}
/>
)

expect(await axe(container)).toHaveNoViolations()
})

it('selects and deselects individual options', async () => {
render(
<MultiSelectPanel
options={options}
label=""
onOptionSelect={onOptionSelect}
/>
)

// Initially, only Option 1 is selected
const option2Checkbox = screen.getByLabelText(/Option 2/i)
await userEvent.click(option2Checkbox) // Select Option 2
expect(onOptionSelect).toHaveBeenCalledWith(options[1])

await userEvent.click(option2Checkbox) // Deselect Option 2
expect(onOptionSelect).toHaveBeenCalledWith(options[1])
})
})

0 comments on commit 90334f3

Please sign in to comment.