|
1 | | -import { EvaluationContext, OpenFeature } from '@openfeature/web-sdk'; |
| 1 | +import { EvaluationContext, InMemoryProvider, OpenFeature } from '@openfeature/web-sdk'; |
2 | 2 | import '@testing-library/jest-dom'; // see: https://testing-library.com/docs/react-testing-library/setup |
3 | 3 | import { render, renderHook, screen, waitFor, fireEvent, act } from '@testing-library/react'; |
4 | 4 | import * as React from 'react'; |
5 | | -import { OpenFeatureProvider, useOpenFeatureClient, useWhenProviderReady, useContextMutator, useStringFlagValue } from '../src'; |
| 5 | +import { |
| 6 | + OpenFeatureProvider, |
| 7 | + useOpenFeatureClient, |
| 8 | + useWhenProviderReady, |
| 9 | + useContextMutator, |
| 10 | + useStringFlagValue, |
| 11 | +} from '../src'; |
6 | 12 | import { TestingProvider } from './test.utils'; |
7 | 13 |
|
8 | 14 | describe('OpenFeatureProvider', () => { |
@@ -139,74 +145,149 @@ describe('OpenFeatureProvider', () => { |
139 | 145 | await waitFor(() => expect(screen.queryByText('👍')).toBeInTheDocument(), { timeout: DELAY * 2 }); |
140 | 146 | }); |
141 | 147 | }); |
| 148 | + }); |
| 149 | + describe('useMutateContext', () => { |
| 150 | + const MutateButton = () => { |
| 151 | + const { setContext } = useContextMutator(); |
142 | 152 |
|
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'); |
| 153 | + return <button onClick={() => setContext({ user: '[email protected]' })}>Update Context </button>; |
| 154 | + }; |
| 155 | + const TestComponent = ({ name }: { name: string }) => { |
| 156 | + const flagValue = useStringFlagValue<'hi' | 'bye' | 'aloha'>(SUSPENSE_FLAG_KEY, 'hi'); |
151 | 157 |
|
152 | | - return <div> |
| 158 | + return ( |
| 159 | + <div> |
153 | 160 | <MutateButton /> |
154 | 161 | <div>{`${name} says ${flagValue}`}</div> |
155 | | - </div>; |
156 | | - }; |
| 162 | + </div> |
| 163 | + ); |
| 164 | + }; |
157 | 165 |
|
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}> |
| 166 | + it('should update context when a domain is set', async () => { |
| 167 | + const DOMAIN = 'mutate-context-tests'; |
| 168 | + OpenFeature.setProvider(DOMAIN, suspendingProvider()); |
| 169 | + render( |
| 170 | + <OpenFeatureProvider domain={DOMAIN}> |
162 | 171 | <React.Suspense fallback={<div>{FALLBACK}</div>}> |
163 | | - <TestComponent name="Will"/> |
| 172 | + <TestComponent name="Will" /> |
164 | 173 | </React.Suspense> |
165 | | - </OpenFeatureProvider>,); |
| 174 | + </OpenFeatureProvider>, |
| 175 | + ); |
166 | 176 |
|
167 | | - await waitFor(() => { |
168 | | - expect(screen.getByText('Will says hi')).toBeInTheDocument(); |
169 | | - }); |
| 177 | + await waitFor(() => { |
| 178 | + expect(screen.getByText('Will says hi')).toBeInTheDocument(); |
| 179 | + }); |
170 | 180 |
|
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 }); |
| 181 | + act(() => { |
| 182 | + fireEvent.click(screen.getByText('Update Context')); |
177 | 183 | }); |
| 184 | + await waitFor( |
| 185 | + () => { |
| 186 | + expect(screen.getByText('Will says aloha')).toBeInTheDocument(); |
| 187 | + }, |
| 188 | + { timeout: DELAY * 4 }, |
| 189 | + ); |
| 190 | + }); |
178 | 191 |
|
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}> |
| 192 | + it('should update nested contexts', async () => { |
| 193 | + const DOMAIN1 = 'Wills Domain'; |
| 194 | + const DOMAIN2 = 'Todds Domain'; |
| 195 | + OpenFeature.setProvider(DOMAIN1, suspendingProvider()); |
| 196 | + OpenFeature.setProvider(DOMAIN2, suspendingProvider()); |
| 197 | + render( |
| 198 | + <OpenFeatureProvider domain={DOMAIN1}> |
185 | 199 | <React.Suspense fallback={<div>{FALLBACK}</div>}> |
186 | | - <TestComponent name="Will"/> |
| 200 | + <TestComponent name="Will" /> |
187 | 201 | <OpenFeatureProvider domain={DOMAIN2}> |
188 | 202 | <React.Suspense fallback={<div>{FALLBACK}</div>}> |
189 | | - <TestComponent name="Todd"/> |
| 203 | + <TestComponent name="Todd" /> |
190 | 204 | </React.Suspense> |
191 | 205 | </OpenFeatureProvider> |
192 | 206 | </React.Suspense> |
193 | | - </OpenFeatureProvider>,); |
| 207 | + </OpenFeatureProvider>, |
| 208 | + ); |
194 | 209 |
|
195 | | - await waitFor(() => { |
196 | | - expect(screen.getByText('Todd says hi')).toBeInTheDocument(); |
197 | | - }); |
| 210 | + await waitFor(() => { |
| 211 | + expect(screen.getByText('Todd says hi')).toBeInTheDocument(); |
| 212 | + }); |
198 | 213 |
|
199 | | - act(() => { |
200 | | - // Click the Update context button in Todds domain |
201 | | - fireEvent.click(screen.getAllByText('Update Context')[1]); |
202 | | - }); |
203 | | - await waitFor(() => { |
| 214 | + act(() => { |
| 215 | + // Click the Update context button in Todds domain |
| 216 | + fireEvent.click(screen.getAllByText('Update Context')[1]); |
| 217 | + }); |
| 218 | + await waitFor( |
| 219 | + () => { |
204 | 220 | expect(screen.getByText('Todd says aloha')).toBeInTheDocument(); |
205 | | - }, { timeout: DELAY * 4 }); |
206 | | - await waitFor(() => { |
| 221 | + }, |
| 222 | + { timeout: DELAY * 4 }, |
| 223 | + ); |
| 224 | + await waitFor( |
| 225 | + () => { |
207 | 226 | expect(screen.getByText('Will says hi')).toBeInTheDocument(); |
208 | | - }, { timeout: DELAY * 4 }); |
| 227 | + }, |
| 228 | + { timeout: DELAY * 4 }, |
| 229 | + ); |
| 230 | + }); |
| 231 | + |
| 232 | + it('should update nested global contexts', async () => { |
| 233 | + const DOMAIN1 = 'Wills Domain'; |
| 234 | + OpenFeature.setProvider(DOMAIN1, suspendingProvider()); |
| 235 | + OpenFeature.setProvider(new InMemoryProvider({ |
| 236 | + globalFlagsHere: { |
| 237 | + defaultVariant: 'a', |
| 238 | + variants: { |
| 239 | + a: 'Smile', |
| 240 | + b: 'Frown', |
| 241 | + }, |
| 242 | + disabled: false, |
| 243 | + contextEvaluator: (ctx: EvaluationContext) => { |
| 244 | + if (ctx.user === '[email protected]') { |
| 245 | + return 'b'; |
| 246 | + } |
| 247 | + |
| 248 | + return 'a'; |
| 249 | + }, |
| 250 | + } |
| 251 | + })); |
| 252 | + const GlobalComponent = ({ name }: { name: string }) => { |
| 253 | + const flagValue = useStringFlagValue<'b' | 'a'>('globalFlagsHere', 'a'); |
| 254 | + |
| 255 | + return ( |
| 256 | + <div> |
| 257 | + <MutateButton /> |
| 258 | + <div>{`${name} likes to ${flagValue}`}</div> |
| 259 | + </div> |
| 260 | + ); |
| 261 | + }; |
| 262 | + render( |
| 263 | + <OpenFeatureProvider domain={DOMAIN1}> |
| 264 | + <React.Suspense fallback={<div>{FALLBACK}</div>}> |
| 265 | + <TestComponent name="Will" /> |
| 266 | + <OpenFeatureProvider> |
| 267 | + <React.Suspense fallback={<div>{FALLBACK}</div>}> |
| 268 | + <GlobalComponent name="Todd" /> |
| 269 | + </React.Suspense> |
| 270 | + </OpenFeatureProvider> |
| 271 | + </React.Suspense> |
| 272 | + </OpenFeatureProvider>, |
| 273 | + ); |
| 274 | + |
| 275 | + await waitFor(() => { |
| 276 | + expect(screen.getByText('Todd likes to Smile')).toBeInTheDocument(); |
209 | 277 | }); |
| 278 | + |
| 279 | + act(() => { |
| 280 | + // Click the Update context button in Todds domain |
| 281 | + fireEvent.click(screen.getAllByText('Update Context')[1]); |
| 282 | + }); |
| 283 | + await waitFor( |
| 284 | + () => { |
| 285 | + expect(screen.getByText('Todd likes to Frown')).toBeInTheDocument(); |
| 286 | + }, |
| 287 | + { timeout: DELAY * 4 }, |
| 288 | + ); |
| 289 | + |
| 290 | + expect(screen.getByText('Will says hi')).toBeInTheDocument(); |
210 | 291 | }); |
211 | 292 | }); |
212 | 293 | }); |
0 commit comments