import React, { useEffect } from 'react';
import { render, act } from '@testing-library/react';
/** Mocks */
import { mockSdk, Event, getLastInstance } from './testUtils/mockSplitFactory';
jest.mock('@splitsoftware/splitio/client', () => {
return { SplitFactory: mockSdk() };
});
import { SplitFactory } from '@splitsoftware/splitio/client';
import { sdkBrowser } from './testUtils/sdkConfigs';
/** Test target */
import { SplitFactoryProvider } from '../SplitFactoryProvider';
import { useTrack } from '../useTrack';
import { useSplitClient } from '../useSplitClient';
import { EXCEPTION_NO_SFP } from '../constants';
describe('useTrack', () => {
const tt = 'user';
const eventType = 'eventType';
const value = 10;
const properties = { prop1: 'prop1' };
test('returns the track method of the main client of the factory at Split context provided by SplitFactoryProvider.', () => {
const outerFactory = SplitFactory(sdkBrowser);
let clientTrack;
let trackResult;
render(
{React.createElement(() => {
clientTrack = useTrack();
trackResult = clientTrack(tt, eventType, value, properties);
const sameTrack = useTrack(sdkBrowser.core.key);
expect(clientTrack).toBe(sameTrack);
return null;
})}
,
);
const track = outerFactory.client().track;
expect(track).toBe(clientTrack);
expect(track).toBeCalledWith(tt, eventType, value, properties);
expect(track).toHaveReturnedWith(trackResult);
});
test('returns the track method of a new client given a splitKey.', () => {
const outerFactory = SplitFactory(sdkBrowser);
let trackResult;
render(
{React.createElement(() => {
const clientTrack = useTrack('user2');
trackResult = clientTrack(tt, eventType, value, properties);
return null;
})}
,
);
const track = outerFactory.client('user2').track;
expect(track).toBeCalledWith(tt, eventType, value, properties);
expect(track).toHaveReturnedWith(trackResult);
});
test('throws error if invoked outside of SplitFactoryProvider.', () => {
expect(() => {
render(
React.createElement(() => {
const track = useTrack('user2');
track(tt, eventType, value, properties);
return null;
}),
);
}).toThrow(EXCEPTION_NO_SFP);
});
test('returns the track method of the client at Split context updated by SplitFactoryProvider (config prop).', () => {
const InnerComponent = ({ splitKey }: { splitKey?: string }) => {
const clientTrack = useTrack(splitKey);
const { client } = useSplitClient({ splitKey });
expect(clientTrack).toBe(client!.track);
clientTrack(tt, eventType, value, properties);
useEffect(() => {
clientTrack(tt, eventType, value, properties);
}, [clientTrack]);
return null;
}
const App = ({ splitKey }: { splitKey?: string }) => {
return (
)
};
const wrapper = render();
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY_FROM_CACHE));
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY));
wrapper.rerender(); // `clientTrack` dependency changed
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_UPDATE));
let track = getLastInstance(SplitFactory).client().track;
expect(track).toBeCalledWith(tt, eventType, value, properties);
expect(track).toBeCalledTimes(4); // 3 from render + 1 from useEffect
track = getLastInstance(SplitFactory).client('user2').track;
expect(track).toBeCalledWith(tt, eventType, value, properties);
expect(track).toBeCalledTimes(2); // 1 from render + 1 from useEffect (`clientTrack` dependency changed)
});
test('does not re-render on SDK events', () => {
render(
{React.createElement(() => {
const clientTrack = useTrack();
clientTrack(tt, eventType, value, properties);
return null;
})}
,
);
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY_TIMED_OUT));
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY_FROM_CACHE));
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY));
act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_UPDATE));
expect(getLastInstance(SplitFactory).client().track).toBeCalledTimes(1);
});
});