Skip to content

Commit b3b4702

Browse files
authored
[CDX-210] Add support for seedItemIds in trackRecommendationClick (#395)
* Add support for seedItemIds in trackRecommendationClick * Update the implementation to match the view event
1 parent aa4efaf commit b3b4702

3 files changed

Lines changed: 128 additions & 1 deletion

File tree

spec/src/modules/tracker.js

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5352,6 +5352,121 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => {
53525352

53535353
expect(tracker.trackRecommendationClick(requiredParameters)).to.equal(true);
53545354
});
5355+
5356+
it('Should respond with a valid response when seedItemIds is provided as an array of strings', (done) => {
5357+
const { tracker } = new ConstructorIO({
5358+
apiKey: testApiKey,
5359+
fetch: fetchSpy,
5360+
...requestQueueOptions,
5361+
});
5362+
const parametersWithSeedItemIds = {
5363+
...requiredParameters,
5364+
seedItemIds: ['item-123', 'item-456', 'item-789'],
5365+
};
5366+
tracker.on('success', (responseParams) => {
5367+
const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy);
5368+
// Request
5369+
expect(fetchSpy).to.have.been.called;
5370+
expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['item-123', 'item-456', 'item-789']);
5371+
// Response
5372+
expect(responseParams).to.have.property('method').to.equal('POST');
5373+
expect(responseParams).to.have.property('message');
5374+
done();
5375+
});
5376+
expect(tracker.trackRecommendationClick(parametersWithSeedItemIds)).to.equal(true);
5377+
});
5378+
5379+
it('Should respond with a valid response and convert seedItemIds to array when provided as string', (done) => {
5380+
const { tracker } = new ConstructorIO({
5381+
apiKey: testApiKey,
5382+
fetch: fetchSpy,
5383+
...requestQueueOptions,
5384+
});
5385+
const parametersWithSeedItemIds = {
5386+
...requiredParameters,
5387+
seedItemIds: 'item-123',
5388+
};
5389+
tracker.on('success', (responseParams) => {
5390+
const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy);
5391+
// Request
5392+
expect(fetchSpy).to.have.been.called;
5393+
expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['item-123']);
5394+
// Response
5395+
expect(responseParams).to.have.property('method').to.equal('POST');
5396+
expect(responseParams).to.have.property('message');
5397+
done();
5398+
});
5399+
expect(tracker.trackRecommendationClick(parametersWithSeedItemIds)).to.equal(true);
5400+
});
5401+
5402+
it('Should respond with a valid response and convert seedItemIds to array when provided as number', (done) => {
5403+
const { tracker } = new ConstructorIO({
5404+
apiKey: testApiKey,
5405+
fetch: fetchSpy,
5406+
...requestQueueOptions,
5407+
});
5408+
const parametersWithSeedItemIds = {
5409+
...requiredParameters,
5410+
seedItemIds: 123,
5411+
};
5412+
tracker.on('success', (responseParams) => {
5413+
const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy);
5414+
// Request
5415+
expect(fetchSpy).to.have.been.called;
5416+
expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['123']);
5417+
// Response
5418+
expect(responseParams).to.have.property('method').to.equal('POST');
5419+
expect(responseParams).to.have.property('message');
5420+
done();
5421+
});
5422+
expect(tracker.trackRecommendationClick(parametersWithSeedItemIds)).to.equal(true);
5423+
});
5424+
5425+
it('Should respond with a valid response and omit seed_item_ids when seedItemIds is empty string', (done) => {
5426+
const { tracker } = new ConstructorIO({
5427+
apiKey: testApiKey,
5428+
fetch: fetchSpy,
5429+
...requestQueueOptions,
5430+
});
5431+
const parametersWithSeedItemIds = {
5432+
...requiredParameters,
5433+
seedItemIds: '',
5434+
};
5435+
tracker.on('success', (responseParams) => {
5436+
const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy);
5437+
// Request
5438+
expect(fetchSpy).to.have.been.called;
5439+
expect(requestParams).to.not.have.property('seed_item_ids');
5440+
// Response
5441+
expect(responseParams).to.have.property('method').to.equal('POST');
5442+
expect(responseParams).to.have.property('message');
5443+
done();
5444+
});
5445+
expect(tracker.trackRecommendationClick(parametersWithSeedItemIds)).to.equal(true);
5446+
});
5447+
5448+
it('Should respond with a valid response and omit seed_item_ids when seedItemIds is empty array', (done) => {
5449+
const { tracker } = new ConstructorIO({
5450+
apiKey: testApiKey,
5451+
fetch: fetchSpy,
5452+
...requestQueueOptions,
5453+
});
5454+
const parametersWithSeedItemIds = {
5455+
...requiredParameters,
5456+
seedItemIds: [],
5457+
};
5458+
tracker.on('success', (responseParams) => {
5459+
const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy);
5460+
// Request
5461+
expect(fetchSpy).to.have.been.called;
5462+
expect(requestParams).to.not.have.property('seed_item_ids');
5463+
// Response
5464+
expect(responseParams).to.have.property('method').to.equal('POST');
5465+
expect(responseParams).to.have.property('message');
5466+
done();
5467+
});
5468+
expect(tracker.trackRecommendationClick(parametersWithSeedItemIds)).to.equal(true);
5469+
});
53555470
});
53565471

53575472
describe('trackBrowseResultsLoaded', () => {
@@ -8385,7 +8500,7 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => {
83858500
it('Should throw an error when providing no messageType parameter', () => {
83868501
const { tracker } = new ConstructorIO({ apiKey: testApiKey });
83878502

8388-
expect(tracker.on(null, () => {})).to.be.an('error');
8503+
expect(tracker.on(null, () => { })).to.be.an('error');
83898504
});
83908505

83918506
it('Should throw an error when providing an invalid callback parameter', () => {

src/modules/tracker.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@ class Tracker {
13571357
* @param {number} [networkParameters.timeout] - Request timeout (in milliseconds)
13581358
* @param {string} [parameters.slCampaignId] - Pass campaign id of sponsored listing
13591359
* @param {string} [parameters.slCampaignOwner] - Pass campaign owner of sponsored listing
1360+
* @param {string[]|string|number} [parameters.seedItemIds] - Item ID(s) to be used as seed
13601361
* @returns {(true|Error)}
13611362
* @description User clicked an item that appeared within a list of recommended results
13621363
* @example
@@ -1372,6 +1373,7 @@ class Tracker {
13721373
* strategyId: 'complimentary',
13731374
* itemId: 'KMH876',
13741375
* itemName: 'Socks',
1376+
* seedItemIds: ['item-123', 'item-456'],
13751377
* },
13761378
* );
13771379
*/
@@ -1405,6 +1407,7 @@ class Tracker {
14051407
analyticsTags,
14061408
slCampaignId,
14071409
slCampaignOwner,
1410+
seedItemIds,
14081411
} = parameters;
14091412

14101413
if (variationId) {
@@ -1463,6 +1466,14 @@ class Tracker {
14631466
bodyParams.sl_campaign_owner = slCampaignOwner;
14641467
}
14651468

1469+
if (typeof seedItemIds === 'number') {
1470+
bodyParams.seed_item_ids = [String(seedItemIds)];
1471+
} else if (seedItemIds?.length && typeof seedItemIds === 'string') {
1472+
bodyParams.seed_item_ids = [seedItemIds];
1473+
} else if (seedItemIds?.length && Array.isArray(seedItemIds)) {
1474+
bodyParams.seed_item_ids = seedItemIds;
1475+
}
1476+
14661477
const requestURL = `${requestPath}${applyParamsAsString({}, this.options)}`;
14671478
const requestMethod = 'POST';
14681479
const requestBody = applyParams(bodyParams, { ...this.options, requestMethod });

src/types/tracker.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ declare class Tracker {
165165
analyticsTags?: Record<string, string>;
166166
slCampaignId?: string;
167167
slCampaignOwner?: string;
168+
seedItemIds?: string[] | string | number;
168169
},
169170
networkParameters?: NetworkParameters
170171
): true | Error;

0 commit comments

Comments
 (0)