Skip to content

Commit 45f9762

Browse files
committed
test: add retry logic tests for BrowserDataManager polling
This commit will: - introduce new unit tests - fixed a counting issue with retries
1 parent 38ca87d commit 45f9762

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

packages/sdk/browser/__tests__/BrowserDataManager.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,4 +527,85 @@ describe('given a BrowserDataManager with mocked dependencies', () => {
527527
'[BrowserDataManager] Identify called after data manager was closed.',
528528
);
529529
});
530+
531+
it('retries initial polling until it succeeds', async () => {
532+
jest.useFakeTimers();
533+
const context = Context.fromLDContext({ kind: 'user', key: 'test-user' });
534+
flagManager.loadCached.mockResolvedValue(false);
535+
536+
// Mock fetch to fail twice with 500 error, then succeed
537+
let callCount = 0;
538+
const mockedFetch = jest.fn().mockImplementation(() => {
539+
callCount += 1;
540+
if (callCount <= 2) {
541+
return mockResponse('', 500);
542+
}
543+
return mockResponse('{"flagA": true}', 200);
544+
});
545+
546+
platform.requests.fetch = mockedFetch as typeof platform.requests.fetch;
547+
548+
const identifyResolve = jest.fn();
549+
const identifyReject = jest.fn();
550+
551+
const identifyOptions: BrowserIdentifyOptions = { initialPollingRetries: 3 };
552+
const identifyPromise = dataManager.identify(
553+
identifyResolve,
554+
identifyReject,
555+
context,
556+
identifyOptions,
557+
);
558+
559+
// Fast-forward through the retry delays (2 retries * 1000ms each)
560+
await jest.advanceTimersByTimeAsync(2000);
561+
562+
await identifyPromise;
563+
564+
expect(mockedFetch).toHaveBeenCalledTimes(3);
565+
expect(identifyResolve).toHaveBeenCalled();
566+
expect(identifyReject).not.toHaveBeenCalled();
567+
expect(flagManager.init).toHaveBeenCalledWith(
568+
expect.anything(),
569+
expect.objectContaining({ flagA: { flag: true, version: undefined } }),
570+
);
571+
572+
jest.useRealTimers();
573+
});
574+
575+
it('throws an error when initial polling reaches max retry limit', async () => {
576+
jest.useFakeTimers();
577+
const context = Context.fromLDContext({ kind: 'user', key: 'test-user' });
578+
flagManager.loadCached.mockResolvedValue(false);
579+
580+
// Mock fetch to always fail with 500 error
581+
const mockedFetch = jest.fn().mockImplementation(() => {
582+
return mockResponse('', 500);
583+
});
584+
585+
platform.requests.fetch = mockedFetch as typeof platform.requests.fetch;
586+
587+
const identifyResolve = jest.fn();
588+
const identifyReject = jest.fn();
589+
590+
const identifyOptions: BrowserIdentifyOptions = { initialPollingRetries: 2 };
591+
const identifyPromise = dataManager.identify(
592+
identifyResolve,
593+
identifyReject,
594+
context,
595+
identifyOptions,
596+
);
597+
598+
// Fast-forward through the retry delays (2 retries * 1000ms each)
599+
await jest.advanceTimersByTimeAsync(2000);
600+
601+
await identifyPromise;
602+
603+
// Should attempt initial request + 2 retries = 3 total attempts
604+
expect(mockedFetch).toHaveBeenCalledTimes(3);
605+
expect(identifyResolve).not.toHaveBeenCalled();
606+
expect(identifyReject).toHaveBeenCalled();
607+
expect(identifyReject).toHaveBeenCalledWith(expect.objectContaining({ status: 500 }));
608+
609+
jest.useRealTimers();
610+
});
530611
});

packages/sdk/browser/src/BrowserDataManager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,9 @@ export default class BrowserDataManager extends BaseDataManager {
136136
let lastError: any;
137137
let validMaxRetries = maxRetries ?? 3;
138138

139-
if (validMaxRetries < 1) {
139+
if (validMaxRetries < 0) {
140140
this.logger.warn(
141-
`initialPollingRetries is set to ${maxRetries}, which is less than 1. This is not supported and will be ignored. Defaulting to 3 retries.`,
141+
`initialPollingRetries is set to ${maxRetries}, which is less than 0. This is not supported and will be ignored. Defaulting to 3 retries.`,
142142
);
143143
validMaxRetries = 3;
144144
}

0 commit comments

Comments
 (0)