diff --git a/docs/INTEGRATION_RECOMMENDATIONS.md b/docs/INTEGRATION_RECOMMENDATIONS.md index 27d0db1c4..0abfb22a7 100644 --- a/docs/INTEGRATION_RECOMMENDATIONS.md +++ b/docs/INTEGRATION_RECOMMENDATIONS.md @@ -18,7 +18,8 @@ Context variables may be applied to individual recommendation profiles similar t | product | current product sku | product detail page | used to identify the current product being viewed | | cart | array (or function that returns an array) of current cart skus | all | optional method of setting cart contents | | options.siteId | global siteId overwrite | all | optional global siteId overwrite | -| options.categories | category path | all | optional category identifier to restrict recommendations | +| options.categories | array of category path strings | all | optional category identifiers used in category trending recommendation profiles | +| options.brands | array of brand strings | all | optional brand identifiers used in brand trending recommendation profiles | | options.branch | template branch overwrite | all | optional branch overwrite for recommendations template (advanced usage) | | options.batched | boolean (default: `true`)| all | only applies to recommendation context, optional disable profile from being batched in a single request, can also be set globally [via config](https://github.com/searchspring/snap/tree/main/packages/snap-controller/src/Recommendation) | | options.order | number | all | optional order number for recommendation params to be added to the batched request. Profiles that do not specify an order will be placed at the end, in the occurrence they appear in the DOM. diff --git a/packages/snap-client/src/Client/apis/Recommend.test.ts b/packages/snap-client/src/Client/apis/Recommend.test.ts index 1199922c8..4ec2e20cc 100644 --- a/packages/snap-client/src/Client/apis/Recommend.test.ts +++ b/packages/snap-client/src/Client/apis/Recommend.test.ts @@ -233,6 +233,41 @@ describe('Recommend Api', () => { requestMock.mockReset(); }); + it('batchRecommendations handles multiple brands as expected', async () => { + const api = new RecommendAPI(new ApiConfiguration({})); + + const requestMock = jest + .spyOn(global.window, 'fetch') + .mockImplementation(() => Promise.resolve({ status: 200, json: () => Promise.resolve(mockData.recommend()) } as Response)); + + const GETRequestUrl = `https://8uyt2m.a.searchspring.io/boost/8uyt2m/recommend?tags=similar&tags=crossSell&limits=14&limits=10&brands=shirts&brands=pants&brands=pants2&siteId=8uyt2m&lastViewed=marnie-runner-2-7x10&lastViewed=ruby-runner-2-7x10&lastViewed=abbie-runner-2-7x10&lastViewed=riley-4x6&lastViewed=joely-5x8&lastViewed=helena-4x6&lastViewed=kwame-4x6&lastViewed=sadie-4x6&lastViewed=candice-runner-2-7x10&lastViewed=esmeray-4x6&lastViewed=camilla-230x160&lastViewed=candice-4x6&lastViewed=sahara-4x6&lastViewed=dayna-4x6&lastViewed=moema-4x6&product=marnie-runner-2-7x10`; + + //shirt category + // @ts-ignore + api.batchRecommendations({ + tags: ['similar'], + brands: ['shirts'], + limits: 14, + batched: true, + ...batchParams, + }); + //pants category + // @ts-ignore + api.batchRecommendations({ + tags: ['crossSell'], + brands: ['pants', 'pants2'], + limits: 10, + batched: true, + ...batchParams, + }); + + //add delay for paramBatch.timeout + await wait(250); + + expect(requestMock).toHaveBeenCalledWith(GETRequestUrl, GETParams); + requestMock.mockReset(); + }); + it('batchRecommendations handles order prop as expected', async () => { const api = new RecommendAPI(new ApiConfiguration({})); diff --git a/packages/snap-client/src/Client/apis/Recommend.ts b/packages/snap-client/src/Client/apis/Recommend.ts index 0b9ef717d..ad4a6f38f 100644 --- a/packages/snap-client/src/Client/apis/Recommend.ts +++ b/packages/snap-client/src/Client/apis/Recommend.ts @@ -74,7 +74,7 @@ export class RecommendAPI extends API { // now that the requests are in proper order, map through them // and build out the batches batch.entries.map((entry) => { - const { tags, categories, ...otherParams } = entry.request; + const { tags, categories, brands, ...otherParams } = entry.request; let limits = entry.request.limits; if (!limits) { @@ -96,6 +96,14 @@ export class RecommendAPI extends API { } } + if (brands) { + if (!batch.request.brands) { + batch.request.brands = Array.isArray(brands) ? brands : [brands]; + } else { + batch.request.brands = batch.request.brands.concat(brands); + } + } + batch.request.limits = (batch.request.limits as number[]).concat(limits); batch.request = { ...batch.request, ...otherParams }; }); diff --git a/packages/snap-client/src/types.ts b/packages/snap-client/src/types.ts index db3124c3f..21ed1cb70 100644 --- a/packages/snap-client/src/types.ts +++ b/packages/snap-client/src/types.ts @@ -101,6 +101,7 @@ export type RecommendRequestModel = { product?: string; shopper?: string; categories?: string[]; + brands?: string[]; cart?: string[]; lastViewed?: string[]; test?: boolean; @@ -150,6 +151,7 @@ export type RecommendCombinedRequestModel = { product?: string; shopper?: string; categories?: string[]; + brands?: string[]; cart?: string[]; lastViewed?: string[]; test?: boolean; diff --git a/packages/snap-controller/src/Recommendation/RecommendationController.ts b/packages/snap-controller/src/Recommendation/RecommendationController.ts index c89c453df..98c858b33 100644 --- a/packages/snap-controller/src/Recommendation/RecommendationController.ts +++ b/packages/snap-controller/src/Recommendation/RecommendationController.ts @@ -27,6 +27,7 @@ type RecommendCombinedRequestModel = { product?: string; shopper?: string; categories?: string[]; + brands?: string[]; cart?: string[]; lastViewed?: string[]; test?: boolean; diff --git a/packages/snap-preact/src/Instantiators/RecommendationInstantiator.test.tsx b/packages/snap-preact/src/Instantiators/RecommendationInstantiator.test.tsx index d61c6de28..314af84e5 100644 --- a/packages/snap-preact/src/Instantiators/RecommendationInstantiator.test.tsx +++ b/packages/snap-preact/src/Instantiators/RecommendationInstantiator.test.tsx @@ -284,6 +284,7 @@ describe('RecommendationInstantiator', () => { branch: 'testing', siteId: 'abc123', categories: ['cats', 'dogs'], + brands: ['nike', 'h&m'], limit: 5 } `; @@ -305,6 +306,7 @@ describe('RecommendationInstantiator', () => { options: { branch: 'testing', categories: ['cats', 'dogs'], + brands: ['nike', 'h&m'], limit: 5, siteId: 'abc123', }, @@ -316,6 +318,7 @@ describe('RecommendationInstantiator', () => { batched: true, branch: 'testing', categories: ['cats', 'dogs'], + brands: ['nike', 'h&m'], limits: 5, product: 'sku1', shopper: 'snapdev', diff --git a/packages/snap-preact/src/Instantiators/RecommendationInstantiator.tsx b/packages/snap-preact/src/Instantiators/RecommendationInstantiator.tsx index 57efe5088..fa4037756 100644 --- a/packages/snap-preact/src/Instantiators/RecommendationInstantiator.tsx +++ b/packages/snap-preact/src/Instantiators/RecommendationInstantiator.tsx @@ -145,7 +145,8 @@ export class RecommendationInstantiator { branch?: string; batched?: boolean; realtime?: boolean; - categories?: any; + categories?: string[]; + brands?: string[]; limit?: number; } } @@ -166,6 +167,9 @@ export class RecommendationInstantiator { if (options?.categories) { contextGlobals.categories = options.categories; } + if (options?.brands) { + contextGlobals.brands = options.brands; + } if (options?.limit && Number.isInteger(Number(options?.limit))) { contextGlobals.limits = Number(options?.limit); }