Skip to content

Commit

Permalink
fix: Fix issue where flush callback could be called twice. (#779)
Browse files Browse the repository at this point in the history
Relates to #777
  • Loading branch information
kinyoklion authored Feb 18, 2025
1 parent 1926b49 commit c377e89
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 2 deletions.
118 changes: 118 additions & 0 deletions packages/shared/sdk-server/__tests__/LDClientImpl.events.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { LDClientImpl } from '../src';
import { createBasicPlatform } from './createBasicPlatform';
import TestLogger from './Logger';
import makeCallbacks from './makeCallbacks';

it('flushes events successfully and executes the callback', async () => {
const platform = createBasicPlatform();
platform.requests.fetch.mockImplementation(() =>
Promise.resolve({ status: 200, headers: new Headers() }),
);

const client = new LDClientImpl(
'sdk-key-events',
platform,
{
logger: new TestLogger(),
stream: false,
},
makeCallbacks(false),
);

client.identify({ key: 'user' });
client.variation('dev-test-flag', { key: 'user' }, false);

const flushCallback = jest.fn();

await client.flush(flushCallback);

expect(platform.requests.fetch).toHaveBeenCalledWith(
'https://events.launchdarkly.com/bulk',
expect.objectContaining({
method: 'POST',
body: expect.any(String),
}),
);
expect(flushCallback).toHaveBeenCalledWith(null, true);
expect(flushCallback).toHaveBeenCalledTimes(1);
});

it('flushes events successfully', async () => {
const platform = createBasicPlatform();
platform.requests.fetch.mockImplementation(() =>
Promise.resolve({ status: 200, headers: new Headers() }),
);

const client = new LDClientImpl(
'sdk-key-events',
platform,
{
logger: new TestLogger(),
stream: false,
},
makeCallbacks(false),
);

client.identify({ key: 'user' });
client.variation('dev-test-flag', { key: 'user' }, false);

await client.flush();

expect(platform.requests.fetch).toHaveBeenCalledWith(
'https://events.launchdarkly.com/bulk',
expect.objectContaining({
method: 'POST',
body: expect.any(String),
}),
);
});

it('calls error callback once when flush fails with http status code', async () => {
const platform = createBasicPlatform();
platform.requests.fetch.mockImplementation(() =>
Promise.resolve({ status: 401, headers: new Headers() }),
);

const flushCallback = jest.fn();
const client = new LDClientImpl(
'sdk-key-events',
platform,
{
logger: new TestLogger(),
stream: false,
},
makeCallbacks(false),
);

client.identify({ key: 'user' });
client.variation('dev-test-flag', { key: 'user' }, false);

await client.flush(flushCallback);

expect(flushCallback).toHaveBeenCalledWith(expect.any(Error), false);
expect(flushCallback).toHaveBeenCalledTimes(1);
});

it('calls error callback once when flush fails with exception', async () => {
const platform = createBasicPlatform();
platform.requests.fetch.mockImplementation(() => Promise.reject(new Error('test error')));

const flushCallback = jest.fn();
const client = new LDClientImpl(
'sdk-key-events',
platform,
{
logger: new TestLogger(),
stream: false,
},
makeCallbacks(false),
);

client.identify({ key: 'user' });
client.variation('dev-test-flag', { key: 'user' }, false);

await client.flush(flushCallback);

expect(flushCallback).toHaveBeenCalledWith(expect.any(Error), false);
expect(flushCallback).toHaveBeenCalledTimes(1);
});
4 changes: 2 additions & 2 deletions packages/shared/sdk-server/src/LDClientImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -773,9 +773,9 @@ export default class LDClientImpl implements LDClient {
try {
await this._eventProcessor.flush();
} catch (err) {
callback?.(err as Error, false);
return callback?.(err as Error, false);
}
callback?.(null, true);
return callback?.(null, true);
}

addHook(hook: Hook): void {
Expand Down

0 comments on commit c377e89

Please sign in to comment.