11import * as React from 'react' ;
2- import { cleanup , render , screen , waitFor } from '@testing-library/react' ;
2+ import { act , cleanup , fireEvent , render , screen , waitFor } from '@testing-library/react' ;
33import { afterEach , describe , it , expect } from 'vitest' ;
44import * as Select from './select' ;
55
@@ -13,10 +13,10 @@ const SelectTest = (props: React.ComponentProps<typeof Select.Root>) => (
1313 < Select . Portal >
1414 < Select . Content position = "popper" >
1515 < Select . Viewport >
16- < Select . Item value = "apple" >
16+ < Select . Item value = "apple" data-testid = "item-apple" >
1717 < Select . ItemText > Apple</ Select . ItemText >
1818 </ Select . Item >
19- < Select . Item value = "banana" >
19+ < Select . Item value = "banana" data-testid = "item-banana" >
2020 < Select . ItemText > Banana</ Select . ItemText >
2121 </ Select . Item >
2222 </ Select . Viewport >
@@ -47,3 +47,87 @@ describe('aria-controls', () => {
4747 expect ( document . getElementById ( content . id ) ) . toBe ( content ) ;
4848 } ) ;
4949} ) ;
50+
51+ describe ( 'given a Select in a form that is reset' , ( ) => {
52+ afterEach ( cleanup ) ;
53+
54+ describe ( 'uncontrolled' , ( ) => {
55+ it ( 'should restore its `defaultValue` when the form is reset' , async ( ) => {
56+ render (
57+ < form >
58+ { /* Keep the content open so the items (and their selection state) stay mounted. */ }
59+ < SelectTest name = "fruit" defaultValue = "apple" open onOpenChange = { ( ) => { } } />
60+ < button type = "reset" > Reset</ button >
61+ </ form > ,
62+ ) ;
63+
64+ const apple = await screen . findByTestId ( 'item-apple' ) ;
65+ const banana = screen . getByTestId ( 'item-banana' ) ;
66+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
67+
68+ act ( ( ) => fireEvent . click ( banana ) ) ;
69+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
70+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'unchecked' ) ;
71+
72+ act ( ( ) => fireEvent . click ( screen . getByText ( 'Reset' ) ) ) ;
73+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
74+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'unchecked' ) ;
75+ } ) ;
76+
77+ it ( 'should restore the placeholder when reset with no initial value' , async ( ) => {
78+ render (
79+ < form >
80+ { /* Keep the content open so the items (and their selection state) stay mounted. */ }
81+ < SelectTest name = "fruit" open onOpenChange = { ( ) => { } } />
82+ < button type = "reset" > Reset</ button >
83+ </ form > ,
84+ ) ;
85+
86+ const banana = await screen . findByTestId ( 'item-banana' ) ;
87+ // No value selected initially, so the placeholder is shown.
88+ expect ( screen . getByText ( PLACEHOLDER_TEXT ) ) . toBeInTheDocument ( ) ;
89+
90+ act ( ( ) => fireEvent . click ( banana ) ) ;
91+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
92+ expect ( screen . queryByText ( PLACEHOLDER_TEXT ) ) . not . toBeInTheDocument ( ) ;
93+
94+ act ( ( ) => fireEvent . click ( screen . getByText ( 'Reset' ) ) ) ;
95+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'unchecked' ) ;
96+ expect ( screen . getByText ( PLACEHOLDER_TEXT ) ) . toBeInTheDocument ( ) ;
97+ } ) ;
98+ } ) ;
99+
100+ describe ( 'controlled' , ( ) => {
101+ it ( 'should restore its initial `value` when the form is reset' , async ( ) => {
102+ function ControlledSelect ( ) {
103+ const [ value , setValue ] = React . useState ( 'apple' ) ;
104+ return (
105+ < form >
106+ < SelectTest
107+ name = "fruit"
108+ value = { value }
109+ onValueChange = { setValue }
110+ open
111+ onOpenChange = { ( ) => { } }
112+ />
113+ < button type = "reset" > Reset</ button >
114+ </ form >
115+ ) ;
116+ }
117+
118+ render ( < ControlledSelect /> ) ;
119+
120+ const apple = await screen . findByTestId ( 'item-apple' ) ;
121+ const banana = screen . getByTestId ( 'item-banana' ) ;
122+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
123+
124+ act ( ( ) => fireEvent . click ( banana ) ) ;
125+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
126+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'unchecked' ) ;
127+
128+ act ( ( ) => fireEvent . click ( screen . getByText ( 'Reset' ) ) ) ;
129+ expect ( apple ) . toHaveAttribute ( 'data-state' , 'checked' ) ;
130+ expect ( banana ) . toHaveAttribute ( 'data-state' , 'unchecked' ) ;
131+ } ) ;
132+ } ) ;
133+ } ) ;
0 commit comments