From 87ee210b2997c1b6734caa6798a371d019e0859b Mon Sep 17 00:00:00 2001 From: Rafin Akther Utshaw Date: Wed, 2 Aug 2023 20:13:15 +0600 Subject: [PATCH 1/2] Fix qualified segments onready --- src/client.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/client.ts b/src/client.ts index d6451fdf..f7e6010c 100644 --- a/src/client.ts +++ b/src/client.ts @@ -219,7 +219,7 @@ class OptimizelyReactSDKClient implements ReactSDKClient { */ constructor(config: optimizely.Config) { this.initialConfig = config; - this.userPromiseResolver = () => {}; + this.userPromiseResolver = () => { }; const configWithClientInfo = { ...config, @@ -244,9 +244,6 @@ class OptimizelyReactSDKClient implements ReactSDKClient { }); this.dataReadyPromise = Promise.all([this.userPromise, this._client!.onReady()]).then(res => { - if (!res[0].success) { - return res[0]; - } // Client and user can become ready synchronously and/or asynchronously. This flag specifically indicates that they became ready asynchronously. this.isReadyPromiseFulfilled = true; @@ -309,8 +306,16 @@ class OptimizelyReactSDKClient implements ReactSDKClient { }, timeout) as any; }); - return Promise.race([this.dataReadyPromise, timeoutPromise]).then(res => { + return Promise.race([this.dataReadyPromise, timeoutPromise]).then(async res => { clearTimeout(timeoutId); + const isSegmentsFetched = await this.fetchQualifiedSegments(); + if (!isSegmentsFetched) { + return { + success: false, + reason: 'USER_NOT_READY', + message: 'Failed to fetch qualified segments', + } + } return res; }); } @@ -357,7 +362,6 @@ class OptimizelyReactSDKClient implements ReactSDKClient { } public async setUser(userInfo: UserInfo): Promise { - this.isUserPromiseResolved = false; this.isUserReady = true; //reset user info @@ -377,16 +381,13 @@ class OptimizelyReactSDKClient implements ReactSDKClient { if (userInfo.attributes) { this.user.attributes = userInfo.attributes; } - const isSegmentsFetched = await this.fetchQualifiedSegments(); - const segmentsResult: ResolveResult = { success: isSegmentsFetched }; - if (!isSegmentsFetched) { - segmentsResult.reason = 'USER_NOT_READY'; - segmentsResult.message = 'Failed to fetch qualified segments'; + if (this.getIsReadyPromiseFulfilled()) { + await this.fetchQualifiedSegments(); } if (!this.isUserPromiseResolved) { - this.userPromiseResolver(segmentsResult); + this.userPromiseResolver({ success: true }); this.isUserPromiseResolved = true; } From 2a9c4553f91fff9d2d9f9dc592cc60ddd4ca48f8 Mon Sep 17 00:00:00 2001 From: Rafin Akther Utshaw Date: Wed, 2 Aug 2023 21:10:39 +0600 Subject: [PATCH 2/2] Fix onready return --- src/client.spec.ts | 28 ++++++++++++++++++++++------ src/client.ts | 14 ++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/client.spec.ts b/src/client.spec.ts index f5989f65..676808c5 100644 --- a/src/client.spec.ts +++ b/src/client.spec.ts @@ -17,10 +17,10 @@ jest.mock('@optimizely/optimizely-sdk'); jest.mock('./logger', () => { return { logger: { - warn: jest.fn(() => () => {}), - info: jest.fn(() => () => {}), - error: jest.fn(() => () => {}), - debug: jest.fn(() => () => {}), + warn: jest.fn(() => () => { }), + info: jest.fn(() => () => { }), + error: jest.fn(() => () => { }), + debug: jest.fn(() => () => { }), }, }; }); @@ -251,7 +251,7 @@ describe('ReactSDKClient', () => { expect(onUserUpdateListener).toBeCalledTimes(1); }); - it('calls fetchqualifiedsegements internally on each setuser call', async () => { + it('does not call fetchqualifiedsegements on setUser if onready is not calleed initially', async () => { const instance = createInstance(config); jest.spyOn(instance, 'fetchQualifiedSegments').mockImplementation(async () => true); @@ -259,11 +259,27 @@ describe('ReactSDKClient', () => { id: 'xxfueaojfe8&86', }); + expect(instance.fetchQualifiedSegments).toBeCalledTimes(0); + }); + + it('calls fetchqualifiedsegements internally on each setuser call after onready', async () => { + const instance = createInstance(config); + jest.spyOn(instance, 'fetchQualifiedSegments').mockImplementation(async () => true); + + await instance.setUser({ + id: 'xxfueaojfe8&86', + }); + await instance.onReady() + + await instance.setUser({ + id: 'xxfueaojfe8&87', + }); + await instance.setUser({ id: 'xxfueaojfe8&87', }); - expect(instance.fetchQualifiedSegments).toBeCalledTimes(2); + expect(instance.fetchQualifiedSegments).toBeCalledTimes(3); }); describe('pre-set user and user overrides', () => { diff --git a/src/client.ts b/src/client.ts index f7e6010c..a3402129 100644 --- a/src/client.ts +++ b/src/client.ts @@ -308,12 +308,14 @@ class OptimizelyReactSDKClient implements ReactSDKClient { return Promise.race([this.dataReadyPromise, timeoutPromise]).then(async res => { clearTimeout(timeoutId); - const isSegmentsFetched = await this.fetchQualifiedSegments(); - if (!isSegmentsFetched) { - return { - success: false, - reason: 'USER_NOT_READY', - message: 'Failed to fetch qualified segments', + if (res.success) { + const isSegmentsFetched = await this.fetchQualifiedSegments(); + if (!isSegmentsFetched) { + return { + success: false, + reason: 'USER_NOT_READY', + message: 'Failed to fetch qualified segments', + } } } return res;