Skip to content

Commit

Permalink
fix(commerce): forward analytics source on context.source (#4086)
Browse files Browse the repository at this point in the history
I also made it so the `requestMetadata` is populated on commerce api
requests in
dd3b369.
This enables hooking into requests with `preprocessRequest` on a
commerce api `method`, instead of matching on an url path.

[CAPI-1053]

[CAPI-1053]:
https://coveord.atlassian.net/browse/CAPI-1053?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
Spuffynism authored Jun 12, 2024
1 parent 19c6363 commit c9822ed
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 15 deletions.
43 changes: 42 additions & 1 deletion packages/headless/src/api/commerce/commerce-api-client.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {SortBy} from '../../features/sort/sort';
import {buildMockCommerceAPIClient} from '../../test/mock-commerce-api-client';
import {VERSION} from '../../utils/version';
import {PlatformClient} from '../platform-client';
import {CommerceAPIClient} from './commerce-api-client';
import {CommerceAPIRequest} from './common/request';
Expand Down Expand Up @@ -47,6 +48,7 @@ describe('commerce api client', () => {
referrer: 'https://example.org/referrer',
},
capture: true,
source: [`@coveo/headless@${VERSION}`],
},
});

Expand All @@ -69,6 +71,7 @@ describe('commerce api client', () => {
referrer: 'https://example.org/referrer',
},
capture: true,
source: [`@coveo/headless@${VERSION}`],
},
};
};
Expand Down Expand Up @@ -98,6 +101,7 @@ describe('commerce api client', () => {
language: request.language,
currency: request.currency,
},
requestMetadata: {method: 'listing'},
});
});

Expand Down Expand Up @@ -130,10 +134,11 @@ describe('commerce api client', () => {
language: request.language,
currency: request.currency,
},
requestMetadata: {method: 'search'},
});
});

it('#recommendations should call the platform endpoint with the correct arguments', async () => {
it('#getRecommendations should call the platform endpoint with the correct arguments', async () => {
const request = await buildRecommendationsCommerceAPIRequest();

mockPlatformCall({
Expand All @@ -158,6 +163,40 @@ describe('commerce api client', () => {
language: request.language,
currency: request.currency,
},
requestMetadata: {method: 'recommendations'},
});
});

it('#productSuggestions should call the platform endpoint with the correct arguments', async () => {
const request = {
...(await buildCommerceAPIRequest()),
query: 'some query',
};

mockPlatformCall({
ok: true,
json: () => Promise.resolve('some content'),
});

await client.productSuggestions(request);

expect(platformCallMock).toHaveBeenCalled();
const mockRequest = platformCallMock.mock.calls[0][0];
expect(mockRequest).toMatchObject({
method: 'POST',
contentType: 'application/json',
url: `${platformUrl}/rest/organizations/${organizationId}/commerce/v2/search/productSuggest`,
accessToken: request.accessToken,
origin: 'commerceApiFetch',
requestParams: {
query: 'some query',
trackingId: request.trackingId,
clientId: request.clientId,
context: request.context,
language: request.language,
currency: request.currency,
},
requestMetadata: {method: 'search/productSuggest'},
});
});

Expand Down Expand Up @@ -190,6 +229,7 @@ describe('commerce api client', () => {
language: request.language,
currency: request.currency,
},
requestMetadata: {method: 'search/querySuggest'},
});
});

Expand Down Expand Up @@ -225,6 +265,7 @@ describe('commerce api client', () => {
query: 'some query',
...searchContext,
},
requestMetadata: {method: 'facet'},
});
});

Expand Down
18 changes: 9 additions & 9 deletions packages/headless/src/api/commerce/commerce-api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,6 @@ export class CommerceAPIClient implements CommerceFacetSearchAPIClient {
});
}

async getRecommendations(
req: CommerceRecommendationsRequest
): Promise<CommerceAPIResponse<RecommendationsCommerceSuccessResponse>> {
return this.query({
...buildRecommendationsRequest(req, 'recommendations'),
...this.options,
});
}

async search(
req: CommerceSearchRequest
): Promise<CommerceAPIResponse<SearchCommerceSuccessResponse>> {
Expand All @@ -93,6 +84,15 @@ export class CommerceAPIClient implements CommerceFacetSearchAPIClient {
});
}

async getRecommendations(
req: CommerceRecommendationsRequest
): Promise<CommerceAPIResponse<RecommendationsCommerceSuccessResponse>> {
return this.query({
...buildRecommendationsRequest(req, 'recommendations'),
...this.options,
});
}

async productSuggestions(
req: CommerceSearchRequest
): Promise<CommerceAPIResponse<SearchCommerceSuccessResponse>> {
Expand Down
1 change: 1 addition & 0 deletions packages/headless/src/api/commerce/commerce-api-params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export interface ContextParams {
cart?: CartItemParam[];
purchased?: CartItemParam[];
capture: boolean;
source: string[];
}

export interface ViewParams {
Expand Down
8 changes: 8 additions & 0 deletions packages/headless/src/api/commerce/commerce-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type CommerceApiMethod =
| 'listing'
| 'search'
| 'recommendations'
| 'search/productSuggest'
| 'search/querySuggest'
| 'querySuggest'
| 'facet';
16 changes: 13 additions & 3 deletions packages/headless/src/api/commerce/common/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
SortParam,
PerPageParam,
} from '../commerce-api-params';
import {CommerceApiMethod} from '../commerce-metadata';

export type BaseCommerceAPIRequest = BaseParam &
TrackingIdParam &
Expand All @@ -27,7 +28,10 @@ export type CommerceAPIRequest = BaseCommerceAPIRequest &
FacetsParam &
SortParam;

export const buildRequest = (req: CommerceAPIRequest, path: string) => {
export const buildRequest = (
req: CommerceAPIRequest,
path: CommerceApiMethod
) => {
return {
...baseRequest(req, path),
requestParams: prepareRequestParams(req),
Expand Down Expand Up @@ -63,10 +67,15 @@ const prepareRequestParams = (req: CommerceAPIRequest) => {

export const baseRequest = (
req: BaseParam,
path: string
path: CommerceApiMethod
): Pick<
PlatformClientCallOptions,
'accessToken' | 'method' | 'contentType' | 'url' | 'origin'
| 'accessToken'
| 'method'
| 'contentType'
| 'url'
| 'origin'
| 'requestMetadata'
> => {
const {url, organizationId, accessToken} = req;
const baseUrl = `${url}/rest/organizations/${organizationId}/commerce/v2/${path}`;
Expand All @@ -77,5 +86,6 @@ export const baseRequest = (
contentType: 'application/json',
url: baseUrl,
origin: 'commerceApiFetch',
requestMetadata: {method: path},
};
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import {SlotIdParam} from '../commerce-api-params';
import {CommerceApiMethod} from '../commerce-metadata';
import {BaseCommerceAPIRequest, baseRequest} from '../common/request';

export type CommerceRecommendationsRequest = BaseCommerceAPIRequest &
SlotIdParam;
export const buildRecommendationsRequest = (
req: CommerceRecommendationsRequest,
path: string
path: CommerceApiMethod
) => {
return {
...baseRequest(req, path),
Expand Down
3 changes: 2 additions & 1 deletion packages/headless/src/api/preprocess-request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {AnalyticsClientOrigin} from 'coveo.analytics/dist/definitions/client/analyticsRequestClient';
import {CommerceApiMethod} from './commerce/commerce-metadata';
import {SearchApiMethod, SearchOrigin} from './search/search-metadata';

export interface PlatformRequestOptions extends RequestInit {
Expand All @@ -16,7 +17,7 @@ export interface RequestMetadata {
/**
* Method called on the client.
*/
method: SearchApiMethod;
method: SearchApiMethod | CommerceApiMethod;
/**
* Origin of the client, helps differentiate in between features using the same method.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {buildMockCommerceFacetRequest} from '../../../test/mock-commerce-facet-r
import {buildMockCommerceFacetSlice} from '../../../test/mock-commerce-facet-slice';
import {buildMockCommerceRegularFacetValue} from '../../../test/mock-commerce-facet-value';
import {buildMockCommerceState} from '../../../test/mock-commerce-state';
import {VERSION} from '../../../utils/version';
import {CommerceFacetSlice} from '../facets/facet-set/facet-set-state';
import {
getCommercePaginationInitialSlice,
Expand Down Expand Up @@ -53,6 +54,7 @@ describe('commerce common actions', () => {
quantity: product.quantity,
},
],
source: [`@coveo/headless@${VERSION}`, '@coveo/atomic@version'],
},
};

Expand All @@ -62,6 +64,9 @@ describe('commerce common actions', () => {
state.configuration.accessToken = expected.accessToken;
state.configuration.organizationId = expected.organizationId;
state.configuration.analytics.trackingId = expected.trackingId;
state.configuration.analytics.source = {
'@coveo/atomic': 'version',
};
state.commerceContext.language = expected.language;
state.commerceContext.country = expected.country;
state.commerceContext.currency = expected.currency as CurrencyCodeISO4217;
Expand Down
2 changes: 2 additions & 0 deletions packages/headless/src/features/commerce/common/actions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {getAnalyticsSource} from '../../../api/analytics/analytics-selectors';
import {getVisitorID} from '../../../api/analytics/coveo-analytics-utils';
import {SortParam} from '../../../api/commerce/commerce-api-params';
import {
Expand Down Expand Up @@ -61,6 +62,7 @@ export const buildBaseCommerceAPIRequest = async (
view,
capture: state.configuration.analytics.enabled,
cart: getProductsFromCartState(state.cart),
source: getAnalyticsSource(state.configuration.analytics),
},
...effectivePagination(state, slotId),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {createAsyncThunk} from '@reduxjs/toolkit';
import {getAnalyticsSource} from '../../../api/analytics/analytics-selectors';
import {getVisitorID} from '../../../api/analytics/coveo-analytics-utils';
import {
AsyncThunkCommerceOptions,
Expand Down Expand Up @@ -81,6 +82,7 @@ export const buildQuerySuggestRequest = async (
view,
capture: state.configuration.analytics.enabled,
cart: getProductsFromCartState(state.cart),
source: getAnalyticsSource(state.configuration.analytics),
},
};
};

0 comments on commit c9822ed

Please sign in to comment.