diff --git a/spec/src/constructorio.js b/spec/src/constructorio.js index d8fecabd..13802aba 100644 --- a/spec/src/constructorio.js +++ b/spec/src/constructorio.js @@ -5,6 +5,7 @@ const chaiAsPromised = require('chai-as-promised'); const sinon = require('sinon'); const sinonChai = require('sinon-chai'); const helpers = require('../mocha.helpers'); +const store = require('../../test/utils/store'); const jsdom = require('./utils/jsdom-global'); const { default: packageVersion } = require('../../test/version'); let ConstructorIO = require('../../test/constructorio'); @@ -307,6 +308,191 @@ describe(`ConstructorIO${bundledDescriptionSuffix}`, () => { expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); }); + it('Should not update the client options with null sendTrackingEvents value', () => { + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: null, + }); + + // Should remain true because null is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + }); + + it('Should not update the client options with numeric sendTrackingEvents value', () => { + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: 0, + }); + + // Should remain true because 0 is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: 1, + }); + + // Should remain true because 1 is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + }); + + it('Should not update the client options with string sendTrackingEvents value', () => { + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: 'false', + }); + + // Should remain true because string is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: '', + }); + + // Should remain true because empty string is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + }); + + it('Should not update the client options with object sendTrackingEvents value', () => { + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: {}, + }); + + // Should remain true because object is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: [], + }); + + // Should remain true because array is not a valid boolean + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + }); + + it('Should actually suppress tracking events when sendTrackingEvents is set to false', (done) => { + const fetchSpy = sinon.spy(fetch); + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + trackingSendDelay: 10, + fetch: fetchSpy, + }); + + instance.tracker.trackSessionStart(); + + // Wait for the first event to be queued + setTimeout(() => { + instance.setClientOptions({ + sendTrackingEvents: false, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(false); + + fetchSpy.resetHistory(); + instance.tracker.trackSessionStart(); + + // Wait to verify no tracking event was sent + setTimeout(() => { + expect(fetchSpy).not.to.have.been.called; + expect(instance.tracker.requests.sendTrackingEvents).to.equal(false); + done(); + }, 100); + }, 50); + }); + + it('Should propagate sendTrackingEvents update to tracker module', () => { + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(true); + expect(instance.tracker.requests.sendTrackingEvents).to.equal(true); + + instance.setClientOptions({ + sendTrackingEvents: false, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(false); + expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(false); + expect(instance.tracker.requests.sendTrackingEvents).to.equal(false); + + instance.setClientOptions({ + sendTrackingEvents: true, + }); + + expect(instance.options).to.have.property('sendTrackingEvents').to.equal(true); + expect(instance.tracker.options).to.have.property('sendTrackingEvents').to.equal(true); + expect(instance.tracker.requests.sendTrackingEvents).to.equal(true); + }); + + it('Should send event, disable and block event, re-enable and allow event', (done) => { + helpers.clearStorage(); + store.session.set('_constructorio_is_human', true); + + const fetchSpy = sinon.spy(fetch); + const instance = new ConstructorIO({ + apiKey: validApiKey, + sendTrackingEvents: true, + trackingSendDelay: 10, + fetch: fetchSpy, + }); + + instance.tracker.trackSessionStart(); + + setTimeout(() => { + expect(fetchSpy.callCount).to.be.at.least(1); + + instance.setClientOptions({ + sendTrackingEvents: false, + }); + + expect(instance.options.sendTrackingEvents).to.equal(false); + expect(instance.tracker.requests.sendTrackingEvents).to.equal(false); + + fetchSpy.resetHistory(); + instance.tracker.trackSessionStart(); + + setTimeout(() => { + expect(fetchSpy).not.to.have.been.called; + + instance.setClientOptions({ + sendTrackingEvents: true, + }); + + expect(instance.options.sendTrackingEvents).to.equal(true); + expect(instance.tracker.requests.sendTrackingEvents).to.equal(true); + + done(); + }, 100); + }, 100); + }); + it('Should update the options for modules with new test cells', () => { const oldTestCells = { 'old-cell-name-1': 'old-cell-value-1', diff --git a/src/constructorio.js b/src/constructorio.js index 31911f2f..a4156d30 100644 --- a/src/constructorio.js +++ b/src/constructorio.js @@ -176,8 +176,9 @@ class ConstructorIO { this.options.testCells = testCells; } - if (sendTrackingEvents !== undefined) { + if (typeof sendTrackingEvents === 'boolean') { this.options.sendTrackingEvents = sendTrackingEvents; + this.tracker.requests.sendTrackingEvents = sendTrackingEvents; } // Set Session ID in dom-less environments only