diff --git a/packages/react/src/context/use-context-mutator.ts b/packages/react/src/context/use-context-mutator.ts index 8e67e7917..3c1351d43 100644 --- a/packages/react/src/context/use-context-mutator.ts +++ b/packages/react/src/context/use-context-mutator.ts @@ -41,9 +41,9 @@ export function useContextMutator(options: ContextMutationOptions = { defaultCon if (previousContext !== resolvedContext) { if (!domain || options?.defaultContext) { - OpenFeature.setContext(resolvedContext); + await OpenFeature.setContext(resolvedContext); } else { - OpenFeature.setContext(domain, resolvedContext); + await OpenFeature.setContext(domain, resolvedContext); } } }, [domain, options?.defaultContext]); diff --git a/packages/react/test/provider.spec.tsx b/packages/react/test/provider.spec.tsx index bda795aee..c3aeaf948 100644 --- a/packages/react/test/provider.spec.tsx +++ b/packages/react/test/provider.spec.tsx @@ -164,8 +164,18 @@ describe('OpenFeatureProvider', () => { describe('useMutateContext', () => { const MutateButton = ({ setter }: { setter?: (prevContext: EvaluationContext) => EvaluationContext }) => { const { setContext } = useContextMutator(); + const [loading, setLoading] = React.useState(false); - return ; + return ( + + ); }; const TestComponent = ({ name, setter }: { name: string; setter?: (prevContext: EvaluationContext) => EvaluationContext }) => { @@ -182,6 +192,10 @@ describe('OpenFeatureProvider', () => { it('should update context when a domain is set', async () => { const DOMAIN = 'mutate-context-tests'; OpenFeature.setProvider(DOMAIN, suspendingProvider()); + + const changed = jest.fn(); + OpenFeature.getClient(DOMAIN).addHandler(ProviderEvents.ContextChanged, changed); + render( {FALLBACK}}> @@ -197,12 +211,17 @@ describe('OpenFeatureProvider', () => { act(() => { fireEvent.click(screen.getByText('Update Context')); }); + expect(screen.getByText('Updating context...')).toBeInTheDocument(); + await waitFor( () => { - expect(screen.getByText('Will says aloha')).toBeInTheDocument(); + expect(screen.getByText('Update Context')).toBeInTheDocument(); }, - { timeout: DELAY * 4 }, + { timeout: DELAY * 2 }, ); + expect(changed).toHaveBeenCalledTimes(1); + + expect(screen.getByText('Will says aloha')).toBeInTheDocument(); }); it('should update nested contexts', async () => { @@ -231,18 +250,17 @@ describe('OpenFeatureProvider', () => { // Click the Update context button in Todds domain fireEvent.click(screen.getAllByText('Update Context')[1]); }); + expect(screen.getByText('Updating context...')).toBeInTheDocument(); + await waitFor( () => { - expect(screen.getByText('Todd says aloha')).toBeInTheDocument(); - }, - { timeout: DELAY * 4 }, - ); - await waitFor( - () => { - expect(screen.getByText('Will says hi')).toBeInTheDocument(); + expect(screen.getAllByText('Update Context')).toHaveLength(2); }, - { timeout: DELAY * 4 }, + { timeout: DELAY * 2 }, ); + + expect(screen.getByText('Todd says aloha')).toBeInTheDocument(); + expect(screen.getByText('Will says hi')).toBeInTheDocument(); }); it('should update nested global contexts', async () => { @@ -296,13 +314,16 @@ describe('OpenFeatureProvider', () => { // Click the Update context button in Todds domain fireEvent.click(screen.getAllByText('Update Context')[1]); }); + expect(screen.getByText('Updating context...')).toBeInTheDocument(); + await waitFor( () => { - expect(screen.getByText('Todd likes to Frown')).toBeInTheDocument(); + expect(screen.getAllByText('Update Context')).toHaveLength(2); }, - { timeout: DELAY * 4 }, + { timeout: DELAY * 2 }, ); + expect(screen.getByText('Todd likes to Frown')).toBeInTheDocument(); expect(screen.getByText('Will says aloha')).toBeInTheDocument(); });