Skip to content

Commit d395744

Browse files
esezenjensmeichler
andauthored
[CDX-280] Allow updating sendTrackingEvents in setClientOptions (#407)
* feat: make sendTrackingEvents updatable This may be necessary in case a cookie consent changes and no tracking event should be dispatched anymore. This would allow it to keep the logic therefore in the client and not having to do this check before each call. * test: add tests for setting the sendTrackingEvents property * Update tests and adjust implementation * Add one more test * Update test --------- Co-authored-by: Jens Meichler <j.meichler@rebuy.com>
1 parent 2321ab1 commit d395744

2 files changed

Lines changed: 188 additions & 1 deletion

File tree

spec/src/constructorio.js

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const chaiAsPromised = require('chai-as-promised');
55
const sinon = require('sinon');
66
const sinonChai = require('sinon-chai');
77
const helpers = require('../mocha.helpers');
8+
const store = require('../../test/utils/store');
89
const jsdom = require('./utils/jsdom-global');
910
const { default: packageVersion } = require('../../test/version');
1011
let ConstructorIO = require('../../test/constructorio');
@@ -307,6 +308,191 @@ describe(`ConstructorIO${bundledDescriptionSuffix}`, () => {
307308
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
308309
});
309310

311+
it('Should not update the client options with null sendTrackingEvents value', () => {
312+
const instance = new ConstructorIO({
313+
apiKey: validApiKey,
314+
sendTrackingEvents: true,
315+
});
316+
317+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
318+
319+
instance.setClientOptions({
320+
sendTrackingEvents: null,
321+
});
322+
323+
// Should remain true because null is not a valid boolean
324+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
325+
});
326+
327+
it('Should not update the client options with numeric sendTrackingEvents value', () => {
328+
const instance = new ConstructorIO({
329+
apiKey: validApiKey,
330+
sendTrackingEvents: true,
331+
});
332+
333+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
334+
335+
instance.setClientOptions({
336+
sendTrackingEvents: 0,
337+
});
338+
339+
// Should remain true because 0 is not a valid boolean
340+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
341+
342+
instance.setClientOptions({
343+
sendTrackingEvents: 1,
344+
});
345+
346+
// Should remain true because 1 is not a valid boolean
347+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
348+
});
349+
350+
it('Should not update the client options with string sendTrackingEvents value', () => {
351+
const instance = new ConstructorIO({
352+
apiKey: validApiKey,
353+
sendTrackingEvents: true,
354+
});
355+
356+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
357+
358+
instance.setClientOptions({
359+
sendTrackingEvents: 'false',
360+
});
361+
362+
// Should remain true because string is not a valid boolean
363+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
364+
365+
instance.setClientOptions({
366+
sendTrackingEvents: '',
367+
});
368+
369+
// Should remain true because empty string is not a valid boolean
370+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
371+
});
372+
373+
it('Should not update the client options with object sendTrackingEvents value', () => {
374+
const instance = new ConstructorIO({
375+
apiKey: validApiKey,
376+
sendTrackingEvents: true,
377+
});
378+
379+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
380+
381+
instance.setClientOptions({
382+
sendTrackingEvents: {},
383+
});
384+
385+
// Should remain true because object is not a valid boolean
386+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
387+
388+
instance.setClientOptions({
389+
sendTrackingEvents: [],
390+
});
391+
392+
// Should remain true because array is not a valid boolean
393+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
394+
});
395+
396+
it('Should actually suppress tracking events when sendTrackingEvents is set to false', (done) => {
397+
const fetchSpy = sinon.spy(fetch);
398+
const instance = new ConstructorIO({
399+
apiKey: validApiKey,
400+
sendTrackingEvents: true,
401+
trackingSendDelay: 10,
402+
fetch: fetchSpy,
403+
});
404+
405+
instance.tracker.trackSessionStart();
406+
407+
// Wait for the first event to be queued
408+
setTimeout(() => {
409+
instance.setClientOptions({
410+
sendTrackingEvents: false,
411+
});
412+
413+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(false);
414+
415+
fetchSpy.resetHistory();
416+
instance.tracker.trackSessionStart();
417+
418+
// Wait to verify no tracking event was sent
419+
setTimeout(() => {
420+
expect(fetchSpy).not.to.have.been.called;
421+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(false);
422+
done();
423+
}, 100);
424+
}, 50);
425+
});
426+
427+
it('Should propagate sendTrackingEvents update to tracker module', () => {
428+
const instance = new ConstructorIO({
429+
apiKey: validApiKey,
430+
sendTrackingEvents: true,
431+
});
432+
433+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
434+
expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(true);
435+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(true);
436+
437+
instance.setClientOptions({
438+
sendTrackingEvents: false,
439+
});
440+
441+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(false);
442+
expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(false);
443+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(false);
444+
445+
instance.setClientOptions({
446+
sendTrackingEvents: true,
447+
});
448+
449+
expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true);
450+
expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(true);
451+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(true);
452+
});
453+
454+
it('Should send event, disable and block event, re-enable and allow event', (done) => {
455+
helpers.clearStorage();
456+
store.session.set('_constructorio_is_human', true);
457+
458+
const fetchSpy = sinon.spy(fetch);
459+
const instance = new ConstructorIO({
460+
apiKey: validApiKey,
461+
sendTrackingEvents: true,
462+
trackingSendDelay: 10,
463+
fetch: fetchSpy,
464+
});
465+
466+
instance.tracker.trackSessionStart();
467+
468+
setTimeout(() => {
469+
expect(fetchSpy.callCount).to.be.at.least(1);
470+
471+
instance.setClientOptions({
472+
sendTrackingEvents: false,
473+
});
474+
475+
expect(instance.options.sendTrackingEvents).to.equal(false);
476+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(false);
477+
478+
fetchSpy.resetHistory();
479+
instance.tracker.trackSessionStart();
480+
481+
setTimeout(() => {
482+
expect(fetchSpy).not.to.have.been.called;
483+
484+
instance.setClientOptions({
485+
sendTrackingEvents: true,
486+
});
487+
488+
expect(instance.options.sendTrackingEvents).to.equal(true);
489+
expect(instance.tracker.requests.sendTrackingEvents).to.equal(true);
490+
491+
done();
492+
}, 100);
493+
}, 100);
494+
});
495+
310496
it('Should update the options for modules with new test cells', () => {
311497
const oldTestCells = {
312498
'old-cell-name-1': 'old-cell-value-1',

src/constructorio.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,9 @@ class ConstructorIO {
176176
this.options.testCells = testCells;
177177
}
178178

179-
if (sendTrackingEvents !== undefined) {
179+
if (typeof sendTrackingEvents === 'boolean') {
180180
this.options.sendTrackingEvents = sendTrackingEvents;
181+
this.tracker.requests.sendTrackingEvents = sendTrackingEvents;
181182
}
182183

183184
// Set Session ID in dom-less environments only

0 commit comments

Comments
 (0)