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 fd0fbd3f..250e38c5 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,18 @@ 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); + 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; }); } @@ -357,7 +364,6 @@ class OptimizelyReactSDKClient implements ReactSDKClient { } public async setUser(userInfo: UserInfo): Promise { - this.isUserPromiseResolved = false; this.isUserReady = true; //reset user info @@ -377,16 +383,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; }