Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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: 3 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
1.14.0 (September XX, 2024)
1.14.0 (September 12, 2024)
- Added `status` property to Split reducer's slice of state to track the SDK events of non-default clients (Related to https://github.com/splitio/redux-client/issues/113).
- Added `lastUpdate` and `isTimedout` properties to the object returned by the `getStatus` helper and `selectTreatmentAndStatus` and `selectTreatmentWithConfigAndStatus` selectors, to expose the last event timestamp and the timedout status of the SDK clients (Related to https://github.com/splitio/redux-client/issues/113).
- Updated `selectTreatmentAndStatus` and `selectTreatmentWithConfigAndStatus` selectors to retrieve status properties from the state rather than the SDK client instances directly.
- Updated @splitsoftware/splitio package to version 10.28.0 that includes minor updates:
- Added `sync.requestOptions.getHeaderOverrides` configuration option to enhance SDK HTTP request Headers for Authorization Frameworks.
- Updated some transitive dependencies for vulnerability fixes.
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@splitsoftware/splitio-redux",
"version": "1.13.0",
"version": "1.14.0",
"description": "A library to easily use Split JS SDK with Redux and React Redux",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down
87 changes: 33 additions & 54 deletions src/__tests__/asyncActions.browser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ describe('initSplitSdk', () => {

});

describe('getTreatments (for default user key)', () => {
describe('getTreatments', () => {

beforeEach(clearSplitSdk);

Expand Down Expand Up @@ -207,9 +207,10 @@ describe('getTreatments (for default user key)', () => {

actionResult.then(() => {
store.dispatch<any>(getTreatments({ splitNames: 'split1' }));
store.dispatch<any>(getTreatments({ splitNames: ['split2'], key: sdkBrowserConfig.core.key }));
store.dispatch<any>(getTreatments({ flagSets: 'set1', key: { matchingKey: sdkBrowserConfig.core.key as string, bucketingKey: 'bucket' } }));

const actions = [store.getActions()[1], store.getActions()[2]];
const actions = [store.getActions()[1], store.getActions()[2], store.getActions()[3]];
actions.forEach(action => {
expect(action).toEqual({
type: ADD_TREATMENTS,
Expand All @@ -221,10 +222,12 @@ describe('getTreatments (for default user key)', () => {
});

// getting the evaluation result and validating it matches the results from SDK
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split1'], undefined);
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveLastReturnedWith(actions[0].payload.treatments);
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveBeenCalledWith(['split1'], undefined);
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveReturnedWith(actions[0].payload.treatments);
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveBeenLastCalledWith(['split2'], undefined);
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveLastReturnedWith(actions[1].payload.treatments);
expect(splitSdk.factory.client().getTreatmentsWithConfigByFlagSets).toHaveBeenLastCalledWith(['set1'], undefined);
expect(splitSdk.factory.client().getTreatmentsWithConfigByFlagSets).toHaveLastReturnedWith(actions[1].payload.treatments);
expect(splitSdk.factory.client().getTreatmentsWithConfigByFlagSets).toHaveLastReturnedWith(actions[2].payload.treatments);

expect(getClient(splitSdk).evalOnUpdate).toEqual({});
expect(getClient(splitSdk).evalOnReady.length).toEqual(0);
Expand Down Expand Up @@ -516,43 +519,7 @@ describe('getTreatments (for default user key)', () => {
}
});

});

describe('getTreatments (providing a non-default user key)', () => {

beforeEach(clearSplitSdk);

afterEach(() => {
jest.clearAllMocks();
});

it('if Split SDK is ready and is provided with the same user key than the main client, it dispatches an ADD_TREATMENTS action as main client', (done) => {

// Init SDK and set ready
const store = mockStore(STATE_INITIAL);
const actionResult = store.dispatch<any>(initSplitSdk({ config: sdkBrowserConfig }));
(splitSdk.factory as any).client().__emitter__.emit(Event.SDK_READY);

actionResult.then(() => {
store.dispatch<any>(getTreatments({ splitNames: 'split1', key: sdkBrowserConfig.core.key }));

const action = store.getActions()[1];
expect(action).toEqual({
type: ADD_TREATMENTS,
payload: {
key: sdkBrowserConfig.core.key,
treatments: expect.any(Object)
}
});
expect(splitSdk.factory.client().getTreatmentsWithConfig).toHaveLastReturnedWith(action.payload.treatments);
expect(getClient(splitSdk).evalOnUpdate).toEqual({});
expect(getClient(splitSdk).evalOnReady.length).toEqual(0);

done();
});
});

it('for non-default clients, it stores control treatments (without calling SDK client), and registers pending evaluations if the client is not operational, to dispatch it when ready from cache, ready, and updated (Using callbacks to assert that registered evaluations are not affected when the client timeouts)', (done) => {
it('for non-default clients, it stores control treatments (without calling SDK client) and registers pending evaluations if the client is not operational, to dispatch it when ready from cache, ready, and updated (Using callbacks to assert that registered evaluations are not affected when the client timeouts)', (done) => {

// Init SDK and set ready
const store = mockStore(STATE_INITIAL);
Expand All @@ -573,8 +540,8 @@ describe('getTreatments (providing a non-default user key)', () => {
// If SDK is ready for the main key and a getTreatment is dispatched for a different user key:
// the item is added to the 'evalOnReady' list of the new client,
store.dispatch<any>(getTreatments({ splitNames: 'split2', key: 'other-user-key' }));
expect(getClient(splitSdk).evalOnReady.length).toEqual(0); // control assertion - no evaluations were registeres for SDK_READY on main client
expect(getClient(splitSdk, 'other-user-key').evalOnReady.length).toEqual(1); // control assertion - 1 evaluation was registeres for SDK_READY on the new client
expect(getClient(splitSdk).evalOnReady.length).toEqual(0); // control assertion - no evaluations were registered for SDK_READY on main client
expect(getClient(splitSdk, 'other-user-key').evalOnReady.length).toEqual(1); // control assertion - 1 evaluation was registered for SDK_READY on the new client
expect(getClient(splitSdk).evalOnUpdate).toEqual({});

// and an ADD_TREATMENTS action is dispatched with control treatments without calling SDK client.
Expand All @@ -590,13 +557,15 @@ describe('getTreatments (providing a non-default user key)', () => {

(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_READY, 'other-user-key');

// The ADD_TREATMENTS action is dispatched synchronously once the SDK is ready for the new user key
// The SPLIT_READY_WITH_EVALUATIONS action is dispatched synchronously once the SDK is ready for the new user key
action = store.getActions()[2];
expect(action).toEqual({
type: ADD_TREATMENTS,
type: SPLIT_READY_WITH_EVALUATIONS,
payload: {
key: 'other-user-key',
treatments: expect.any(Object)
treatments: expect.any(Object),
timestamp: expect.any(Number),
nonDefaultKey: true
}
});

Expand All @@ -621,15 +590,16 @@ describe('getTreatments (providing a non-default user key)', () => {
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).lastCalledWith(['split2'], attributes);
expect(Object.values(getClient(splitSdk, 'other-user-key').evalOnUpdate).length).toBe(1); // control assertion - added evalOnUpdate subscription

// The ADD_TREATMENTS action is dispatched when the SDK is updated
// SPLIT_UPDATE is not triggered since it is an update for a shared client
// The SPLIT_UPDATE_WITH_EVALUATIONS action is dispatched when the SDK is updated for the new user key
(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_UPDATE);
action = store.getActions()[4];
expect(action).toEqual({
type: ADD_TREATMENTS,
type: SPLIT_UPDATE_WITH_EVALUATIONS,
payload: {
key: 'other-user-key',
treatments: expect.any(Object)
treatments: expect.any(Object),
timestamp: expect.any(Number),
nonDefaultKey: true
}
});
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).lastCalledWith(['split2'], attributes);
Expand All @@ -650,10 +620,19 @@ describe('getTreatments (providing a non-default user key)', () => {
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toHaveLastReturnedWith(action.payload.treatments);
expect(Object.values(getClient(splitSdk).evalOnUpdate).length).toBe(0); // control assertion - removed evalOnUpdate subscription

// Now, SDK_UPDATE events do not trigger ADD_TREATMENTS
// Now, SDK_UPDATE events do not trigger SPLIT_UPDATE_WITH_EVALUATIONS but SPLIT_UPDATE instead
(splitSdk.factory as any).client('other-user-key').__emitter__.emit(Event.SDK_UPDATE);
expect(store.getActions().length).toBe(6); // control assertion - no more actions after the update.
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toBeCalledTimes(4); // control assertion - called 4 times
action = store.getActions()[6];
expect(action).toEqual({
type: SPLIT_UPDATE,
payload: {
key: 'other-user-key',
timestamp: expect.any(Number)
}
});

expect(store.getActions().length).toBe(7); // control assertion - no more actions after the update.
expect(splitSdk.factory.client('other-user-key').getTreatmentsWithConfig).toBeCalledTimes(4); // control assertion - called 4 times, in actions SPLIT_READY_FROM_CACHE_WITH_EVALUATIONS, SPLIT_READY_WITH_EVALUATIONS, SPLIT_UPDATE_WITH_EVALUATIONS and ADD_TREATMENTS.

done();
});
Expand Down
Loading
Loading