11import type { EvaluationContext } from '@openfeature/web-sdk' ;
2- import { InMemoryProvider , OpenFeature } from '@openfeature/web-sdk' ;
2+ import { InMemoryProvider , OpenFeature , ProviderEvents } from '@openfeature/web-sdk' ;
33import '@testing-library/jest-dom' ; // see: https://testing-library.com/docs/react-testing-library/setup
44import { render , renderHook , screen , waitFor , fireEvent , act } from '@testing-library/react' ;
55import * as React from 'react' ;
@@ -164,8 +164,18 @@ describe('OpenFeatureProvider', () => {
164164 describe ( 'useMutateContext' , ( ) => {
165165 const MutateButton = ( { setter } : { setter ?: ( prevContext : EvaluationContext ) => EvaluationContext } ) => {
166166 const { setContext } = useContextMutator ( ) ;
167+ const [ loading , setLoading ] = React . useState ( false ) ;
167168
168- return < button onClick = { ( ) => setContext ( setter ?? { user :
'[email protected] ' } ) } > Update Context
</ button > ; 169+ return (
170+ < button
171+ onClick = { ( ) => {
172+ setLoading ( true ) ;
173+ setContext ( setter ?? { user :
'[email protected] ' } ) . finally ( ( ) => setLoading ( false ) ) ; 174+ } }
175+ >
176+ { loading ? 'Updating context...' : 'Update Context' }
177+ </ button >
178+ ) ;
169179 } ;
170180
171181 const TestComponent = ( { name, setter } : { name : string ; setter ?: ( prevContext : EvaluationContext ) => EvaluationContext } ) => {
@@ -182,6 +192,10 @@ describe('OpenFeatureProvider', () => {
182192 it ( 'should update context when a domain is set' , async ( ) => {
183193 const DOMAIN = 'mutate-context-tests' ;
184194 OpenFeature . setProvider ( DOMAIN , suspendingProvider ( ) ) ;
195+
196+ const changed = jest . fn ( ) ;
197+ OpenFeature . getClient ( DOMAIN ) . addHandler ( ProviderEvents . ContextChanged , changed ) ;
198+
185199 render (
186200 < OpenFeatureProvider domain = { DOMAIN } >
187201 < React . Suspense fallback = { < div > { FALLBACK } </ div > } >
@@ -197,12 +211,17 @@ describe('OpenFeatureProvider', () => {
197211 act ( ( ) => {
198212 fireEvent . click ( screen . getByText ( 'Update Context' ) ) ;
199213 } ) ;
214+ expect ( screen . getByText ( 'Updating context...' ) ) . toBeInTheDocument ( ) ;
215+
200216 await waitFor (
201217 ( ) => {
202- expect ( screen . getByText ( 'Will says aloha ' ) ) . toBeInTheDocument ( ) ;
218+ expect ( screen . getByText ( 'Update Context ' ) ) . toBeInTheDocument ( ) ;
203219 } ,
204- { timeout : DELAY * 4 } ,
220+ { timeout : DELAY * 2 } ,
205221 ) ;
222+ expect ( changed ) . toHaveBeenCalledTimes ( 1 ) ;
223+
224+ expect ( screen . getByText ( 'Will says aloha' ) ) . toBeInTheDocument ( ) ;
206225 } ) ;
207226
208227 it ( 'should update nested contexts' , async ( ) => {
@@ -231,18 +250,17 @@ describe('OpenFeatureProvider', () => {
231250 // Click the Update context button in Todds domain
232251 fireEvent . click ( screen . getAllByText ( 'Update Context' ) [ 1 ] ) ;
233252 } ) ;
253+ expect ( screen . getByText ( 'Updating context...' ) ) . toBeInTheDocument ( ) ;
254+
234255 await waitFor (
235256 ( ) => {
236- expect ( screen . getByText ( 'Todd says aloha' ) ) . toBeInTheDocument ( ) ;
237- } ,
238- { timeout : DELAY * 4 } ,
239- ) ;
240- await waitFor (
241- ( ) => {
242- expect ( screen . getByText ( 'Will says hi' ) ) . toBeInTheDocument ( ) ;
257+ expect ( screen . getAllByText ( 'Update Context' ) ) . toHaveLength ( 2 ) ;
243258 } ,
244- { timeout : DELAY * 4 } ,
259+ { timeout : DELAY * 2 } ,
245260 ) ;
261+
262+ expect ( screen . getByText ( 'Todd says aloha' ) ) . toBeInTheDocument ( ) ;
263+ expect ( screen . getByText ( 'Will says hi' ) ) . toBeInTheDocument ( ) ;
246264 } ) ;
247265
248266 it ( 'should update nested global contexts' , async ( ) => {
@@ -296,13 +314,16 @@ describe('OpenFeatureProvider', () => {
296314 // Click the Update context button in Todds domain
297315 fireEvent . click ( screen . getAllByText ( 'Update Context' ) [ 1 ] ) ;
298316 } ) ;
317+ expect ( screen . getByText ( 'Updating context...' ) ) . toBeInTheDocument ( ) ;
318+
299319 await waitFor (
300320 ( ) => {
301- expect ( screen . getByText ( 'Todd likes to Frown ') ) . toBeInTheDocument ( ) ;
321+ expect ( screen . getAllByText ( 'Update Context ') ) . toHaveLength ( 2 ) ;
302322 } ,
303- { timeout : DELAY * 4 } ,
323+ { timeout : DELAY * 2 } ,
304324 ) ;
305325
326+ expect ( screen . getByText ( 'Todd likes to Frown' ) ) . toBeInTheDocument ( ) ;
306327 expect ( screen . getByText ( 'Will says aloha' ) ) . toBeInTheDocument ( ) ;
307328 } ) ;
308329
@@ -326,13 +347,17 @@ describe('OpenFeatureProvider', () => {
326347 act ( ( ) => {
327348 fireEvent . click ( screen . getByText ( 'Update Context' ) ) ;
328349 } ) ;
350+ expect ( screen . getByText ( 'Updating context...' ) ) . toBeInTheDocument ( ) ;
351+
329352 await waitFor (
330353 ( ) => {
331- expect ( screen . getByText ( 'Will says aloha ' ) ) . toBeInTheDocument ( ) ;
354+ expect ( screen . getByText ( 'Update Context ' ) ) . toBeInTheDocument ( ) ;
332355 } ,
333- { timeout : DELAY * 4 } ,
356+ { timeout : DELAY * 2 } ,
334357 ) ;
335358
359+ expect ( screen . getByText ( 'Will says aloha' ) ) . toBeInTheDocument ( ) ;
360+
336361 expect ( setter ) . toHaveBeenCalledTimes ( 1 ) ;
337362 expect ( setter ) . toHaveBeenCalledWith ( { done : false } ) ;
338363 expect ( OpenFeature . getContext ( DOMAIN ) ) . toEqual ( { done :
false , user :
'[email protected] ' } ) ;
0 commit comments