Skip to content

Commit c7091f6

Browse files
committed
init refac
1 parent 16e638a commit c7091f6

32 files changed

+863
-1278
lines changed

lib/index.browser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { createNotificationCenter } from './notification_center';
2626
import { OptimizelyDecideOption, Client, Config, OptimizelyOptions } from './shared_types';
2727
import { BrowserOdpManager } from './odp/odp_manager.browser';
2828
import Optimizely from './optimizely';
29-
import { IUserAgentParser } from './odp/ua_parser/user_agent_parser';
29+
import { UserAgentParser } from './odp/ua_parser/user_agent_parser';
3030
import { getUserAgentParser } from './odp/ua_parser/ua_parser.browser';
3131
import * as commonExports from './common_exports';
3232
import { PollingConfigManagerConfig } from './project_config/config_manager_factory';
@@ -192,7 +192,7 @@ export {
192192
createInstance,
193193
__internalResetRetryState,
194194
OptimizelyDecideOption,
195-
IUserAgentParser,
195+
UserAgentParser as IUserAgentParser,
196196
getUserAgentParser,
197197
createPollingProjectConfigManager,
198198
createForwardingEventProcessor,

lib/odp/constant.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export enum ODP_USER_KEY {
2+
VUID = 'vuid',
3+
FS_USER_ID = 'fs_user_id',
4+
FS_USER_ID_ALIAS = 'fs-user-id',
5+
}
6+
7+
export enum ODP_EVENT_ACTION {
8+
IDENTIFIED = 'identified',
9+
INITIALIZED = 'client_initialized',
10+
}
11+
12+
export const ODP_DEFAULT_EVENT_TYPE = 'fullstack';

lib/odp/event_manager/event_api_manager.browser.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.

lib/odp/event_manager/event_api_manager.node.ts

Lines changed: 0 additions & 51 deletions
This file was deleted.

lib/odp/event_manager/event_manager.browser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { IOdpEventManager, OdpEventManager } from './odp_event_manager';
17+
import { OdpEventManager, DefaultOdpEventManager } from './odp_event_manager';
1818
import { LogLevel } from '../../modules/logging';
1919
import { OdpEvent } from './odp_event';
2020

2121
const DEFAULT_BROWSER_QUEUE_SIZE = 100;
2222

23-
export class BrowserOdpEventManager extends OdpEventManager implements IOdpEventManager {
23+
export class BrowserOdpEventManager extends DefaultOdpEventManager implements OdpEventManager {
2424
protected initParams(
2525
batchSize: number | undefined,
2626
queueSize: number | undefined,

lib/odp/event_manager/event_manager.node.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
*/
1616

1717
import { OdpEvent } from './odp_event';
18-
import { IOdpEventManager, OdpEventManager } from './odp_event_manager';
18+
import { OdpEventManager, DefaultOdpEventManager } from './odp_event_manager';
1919
import { LogLevel } from '../../modules/logging';
2020

2121
const DEFAULT_BATCH_SIZE = 10;
2222
const DEFAULT_FLUSH_INTERVAL_MSECS = 1000;
2323
const DEFAULT_SERVER_QUEUE_SIZE = 10000;
2424

25-
export class NodeOdpEventManager extends OdpEventManager implements IOdpEventManager {
25+
export class NodeOdpEventManager extends DefaultOdpEventManager implements OdpEventManager {
2626
protected initParams(
2727
batchSize: number | undefined,
2828
queueSize: number | undefined,
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/**
2+
* Copyright 2022-2024, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { describe, beforeEach, beforeAll, it, expect, vi } from 'vitest';
18+
19+
import { LogHandler, LogLevel } from '../../modules/logging';
20+
import { DefaultOdpEventApiManager, eventApiRequestGenerator, pixelApiRequestGenerator } from './odp_event_api_manager';
21+
import { OdpEvent } from './odp_event';
22+
import { RequestHandler } from '../../utils/http_request_handler/http';
23+
import { OdpConfig } from '../odp_config';
24+
import { get } from 'http';
25+
26+
const data1 = new Map<string, unknown>();
27+
data1.set('key11', 'value-1');
28+
data1.set('key12', true);
29+
data1.set('key13', 3.5);
30+
data1.set('key14', null);
31+
32+
const data2 = new Map<string, unknown>();
33+
34+
data2.set('key2', 'value-2');
35+
36+
const ODP_EVENTS = [
37+
new OdpEvent('t1', 'a1', new Map([['id-key-1', 'id-value-1']]), data1),
38+
new OdpEvent('t2', 'a2', new Map([['id-key-2', 'id-value-2']]), data2),
39+
];
40+
41+
const API_KEY = 'test-api-key';
42+
const API_HOST = 'https://odp.example.com';
43+
const PIXEL_URL = 'https://odp.pixel.com';
44+
45+
const odpConfig = new OdpConfig(API_KEY, API_HOST, PIXEL_URL, []);
46+
47+
import { getMockRequestHandler } from '../../tests/mock/mock_request_handler';
48+
49+
describe('DefaultOdpEventApiManager', () => {
50+
it('should generate the event request using the correct odp config and event', async () => {
51+
const mockRequestHandler = getMockRequestHandler();
52+
mockRequestHandler.makeRequest.mockReturnValue({
53+
responsePromise: Promise.resolve({
54+
statusCode: 200,
55+
body: '',
56+
headers: {},
57+
}),
58+
});
59+
const requestGenerator = vi.fn().mockReturnValue({
60+
method: 'PATCH',
61+
endpoint: 'https://odp.example.com/v3/events',
62+
headers: {
63+
'x-api-key': 'test-api',
64+
},
65+
data: 'event-data',
66+
});
67+
68+
const manager = new DefaultOdpEventApiManager(mockRequestHandler, requestGenerator);
69+
manager.sendEvents(odpConfig, ODP_EVENTS);
70+
71+
expect(requestGenerator.mock.calls[0][0]).toEqual(odpConfig);
72+
expect(requestGenerator.mock.calls[0][1]).toEqual(ODP_EVENTS);
73+
});
74+
75+
it('should send the correct request using the request handler', async () => {
76+
const mockRequestHandler = getMockRequestHandler();
77+
mockRequestHandler.makeRequest.mockReturnValue({
78+
responsePromise: Promise.resolve({
79+
statusCode: 200,
80+
body: '',
81+
headers: {},
82+
}),
83+
});
84+
const requestGenerator = vi.fn().mockReturnValue({
85+
method: 'PATCH',
86+
endpoint: 'https://odp.example.com/v3/events',
87+
headers: {
88+
'x-api-key': 'test-api',
89+
},
90+
data: 'event-data',
91+
});
92+
93+
const manager = new DefaultOdpEventApiManager(mockRequestHandler, requestGenerator);
94+
manager.sendEvents(odpConfig, ODP_EVENTS);
95+
96+
expect(mockRequestHandler.makeRequest.mock.calls[0][0]).toEqual('https://odp.example.com/v3/events');
97+
expect(mockRequestHandler.makeRequest.mock.calls[0][1]).toEqual({
98+
'x-api-key': 'test-api',
99+
});
100+
expect(mockRequestHandler.makeRequest.mock.calls[0][2]).toEqual('PATCH');
101+
expect(mockRequestHandler.makeRequest.mock.calls[0][3]).toEqual('event-data');
102+
});
103+
104+
it('should return a promise that fails if the requestHandler response promise fails', async () => {
105+
const mockRequestHandler = getMockRequestHandler();
106+
mockRequestHandler.makeRequest.mockReturnValue({
107+
responsePromise: Promise.reject(new Error('Request failed')),
108+
});
109+
const requestGenerator = vi.fn().mockReturnValue({
110+
method: 'PATCH',
111+
endpoint: 'https://odp.example.com/v3/events',
112+
headers: {
113+
'x-api-key': 'test-api',
114+
},
115+
data: 'event-data',
116+
});
117+
118+
const manager = new DefaultOdpEventApiManager(mockRequestHandler, requestGenerator);
119+
const response = manager.sendEvents(odpConfig, ODP_EVENTS);
120+
121+
await expect(response).rejects.toThrow('Request failed');
122+
});
123+
124+
it('should return a promise that resolves with correct response code from the requestHandler', async () => {
125+
const mockRequestHandler = getMockRequestHandler();
126+
mockRequestHandler.makeRequest.mockReturnValue({
127+
responsePromise: Promise.resolve({
128+
statusCode: 226,
129+
body: '',
130+
headers: {},
131+
}),
132+
});
133+
const requestGenerator = vi.fn().mockReturnValue({
134+
method: 'PATCH',
135+
endpoint: 'https://odp.example.com/v3/events',
136+
headers: {
137+
'x-api-key': 'test-api',
138+
},
139+
data: 'event-data',
140+
});
141+
142+
const manager = new DefaultOdpEventApiManager(mockRequestHandler, requestGenerator);
143+
const response = manager.sendEvents(odpConfig, ODP_EVENTS);
144+
145+
await expect(response).resolves.not.toThrow();
146+
const statusCode = await response.then((r) => r.statusCode);
147+
expect(statusCode).toBe(226);
148+
});
149+
});
150+
151+
describe('pixelApiRequestGenerator', () => {
152+
it('should generate the correct request for the pixel API using only the first event', () => {
153+
const request = pixelApiRequestGenerator(odpConfig, ODP_EVENTS);
154+
expect(request.method).toBe('GET');
155+
const endpoint = new URL(request.endpoint);
156+
expect(endpoint.origin).toBe(PIXEL_URL);
157+
expect(endpoint.pathname).toBe('/v2/zaius.gif');
158+
expect(endpoint.searchParams.get('id-key-1')).toBe('id-value-1');
159+
expect(endpoint.searchParams.get('key11')).toBe('value-1');
160+
expect(endpoint.searchParams.get('key12')).toBe('true');
161+
expect(endpoint.searchParams.get('key13')).toBe('3.5');
162+
expect(endpoint.searchParams.get('key14')).toBe('null');
163+
expect(endpoint.searchParams.get('tracker_id')).toBe(API_KEY);
164+
expect(endpoint.searchParams.get('event_type')).toBe('t1');
165+
expect(endpoint.searchParams.get('vdl_action')).toBe('a1');
166+
167+
expect(request.headers).toEqual({});
168+
expect(request.data).toBe('');
169+
});
170+
});
171+
172+
describe('eventApiRequestGenerator', () => {
173+
it('should generate the correct request for the event API using all events', () => {
174+
const request = eventApiRequestGenerator(odpConfig, ODP_EVENTS);
175+
expect(request.method).toBe('POST');
176+
expect(request.endpoint).toBe('https://odp.example.com/v3/events');
177+
expect(request.headers).toEqual({
178+
'Content-Type': 'application/json',
179+
'x-api-key': API_KEY,
180+
});
181+
182+
const data = JSON.parse(request.data);
183+
expect(data).toEqual([
184+
{
185+
type: 't1',
186+
action: 'a1',
187+
identifiers: {
188+
'id-key-1': 'id-value-1',
189+
},
190+
data: {
191+
key11: 'value-1',
192+
key12: true,
193+
key13: 3.5,
194+
key14: null,
195+
},
196+
},
197+
{
198+
type: 't2',
199+
action: 'a2',
200+
identifiers: {
201+
'id-key-2': 'id-value-2',
202+
},
203+
data: {
204+
key2: 'value-2',
205+
},
206+
},
207+
]);
208+
});
209+
});

0 commit comments

Comments
 (0)