diff --git a/spec/src/modules/tracker.js b/spec/src/modules/tracker.js index 4d10d3a3..955bee1e 100644 --- a/spec/src/modules/tracker.js +++ b/spec/src/modules/tracker.js @@ -4660,6 +4660,151 @@ describe(`ConstructorIO - Tracker${bundledDescriptionSuffix}`, () => { expect(tracker.trackRecommendationView(requiredParameters)).to.equal(true); }); + + it('Should respond with a valid response when seedItemIds is an array', (done) => { + const seedItemIds = ['123']; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + const requiredParamsWithSeedItemIds = { + seedItemIds, + ...requiredParameters, + }; + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['123']); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationView(requiredParamsWithSeedItemIds)).to.equal(true); + }); + + it('Should respond with a valid response and convert seedItemIds to an array if it\'s is a number', (done) => { + const seedItemIds = 123; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + const requiredParamsWithSeedItemIds = { + seedItemIds, + ...requiredParameters, + }; + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['123']); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationView(requiredParamsWithSeedItemIds)).to.equal(true); + }); + + it('Should respond with a valid response and convert seedItemIds to an array if it\'s a string', (done) => { + const seedItemIds = '123'; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + const requiredParamsWithSeedItemIds = { + seedItemIds, + ...requiredParameters, + }; + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.have.property('seed_item_ids').to.deep.equal(['123']); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationView(requiredParamsWithSeedItemIds)).to.equal(true); + }); + + it('Should respond with a valid response and omit seed_item_ids if seedItemIds is null', (done) => { + const seedItemIds = null; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + const requiredParamsWithSeedItemIds = { + seedItemIds, + ...requiredParameters, + }; + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.not.have.property('seed_item_ids'); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationView(requiredParamsWithSeedItemIds)).to.equal(true); + }); + + it('Should respond with a valid response and omit seed_item_ids if seedItemIds is an object', (done) => { + const seedItemIds = { seedItemIds: '123' }; + const { tracker } = new ConstructorIO({ + apiKey: testApiKey, + fetch: fetchSpy, + ...requestQueueOptions, + }); + const requiredParamsWithSeedItemIds = { + seedItemIds, + ...requiredParameters, + }; + + tracker.on('success', (responseParams) => { + const requestParams = helpers.extractBodyParamsFromFetch(fetchSpy); + + // Request + expect(fetchSpy).to.have.been.called; + expect(requestParams).to.not.have.property('seed_item_ids'); + + // Response + expect(responseParams).to.have.property('method').to.equal('POST'); + expect(responseParams).to.have.property('message'); + + done(); + }); + + expect(tracker.trackRecommendationView(requiredParamsWithSeedItemIds)).to.equal(true); + }); }); describe('trackRecommendationClick', () => { diff --git a/src/modules/tracker.js b/src/modules/tracker.js index e8f0c6ee..2a2b9922 100644 --- a/src/modules/tracker.js +++ b/src/modules/tracker.js @@ -1222,6 +1222,7 @@ class Tracker { * @param {string} [parameters.resultId] - Recommendation result identifier (returned in response from Constructor) * @param {string} [parameters.section="Products"] - Results section * @param {object} [parameters.analyticsTags] - Pass additional analytics data + * @param {string[]|string|number} [parameters.seedItemIds] - Item ID(s) to be used as seed * @param {object} [networkParameters] - Parameters relevant to the network request * @param {number} [networkParameters.timeout] - Request timeout (in milliseconds) * @returns {(true|Error)} @@ -1258,6 +1259,7 @@ class Tracker { numResultsViewed = num_results_viewed, items, analyticsTags, + seedItemIds, resultCount = result_count || items?.length || 0, } = parameters; @@ -1299,6 +1301,14 @@ class Tracker { bodyParams.analytics_tags = analyticsTags; } + if (typeof seedItemIds === 'number') { + bodyParams.seed_item_ids = [String(seedItemIds)]; + } else if (seedItemIds?.length && typeof seedItemIds === 'string') { + bodyParams.seed_item_ids = [seedItemIds]; + } else if (seedItemIds?.length && Array.isArray(seedItemIds)) { + bodyParams.seed_item_ids = seedItemIds; + } + const requestURL = `${requestPath}${applyParamsAsString({}, this.options)}`; const requestMethod = 'POST'; const requestBody = applyParams(bodyParams, { ...this.options, requestMethod });