-
Notifications
You must be signed in to change notification settings - Fork 14
[CDX-470] Add additionalTrackingKeys option
#472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
bfb3d45
ad68a18
35750b3
b2b471b
2947a6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16345,4 +16345,84 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { | |
| ).to.equal(true); | ||
| }); | ||
| }); | ||
|
|
||
| describe('additionalTrackingKeys', () => { | ||
| it('Should send tracking events to both primary and additional keys', (done) => { | ||
| const additionalKey = 'extra-test-key'; | ||
| const { tracker } = new ConstructorIO({ | ||
| apiKey: testApiKey, | ||
| fetch: fetchSpy, | ||
| ...requestQueueOptions, | ||
| additionalTrackingKeys: [additionalKey], | ||
| }); | ||
|
|
||
| let callCount = 0; | ||
|
|
||
| const checkComplete = () => { | ||
| callCount += 1; | ||
|
|
||
| if (callCount === 2) { | ||
| expect(fetchSpy).to.have.been.calledTwice; | ||
|
constructor-claude-bedrock[bot] marked this conversation as resolved.
constructor-claude-bedrock[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Important Issue: The integration test relies on Use const localSpy = sinon.spy(fetch);
const { tracker } = new ConstructorIO({
apiKey: testApiKey,
fetch: localSpy,
...
});
// then assert localSpy.getCall(0) / localSpy.getCall(1)Also, |
||
|
|
||
| const firstCallUrl = fetchSpy.getCall(0).args[0]; | ||
| const secondCallUrl = fetchSpy.getCall(1).args[0]; | ||
|
|
||
| expect(firstCallUrl).to.contain(`key=${testApiKey}`); | ||
| expect(secondCallUrl).to.contain(`key=${additionalKey}`); | ||
|
t3t3c marked this conversation as resolved.
|
||
| expect(secondCallUrl).to.not.contain(`key=${testApiKey}`); | ||
|
|
||
| done(); | ||
| } | ||
| }; | ||
|
|
||
| tracker.on('success', checkComplete); | ||
| tracker.on('error', checkComplete); | ||
|
|
||
| expect(tracker.trackSessionStartV2()).to.equal(true); | ||
| }); | ||
|
|
||
| it('Should send identical request bodies for primary and additional keys', (done) => { | ||
| const additionalKey = 'extra-test-key'; | ||
| const { tracker } = new ConstructorIO({ | ||
| apiKey: testApiKey, | ||
| fetch: fetchSpy, | ||
| ...requestQueueOptions, | ||
| additionalTrackingKeys: [additionalKey], | ||
| }); | ||
|
|
||
| let callCount = 0; | ||
|
|
||
| const checkComplete = () => { | ||
| callCount += 1; | ||
|
|
||
| if (callCount === 2) { | ||
| expect(fetchSpy).to.have.been.calledTwice; | ||
|
|
||
| const firstCallOptions = fetchSpy.getCall(0).args[1]; | ||
| const secondCallOptions = fetchSpy.getCall(1).args[1]; | ||
|
|
||
| const firstBody = JSON.parse(firstCallOptions.body); | ||
| const secondBody = JSON.parse(secondCallOptions.body); | ||
|
|
||
| expect(firstBody.key).to.equal(testApiKey); | ||
| expect(secondBody.key).to.equal(additionalKey); | ||
|
|
||
| // Verify bodies are the same except for the key | ||
| const firstBodyWithoutKey = { ...firstBody }; | ||
| const secondBodyWithoutKey = { ...secondBody }; | ||
| delete firstBodyWithoutKey.key; | ||
| delete secondBodyWithoutKey.key; | ||
|
|
||
| expect(firstBodyWithoutKey).to.deep.equal(secondBodyWithoutKey); | ||
|
|
||
| done(); | ||
| } | ||
| }; | ||
|
|
||
| tracker.on('success', checkComplete); | ||
| tracker.on('error', checkComplete); | ||
|
|
||
| expect(tracker.trackInputFocusV2('test query')).to.equal(true); | ||
| }); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -318,6 +318,121 @@ describe('ConstructorIO - Utils - Request Queue', function utilsRequestQueue() { | |
| }); | ||
| }); | ||
|
|
||
| describe('additionalTrackingKeys', () => { | ||
| let defaultAgent; | ||
| let cleanup; | ||
|
|
||
| before(() => { | ||
| helpers.clearStorage(); | ||
| }); | ||
|
|
||
| beforeEach(() => { | ||
| global.CLIENT_VERSION = 'cio-mocha'; | ||
| cleanup = jsdom(); | ||
| defaultAgent = window.navigator.userAgent; | ||
| }); | ||
|
|
||
| afterEach(() => { | ||
| window.navigator.__defineGetter__('userAgent', () => defaultAgent); | ||
| delete global.CLIENT_VERSION; | ||
| cleanup(); | ||
| helpers.clearStorage(); | ||
| }); | ||
|
|
||
| it('Should add duplicate requests for each additional tracking key', () => { | ||
| store.session.set(humanityStorageKey, true); | ||
| const requests = new RequestQueue({ | ||
| sendTrackingEvents: true, | ||
| trackingSendDelay: 1, | ||
| apiKey: 'primary-key', | ||
| additionalTrackingKeys: ['extra-key-1', 'extra-key-2'], | ||
| }); | ||
|
|
||
| requests.queue('https://ac.cnstrc.com/behavior?action=session_start&key=primary-key&_dt=123', 'POST', { action: 'session_start', key: 'primary-key' }); | ||
|
|
||
| const queue = RequestQueue.get(); | ||
| expect(queue).to.be.an('array').length(3); | ||
|
|
||
| // Primary request | ||
| expect(queue[0].url).to.contain('key=primary-key'); | ||
| expect(queue[0].body.key).to.equal('primary-key'); | ||
|
|
||
| // First additional key | ||
| expect(queue[1].url).to.contain('key=extra-key-1'); | ||
| expect(queue[1].url).to.not.contain('key=primary-key'); | ||
| expect(queue[1].body.key).to.equal('extra-key-1'); | ||
|
constructor-claude-bedrock[bot] marked this conversation as resolved.
constructor-claude-bedrock[bot] marked this conversation as resolved.
|
||
|
|
||
| // Second additional key | ||
| expect(queue[2].url).to.contain('key=extra-key-2'); | ||
| expect(queue[2].url).to.not.contain('key=primary-key'); | ||
| expect(queue[2].body.key).to.equal('extra-key-2'); | ||
| }); | ||
|
|
||
| it('Should not add duplicates when additionalTrackingKeys is an empty array', () => { | ||
| store.session.set(humanityStorageKey, true); | ||
| const requests = new RequestQueue({ | ||
| sendTrackingEvents: true, | ||
| trackingSendDelay: 1, | ||
| apiKey: 'primary-key', | ||
| additionalTrackingKeys: [], | ||
| }); | ||
|
|
||
| requests.queue('https://ac.cnstrc.com/behavior?action=session_start&key=primary-key&_dt=123'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Important Issue: The GET test ( |
||
|
|
||
| expect(RequestQueue.get()).to.be.an('array').length(1); | ||
| }); | ||
|
|
||
| it('Should not add duplicates when additionalTrackingKeys is not provided', () => { | ||
| store.session.set(humanityStorageKey, true); | ||
| const requests = new RequestQueue({ | ||
| sendTrackingEvents: true, | ||
| trackingSendDelay: 1, | ||
| apiKey: 'primary-key', | ||
| }); | ||
|
|
||
| requests.queue('https://ac.cnstrc.com/behavior?action=session_start&key=primary-key&_dt=123'); | ||
|
|
||
| expect(RequestQueue.get()).to.be.an('array').length(1); | ||
| }); | ||
|
|
||
| it('Should add duplicate requests for GET method', () => { | ||
| store.session.set(humanityStorageKey, true); | ||
| const requests = new RequestQueue({ | ||
| sendTrackingEvents: true, | ||
| trackingSendDelay: 1, | ||
| apiKey: 'primary-key', | ||
| additionalTrackingKeys: ['extra-key-1'], | ||
| }); | ||
|
|
||
| requests.queue('https://ac.cnstrc.com/behavior?action=session_start&key=primary-key&_dt=123'); | ||
|
|
||
| const queue = RequestQueue.get(); | ||
| expect(queue).to.be.an('array').length(2); | ||
|
|
||
| expect(queue[0].url).to.contain('key=primary-key'); | ||
| expect(queue[1].url).to.contain('key=extra-key-1'); | ||
| expect(queue[1].url).to.contain('action=session_start'); | ||
| expect(queue[1].body.key).to.equal('extra-key-1'); | ||
| }); | ||
|
|
||
| it('Should skip invalid entries in additionalTrackingKeys', () => { | ||
| store.session.set(humanityStorageKey, true); | ||
| const requests = new RequestQueue({ | ||
| sendTrackingEvents: true, | ||
| trackingSendDelay: 1, | ||
| apiKey: 'primary-key', | ||
| additionalTrackingKeys: ['valid-key', '', null, 123, 'another-valid-key'], | ||
| }); | ||
|
|
||
| requests.queue('https://ac.cnstrc.com/behavior?action=session_start&key=primary-key&_dt=123', 'POST', { action: 'session_start', key: 'primary-key' }); | ||
|
|
||
| const queue = RequestQueue.get(); | ||
| expect(queue).to.be.an('array').length(3); | ||
| expect(queue[1].url).to.contain('key=valid-key'); | ||
| expect(queue[2].url).to.contain('key=another-valid-key'); | ||
| }); | ||
| }); | ||
|
|
||
| describe('send', () => { | ||
| let fetchSpy = null; | ||
| let cleanup; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,7 @@ class ConstructorIO { | |
| * @param {object} [parameters.networkParameters] - Parameters relevant to network requests | ||
| * @param {number} [parameters.networkParameters.timeout] - Request timeout (in milliseconds) - may be overridden within individual method calls | ||
| * @param {string} [parameters.humanityCheckLocation='session'] - Storage location for the humanity check flag ('session' for sessionStorage, 'local' for localStorage) | ||
| * @param {string[]} [parameters.additionalTrackingKeys] - Additional API keys that each receive a duplicate of every tracking event. Events are always sent to the primary `apiKey` and, in addition, to every key in this array. | ||
| * @property {object} search - Interface to {@link module:search} | ||
| * @property {object} browse - Interface to {@link module:browse} | ||
| * @property {object} autocomplete - Interface to {@link module:autocomplete} | ||
|
|
@@ -93,6 +94,7 @@ class ConstructorIO { | |
| beaconMode, | ||
| networkParameters, | ||
| humanityCheckLocation, | ||
| additionalTrackingKeys, | ||
|
constructor-claude-bedrock[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: |
||
| } = options; | ||
|
Comment on lines
+97
to
98
|
||
|
|
||
| if (!apiKey || typeof apiKey !== 'string') { | ||
|
|
@@ -141,6 +143,7 @@ class ConstructorIO { | |
| beaconMode: (beaconMode === false) ? false : true, // Defaults to 'true', | ||
| networkParameters: networkParameters || {}, | ||
| humanityCheckLocation: humanityCheckLocation || 'session', | ||
| additionalTrackingKeys, | ||
| }; | ||
|
|
||
| // Expose global modules | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.