diff --git a/packages/react-bindings/src/__tests__/useStatsigInternalClientFactoryBootstrap.test.tsx b/packages/react-bindings/src/__tests__/useStatsigInternalClientFactoryBootstrap.test.tsx new file mode 100644 index 00000000..c0e39414 --- /dev/null +++ b/packages/react-bindings/src/__tests__/useStatsigInternalClientFactoryBootstrap.test.tsx @@ -0,0 +1,145 @@ +import '@testing-library/jest-dom'; +import { render } from '@testing-library/react'; +import * as React from 'react'; +import { MockRemoteServerEvalClient } from 'statsig-test-helpers'; + +import { _getStatsigGlobal } from '@statsig/client-core'; + +import { useStatsigInternalClientFactoryBootstrap } from '../useStatsigInternalClientFactoryBootstrap'; + +function clientFactory() { + const client = MockRemoteServerEvalClient.create(); + + // Add dataAdapter mock with both setData and setDataLegacy methods + client.dataAdapter = { + setData: jest.fn(), + setDataLegacy: jest.fn(), + }; + + let resolveinitializeAsync: (() => void) | undefined; + client.initializeAsync.mockReturnValue( + new Promise((resolve) => { + resolveinitializeAsync = resolve; + }), + ); + return { + client, + finishInitializeAsync: () => { + resolveinitializeAsync?.(); + }, + }; +} + +const TestComponent = ({ + sdkKey, + useLegacyClient, + onClientCreated, +}: { + sdkKey: string; + useLegacyClient?: boolean; + onClientCreated?: (client: any) => void; +}) => { + const client = useStatsigInternalClientFactoryBootstrap( + (_args) => { + const { client } = clientFactory(); + onClientCreated?.(client); + return client; + }, + { + sdkKey, + initialUser: { userID: 'test-user' }, + initialValues: JSON.stringify({ test: 'data' }), + statsigOptions: null, + useLegacyClient, + }, + ); + + return
{client ? 'Ready' : 'Not Ready'}
; +}; + +describe('useStatsigInternalClientFactoryBootstrap', () => { + const readySdkKey = 'client-key-ready'; + + beforeAll(() => { + // Create mock SDK that's ready + const { client } = clientFactory(); + (client.loadingStatus as any) = 'Ready'; + + // Add this client to Statsig Global with the sdkKey + const global = _getStatsigGlobal(); + const instances = global.instances ?? {}; + instances[readySdkKey] = client; + global.instances = instances; + }); + + afterAll(() => { + delete _getStatsigGlobal().instances; + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('calls setData when useLegacyClient is false', () => { + let capturedClient: any = null; + + render( + { + capturedClient = client; + }} + />, + ); + + expect(capturedClient).not.toBeNull(); + expect(capturedClient.dataAdapter.setData).toHaveBeenCalledWith( + JSON.stringify({ test: 'data' }), + ); + expect(capturedClient.dataAdapter.setDataLegacy).not.toHaveBeenCalled(); + expect(capturedClient.initializeSync).toHaveBeenCalled(); + }); + + it('calls setData when useLegacyClient is not provided (default behavior)', () => { + let capturedClient: any = null; + + render( + { + capturedClient = client; + }} + />, + ); + + expect(capturedClient).not.toBeNull(); + expect(capturedClient.dataAdapter.setData).toHaveBeenCalledWith( + JSON.stringify({ test: 'data' }), + ); + expect(capturedClient.dataAdapter.setDataLegacy).not.toHaveBeenCalled(); + expect(capturedClient.initializeSync).toHaveBeenCalled(); + }); + + it('calls setDataLegacy when useLegacyClient is true', () => { + let capturedClient: any = null; + + render( + { + capturedClient = client; + }} + />, + ); + + expect(capturedClient).not.toBeNull(); + expect(capturedClient.dataAdapter.setDataLegacy).toHaveBeenCalledWith( + JSON.stringify({ test: 'data' }), + { userID: 'test-user' }, + ); + expect(capturedClient.dataAdapter.setData).not.toHaveBeenCalled(); + expect(capturedClient.initializeSync).toHaveBeenCalled(); + }); +}); diff --git a/packages/react-bindings/src/useClientBootstrapInit.ts b/packages/react-bindings/src/useClientBootstrapInit.ts index 50864cd6..edc4250e 100644 --- a/packages/react-bindings/src/useClientBootstrapInit.ts +++ b/packages/react-bindings/src/useClientBootstrapInit.ts @@ -8,6 +8,7 @@ export function useClientBootstrapInit( initialUser: StatsigUser, initialValues: string, statsigOptions: StatsigOptions | null = null, + useLegacyClient?: boolean, ): StatsigClient { return useStatsigInternalClientFactoryBootstrap( (args) => @@ -17,6 +18,7 @@ export function useClientBootstrapInit( initialUser, initialValues, statsigOptions, + useLegacyClient, }, ); } diff --git a/packages/react-bindings/src/useStatsigInternalClientFactoryBootstrap.ts b/packages/react-bindings/src/useStatsigInternalClientFactoryBootstrap.ts index 69980d8c..32bb7542 100644 --- a/packages/react-bindings/src/useStatsigInternalClientFactoryBootstrap.ts +++ b/packages/react-bindings/src/useStatsigInternalClientFactoryBootstrap.ts @@ -8,6 +8,7 @@ type FactoryArgs = { initialUser: StatsigUser; initialValues: string; statsigOptions: StatsigOptions | null; + useLegacyClient?: boolean; }; export function useStatsigInternalClientFactoryBootstrap< @@ -23,7 +24,12 @@ export function useStatsigInternalClientFactoryBootstrap< const inst = factory(args); clientRef.current = inst; - inst.dataAdapter.setData(args.initialValues); + if (args.useLegacyClient) { + inst.dataAdapter.setDataLegacy(args.initialValues, args.initialUser); + } else { + inst.dataAdapter.setData(args.initialValues); + } + inst.initializeSync(); return inst;