Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle defaults of updateOnSdk props, when non boolean values are provided #219

Merged
merged 15 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
2.0.1 (November XX, 2024)
- Updated internal handling of the `updateOnSdkTimedout` param to remove the wrong log "[ERROR] A listener was added for SDK_READY_TIMED_OUT on the SDK, which has already fired and won't be emitted again".
- Bugfixing - Fixed an issue with the `updateOn***` object parameters of the `useSplitClient` and `useSplitTreatments` hooks, and their components and HOCs alternatives, which were not defaulting to `true` when a non-boolean value was provided.

2.0.0 (November 1, 2024)
- Added support for targeting rules based on large segments.
- Added support for passing factory instances to the `factory` prop of the `SplitFactoryProvider` component from other SDK packages that extends the `SplitIO.IBrowserSDK` interface, such as `@splitsoftware/splitio-react-native`, `@splitsoftware/splitio-browserjs` and `@splitsoftware/browser-suite` packages.
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/useSplitClient.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ describe('useSplitClient', () => {
return null;
})}
{React.createElement(() => {
const { client, isReady, isReadyFromCache, hasTimedout } = useSplitClient({ splitKey: 'user_2', updateOnSdkUpdate: true });
const { client, isReady, isReadyFromCache, hasTimedout } = useSplitClient({ splitKey: 'user_2', updateOnSdkUpdate: undefined /* default is true */ });
expect(client).toBe(user2Client);

countUseSplitClientUser2++;
Expand Down Expand Up @@ -218,7 +218,7 @@ describe('useSplitClient', () => {
act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // do not trigger re-render because updateOnSdkUpdate is false
expect(rendersCount).toBe(2);

wrapper.rerender(<Component updateOnSdkUpdate={true} />); // trigger re-render
wrapper.rerender(<Component updateOnSdkUpdate={null /** invalid type should default to `true` */} />); // trigger re-render
expect(rendersCount).toBe(3);

act(() => mainClient.__emitter__.emit(Event.SDK_UPDATE)); // trigger re-render because updateOnSdkUpdate is true now
Expand Down
32 changes: 29 additions & 3 deletions src/__tests__/withSplitTreatments.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import { render } from '@testing-library/react';
import { act, render } from '@testing-library/react';

/** Mocks */
import { mockSdk } from './testUtils/mockSplitFactory';
import { mockSdk, getLastInstance, Event } from './testUtils/mockSplitFactory';
jest.mock('@splitsoftware/splitio/client', () => {
return { SplitFactory: mockSdk() };
});
import { SplitFactory } from '@splitsoftware/splitio/client';
import { sdkBrowser } from './testUtils/sdkConfigs';

/** Test target */
Expand All @@ -14,12 +15,13 @@ import { withSplitClient } from '../withSplitClient';
import { withSplitTreatments } from '../withSplitTreatments';
import { getControlTreatmentsWithConfig } from '../utils';

const featureFlagNames = ['split1', 'split2'];

describe('withSplitTreatments', () => {

it(`passes Split props and outer props to the child.
In this test, the value of "props.treatments" is obtained by the function "getControlTreatmentsWithConfig",
and not "client.getTreatmentsWithConfig" since the client is not ready.`, () => {
const featureFlagNames = ['split1', 'split2'];

const Component = withSplitFactory(sdkBrowser)<{ outerProp1: string, outerProp2: number }>(
({ outerProp1, outerProp2, factory }) => {
Expand Down Expand Up @@ -51,4 +53,28 @@ describe('withSplitTreatments', () => {
render(<Component outerProp1='outerProp1' outerProp2={2} />);
});

it('disabling "updateOnSdkTimedout" requires passing `false` in all HOCs since the default value is `true`.', () => {

let renderCount = 0;

const Component = withSplitFactory(sdkBrowser)(
withSplitClient(sdkBrowser.core.key)(
withSplitTreatments(featureFlagNames)(
(props) => {
renderCount++;
expect(props.hasTimedout).toBe(false);

return null;
}, undefined, false
), undefined, false
), undefined, false
);

render(<Component />);

act(() => getLastInstance(SplitFactory).client().__emitter__.emit(Event.SDK_READY_TIMED_OUT));

expect(renderCount).toBe(1);
});

});
16 changes: 10 additions & 6 deletions src/useSplitClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,23 @@ export function useSplitClient(options?: IUseSplitClientOptions): ISplitContextV
const statusOnEffect = getStatus(client);

// Subscribe to SDK events
if (updateOnSdkReady) {
if (updateOnSdkReady !== false) {
if (!statusOnEffect.isReady) client.once(client.Event.SDK_READY, update);
else if (!status.isReady) update();
}
if (updateOnSdkReadyFromCache) {
if (updateOnSdkReadyFromCache !== false) {
if (!statusOnEffect.isReadyFromCache) client.once(client.Event.SDK_READY_FROM_CACHE, update);
else if (!status.isReadyFromCache) update();
}
if (updateOnSdkTimedout) {
if (!statusOnEffect.hasTimedout) client.once(client.Event.SDK_READY_TIMED_OUT, update);
else if (!status.hasTimedout) update();
if (updateOnSdkTimedout !== false) {
if (!statusOnEffect.hasTimedout) {
// Required to avoid error log for event already emitted
if (!statusOnEffect.isReady) client.once(client.Event.SDK_READY_TIMED_OUT, update);
} else {
if (!status.hasTimedout) update();
}
}
if (updateOnSdkUpdate) client.on(client.Event.SDK_UPDATE, update);
if (updateOnSdkUpdate !== false) client.on(client.Event.SDK_UPDATE, update);

return () => {
// Unsubscribe from events
Expand Down
8 changes: 4 additions & 4 deletions src/withSplitClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export function withSplitClient(splitKey: SplitIO.SplitKey, attributes?: SplitIO

return function withSplitClientHoc<OuterProps>(
WrappedComponent: React.ComponentType<OuterProps & ISplitClientChildProps>,
updateOnSdkUpdate = false,
updateOnSdkTimedout = false,
updateOnSdkReady = true,
updateOnSdkReadyFromCache = true,
updateOnSdkUpdate?: boolean,
updateOnSdkTimedout?: boolean,
updateOnSdkReady?: boolean,
updateOnSdkReadyFromCache?: boolean,
) {

return function wrapper(props: OuterProps) {
Expand Down
8 changes: 4 additions & 4 deletions src/withSplitFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export function withSplitFactory(config?: SplitIO.IBrowserSettings, factory?: Sp

return function withSplitFactoryHoc<OuterProps>(
WrappedComponent: React.ComponentType<OuterProps & ISplitFactoryChildProps>,
updateOnSdkUpdate = false,
updateOnSdkTimedout = false,
updateOnSdkReady = true,
updateOnSdkReadyFromCache = true,
updateOnSdkUpdate?: boolean,
updateOnSdkTimedout?: boolean,
updateOnSdkReady?: boolean,
updateOnSdkReadyFromCache?: boolean,
) {

return function wrapper(props: OuterProps) {
Expand Down
8 changes: 8 additions & 0 deletions src/withSplitTreatments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ export function withSplitTreatments(names: string[], attributes?: SplitIO.Attrib

return function withSplitTreatmentsHoc<OuterProps>(
WrappedComponent: React.ComponentType<OuterProps & ISplitTreatmentsChildProps>,
updateOnSdkUpdate?: boolean,
updateOnSdkTimedout?: boolean,
updateOnSdkReady?: boolean,
updateOnSdkReadyFromCache?: boolean,
) {

return function wrapper(props: OuterProps) {
return (
<SplitTreatments
names={names}
updateOnSdkUpdate={updateOnSdkUpdate}
updateOnSdkTimedout={updateOnSdkTimedout}
updateOnSdkReady={updateOnSdkReady}
updateOnSdkReadyFromCache={updateOnSdkReadyFromCache}
attributes={attributes} >
{(splitProps) => {
return (
Expand Down
Loading