Skip to content

Commit

Permalink
fix(commerce): populate context.user.userAgent with `navigatorConte…
Browse files Browse the repository at this point in the history
…xt` (#4113)

headless was populating the `context.user.userAgent` property with what
was set through the `setUser`. With this PR, we extract the `userAgent`
and the `referrer` from the relay instance and use these values instead.
This makes using the headless commerce controllers less error-prone.

⚠️ This means we can remove the `setUser` action (and its sibling method
on the context controller), and `setView`'s `referrer` parameter, which
I do in this PR. Do you think this makes sense? Is there a use case for
allowing manual control over these parameters? @samisayegh
@louis-bompart @fbeaudoincoveo ?

[CAPI-1091]

[CAPI-1091]:
https://coveord.atlassian.net/browse/CAPI-1091?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Co-authored-by: Frederic Beaudoin <fbeaudoin@coveo.com>
Co-authored-by: Louis Bompart <lbompart@coveo.com>
  • Loading branch information
3 people authored Jun 27, 2024
1 parent 6ad5665 commit 0dc9434
Show file tree
Hide file tree
Showing 31 changed files with 340 additions and 224 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export function getSampleCommerceEngineConfiguration(): CommerceEngineConfigurat
currency: 'USD',
view: {
url: 'https://sports-dev.barca.group/browse/promotions/skis-boards/surfboards',
referrer: document.referrer,
},
},
cart: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ describe('buildCommerceEngine', () => {
}

beforeEach(() => {
Object.defineProperty(global, 'document', {
value: {referrer: 'referrer'},
configurable: true,
});
options = {
configuration: getSampleCommerceEngineConfiguration(),
loggerOptions: {level: 'silent'},
Expand Down
1 change: 0 additions & 1 deletion packages/headless/src/commerce.index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export {buildController} from './controllers/controller/headless-controller';

export type {
ContextOptions,
User,
View,
ContextProps,
Context,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
setContext,
setUser,
setView,
} from '../../../features/commerce/context/context-actions';
import {contextReducer} from '../../../features/commerce/context/context-slice';
Expand Down Expand Up @@ -77,19 +76,9 @@ describe('headless commerce context', () => {
);
});

it('setUser dispatches #setUser', () => {
context.setUser({
userAgent: 'some-user-agent',
});
expect(setUser).toHaveBeenCalledWith(
expect.objectContaining({userAgent: 'some-user-agent'})
);
});

it('setView dispatches #setView', () => {
context.setView({
url: 'https://example.org',
referrer: 'https://example.org/referrer',
});
expect(setView).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {CommerceEngine} from '../../../app/commerce-engine/commerce-engine';
import {stateKey} from '../../../app/state-key';
import {
setContext,
setUser,
setView,
} from '../../../features/commerce/context/context-actions';
import {contextReducer as commerceContext} from '../../../features/commerce/context/context-slice';
Expand All @@ -19,17 +18,11 @@ export interface ContextOptions {
language: string;
country: string;
currency: CurrencyCodeISO4217;
user?: User;
view: View;
}

export type User = {
userAgent?: string;
};

export interface View {
url: string;
referrer?: string;
}

export interface ContextProps {
Expand Down Expand Up @@ -61,12 +54,6 @@ export interface Context extends Controller {
*/
setCurrency(currency: CurrencyCodeISO4217): void;

/**
* Sets the user.
* @param user - The new user.
*/
setUser(user: User): void;

/**
* Sets the view.
* @param view - The new view.
Expand All @@ -83,7 +70,6 @@ export interface ContextState {
language: string;
country: string;
currency: CurrencyCodeISO4217;
user?: User;
view: View;
}

Expand Down Expand Up @@ -142,8 +128,6 @@ export function buildContext(
})
),

setUser: (user: User) => dispatch(setUser(user)),

setView: (view: View) => dispatch(setView(view)),
};
}
Expand Down
127 changes: 103 additions & 24 deletions packages/headless/src/features/commerce/common/actions.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import {Relay, createRelay} from '@coveo/relay';
import {Meta, Relay, createRelay} from '@coveo/relay';
import {CurrencyCodeISO4217} from '@coveo/relay-event-types';
import {
BaseCommerceAPIRequest,
CommerceAPIRequest,
} from '../../../api/commerce/common/request';
import {NavigatorContext} from '../../../app/navigatorContextProvider';
import {buildMockCommerceFacetRequest} from '../../../test/mock-commerce-facet-request';
import {buildMockCommerceFacetSlice} from '../../../test/mock-commerce-facet-slice';
import {buildMockCommerceRegularFacetValue} from '../../../test/mock-commerce-facet-value';
import {buildMockCommerceState} from '../../../test/mock-commerce-state';
import {buildMockNavigatorContextProvider} from '../../../test/mock-navigator-context-provider';
import {VERSION} from '../../../utils/version';
import {CommerceFacetSlice} from '../facets/facet-set/facet-set-state';
import {
Expand All @@ -18,15 +20,40 @@ import {SortBy, SortCriterion, SortDirection} from '../sort/sort';
import {getCommerceSortInitialState} from '../sort/sort-state';
import * as Actions from './actions';

jest.mock('@coveo/relay');

describe('commerce common actions', () => {
let relay: Relay;
let navigatorContext: NavigatorContext;

beforeEach(() => {
relay = createRelay({
const mockedCreateRelay = jest
.mocked(createRelay)
.mockImplementation(() => ({
emit: jest.fn(),
on: jest.fn(),
off: jest.fn(),
clearStorage: jest.fn(),
getMeta: jest.fn(
() =>
({
clientId: 'client_id',
}) as Meta
),
updateConfig: jest.fn(),
version: 'test',
}));
relay = mockedCreateRelay({
token: 'token',
trackingId: 'trackingId',
url: 'url',
});
navigatorContext = buildMockNavigatorContextProvider({
userAgent: 'user_agent',
referrer: 'referrer',
})();
});

describe('#buildBaseCommerceAPIRequest', () => {
let expected: BaseCommerceAPIRequest;
let state: Actions.StateNeededByQueryCommerceAPI;
Expand All @@ -47,14 +74,14 @@ describe('commerce common actions', () => {
language: 'en',
country: 'CA',
currency: 'CAD',
clientId: expect.any(String),
clientId: 'client_id',
context: {
user: {
userAgent: 'user_agent',
},
view: {
url: 'https://example.com',
referrer: 'https://referrer.com',
referrer: 'referrer',
},
capture: true,
cart: [
Expand All @@ -79,7 +106,6 @@ describe('commerce common actions', () => {
state.commerceContext.language = expected.language;
state.commerceContext.country = expected.country;
state.commerceContext.currency = expected.currency as CurrencyCodeISO4217;
state.commerceContext.user = expected.context.user;
state.commerceContext.view = expected.context.view;
state.cart.cartItems = [product.productId];
state.cart.cart = {
Expand All @@ -92,7 +118,11 @@ describe('commerce common actions', () => {
it('given a state with no commercePagination section, returns the expected base request', () => {
delete state.commercePagination;

const request = Actions.buildBaseCommerceAPIRequest(state, relay);
const request = Actions.buildBaseCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(request).toEqual({...expected});
});
Expand All @@ -113,7 +143,11 @@ describe('commerce common actions', () => {
perPage: state.commercePagination.principal.perPage,
};

const request = Actions.buildBaseCommerceAPIRequest(state, relay);
const request = Actions.buildBaseCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(request).toEqual(expectedWithPagination);
});
Expand All @@ -137,7 +171,12 @@ describe('commerce common actions', () => {
perPage: state.commercePagination.recommendations[slotId]!.perPage,
};

const request = Actions.buildBaseCommerceAPIRequest(state, relay, slotId);
const request = Actions.buildBaseCommerceAPIRequest(
state,
relay,
navigatorContext,
slotId
);

expect(request).toEqual(expectedWithPagination);
});
Expand All @@ -160,11 +199,16 @@ describe('commerce common actions', () => {
delete state.facetOrder;
delete state.commerceFacetSet;

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request).toEqual({
Expand All @@ -179,11 +223,16 @@ describe('commerce common actions', () => {

state.facetOrder = ['facet_id'];

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request).toEqual({
Expand All @@ -200,11 +249,16 @@ describe('commerce common actions', () => {
facet_id: buildMockCommerceFacetSlice(),
};

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request).toEqual({
Expand All @@ -218,11 +272,16 @@ describe('commerce common actions', () => {
(analyticsEnabled) => {
state.configuration.analytics.enabled = analyticsEnabled;

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request.context.capture).toEqual(analyticsEnabled);
Expand Down Expand Up @@ -262,11 +321,16 @@ describe('commerce common actions', () => {
};
});
it('includes all non-empty facets in the #facets array of the returned request', () => {
const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request).toEqual({
Expand All @@ -289,11 +353,16 @@ describe('commerce common actions', () => {
state.commerceFacetSet![facet3.request.facetId] = facet3;
state.facetOrder.push(facet3.request.facetId);

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

expect(request).toEqual({
Expand All @@ -317,11 +386,16 @@ describe('commerce common actions', () => {
},
};

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

const expectedWithSort: CommerceAPIRequest = {
Expand Down Expand Up @@ -351,11 +425,16 @@ describe('commerce common actions', () => {
appliedSort: sortCriterion,
};

const request = Actions.buildCommerceAPIRequest(state, relay);
const request = Actions.buildCommerceAPIRequest(
state,
relay,
navigatorContext
);

expect(mockedBuildBaseCommerceAPIRequest).toHaveBeenCalledWith(
state,
relay
relay,
navigatorContext
);

const expectedWithSort: CommerceAPIRequest = {
Expand Down
Loading

0 comments on commit 0dc9434

Please sign in to comment.