Skip to content

Commit f438017

Browse files
committed
test: the hook
Signed-off-by: Will Chou <[email protected]>
1 parent c8991f5 commit f438017

File tree

2 files changed

+79
-5
lines changed

2 files changed

+79
-5
lines changed

packages/react/src/provider/use-context-mutator.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { Context } from './context';
88
*
99
*/
1010
export function useContextMutator() {
11-
async function mutateContext(updatedContext: EvaluationContext): Promise<void> {
12-
const { domain } = useContext(Context) || {};
11+
const { domain } = useContext(Context) || {};
1312

13+
async function mutateContext(updatedContext: EvaluationContext): Promise<void> {
1414
if (!domain) {
15-
throw new Error('No domain set for your context');
15+
// Set the global context
16+
OpenFeature.setContext(updatedContext);
17+
return;
1618
}
1719

1820
OpenFeature.setContext(domain, updatedContext);

packages/react/test/provider.spec.tsx

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { EvaluationContext, OpenFeature } from '@openfeature/web-sdk';
22
import '@testing-library/jest-dom'; // see: https://testing-library.com/docs/react-testing-library/setup
3-
import { render, renderHook, screen, waitFor } from '@testing-library/react';
3+
import { render, renderHook, screen, waitFor, fireEvent, act } from '@testing-library/react';
44
import * as React from 'react';
5-
import { OpenFeatureProvider, useOpenFeatureClient, useWhenProviderReady } from '../src';
5+
import { OpenFeatureProvider, useOpenFeatureClient, useWhenProviderReady, useContextMutator, useStringFlagValue } from '../src';
66
import { TestingProvider } from './test.utils';
77

88
describe('OpenFeatureProvider', () => {
@@ -33,6 +33,9 @@ describe('OpenFeatureProvider', () => {
3333
if (context.user == '[email protected]') {
3434
return 'both';
3535
}
36+
if (context.done === true) {
37+
return 'parting';
38+
}
3639
return 'greeting';
3740
},
3841
},
@@ -136,5 +139,74 @@ describe('OpenFeatureProvider', () => {
136139
await waitFor(() => expect(screen.queryByText('👍')).toBeInTheDocument(), { timeout: DELAY * 2 });
137140
});
138141
});
142+
143+
describe('useMutateContext', () => {
144+
const MutateButton = () => {
145+
const { mutateContext } = useContextMutator();
146+
147+
return <button onClick={() => mutateContext({ user: '[email protected]' })}>Update Context</button>;
148+
};
149+
const TestComponent = ({ name }: { name: string}) => {
150+
const flagValue = useStringFlagValue<'hi' | 'bye' | 'aloha'>(SUSPENSE_FLAG_KEY, 'hi');
151+
152+
return <div>
153+
<MutateButton />
154+
<div>{`${name} says ${flagValue}`}</div>
155+
</div>;
156+
};
157+
158+
it('should update context when a domain is set', async () => {
159+
const DOMAIN = 'mutate-context-tests';
160+
OpenFeature.setProvider(DOMAIN, suspendingProvider());
161+
render(<OpenFeatureProvider domain={DOMAIN}>
162+
<React.Suspense fallback={<div>{FALLBACK}</div>}>
163+
<TestComponent name="Will"/>
164+
</React.Suspense>
165+
</OpenFeatureProvider>,);
166+
167+
await waitFor(() => {
168+
expect(screen.getByText('Will says hi')).toBeInTheDocument();
169+
});
170+
171+
act(() => {
172+
fireEvent.click(screen.getByText('Update Context'));
173+
});
174+
await waitFor(() => {
175+
expect(screen.getByText('Will says aloha')).toBeInTheDocument();
176+
}, { timeout: DELAY * 4 });
177+
});
178+
179+
it('should update nested contexts', async () => {
180+
const DOMAIN1 = 'Wills Domain';
181+
const DOMAIN2 = 'Todds Domain';
182+
OpenFeature.setProvider(DOMAIN1, suspendingProvider());
183+
OpenFeature.setProvider(DOMAIN2, suspendingProvider());
184+
render(<OpenFeatureProvider domain={DOMAIN1}>
185+
<React.Suspense fallback={<div>{FALLBACK}</div>}>
186+
<TestComponent name="Will"/>
187+
<OpenFeatureProvider domain={DOMAIN2}>
188+
<React.Suspense fallback={<div>{FALLBACK}</div>}>
189+
<TestComponent name="Todd"/>
190+
</React.Suspense>
191+
</OpenFeatureProvider>
192+
</React.Suspense>
193+
</OpenFeatureProvider>,);
194+
195+
await waitFor(() => {
196+
expect(screen.getByText('Todd says hi')).toBeInTheDocument();
197+
});
198+
199+
act(() => {
200+
// Click the Update context button in Todds domain
201+
fireEvent.click(screen.getAllByText('Update Context')[1]);
202+
});
203+
await waitFor(() => {
204+
expect(screen.getByText('Todd says aloha')).toBeInTheDocument();
205+
}, { timeout: DELAY * 4 });
206+
await waitFor(() => {
207+
expect(screen.getByText('Will says hi')).toBeInTheDocument();
208+
}, { timeout: DELAY * 4 });
209+
});
210+
});
139211
});
140212
});

0 commit comments

Comments
 (0)