Skip to content

Commit 9a4aebc

Browse files
committed
Add cookieExtensionService argument as replacement for idService, deprecate idService (close #1425)
1 parent a083809 commit 9a4aebc

File tree

8 files changed

+121
-84
lines changed

8 files changed

+121
-84
lines changed

Diff for: api-docs/docs/browser-tracker/browser-tracker.api.md

+2
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,14 @@ export function discardHashTag(enable: boolean, trackers?: Array<string>): void;
219219
export interface EmitterConfigurationBase {
220220
bufferSize?: number;
221221
connectionTimeout?: number;
222+
cookieExtensionService?: string;
222223
credentials?: "omit" | "same-origin" | "include";
223224
customFetch?: (input: Request, options?: RequestInit) => Promise<Response>;
224225
customHeaders?: Record<string, string>;
225226
dontRetryStatusCodes?: number[];
226227
eventMethod?: EventMethod;
227228
eventStore?: EventStore;
229+
// @deprecated (undocumented)
228230
idService?: string;
229231
keepalive?: boolean;
230232
maxGetBytes?: number;

Diff for: api-docs/docs/node-tracker/node-tracker.api.md

+2
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,14 @@ export interface EmitterConfiguration extends EmitterConfigurationBase {
244244
export interface EmitterConfigurationBase {
245245
bufferSize?: number;
246246
connectionTimeout?: number;
247+
cookieExtensionService?: string;
247248
credentials?: "omit" | "same-origin" | "include";
248249
customFetch?: (input: Request, options?: RequestInit) => Promise<Response>;
249250
customHeaders?: Record<string, string>;
250251
dontRetryStatusCodes?: number[];
251252
eventMethod?: EventMethod;
252253
eventStore?: EventStore;
254+
// @deprecated (undocumented)
253255
idService?: string;
254256
keepalive?: boolean;
255257
maxGetBytes?: number;

Diff for: api-docs/docs/react-native-tracker/react-native-tracker.api.md

+2
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,15 @@ export interface EmitterConfiguration extends EmitterConfigurationBase {
120120
export interface EmitterConfigurationBase {
121121
bufferSize?: number;
122122
connectionTimeout?: number;
123+
cookieExtensionService?: string;
123124
credentials?: "omit" | "same-origin" | "include";
124125
customFetch?: (input: Request, options?: RequestInit) => Promise<Response>;
125126
customHeaders?: Record<string, string>;
126127
dontRetryStatusCodes?: number[];
127128
eventMethod?: EventMethod;
128129
// Warning: (ae-forgotten-export) The symbol "EventStore" needs to be exported by the entry point index.d.ts
129130
eventStore?: EventStore;
131+
// @deprecated (undocumented)
130132
idService?: string;
131133
keepalive?: boolean;
132134
maxGetBytes?: number;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/browser-tracker-core",
5+
"comment": "Add `cookieExtensionService` argument as replacement for `idService`, deprecated `idService`",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/browser-tracker-core"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@snowplow/tracker-core",
5+
"comment": "Add `cookieExtensionService` argument as replacement for `idService`, deprecate `idService`",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@snowplow/tracker-core"
10+
}

Diff for: libraries/browser-tracker-core/test/out_queue.test.ts

+75-72
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,8 @@ describe('OutQueueManager', () => {
193193
});
194194
});
195195

196-
describe('idService requests', () => {
197-
const idServiceEndpoint = 'http://example.com/id';
196+
describe('cookieExtensionService requests', () => {
197+
const cookieExtensionServiceEndpoint = 'http://example.com/id';
198198

199199
const getQuerystring = (p: object) =>
200200
'?' +
@@ -203,85 +203,87 @@ describe('OutQueueManager', () => {
203203
.join('&');
204204

205205
describe('GET requests', () => {
206-
let createGetQueue = () => newOutQueue(
207-
{
208-
endpoint: 'http://example.com',
209-
trackerId: 'sp',
210-
eventMethod: 'get',
211-
useStm: false,
212-
maxLocalStorageQueueSize: maxQueueSize,
213-
eventStore,
214-
customFetch,
215-
idService: idServiceEndpoint,
216-
},
217-
new SharedState()
218-
);
219-
206+
let createGetQueue = () =>
207+
newOutQueue(
208+
{
209+
endpoint: 'http://example.com',
210+
trackerId: 'sp',
211+
eventMethod: 'get',
212+
useStm: false,
213+
maxLocalStorageQueueSize: maxQueueSize,
214+
eventStore,
215+
customFetch,
216+
cookieExtensionService: cookieExtensionServiceEndpoint,
217+
},
218+
new SharedState()
219+
);
220220

221-
it('should first execute the idService request and in the same `enqueueRequest` the tracking request', async () => {
221+
it('should first execute the cookieExtensionService request and in the same `enqueueRequest` the tracking request', async () => {
222222
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
223223
const getQueue = createGetQueue();
224224

225225
await getQueue.enqueueRequest(request);
226226

227227
expect(requests).toHaveLength(2);
228-
expect(requests[0].url).toEqual(idServiceEndpoint);
228+
expect(requests[0].url).toEqual(cookieExtensionServiceEndpoint);
229229
expect(requests[1].url).toEqual('http://example.com/i' + getQuerystring(request));
230230
});
231231

232-
it('should first execute the idService request and in the same `enqueueRequest` the tracking request irregardless of failure of the idService endpoint', async () => {
232+
it('should first execute the cookieExtensionService request and in the same `enqueueRequest` the tracking request irregardless of failure of the cookieExtensionService endpoint', async () => {
233233
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
234234
const getQueue = createGetQueue();
235235

236236
responseStatusCode = 500;
237237
await getQueue.enqueueRequest(request);
238238

239239
expect(requests).toHaveLength(2);
240-
expect(requests[0].url).toEqual(idServiceEndpoint);
240+
expect(requests[0].url).toEqual(cookieExtensionServiceEndpoint);
241241
expect(requests[1].url).toEqual('http://example.com/i' + getQuerystring(request));
242242
expect(await eventStore.count()).toEqual(1);
243243
});
244244
});
245245

246246
describe('POST requests', () => {
247-
let createPostQueue = () => newOutQueue(
248-
{
249-
endpoint: 'http://example.com',
250-
trackerId: 'sp',
251-
eventMethod: 'post',
252-
eventStore,
253-
customFetch,
254-
idService: idServiceEndpoint,
255-
},
256-
new SharedState()
257-
);
247+
let createPostQueue = () =>
248+
newOutQueue(
249+
{
250+
endpoint: 'http://example.com',
251+
trackerId: 'sp',
252+
eventMethod: 'post',
253+
eventStore,
254+
customFetch,
255+
cookieExtensionService: cookieExtensionServiceEndpoint,
256+
},
257+
new SharedState()
258+
);
258259

259-
it('should first execute the idService request and in the same `enqueueRequest` the tracking request irregardless of failure of the idService endpoint', async () => {
260+
it('should first execute the cookieExtensionService request and in the same `enqueueRequest` the tracking request irregardless of failure of the cookieExtensionService endpoint', async () => {
260261
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
261262
const postQueue = createPostQueue();
262263

263264
await postQueue.enqueueRequest(request);
264265

265266
expect(requests).toHaveLength(2);
266-
expect(requests[0].url).toEqual(idServiceEndpoint);
267+
expect(requests[0].url).toEqual(cookieExtensionServiceEndpoint);
267268
expect(requests[1].url).toEqual('http://example.com/com.snowplowanalytics.snowplow/tp2');
268269
});
269270
});
270271
});
271272

272273
describe('retryFailures = true', () => {
273274
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
274-
let createOutQueue = () => newOutQueue(
275-
{
276-
endpoint: 'http://example.com',
277-
trackerId: 'sp',
278-
eventMethod: 'post',
279-
retryFailedRequests: true,
280-
eventStore,
281-
customFetch,
282-
},
283-
new SharedState()
284-
);
275+
let createOutQueue = () =>
276+
newOutQueue(
277+
{
278+
endpoint: 'http://example.com',
279+
trackerId: 'sp',
280+
eventMethod: 'post',
281+
retryFailedRequests: true,
282+
eventStore,
283+
customFetch,
284+
},
285+
new SharedState()
286+
);
285287

286288
it('should remain in queue on failure', async () => {
287289
let outQueue = createOutQueue();
@@ -295,17 +297,18 @@ describe('OutQueueManager', () => {
295297

296298
describe('retryFailures = false', () => {
297299
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
298-
let createOutQueue = () => newOutQueue(
299-
{
300-
endpoint: 'http://example.com',
301-
trackerId: 'sp',
302-
eventMethod: 'post',
303-
retryFailedRequests: false,
304-
eventStore,
305-
customFetch,
306-
},
307-
new SharedState()
308-
);
300+
let createOutQueue = () =>
301+
newOutQueue(
302+
{
303+
endpoint: 'http://example.com',
304+
trackerId: 'sp',
305+
eventMethod: 'post',
306+
retryFailedRequests: false,
307+
eventStore,
308+
customFetch,
309+
},
310+
new SharedState()
311+
);
309312

310313
it('should remove from queue on failure', async () => {
311314
let outQueue = createOutQueue();
@@ -441,23 +444,23 @@ describe('OutQueueManager', () => {
441444
describe('onRequestFailure', () => {
442445
const request = { e: 'pv', eid: '65cb78de-470c-4764-8c10-02bd79477a3a' };
443446

444-
const createQueue = (args: createQueueArgs) =>
445-
newOutQueue(
446-
{
447-
endpoint: 'http://example.com',
448-
trackerId: 'sp',
449-
eventMethod: args.method,
450-
maxPostBytes: args.maxPostBytes,
451-
maxGetBytes: args.maxGetBytes,
452-
maxLocalStorageQueueSize: maxQueueSize,
453-
onRequestSuccess: args.onSuccess,
454-
onRequestFailure: args.onFailure,
455-
dontRetryStatusCodes: [500],
456-
customFetch,
457-
eventStore,
458-
},
459-
new SharedState()
460-
);
447+
const createQueue = (args: createQueueArgs) =>
448+
newOutQueue(
449+
{
450+
endpoint: 'http://example.com',
451+
trackerId: 'sp',
452+
eventMethod: args.method,
453+
maxPostBytes: args.maxPostBytes,
454+
maxGetBytes: args.maxGetBytes,
455+
maxLocalStorageQueueSize: maxQueueSize,
456+
onRequestSuccess: args.onSuccess,
457+
onRequestFailure: args.onFailure,
458+
dontRetryStatusCodes: [500],
459+
customFetch,
460+
eventStore,
461+
},
462+
new SharedState()
463+
);
461464

462465
describe('POST requests', () => {
463466
const method = 'post';

Diff for: libraries/tracker-core/src/emitter/index.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,15 @@ export interface EmitterConfigurationBase {
107107
*/
108108
dontRetryStatusCodes?: number[];
109109
/**
110-
* Id service full URL. This URL will be added to the queue and will be called using a GET method.
110+
* Cookie extension service full URL. This URL will be added to the queue and will be called using a GET method.
111111
* This option is there to allow the service URL to be called in order to set any required identifiers e.g. extra cookies.
112112
*
113113
* The request respects the `anonymousTracking` option, including the SP-Anonymous header if needed, and any additional custom headers from the customHeaders option.
114114
*/
115+
cookieExtensionService?: string;
116+
/**
117+
* @deprecated Use `cookieExtensionService` instead.
118+
*/
115119
idService?: string;
116120
/**
117121
* Indicates that the request should be allowed to outlive the webpage that initiated it.
@@ -208,6 +212,7 @@ export function newEmitter({
208212
serverAnonymization,
209213
connectionTimeout,
210214
keepalive,
215+
cookieExtensionService,
211216
idService,
212217
dontRetryStatusCodes = [],
213218
retryStatusCodes = [],
@@ -219,7 +224,10 @@ export function newEmitter({
219224
eventStore = newInMemoryEventStore({}),
220225
credentials,
221226
}: EmitterConfiguration): Emitter {
222-
let idServiceCalled = false;
227+
/* `cookieExtensionService` gets priority until `idService` is completely removed. */
228+
cookieExtensionService = cookieExtensionService || idService;
229+
230+
let cookieExtensionServiceCalled = false;
223231
let flushInProgress = false;
224232
const usePost = eventMethod.toLowerCase() === 'post';
225233
dontRetryStatusCodes = dontRetryStatusCodes.concat([400, 401, 403, 410, 422]);
@@ -349,10 +357,10 @@ export function newEmitter({
349357
}
350358
}
351359

352-
async function callIdService() {
353-
if (idService && !idServiceCalled) {
354-
idServiceCalled = true;
355-
const request = new Request(idService, { method: 'GET' });
360+
async function callCookieExtensionService() {
361+
if (cookieExtensionService && !cookieExtensionServiceCalled) {
362+
cookieExtensionServiceCalled = true;
363+
const request = new Request(cookieExtensionService, { method: 'GET' });
356364
await customFetch(request);
357365
}
358366
}
@@ -372,7 +380,7 @@ export function newEmitter({
372380
}
373381

374382
async function continueFlush() {
375-
await callIdService();
383+
await callCookieExtensionService();
376384

377385
const request = newEmitterRequestWithConfig();
378386
const eventStoreIterator = eventStore.iterator();

Diff for: libraries/tracker-core/test/emitter/index.test.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import test from 'ava';
22

33
import { newEmitter, Emitter } from '../../src/emitter';
4-
import { newInMemoryEventStore } from "../../src/event_store";
4+
import { newInMemoryEventStore } from '../../src/event_store';
55

66
function createMockFetch(status: number, requests: Request[]) {
77
return async (input: Request) => {
@@ -15,7 +15,7 @@ test.before(() => {
1515
console.error = () => {}; // Silence console.error globally
1616
});
1717

18-
test("input adds an event to the event store", async (t) => {
18+
test('input adds an event to the event store', async (t) => {
1919
const requests: Request[] = [];
2020
const mockFetch = createMockFetch(200, requests);
2121
const eventStore = newInMemoryEventStore({});
@@ -26,7 +26,7 @@ test("input adds an event to the event store", async (t) => {
2626
eventStore,
2727
});
2828

29-
await emitter.input({ e: "pv" });
29+
await emitter.input({ e: 'pv' });
3030

3131
t.is(await eventStore.count(), 1);
3232
t.is(requests.length, 0);
@@ -288,7 +288,7 @@ test('makes a request to the id service only once', async (t) => {
288288
const emitter: Emitter = newEmitter({
289289
endpoint: 'https://example.com',
290290
customFetch: mockFetch,
291-
idService: 'https://id-example.com',
291+
cookieExtensionService: 'https://id-example.com',
292292
});
293293

294294
await emitter.input({ e: 'pv' });
@@ -325,7 +325,7 @@ test('adds a timeout to the request', async (t) => {
325325
endpoint: 'https://example.com',
326326
customFetch: mockFetch,
327327
connectionTimeout: 100,
328-
eventStore
328+
eventStore,
329329
});
330330

331331
await emitter.input({ e: 'pv' });

0 commit comments

Comments
 (0)