Skip to content

Commit 59b678b

Browse files
committed
node test
1 parent 8d73fad commit 59b678b

File tree

5 files changed

+186
-23
lines changed

5 files changed

+186
-23
lines changed

lib/event_processor/event_processor_factory.node.spec.ts

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,29 @@ vi.mock('./forwarding_event_processor', () => {
2424
return { getForwardingEventProcessor };
2525
});
2626

27-
import { createForwardingEventProcessor } from './event_processor_factory.node';
27+
vi.mock('./event_processor_factory', async (importOriginal) => {
28+
const getBatchEventProcessor = vi.fn().mockImplementation(() => {
29+
return {};
30+
});
31+
const original: any = await importOriginal();
32+
return { ...original, getBatchEventProcessor };
33+
});
34+
35+
vi.mock('../utils/cache/async_storage_cache.react_native', () => {
36+
return { AsyncStorageCache: vi.fn() };
37+
});
38+
39+
vi.mock('../utils/cache/cache', () => {
40+
return { SyncPrefixCache: vi.fn(), AsyncPrefixCache: vi.fn() };
41+
});
42+
43+
import { createBatchEventProcessor, createForwardingEventProcessor } from './event_processor_factory.node';
2844
import { getForwardingEventProcessor } from './forwarding_event_processor';
2945
import nodeDefaultEventDispatcher from './default_dispatcher.node';
46+
import { EVENT_STORE_PREFIX, FAILED_EVENT_RETRY_INTERVAL } from './event_processor_factory';
47+
import { getBatchEventProcessor } from './event_processor_factory';
48+
import { AsyncCache, AsyncPrefixCache, SyncCache, SyncPrefixCache } from '../utils/cache/cache';
49+
import { AsyncStorageCache } from '../utils/cache/async_storage_cache.react_native';
3050

3151
describe('createForwardingEventProcessor', () => {
3252
const mockGetForwardingEventProcessor = vi.mocked(getForwardingEventProcessor);
@@ -53,3 +73,126 @@ describe('createForwardingEventProcessor', () => {
5373
expect(mockGetForwardingEventProcessor).toHaveBeenNthCalledWith(1, nodeDefaultEventDispatcher);
5474
});
5575
});
76+
77+
describe('createBatchEventProcessor', () => {
78+
const mockGetBatchEventProcessor = vi.mocked(getBatchEventProcessor);
79+
const MockAsyncStorageCache = vi.mocked(AsyncStorageCache);
80+
const MockSyncPrefixCache = vi.mocked(SyncPrefixCache);
81+
const MockAsyncPrefixCache = vi.mocked(AsyncPrefixCache);
82+
83+
beforeEach(() => {
84+
mockGetBatchEventProcessor.mockClear();
85+
MockAsyncStorageCache.mockClear();
86+
MockSyncPrefixCache.mockClear();
87+
MockAsyncPrefixCache.mockClear();
88+
});
89+
90+
it('uses no default event store if no eventStore is provided', () => {
91+
const processor = createBatchEventProcessor({});
92+
93+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
94+
const eventStore = mockGetBatchEventProcessor.mock.calls[0][0].eventStore;
95+
expect(eventStore).toBe(undefined);
96+
});
97+
98+
it('wraps the provided eventStore in a SyncPrefixCache if a SyncCache is provided as eventStore', () => {
99+
const eventStore = {
100+
operation: 'sync',
101+
} as SyncCache<string>;
102+
103+
const processor = createBatchEventProcessor({ eventStore });
104+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
105+
106+
expect(mockGetBatchEventProcessor.mock.calls[0][0].eventStore).toBe(MockSyncPrefixCache.mock.results[0].value);
107+
const [cache, prefix, transformGet, transformSet] = MockSyncPrefixCache.mock.calls[0];
108+
109+
expect(cache).toBe(eventStore);
110+
expect(prefix).toBe(EVENT_STORE_PREFIX);
111+
112+
// transformGet and transformSet should be JSON.parse and JSON.stringify
113+
expect(transformGet('{"value": 1}')).toEqual({ value: 1 });
114+
expect(transformSet({ value: 1 })).toBe('{"value":1}');
115+
});
116+
117+
it('wraps the provided eventStore in a AsyncPrefixCache if a AsyncCache is provided as eventStore', () => {
118+
const eventStore = {
119+
operation: 'async',
120+
} as AsyncCache<string>;
121+
122+
const processor = createBatchEventProcessor({ eventStore });
123+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
124+
125+
expect(mockGetBatchEventProcessor.mock.calls[0][0].eventStore).toBe(MockAsyncPrefixCache.mock.results[0].value);
126+
const [cache, prefix, transformGet, transformSet] = MockAsyncPrefixCache.mock.calls[0];
127+
128+
expect(cache).toBe(eventStore);
129+
expect(prefix).toBe(EVENT_STORE_PREFIX);
130+
131+
// transformGet and transformSet should be JSON.parse and JSON.stringify
132+
expect(transformGet('{"value": 1}')).toEqual({ value: 1 });
133+
expect(transformSet({ value: 1 })).toBe('{"value":1}');
134+
});
135+
136+
137+
it('uses the provided eventDispatcher', () => {
138+
const eventDispatcher = {
139+
dispatchEvent: vi.fn(),
140+
};
141+
142+
const processor = createBatchEventProcessor({ eventDispatcher });
143+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
144+
expect(mockGetBatchEventProcessor.mock.calls[0][0].eventDispatcher).toBe(eventDispatcher);
145+
});
146+
147+
it('uses the default node event dispatcher if none is provided', () => {
148+
const processor = createBatchEventProcessor({ });
149+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
150+
expect(mockGetBatchEventProcessor.mock.calls[0][0].eventDispatcher).toBe(nodeDefaultEventDispatcher);
151+
});
152+
153+
it('uses the provided closingEventDispatcher', () => {
154+
const closingEventDispatcher = {
155+
dispatchEvent: vi.fn(),
156+
};
157+
158+
const processor = createBatchEventProcessor({ closingEventDispatcher });
159+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
160+
expect(mockGetBatchEventProcessor.mock.calls[0][0].closingEventDispatcher).toBe(closingEventDispatcher);
161+
162+
const processor2 = createBatchEventProcessor({ });
163+
expect(Object.is(processor2, mockGetBatchEventProcessor.mock.results[1].value)).toBe(true);
164+
expect(mockGetBatchEventProcessor.mock.calls[1][0].closingEventDispatcher).toBe(undefined);
165+
});
166+
167+
it('uses the provided flushInterval', () => {
168+
const processor1 = createBatchEventProcessor({ flushInterval: 2000 });
169+
expect(Object.is(processor1, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
170+
expect(mockGetBatchEventProcessor.mock.calls[0][0].flushInterval).toBe(2000);
171+
172+
const processor2 = createBatchEventProcessor({ });
173+
expect(Object.is(processor2, mockGetBatchEventProcessor.mock.results[1].value)).toBe(true);
174+
expect(mockGetBatchEventProcessor.mock.calls[1][0].flushInterval).toBe(undefined);
175+
});
176+
177+
it('uses the provided batchSize', () => {
178+
const processor1 = createBatchEventProcessor({ batchSize: 20 });
179+
expect(Object.is(processor1, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
180+
expect(mockGetBatchEventProcessor.mock.calls[0][0].batchSize).toBe(20);
181+
182+
const processor2 = createBatchEventProcessor({ });
183+
expect(Object.is(processor2, mockGetBatchEventProcessor.mock.results[1].value)).toBe(true);
184+
expect(mockGetBatchEventProcessor.mock.calls[1][0].batchSize).toBe(undefined);
185+
});
186+
187+
it('uses maxRetries value of 10', () => {
188+
const processor = createBatchEventProcessor({ });
189+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
190+
expect(mockGetBatchEventProcessor.mock.calls[0][0].retryOptions?.maxRetries).toBe(10);
191+
});
192+
193+
it('uses the default failedEventRetryInterval', () => {
194+
const processor = createBatchEventProcessor({ });
195+
expect(Object.is(processor, mockGetBatchEventProcessor.mock.results[0].value)).toBe(true);
196+
expect(mockGetBatchEventProcessor.mock.calls[0][0].failedEventRetryInterval).toBe(FAILED_EVENT_RETRY_INTERVAL);
197+
});
198+
});

lib/event_processor/event_processor_factory.node.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,29 @@ import { getForwardingEventProcessor } from './forwarding_event_processor';
1717
import { EventDispatcher } from './eventDispatcher';
1818
import { EventProcessor } from './eventProcessor';
1919
import defaultEventDispatcher from './default_dispatcher.node';
20+
import { BatchEventProcessorOptions, FAILED_EVENT_RETRY_INTERVAL, getBatchEventProcessor, getPrefixEventStore } from './event_processor_factory';
2021

2122
export const createForwardingEventProcessor = (
2223
eventDispatcher: EventDispatcher = defaultEventDispatcher,
2324
): EventProcessor => {
2425
return getForwardingEventProcessor(eventDispatcher);
2526
};
27+
28+
29+
export const createBatchEventProcessor = (
30+
options: BatchEventProcessorOptions
31+
): EventProcessor => {
32+
const eventStore = options.eventStore ? getPrefixEventStore(options.eventStore) : undefined;
33+
34+
return getBatchEventProcessor({
35+
eventDispatcher: options.eventDispatcher || defaultEventDispatcher,
36+
closingEventDispatcher: options.closingEventDispatcher,
37+
flushInterval: options.flushInterval,
38+
batchSize: options.batchSize,
39+
retryOptions: {
40+
maxRetries: 10,
41+
},
42+
failedEventRetryInterval: FAILED_EVENT_RETRY_INTERVAL,
43+
eventStore,
44+
});
45+
};

lib/event_processor/event_processor_factory.react_native.ts

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ import { getForwardingEventProcessor } from './forwarding_event_processor';
1717
import { EventDispatcher } from './eventDispatcher';
1818
import { EventProcessor } from './eventProcessor';
1919
import defaultEventDispatcher from './default_dispatcher.browser';
20-
import { BatchEventProcessorOptions, getBatchEventProcessor } from './event_processor_factory';
20+
import { BatchEventProcessorOptions, getBatchEventProcessor, getPrefixEventStore } from './event_processor_factory';
2121
import { EVENT_STORE_PREFIX, FAILED_EVENT_RETRY_INTERVAL } from './event_processor_factory';
22-
import { AsyncPrefixCache, Cache, SyncPrefixCache } from '../utils/cache/cache';
22+
import { AsyncPrefixCache } from '../utils/cache/cache';
2323
import { EventWithId } from './batch_event_processor';
2424
import { AsyncStorageCache } from '../utils/cache/async_storage_cache.react_native';
2525

@@ -44,24 +44,6 @@ const getDefaultEventStore = () => {
4444
return eventStore;
4545
}
4646

47-
const getPrefixEventStore = (cache: Cache<string>): Cache<EventWithId> => {
48-
if (cache.operation === 'async') {
49-
return new AsyncPrefixCache<string, EventWithId>(
50-
cache,
51-
EVENT_STORE_PREFIX,
52-
JSON.parse,
53-
JSON.stringify,
54-
);
55-
} else {
56-
return new SyncPrefixCache<string, EventWithId>(
57-
cache,
58-
EVENT_STORE_PREFIX,
59-
JSON.parse,
60-
JSON.stringify,
61-
);
62-
}
63-
};
64-
6547
export const createBatchEventProcessor = (
6648
options: BatchEventProcessorOptions
6749
): EventProcessor => {

lib/event_processor/event_processor_factory.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ExponentialBackoff, IntervalRepeater } from "../utils/repeater/repeater
44
import { EventDispatcher } from "./eventDispatcher";
55
import { EventProcessor } from "./eventProcessor";
66
import { BatchEventProcessor, EventWithId, RetryConfig } from "./batch_event_processor";
7-
import { Cache } from "../utils/cache/cache";
7+
import { AsyncPrefixCache, Cache, SyncPrefixCache } from "../utils/cache/cache";
88

99
export const DEFAULT_EVENT_BATCH_SIZE = 10;
1010
export const DEFAULT_EVENT_FLUSH_INTERVAL = 1000;
@@ -14,6 +14,24 @@ export const DEFAULT_MAX_BACKOFF = 32000;
1414
export const FAILED_EVENT_RETRY_INTERVAL = 20 * 1000;
1515
export const EVENT_STORE_PREFIX = 'optly_event:';
1616

17+
export const getPrefixEventStore = (cache: Cache<string>): Cache<EventWithId> => {
18+
if (cache.operation === 'async') {
19+
return new AsyncPrefixCache<string, EventWithId>(
20+
cache,
21+
EVENT_STORE_PREFIX,
22+
JSON.parse,
23+
JSON.stringify,
24+
);
25+
} else {
26+
return new SyncPrefixCache<string, EventWithId>(
27+
cache,
28+
EVENT_STORE_PREFIX,
29+
JSON.parse,
30+
JSON.stringify,
31+
);
32+
}
33+
};
34+
1735
export type BatchEventProcessorOptions = {
1836
eventDispatcher?: EventDispatcher;
1937
closingEventDispatcher?: EventDispatcher;

vitest.config.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default defineConfig({
2020
test: {
2121
onConsoleLog: () => true,
2222
environment: 'happy-dom',
23-
include: ['**/event_processor_factory.react_native.spec.ts'],
23+
include: ['**/event_processor_factory.node.spec.ts'],
2424
typecheck: {
2525
tsconfig: 'tsconfig.spec.json',
2626
},

0 commit comments

Comments
 (0)