Skip to content

Commit

Permalink
feat(headless commerce SSR): allow setting / getting the access token…
Browse files Browse the repository at this point in the history
… on commerce SSR engine definitions (#4993)

https://coveord.atlassian.net/browse/KIT-3985
  • Loading branch information
fbeaudoincoveo authored Feb 25, 2025
1 parent 309bc78 commit f37b44f
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 63 deletions.
204 changes: 141 additions & 63 deletions packages/headless/src/app/commerce-engine/commerce-engine.ssr.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,81 +3,159 @@ import {defineParameterManager} from '../../controllers/commerce/core/parameter-
import {defineSummary} from '../../controllers/commerce/core/summary/headless-core-summary.ssr.js';
import {defineRecommendations} from '../../controllers/commerce/recommendations/headless-recommendations.ssr.js';
import {defineDidYouMean} from '../../controllers/commerce/search/did-you-mean/headless-did-you-mean.ssr.js';
import {CommerceEngineDefinitionOptions} from '../commerce-ssr-engine/factories/build-factory.js';
import {getSampleCommerceEngineConfiguration} from './commerce-engine-configuration.js';
import {defineCommerceEngine} from './commerce-engine.ssr.js';

describe('Commerce Engine SSR', () => {
const {
listingEngineDefinition,
recommendationEngineDefinition,
searchEngineDefinition,
standaloneEngineDefinition,
} = defineCommerceEngine({
configuration: {
...getSampleCommerceEngineConfiguration(),
},
controllers: {
summary: defineSummary(),
didYouMean: defineDidYouMean(),
paramManager: defineParameterManager({listing: false}),
cart: defineCart(),
popularViewed: defineRecommendations({
options: {
slotId: 'd73afbd2-8521-4ee6-a9b8-31f064721e73',
},
}),
},
});
let definitionOptions: NonNullable<CommerceEngineDefinitionOptions>;

let engineDefinition: ReturnType<
typeof defineCommerceEngine<
NonNullable<typeof definitionOptions.controllers>
>
>;

let listingEngineDefinition: (typeof engineDefinition)['listingEngineDefinition'];
let recommendationEngineDefinition: (typeof engineDefinition)['recommendationEngineDefinition'];
let searchEngineDefinition: (typeof engineDefinition)['searchEngineDefinition'];
let standaloneEngineDefinition: (typeof engineDefinition)['standaloneEngineDefinition'];

it('should only require cart options for standaloneEngineDefinition', () => {
expect(() =>
standaloneEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
beforeEach(() => {
definitionOptions = {
configuration: {
...getSampleCommerceEngineConfiguration(),
},
controllers: {
summary: defineSummary(),
didYouMean: defineDidYouMean(),
paramManager: defineParameterManager({listing: false}),
cart: defineCart(),
popularViewed: defineRecommendations({
options: {
slotId: 'd73afbd2-8521-4ee6-a9b8-31f064721e73',
},
}),
},
};
engineDefinition = defineCommerceEngine(definitionOptions);

listingEngineDefinition = engineDefinition.listingEngineDefinition;
recommendationEngineDefinition =
engineDefinition.recommendationEngineDefinition;
searchEngineDefinition = engineDefinition.searchEngineDefinition;
standaloneEngineDefinition = engineDefinition.standaloneEngineDefinition;
});

it('should only require cart options for listingEngineDefinition', () => {
expect(() =>
listingEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
describe('#standaloneEngineDefinition', () => {
it('should only require cart options', () => {
expect(() =>
standaloneEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
});

it('#getAccessToken should return the access token', () => {
expect(standaloneEngineDefinition.getAccessToken()).toBe(
getSampleCommerceEngineConfiguration().accessToken
);
});

it('#setAccessToken should update the access token', () => {
standaloneEngineDefinition.setAccessToken('new-access-token');

expect(standaloneEngineDefinition.getAccessToken()).toBe(
'new-access-token'
);
});
});

it('should only require cart and paramManager options for searchEngineDefinition', () => {
expect(() =>
searchEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
paramManager: {initialState: {parameters: {}}},
},
})
).not.toThrow();
describe('#listingEngineDefinition', () => {
it('should only require cart options', () => {
expect(() =>
listingEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
});

it('#getAccessToken should return the access token', () => {
expect(listingEngineDefinition.getAccessToken()).toBe(
getSampleCommerceEngineConfiguration().accessToken
);
});

it('#setAccessToken should update the access token', () => {
listingEngineDefinition.setAccessToken('new-access-token');

expect(listingEngineDefinition.getAccessToken()).toBe('new-access-token');
});
});

it('should only require cart options for recommendationEngineDefinition', () => {
expect(() =>
recommendationEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
describe('#searchEngineDefinition', () => {
it('should only require cart and paramManager options', () => {
expect(() =>
searchEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
paramManager: {initialState: {parameters: {}}},
},
})
).not.toThrow();
});

it('#getAccessToken should return the access token', () => {
expect(searchEngineDefinition.getAccessToken()).toBe(
getSampleCommerceEngineConfiguration().accessToken
);
});

it('#setAccessToken should update the access token', () => {
searchEngineDefinition.setAccessToken('new-access-token');

expect(searchEngineDefinition.getAccessToken()).toBe('new-access-token');
});
});

it('should allow optional recommendation controller options for recommendationEngineDefinition', () => {
expect(() =>
recommendationEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
popularViewed: {enabled: true, productId: 'some-product-id'},
},
})
).not.toThrow();
describe('#recommendationEngineDefinition', () => {
it('should only require cart options', () => {
expect(() =>
recommendationEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
},
})
).not.toThrow();
});

it('should allow optional recommendation controller options', () => {
expect(() =>
recommendationEngineDefinition.fetchStaticState({
controllers: {
cart: {initialState: {items: []}},
popularViewed: {enabled: true, productId: 'some-product-id'},
},
})
).not.toThrow();
});

it('#getAccessToken should return the access token', () => {
expect(recommendationEngineDefinition.getAccessToken()).toBe(
getSampleCommerceEngineConfiguration().accessToken
);
});

it('#setAccessToken should update the access token', () => {
recommendationEngineDefinition.setAccessToken('new-access-token');

expect(recommendationEngineDefinition.getAccessToken()).toBe(
'new-access-token'
);
});
});
});
14 changes: 14 additions & 0 deletions packages/headless/src/app/commerce-engine/commerce-engine.ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ export function defineCommerceEngine<
engineOptions.navigatorContextProvider = navigatorContextProvider;
};

const getAccessToken = () => engineOptions.configuration.accessToken;

const setAccessToken = (accessToken: string) => {
engineOptions.configuration.accessToken = accessToken;
};

const build = buildFactory<TControllerDefinitions>(
controllerDefinitions,
getOptions()
Expand Down Expand Up @@ -96,18 +102,24 @@ export function defineCommerceEngine<
fetchStaticState: fetchStaticState(SolutionType.listing),
hydrateStaticState: hydrateStaticState(SolutionType.listing),
setNavigatorContextProvider,
getAccessToken,
setAccessToken,
} as CommerceEngineDefinition<TControllerDefinitions, SolutionType.listing>,
searchEngineDefinition: {
build: build(SolutionType.search),
fetchStaticState: fetchStaticState(SolutionType.search),
hydrateStaticState: hydrateStaticState(SolutionType.search),
setNavigatorContextProvider,
getAccessToken,
setAccessToken,
} as CommerceEngineDefinition<TControllerDefinitions, SolutionType.search>,
recommendationEngineDefinition: {
build: build(SolutionType.recommendation),
fetchStaticState: fetchRecommendationStaticState,
hydrateStaticState: hydrateRecommendationStaticState,
setNavigatorContextProvider,
getAccessToken,
setAccessToken,
} as CommerceEngineDefinition<
TControllerDefinitions,
SolutionType.recommendation
Expand All @@ -118,6 +130,8 @@ export function defineCommerceEngine<
fetchStaticState: fetchStaticState(SolutionType.standalone),
hydrateStaticState: hydrateStaticState(SolutionType.standalone),
setNavigatorContextProvider,
getAccessToken,
setAccessToken,
} as CommerceEngineDefinition<
TControllerDefinitions,
SolutionType.standalone
Expand Down
11 changes: 11 additions & 0 deletions packages/headless/src/app/commerce-ssr-engine/types/core-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ export interface EngineDefinition<
setNavigatorContextProvider: (
navigatorContextProvider: NavigatorContextProvider
) => void;

/**
* Returns the access token.
*/
getAccessToken: () => string;

/**
* Updates the access token.
* @param accessToken - The access token to update.
*/
setAccessToken: (accessToken: string) => void;
}

export type InferStaticState<
Expand Down

0 comments on commit f37b44f

Please sign in to comment.