From 1d1b6c7ca5e76740fb74aae7246dea62f474d8e6 Mon Sep 17 00:00:00 2001 From: nadiya Date: Tue, 2 Sep 2025 22:33:29 -0500 Subject: [PATCH 01/10] DINT-1856: Allow custom context for multiple ProductListItems --- .../src/utils/aep/productListItems.ts | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/packages/storefront-events-collector/src/utils/aep/productListItems.ts b/packages/storefront-events-collector/src/utils/aep/productListItems.ts index 719523d1..3461cc9e 100644 --- a/packages/storefront-events-collector/src/utils/aep/productListItems.ts +++ b/packages/storefront-events-collector/src/utils/aep/productListItems.ts @@ -22,25 +22,35 @@ const createProductListItems = ( const productListFromCustomContextMap: Map = new Map(); + /** + * If there's only one item in the custom context and it doesn't have a SKU, + * then merge this context with every item, + * otherwise match by SKU + */ + const generalCustomContext = + productListItemsFromCustomContext?.length === 1 && productListItemsFromCustomContext[0]?.SKU === undefined + ? productListItemsFromCustomContext[0] + : undefined; + productListItemsFromCustomContext?.forEach((item) => { productListFromCustomContextMap.set(item.SKU as string, item); }); if (requisitionListItemsContext) { requisitionListItemsContext.items?.map((item) => { - const productListItemFromCustomContext = productListFromCustomContextMap.get(item.sku); - const requisitionListItem = { - SKU: item.sku, - name: productListItemFromCustomContext?.name || item.name, - quantity: productListItemFromCustomContext?.quantity || Number(item.quantity), - priceTotal: - productListItemFromCustomContext?.priceTotal || - formatPrice((Number(item.pricing?.regularPrice) || 0) * Number(item.quantity)), - currencyCode: - productListItemFromCustomContext?.currencyCode || - (item.pricing?.currencyCode ?? storefrontContext.storeViewCurrencyCode), - selectedOptions: productListItemFromCustomContext?.selectedOptions || item.selectedOptions, - }; + const requisitionListItem = generalCustomContext || productListFromCustomContextMap.get(item.sku) || {}; + + // custom SKU is not supported as it is used as identification for merging + requisitionListItem.SKU = item.sku; + requisitionListItem.name = requisitionListItem?.name || item.name; + requisitionListItem.quantity = requisitionListItem?.quantity || Number(item.quantity); + requisitionListItem.priceTotal = + requisitionListItem?.priceTotal || + formatPrice((Number(item.pricing?.regularPrice) || 0) * Number(item.quantity)); + requisitionListItem.currencyCode = + requisitionListItem?.currencyCode || + (item.pricing?.currencyCode ?? storefrontContext.storeViewCurrencyCode); + requisitionListItem.selectedOptions = requisitionListItem?.selectedOptions || item.selectedOptions; returnList.push(requisitionListItem); }); } else { @@ -53,26 +63,22 @@ const createProductListItems = ( }); }); - const productListItemFromCustomContext = productListFromCustomContextMap.get(item.product?.sku); + const productListItem = + generalCustomContext || productListFromCustomContextMap.get(item.product?.sku) || {}; - const productListItem: ProductListItem = { - SKU: item.product?.sku, - name: productListItemFromCustomContext?.name || item.product?.name, - quantity: productListItemFromCustomContext?.quantity || item.quantity, - priceTotal: - productListItemFromCustomContext?.priceTotal || - formatPrice(item.prices?.price?.value * item.quantity) || - 0, - productImageUrl: productListItemFromCustomContext?.productImageUrl || item.product.mainImageUrl, - currencyCode: - productListItemFromCustomContext?.currencyCode || - (item.prices?.price?.currency ?? storefrontContext.storeViewCurrencyCode), - discountAmount: - productListItemFromCustomContext?.discountAmount || - item.discountAmount || - getDiscountAmount(item.product), - selectedOptions: productListItemFromCustomContext?.selectedOptions || selectedOptions, - }; + // custom SKU is not supported as it is used as identification for merging + productListItem.SKU = item.product?.sku; + productListItem.name = productListItem.name || item.product?.name; + productListItem.quantity = productListItem?.quantity || item.quantity; + productListItem.priceTotal = + productListItem?.priceTotal || formatPrice(item.prices?.price?.value * item.quantity) || 0; + productListItem.productImageUrl = productListItem?.productImageUrl || item.product.mainImageUrl; + productListItem.currencyCode = + productListItem?.currencyCode || + (item.prices?.price?.currency ?? storefrontContext.storeViewCurrencyCode); + productListItem.discountAmount = + productListItem?.discountAmount || item.discountAmount || getDiscountAmount(item.product); + productListItem.selectedOptions = productListItem?.selectedOptions || selectedOptions; returnList.push(productListItem); }); From 0df42422d0ecd4a7a6097799d5e74ad0d0c87348 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Wed, 10 Sep 2025 15:07:40 -0500 Subject: [PATCH 02/10] Use custom context for product List itmes --- .../src/utils/aep/productListItems.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/packages/storefront-events-collector/src/utils/aep/productListItems.ts b/packages/storefront-events-collector/src/utils/aep/productListItems.ts index 3461cc9e..c068cf14 100644 --- a/packages/storefront-events-collector/src/utils/aep/productListItems.ts +++ b/packages/storefront-events-collector/src/utils/aep/productListItems.ts @@ -22,23 +22,13 @@ const createProductListItems = ( const productListFromCustomContextMap: Map = new Map(); - /** - * If there's only one item in the custom context and it doesn't have a SKU, - * then merge this context with every item, - * otherwise match by SKU - */ - const generalCustomContext = - productListItemsFromCustomContext?.length === 1 && productListItemsFromCustomContext[0]?.SKU === undefined - ? productListItemsFromCustomContext[0] - : undefined; - productListItemsFromCustomContext?.forEach((item) => { productListFromCustomContextMap.set(item.SKU as string, item); }); if (requisitionListItemsContext) { requisitionListItemsContext.items?.map((item) => { - const requisitionListItem = generalCustomContext || productListFromCustomContextMap.get(item.sku) || {}; + const requisitionListItem = productListFromCustomContextMap.get(item.sku) || {}; // custom SKU is not supported as it is used as identification for merging requisitionListItem.SKU = item.sku; @@ -63,8 +53,7 @@ const createProductListItems = ( }); }); - const productListItem = - generalCustomContext || productListFromCustomContextMap.get(item.product?.sku) || {}; + const productListItem = productListFromCustomContextMap.get(item.product?.sku) || {}; // custom SKU is not supported as it is used as identification for merging productListItem.SKU = item.product?.sku; From bb8fc773ef7128daad67b94c6c176513425288c8 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Wed, 10 Sep 2025 15:16:02 -0500 Subject: [PATCH 03/10] update documentation --- examples/events/custom-event-override.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/examples/events/custom-event-override.md b/examples/events/custom-event-override.md index f078d5ff..c4278877 100644 --- a/examples/events/custom-event-override.md +++ b/examples/events/custom-event-override.md @@ -75,3 +75,26 @@ mse.publish.pageView({ }, }); ``` + +### Example 4 - adding custom context to productListItems with events with multiple products + +```javascript +const mse = window.magentoStorefrontEvents; + +mse.context.setCustom({ + productListItems: [ + { + SKU: "24-WB01", //Match SKU to override correct product in event payload + productCategory: "Hand Bag", //Custom attribute added to event payload + name: "Strive Handbag (CustomName)" //Override existing attribute with custom value in event payload + }, + { + SKU: "24-MB04", + productCategory: "Backpack Bag", + name: "Strive Backpack (CustomName)" + }, + ], +}); + +mse.publish.shoppingCartView(); +``` \ No newline at end of file From 365ae515e61443b2c726cfe0d78f4a7067e89498 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 09:35:36 -0500 Subject: [PATCH 04/10] add custom context test, fix context manipulation issue --- .../src/handlers/account/signOutAEP.ts | 2 +- .../src/handlers/checkout/placeOrderAEP.ts | 2 +- .../src/handlers/page/viewAEP.ts | 2 +- .../src/handlers/product/addToCartAEP.ts | 2 +- .../src/handlers/product/removeFromCartAEP.ts | 2 +- .../src/handlers/product/viewAEP.ts | 2 +- .../addToRequisitionListAEP.ts | 2 +- .../createRequisitionListAEP.ts | 2 +- .../deleteRequisitionListAEP.ts | 2 +- .../removeFromRequisitionListAEP.ts | 2 +- .../handlers/search/searchRequestSentAEP.ts | 2 +- .../search/searchResponseReceivedAEP.ts | 2 +- .../shoppingCart/initiateCheckoutAEP.ts | 2 +- .../src/handlers/shoppingCart/openCartAEP.ts | 2 +- .../src/handlers/shoppingCart/viewAEP.ts | 2 +- .../src/utils/aep/account.ts | 2 +- .../shoppingCart/shoppingCartViewAep.test.ts | 140 ++++++++++++++++++ 17 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts diff --git a/packages/storefront-events-collector/src/handlers/account/signOutAEP.ts b/packages/storefront-events-collector/src/handlers/account/signOutAEP.ts index b87456c8..d6d47504 100644 --- a/packages/storefront-events-collector/src/handlers/account/signOutAEP.ts +++ b/packages/storefront-events-collector/src/handlers/account/signOutAEP.ts @@ -11,7 +11,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.userAccount = { diff --git a/packages/storefront-events-collector/src/handlers/checkout/placeOrderAEP.ts b/packages/storefront-events-collector/src/handlers/checkout/placeOrderAEP.ts index c1d81343..c20f4bc2 100644 --- a/packages/storefront-events-collector/src/handlers/checkout/placeOrderAEP.ts +++ b/packages/storefront-events-collector/src/handlers/checkout/placeOrderAEP.ts @@ -23,7 +23,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/page/viewAEP.ts b/packages/storefront-events-collector/src/handlers/page/viewAEP.ts index 4dbcde9d..e8705582 100644 --- a/packages/storefront-events-collector/src/handlers/page/viewAEP.ts +++ b/packages/storefront-events-collector/src/handlers/page/viewAEP.ts @@ -12,7 +12,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.web = payload.web || {}; diff --git a/packages/storefront-events-collector/src/handlers/product/addToCartAEP.ts b/packages/storefront-events-collector/src/handlers/product/addToCartAEP.ts index e479196f..38c5679a 100644 --- a/packages/storefront-events-collector/src/handlers/product/addToCartAEP.ts +++ b/packages/storefront-events-collector/src/handlers/product/addToCartAEP.ts @@ -15,7 +15,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/product/removeFromCartAEP.ts b/packages/storefront-events-collector/src/handlers/product/removeFromCartAEP.ts index bfd61a63..c22657ee 100644 --- a/packages/storefront-events-collector/src/handlers/product/removeFromCartAEP.ts +++ b/packages/storefront-events-collector/src/handlers/product/removeFromCartAEP.ts @@ -15,7 +15,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/product/viewAEP.ts b/packages/storefront-events-collector/src/handlers/product/viewAEP.ts index 41f20ecf..374ef188 100644 --- a/packages/storefront-events-collector/src/handlers/product/viewAEP.ts +++ b/packages/storefront-events-collector/src/handlers/product/viewAEP.ts @@ -13,7 +13,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } const productListItemFromCustomContext: ProductListItem | undefined = payload.productListItems?.length diff --git a/packages/storefront-events-collector/src/handlers/requisitionList/addToRequisitionListAEP.ts b/packages/storefront-events-collector/src/handlers/requisitionList/addToRequisitionListAEP.ts index 6403921b..276ee4bd 100644 --- a/packages/storefront-events-collector/src/handlers/requisitionList/addToRequisitionListAEP.ts +++ b/packages/storefront-events-collector/src/handlers/requisitionList/addToRequisitionListAEP.ts @@ -23,7 +23,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/requisitionList/createRequisitionListAEP.ts b/packages/storefront-events-collector/src/handlers/requisitionList/createRequisitionListAEP.ts index 264d8b21..f7f58e6b 100644 --- a/packages/storefront-events-collector/src/handlers/requisitionList/createRequisitionListAEP.ts +++ b/packages/storefront-events-collector/src/handlers/requisitionList/createRequisitionListAEP.ts @@ -14,7 +14,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/requisitionList/deleteRequisitionListAEP.ts b/packages/storefront-events-collector/src/handlers/requisitionList/deleteRequisitionListAEP.ts index 51257188..86e04e81 100644 --- a/packages/storefront-events-collector/src/handlers/requisitionList/deleteRequisitionListAEP.ts +++ b/packages/storefront-events-collector/src/handlers/requisitionList/deleteRequisitionListAEP.ts @@ -14,7 +14,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/requisitionList/removeFromRequisitionListAEP.ts b/packages/storefront-events-collector/src/handlers/requisitionList/removeFromRequisitionListAEP.ts index 790fbf66..0ce9262f 100644 --- a/packages/storefront-events-collector/src/handlers/requisitionList/removeFromRequisitionListAEP.ts +++ b/packages/storefront-events-collector/src/handlers/requisitionList/removeFromRequisitionListAEP.ts @@ -22,7 +22,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/search/searchRequestSentAEP.ts b/packages/storefront-events-collector/src/handlers/search/searchRequestSentAEP.ts index d7a58b63..ab8f7ec1 100644 --- a/packages/storefront-events-collector/src/handlers/search/searchRequestSentAEP.ts +++ b/packages/storefront-events-collector/src/handlers/search/searchRequestSentAEP.ts @@ -18,7 +18,7 @@ const handler = async (event: Event): Promise => { if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } const sortFromCtx: SearchSort[] = (searchInputCtx?.data.sort as SearchSort[]) ?? []; diff --git a/packages/storefront-events-collector/src/handlers/search/searchResponseReceivedAEP.ts b/packages/storefront-events-collector/src/handlers/search/searchResponseReceivedAEP.ts index c701eae6..6cb0f449 100644 --- a/packages/storefront-events-collector/src/handlers/search/searchResponseReceivedAEP.ts +++ b/packages/storefront-events-collector/src/handlers/search/searchResponseReceivedAEP.ts @@ -29,7 +29,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.siteSearch = { diff --git a/packages/storefront-events-collector/src/handlers/shoppingCart/initiateCheckoutAEP.ts b/packages/storefront-events-collector/src/handlers/shoppingCart/initiateCheckoutAEP.ts index d462f4d6..9975999b 100644 --- a/packages/storefront-events-collector/src/handlers/shoppingCart/initiateCheckoutAEP.ts +++ b/packages/storefront-events-collector/src/handlers/shoppingCart/initiateCheckoutAEP.ts @@ -14,7 +14,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/shoppingCart/openCartAEP.ts b/packages/storefront-events-collector/src/handlers/shoppingCart/openCartAEP.ts index ed7a6f8f..6ee74776 100644 --- a/packages/storefront-events-collector/src/handlers/shoppingCart/openCartAEP.ts +++ b/packages/storefront-events-collector/src/handlers/shoppingCart/openCartAEP.ts @@ -13,7 +13,7 @@ const handler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/handlers/shoppingCart/viewAEP.ts b/packages/storefront-events-collector/src/handlers/shoppingCart/viewAEP.ts index dca8e3c8..672ea6e6 100644 --- a/packages/storefront-events-collector/src/handlers/shoppingCart/viewAEP.ts +++ b/packages/storefront-events-collector/src/handlers/shoppingCart/viewAEP.ts @@ -15,7 +15,7 @@ const aepHandler = async (event: Event): Promise => { let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.commerce = payload.commerce || {}; diff --git a/packages/storefront-events-collector/src/utils/aep/account.ts b/packages/storefront-events-collector/src/utils/aep/account.ts index f7cbe079..044bb74e 100644 --- a/packages/storefront-events-collector/src/utils/aep/account.ts +++ b/packages/storefront-events-collector/src/utils/aep/account.ts @@ -7,7 +7,7 @@ const createAccountPayload = (customContext: any, accountContext: sdkSchemas.Acc let payload: BeaconSchema = {}; if (customContext && Object.keys(customContext as BeaconSchema).length !== 0) { // override payload on custom context - payload = customContext as BeaconSchema; + payload = { ...customContext } as BeaconSchema; } payload.person = payload.person || {}; diff --git a/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts new file mode 100644 index 00000000..052dd866 --- /dev/null +++ b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts @@ -0,0 +1,140 @@ +jest.mock("../../../src/alloy"); +import { Event } from "@adobe/magento-storefront-events-sdk/dist/types/types/events"; +import { sendEvent } from "../../../src/alloy"; +import { shoppingCartViewHandlerAEP } from "../../../src/handlers"; +import { mockEvent } from "../../utils/mocks"; + +const AEPevent = { ...mockEvent }; +delete AEPevent.eventInfo.customContext; + +test("correctly structures AEP event and calls alloy.sendEvent", () => { + shoppingCartViewHandlerAEP(mockEvent); + + expect(sendEvent).toHaveBeenCalledTimes(1); + + expect(sendEvent).toHaveBeenCalledWith( + { + commerce: { + cart: { + cartID: "111111", + }, + productListViews: { + value: 1, + }, + commerceScope: { + environmentID: "aaaaaa", + storeCode: "magento", + storeViewCode: "default", + websiteCode: "website", + }, + order: { + discountAmount: 0, + }, + }, + productListItems: [ + { + SKU: "ts001", + name: "T-Shirt", + quantity: 1, + priceTotal: 20, + productImageUrl: undefined, + currencyCode: "USD", + discountAmount: 0, + selectedOptions: [], + }, + { + SKU: "h001", + name: "Hoodie", + quantity: 1, + priceTotal: 50, + productImageUrl: undefined, + currencyCode: "USD", + discountAmount: 0, + selectedOptions: [], + }, + ], + _id: undefined, + eventType: "commerce.productListViews", + }, + mockEvent, + ); +}); + +test("correctly structures AEP event with customContext and calls alloy.sendEvent", () => { + const customContext = { + commerce: { + order: { + couponCode: "couponCode123", + }, + }, + productListItems: [ + { + SKU: "ts001", + name: "Custom Product Name", + categoryId: "customCat001", + }, + ], + }; + const mockedAEPevent = { + event: 'shopping-cart-view', + eventInfo: { + ...AEPevent.eventInfo, + customContext, + } + } as Event; + + console.log(customContext.productListItems); + + shoppingCartViewHandlerAEP(mockedAEPevent); + + expect(sendEvent).toHaveBeenCalledTimes(1); + + expect(sendEvent).toHaveBeenCalledWith( + { + commerce: { + cart: { + cartID: "111111", + }, + productListViews: { + value: 1, + }, + commerceScope: { + environmentID: "aaaaaa", + storeCode: "magento", + storeViewCode: "default", + websiteCode: "website", + }, + order: { + discountAmount: 0, + couponCode: customContext.commerce.order.couponCode, + }, + }, + productListItems: [ + { + SKU: "ts001", + name: customContext.productListItems[0].name, + quantity: 1, + priceTotal: 20, + productImageUrl: undefined, + currencyCode: "USD", + discountAmount: 0, + selectedOptions: [], + categoryId: customContext.productListItems[0].categoryId, + }, + { + SKU: "h001", + name: "Hoodie", + quantity: 1, + priceTotal: 50, + productImageUrl: undefined, + currencyCode: "USD", + discountAmount: 0, + selectedOptions: [], + }, + ], + _id: undefined, + eventType: "commerce.productListViews", + }, + mockedAEPevent, + ); +}); From cca268a5a17a7d0c2b4e22bf3ffa7a2d3f3e7562 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 09:37:04 -0500 Subject: [PATCH 05/10] remove console log --- .../tests/handlers/shoppingCart/shoppingCartViewAep.test.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts index 052dd866..17d87b68 100644 --- a/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts +++ b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts @@ -83,8 +83,6 @@ test("correctly structures AEP event with customContext and calls alloy.sendEven } } as Event; - console.log(customContext.productListItems); - shoppingCartViewHandlerAEP(mockedAEPevent); expect(sendEvent).toHaveBeenCalledTimes(1); From d26a349591de78eb9450af95704c5a499db966b3 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 10:44:21 -0500 Subject: [PATCH 06/10] add note to custom event override doc --- examples/events/custom-event-override.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/events/custom-event-override.md b/examples/events/custom-event-override.md index c4278877..3f45ed68 100644 --- a/examples/events/custom-event-override.md +++ b/examples/events/custom-event-override.md @@ -4,6 +4,10 @@ For any event with a set `customContext`, the collector overrides joins fields s Event overrides are only applicable when forwarding to AEP. They are not applied to Adobe Commerce and Sensei analytics events. Additional info in [README](../../packages/storefront-events-collector/README.md) +> [!NOTE] +> When using `customContext` to override product information in the `productListItems` fields, `SKU` is needed to properly match which product to override. The one exception is the `productPageView` event where only one product should be used and `SKU` is not needed for matching. + + ### 🔧 Usage ```javascript From 9cfe7130982b619b4ffb66a0deba10a363dfd5f1 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 10:48:20 -0500 Subject: [PATCH 07/10] Update custom context doc --- examples/events/custom-event-override.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/events/custom-event-override.md b/examples/events/custom-event-override.md index 3f45ed68..ea0f6135 100644 --- a/examples/events/custom-event-override.md +++ b/examples/events/custom-event-override.md @@ -5,7 +5,7 @@ For any event with a set `customContext`, the collector overrides joins fields s Event overrides are only applicable when forwarding to AEP. They are not applied to Adobe Commerce and Sensei analytics events. Additional info in [README](../../packages/storefront-events-collector/README.md) > [!NOTE] -> When using `customContext` to override product information in the `productListItems` fields, `SKU` is needed to properly match which product to override. The one exception is the `productPageView` event where only one product should be used and `SKU` is not needed for matching. +> When augmenting `productListItems` with custom attributes in AEP event payloads, match products using SKU. This requirement does not apply to `product-page-view`events. ### 🔧 Usage From cf71ebeafb4eb8834484ad022d140bb968a0e090 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 10:49:13 -0500 Subject: [PATCH 08/10] Fix doc spacing --- examples/events/custom-event-override.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/events/custom-event-override.md b/examples/events/custom-event-override.md index ea0f6135..6e8664af 100644 --- a/examples/events/custom-event-override.md +++ b/examples/events/custom-event-override.md @@ -5,7 +5,7 @@ For any event with a set `customContext`, the collector overrides joins fields s Event overrides are only applicable when forwarding to AEP. They are not applied to Adobe Commerce and Sensei analytics events. Additional info in [README](../../packages/storefront-events-collector/README.md) > [!NOTE] -> When augmenting `productListItems` with custom attributes in AEP event payloads, match products using SKU. This requirement does not apply to `product-page-view`events. +> When augmenting `productListItems` with custom attributes in AEP event payloads, match products using SKU. This requirement does not apply to `product-page-view` events. ### 🔧 Usage From 107bbb9b5b39f2c9703aea95481e116b8efc96c9 Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 10:51:41 -0500 Subject: [PATCH 09/10] lint fix --- .../tests/handlers/shoppingCart/shoppingCartViewAep.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts index 17d87b68..80c7f386 100644 --- a/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts +++ b/packages/storefront-events-collector/tests/handlers/shoppingCart/shoppingCartViewAep.test.ts @@ -76,11 +76,11 @@ test("correctly structures AEP event with customContext and calls alloy.sendEven ], }; const mockedAEPevent = { - event: 'shopping-cart-view', + event: "shopping-cart-view", eventInfo: { ...AEPevent.eventInfo, customContext, - } + }, } as Event; shoppingCartViewHandlerAEP(mockedAEPevent); From e34bcfc0deca8d5ac1f9310fc1ee4c1becf4ffbb Mon Sep 17 00:00:00 2001 From: Benjamin Kalk Date: Thu, 11 Sep 2025 11:03:48 -0500 Subject: [PATCH 10/10] Fix typo --- examples/events/custom-event-override.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/events/custom-event-override.md b/examples/events/custom-event-override.md index 6e8664af..88439871 100644 --- a/examples/events/custom-event-override.md +++ b/examples/events/custom-event-override.md @@ -1,6 +1,6 @@ ## event overrides -For any event with a set `customContext`, the collector overrides joins fields set in the relevant contexts with fields in `customContext`. The use case for overrides is when a developer wants to reuse and extend contexts set by other parts of the page in already supporte events. +For any event with a set `customContext`, the collector overrides joins fields set in the relevant contexts with fields in `customContext`. The use case for overrides is when a developer wants to reuse and extend contexts set by other parts of the page in already supported events. Event overrides are only applicable when forwarding to AEP. They are not applied to Adobe Commerce and Sensei analytics events. Additional info in [README](../../packages/storefront-events-collector/README.md)