From b2c62e7d801c3edfc6deeaa31e64114e7dfda751 Mon Sep 17 00:00:00 2001 From: hardikmashru Date: Wed, 19 Jun 2024 17:58:41 +0530 Subject: [PATCH 1/3] Fixed single item matches code --- react-example/src/views/AUTTesting.tsx | 7 +- .../criteriaCompletionChecker.ts | 132 ++++++++++-------- 2 files changed, 80 insertions(+), 59 deletions(-) diff --git a/react-example/src/views/AUTTesting.tsx b/react-example/src/views/AUTTesting.tsx index 8135b584..02151417 100644 --- a/react-example/src/views/AUTTesting.tsx +++ b/react-example/src/views/AUTTesting.tsx @@ -30,7 +30,7 @@ export const AUTTesting: FC = () => { ); const [cartItem, setCartItem] = useState( - '{"items":[{"name":"piano","id":"fdsafds","price":100,"quantity":2}]}' + '{"items":[{"name":"piano","id":"fdsafds","price":100,"quantity":2}, {"name":"piano2","id":"fdsafds2","price":100,"quantity":5}]}' ); const [purchaseItem, setPurchaseItem] = useState( @@ -59,7 +59,6 @@ export const AUTTesting: FC = () => { const handleParseJson = (isUpdateCartCalled: boolean) => { try { // Parse JSON and assert its type - // {"items":[{"name":"piano","id":"fdsafds","price":100,"quantity":2}]} if (isUpdateCartCalled) { const parsedObject = JSON.parse(cartItem) as UpdateCartRequestParams; return parsedObject; @@ -109,11 +108,11 @@ export const AUTTesting: FC = () => { const handleTrackPurchase = (e: FormEvent) => { e.preventDefault(); - const jsonObj = handleParseJson(false); + const jsonObj: TrackPurchaseRequestParams = handleParseJson(false); if (jsonObj) { setTrackingPurchase(true); try { - trackPurchase({ ...jsonObj, total: 20 }) + trackPurchase(jsonObj) .then((response: any) => { setTrackingPurchase(false); setTrackPurchaseResponse(JSON.stringify(response.data)); diff --git a/src/anonymousUserTracking/criteriaCompletionChecker.ts b/src/anonymousUserTracking/criteriaCompletionChecker.ts index 3e2a6aaa..6875f8cb 100644 --- a/src/anonymousUserTracking/criteriaCompletionChecker.ts +++ b/src/anonymousUserTracking/criteriaCompletionChecker.ts @@ -234,8 +234,12 @@ class CriteriaCompletionChecker { return false; } } else if (node.searchCombo) { - const vv = this.evaluateSearchQueries(node, localEventData, criteriaId); - return vv; + const result = this.evaluateSearchQueries( + node, + localEventData, + criteriaId + ); + return result; } } catch (e) { this.handleException(e); @@ -290,8 +294,12 @@ class CriteriaCompletionChecker { nodeCombo: { searchCombo: object; count: number }[]; }) => item.criteriaId === criteriaId ); - - if (this.evaluateEvent(eventData, searchQueries, combinator)) { + const result = this.evaluateEvent( + eventData, + searchQueries, + combinator + ); + if (result) { if (Object.prototype.hasOwnProperty.call(node, 'minMatch')) { const matchedNode = matchedCriteria && @@ -353,7 +361,11 @@ class CriteriaCompletionChecker { SHARED_PREF_MATCHED_CRITERIAS, JSON.stringify(tempMatchedCriterias) ); - return false; + if (node.minMatch === 1) { + return true; + } else { + return false; + } } } else { return true; @@ -371,73 +383,83 @@ class CriteriaCompletionChecker { combinator: string ): boolean { if (combinator === 'And') { - for (let i = 0; i < searchQueries.length; i++) { - if (!this.evaluateFieldLogic(searchQueries[i], localEvent)) { - return false; - } + if (!this.evaluateFieldLogic(searchQueries, localEvent)) { + return false; } return true; } else if (combinator === 'Or') { - for (let i = 0; i < searchQueries.length; i++) { - if (this.evaluateFieldLogic(searchQueries[i], localEvent)) { - return true; - } + if (this.evaluateFieldLogic(searchQueries, localEvent)) { + return true; } return false; } return false; } - private evaluateFieldLogic(node: any, eventData: any): boolean { - const field = node.field; - const comparatorType = node.comparatorType ? node.comparatorType : ''; + private evaluateFieldLogic(searchQueries: any[], eventData: any): boolean { const localDataKeys = Object.keys(eventData); - let shouldReturn = false; - for (let j = 0; j < localDataKeys.length; j++) { - const key = localDataKeys[j]; - if (key === KEY_ITEMS) { - // scenario of items inside purchase and updateCart Events - const items = eventData[key]; - items.forEach((item: any) => { - const keys = Object.keys(item); - keys.forEach((keyItem: any) => { - if (field === keyItem) { - const matchedCountObj = item[keyItem]; - if ( - this.evaluateComparison( - comparatorType, - matchedCountObj, - node.value ? node.value : '' - ) - ) { - shouldReturn = true; - return; - } - } - }); - if (shouldReturn) return; // Exit outer forEach loop - }); - if (shouldReturn) break; // Exit main for loop - } else { + let combinedResult = false; + if (localDataKeys.includes(KEY_ITEMS)) { + // scenario of items inside purchase and updateCart Events + const items = eventData[KEY_ITEMS]; + const result = items.some((item: any) => { + return this.doesItemMatchQueries(item, searchQueries); + }); + if (!result) { + return result; + } + combinedResult = result; + } + const filteredLocalDataKeys = localDataKeys.filter( + (item: any) => item !== KEY_ITEMS + ); + const filteredSearchQueries = searchQueries.filter((searchQuery) => + filteredLocalDataKeys.includes(searchQuery.field) + ); + if (filteredSearchQueries.length === 0) { + return combinedResult; + } + for (let index = 0; index < filteredLocalDataKeys.length; index++) { + const key = filteredLocalDataKeys[index]; + const result = filteredSearchQueries.some((query: any) => { + const field = query.field; + if (field === key) { - const matchedCountObj = eventData[key]; - if ( - this.evaluateComparison( - comparatorType, - matchedCountObj, - node.value ? node.value : '' - ) - ) { - return true; + if (Object.prototype.hasOwnProperty.call(eventData, field)) { + const result = this.evaluateComparison( + query.comparatorType, + eventData[field], + query.value ? query.value : '' + ); + return result; } } + }); + if (result) { + return result; } } + return false; + } - if (shouldReturn) { - return true; + private doesItemMatchQueries(item: any, searchQueries: any[]): boolean { + const filteredSearchQueries = searchQueries.filter((searchQuery) => + Object.keys(item).includes(searchQuery.field) + ); + if (filteredSearchQueries.length === 0) { + return false; } - return false; + return filteredSearchQueries.every((query: any) => { + const field = query.field; + if (Object.prototype.hasOwnProperty.call(item, field)) { + return this.evaluateComparison( + query.comparatorType, + item[field], + query.value ? query.value : '' + ); + } + return false; + }); } private evaluateComparison( From 2effb954bedae05b3f173f394dcbc88ccd6c1078 Mon Sep 17 00:00:00 2001 From: hardikmashru Date: Wed, 19 Jun 2024 18:36:28 +0530 Subject: [PATCH 2/3] Fixed comments --- .../criteriaCompletionChecker.ts | 41 +++++-------------- 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/anonymousUserTracking/criteriaCompletionChecker.ts b/src/anonymousUserTracking/criteriaCompletionChecker.ts index 6875f8cb..bf588f48 100644 --- a/src/anonymousUserTracking/criteriaCompletionChecker.ts +++ b/src/anonymousUserTracking/criteriaCompletionChecker.ts @@ -234,12 +234,7 @@ class CriteriaCompletionChecker { return false; } } else if (node.searchCombo) { - const result = this.evaluateSearchQueries( - node, - localEventData, - criteriaId - ); - return result; + return this.evaluateSearchQueries(node, localEventData, criteriaId); } } catch (e) { this.handleException(e); @@ -294,12 +289,7 @@ class CriteriaCompletionChecker { nodeCombo: { searchCombo: object; count: number }[]; }) => item.criteriaId === criteriaId ); - const result = this.evaluateEvent( - eventData, - searchQueries, - combinator - ); - if (result) { + if (this.evaluateEvent(eventData, searchQueries, combinator)) { if (Object.prototype.hasOwnProperty.call(node, 'minMatch')) { const matchedNode = matchedCriteria && @@ -338,11 +328,7 @@ class CriteriaCompletionChecker { JSON.stringify(this.localStoredEventList) ); - if (matchedNode[0].count === node.minMatch) { - return true; - } else { - return false; - } + return matchedNode[0].count === node.minMatch; } else { const tempMatchedCriterias = matchedCriterias || []; tempMatchedCriterias.push({ @@ -361,11 +347,7 @@ class CriteriaCompletionChecker { SHARED_PREF_MATCHED_CRITERIAS, JSON.stringify(tempMatchedCriterias) ); - if (node.minMatch === 1) { - return true; - } else { - return false; - } + return node.minMatch === 1; } } else { return true; @@ -398,7 +380,7 @@ class CriteriaCompletionChecker { private evaluateFieldLogic(searchQueries: any[], eventData: any): boolean { const localDataKeys = Object.keys(eventData); - let combinedResult = false; + let itemMatchedResult = false; if (localDataKeys.includes(KEY_ITEMS)) { // scenario of items inside purchase and updateCart Events const items = eventData[KEY_ITEMS]; @@ -408,7 +390,7 @@ class CriteriaCompletionChecker { if (!result) { return result; } - combinedResult = result; + itemMatchedResult = result; } const filteredLocalDataKeys = localDataKeys.filter( (item: any) => item !== KEY_ITEMS @@ -417,26 +399,25 @@ class CriteriaCompletionChecker { filteredLocalDataKeys.includes(searchQuery.field) ); if (filteredSearchQueries.length === 0) { - return combinedResult; + return itemMatchedResult; } for (let index = 0; index < filteredLocalDataKeys.length; index++) { const key = filteredLocalDataKeys[index]; - const result = filteredSearchQueries.some((query: any) => { + const filteredResult = filteredSearchQueries.some((query: any) => { const field = query.field; if (field === key) { if (Object.prototype.hasOwnProperty.call(eventData, field)) { - const result = this.evaluateComparison( + return this.evaluateComparison( query.comparatorType, eventData[field], query.value ? query.value : '' ); - return result; } } }); - if (result) { - return result; + if (filteredResult) { + return filteredResult; } } return false; From 3bcb00391e5219de3a6c11eb073674532034aa3e Mon Sep 17 00:00:00 2001 From: Hardik Mashru Date: Mon, 24 Jun 2024 17:19:44 +0530 Subject: [PATCH 3/3] added more unit tests, bug fixes --- .../criteriaCompletionChecker.test.ts | 329 +++++++++++++++++- .../criteriaCompletionChecker.ts | 73 ++-- src/constants.ts | 3 + 3 files changed, 365 insertions(+), 40 deletions(-) diff --git a/src/anonymousUserTracking/criteriaCompletionChecker.test.ts b/src/anonymousUserTracking/criteriaCompletionChecker.test.ts index ff18bb84..70b5d460 100644 --- a/src/anonymousUserTracking/criteriaCompletionChecker.test.ts +++ b/src/anonymousUserTracking/criteriaCompletionChecker.test.ts @@ -31,14 +31,14 @@ describe('CriteriaCompletionChecker', () => { expect(result).toBeNull(); }); - it('should return criteriaId if criteriaData condition is matched', () => { + it('should return criteriaId if customEvent is matched', () => { (localStorage.getItem as jest.Mock).mockImplementation((key) => { if (key === SHARED_PREFS_EVENT_LIST_KEY) { return JSON.stringify([ { eventName: 'testEvent', createdAt: 1708494757530, - dataFields: undefined, + dataFields: { 'browserVisit.website.domain': 'google.com' }, createNewFields: true, eventType: 'customEvent' } @@ -80,6 +80,13 @@ describe('CriteriaCompletionChecker', () => { comparatorType: 'Equals', value: 'testEvent', fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'browserVisit.website.domain', + comparatorType: 'Equals', + value: 'google.com', + fieldType: 'string' } ] } @@ -95,14 +102,14 @@ describe('CriteriaCompletionChecker', () => { expect(result).toEqual('6'); }); - it('should return null if criteriaData condition is matched', () => { + it('should return criteriaId if customEvent is matched when minMatch present', () => { (localStorage.getItem as jest.Mock).mockImplementation((key) => { if (key === SHARED_PREFS_EVENT_LIST_KEY) { return JSON.stringify([ { - eventName: 'Event', + eventName: 'testEvent', createdAt: 1708494757530, - dataFields: undefined, + dataFields: { 'browserVisit.website.domain': 'google.com' }, createNewFields: true, eventType: 'customEvent' } @@ -134,7 +141,9 @@ describe('CriteriaCompletionChecker', () => { combinator: 'Or', searchQueries: [ { - dataType: 'purchase', + dataType: 'customEvent', + minMatch: 1, + maxMatch: 2, searchCombo: { combinator: 'And', searchQueries: [ @@ -144,6 +153,243 @@ describe('CriteriaCompletionChecker', () => { comparatorType: 'Equals', value: 'testEvent', fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'browserVisit.website.domain', + comparatorType: 'Equals', + value: 'google.com', + fieldType: 'string' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('6'); + }); + + it('should return criteriaId if purchase event is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + createdAt: 1708494757530, + items: [ + { name: 'keyboard', id: 'fdsafds', price: 10, quantity: 2 } + ], + total: 10, + eventType: 'purchase' + } + ]); + } + return null; + }); + + const localStoredEventList = localStorage.getItem( + SHARED_PREFS_EVENT_LIST_KEY + ); + + const checker = new CriteriaCompletionChecker( + localStoredEventList === null ? '' : localStoredEventList + ); + const result = checker.getMatchedCriteria( + JSON.stringify({ + count: 1, + criterias: [ + { + criteriaId: '6', + name: 'EventCriteria', + createdAt: 1704754280210, + updatedAt: 1704754280210, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'keyboard', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '10', + fieldType: 'double' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('6'); + }); + + it('should return null if updateCart event with all props in item is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + createdAt: 1708494757530, + items: [ + { name: 'keyboard', id: 'fdsafds', price: 10, quantity: 2 }, + { name: 'Cofee', id: 'fdsafds', price: 10, quantity: 2 } + ], + eventType: 'cartUpdate' + } + ]); + } + return null; + }); + + const localStoredEventList = localStorage.getItem( + SHARED_PREFS_EVENT_LIST_KEY + ); + + const checker = new CriteriaCompletionChecker( + localStoredEventList === null ? '' : localStoredEventList + ); + const result = checker.getMatchedCriteria( + JSON.stringify({ + count: 1, + criterias: [ + { + criteriaId: '6', + name: 'EventCriteria', + createdAt: 1704754280210, + updatedAt: 1704754280210, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'eventName', + comparatorType: 'Equals', + value: 'updateCart', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.name', + comparatorType: 'Equals', + value: 'keyboard', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '10', + fieldType: 'double' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('6'); + }); + + it('should return null if updateCart event with items is NOT matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + createdAt: 1708494757530, + items: [ + { name: 'keyboard', id: 'fdsafds', price: 9, quantity: 2 }, + { name: 'Cofee', id: 'fdsafds', price: 10, quantity: 2 } + ], + eventType: 'cartUpdate' + } + ]); + } + return null; + }); + + const localStoredEventList = localStorage.getItem( + SHARED_PREFS_EVENT_LIST_KEY + ); + + const checker = new CriteriaCompletionChecker( + localStoredEventList === null ? '' : localStoredEventList + ); + const result = checker.getMatchedCriteria( + JSON.stringify({ + count: 1, + criterias: [ + { + criteriaId: '6', + name: 'EventCriteria', + createdAt: 1704754280210, + updatedAt: 1704754280210, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'eventName', + comparatorType: 'Equals', + value: 'updateCart', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.name', + comparatorType: 'Equals', + value: 'keyboard', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '10', + fieldType: 'double' } ] } @@ -159,6 +405,77 @@ describe('CriteriaCompletionChecker', () => { expect(result).toBeNull(); }); + it('should return criteriaId if updateCart event is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + createdAt: 1708494757530, + items: [ + { name: 'keyboard', id: 'fdsafds', price: 10, quantity: 2 } + ], + eventType: 'cartUpdate' + } + ]); + } + return null; + }); + + const localStoredEventList = localStorage.getItem( + SHARED_PREFS_EVENT_LIST_KEY + ); + + const checker = new CriteriaCompletionChecker( + localStoredEventList === null ? '' : localStoredEventList + ); + const result = checker.getMatchedCriteria( + JSON.stringify({ + count: 1, + criterias: [ + { + criteriaId: '6', + name: 'EventCriteria', + createdAt: 1704754280210, + updatedAt: 1704754280210, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'eventName', + comparatorType: 'Equals', + value: 'updateCart', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '10', + fieldType: 'double' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('6'); + }); + it('should return criteriaId if criteriaData condition with numeric is matched', () => { (localStorage.getItem as jest.Mock).mockImplementation((key) => { if (key === SHARED_PREFS_EVENT_LIST_KEY) { diff --git a/src/anonymousUserTracking/criteriaCompletionChecker.ts b/src/anonymousUserTracking/criteriaCompletionChecker.ts index bf588f48..5eed0f4c 100644 --- a/src/anonymousUserTracking/criteriaCompletionChecker.ts +++ b/src/anonymousUserTracking/criteriaCompletionChecker.ts @@ -7,6 +7,8 @@ import { UPDATE_CART, UPDATE_USER, KEY_EVENT_NAME, + UPDATECART_ITEM_PREFIX, + PURCHASE_ITEM_PREFIX, SHARED_PREFS_EVENT_LIST_KEY, SHARED_PREF_MATCHED_CRITERIAS } from '../constants'; @@ -110,7 +112,7 @@ class CriteriaCompletionChecker { items = items.map((item: any) => { const updatItem: any = {}; Object.keys(item).forEach((key) => { - updatItem[`shoppingCartItems.${key}`] = item[key]; + updatItem[`${PURCHASE_ITEM_PREFIX}${key}`] = item[key]; }); return updatItem; }); @@ -143,8 +145,7 @@ class CriteriaCompletionChecker { items = items.map((item: any) => { const updatItem: any = {}; Object.keys(item).forEach((key) => { - updatItem[`updateCart.updatedShoppingCartItems.${key}`] = - item[key]; + updatItem[`${UPDATECART_ITEM_PREFIX}${key}`] = item[key]; }); return updatItem; }); @@ -155,6 +156,7 @@ class CriteriaCompletionChecker { Object.keys(localEventData.dataFields).forEach((key) => { updatedItem[key] = localEventData.dataFields[key]; }); + delete localEventData.dataFields; } Object.keys(localEventData).forEach((key) => { if (key !== KEY_ITEMS && key !== 'dataFields') { @@ -198,6 +200,7 @@ class CriteriaCompletionChecker { Object.keys(localEventData.dataFields).forEach((key) => { updatedItem[key] = localEventData.dataFields[key]; }); + delete localEventData.dataFields; } nonPurchaseEvents.push(updatedItem); } @@ -257,13 +260,6 @@ class CriteriaCompletionChecker { const searchCombo = node.searchCombo; const searchQueries = searchCombo?.searchQueries || []; const combinator = searchCombo?.combinator || ''; - // matchedCriterias format - // [ - // { - // criteriaId: '6', - // nodeCombo: [{searchCombo: {}, count: 1}], - // }, - // ]; const matchedCriteriasFromLocalStorage = localStorage.getItem( SHARED_PREF_MATCHED_CRITERIAS ); @@ -378,6 +374,15 @@ class CriteriaCompletionChecker { return false; } + private doesItemCriteriaExists(searchQueries: any[]): boolean { + const foundIndex = searchQueries.findIndex( + (item) => + item.field.startsWith(UPDATECART_ITEM_PREFIX) || + item.field.startsWith(PURCHASE_ITEM_PREFIX) + ); + return foundIndex !== -1; + } + private evaluateFieldLogic(searchQueries: any[], eventData: any): boolean { const localDataKeys = Object.keys(eventData); let itemMatchedResult = false; @@ -387,7 +392,8 @@ class CriteriaCompletionChecker { const result = items.some((item: any) => { return this.doesItemMatchQueries(item, searchQueries); }); - if (!result) { + if (!result && this.doesItemCriteriaExists(searchQueries)) { + // items criteria existed and it did not match return result; } itemMatchedResult = result; @@ -395,32 +401,31 @@ class CriteriaCompletionChecker { const filteredLocalDataKeys = localDataKeys.filter( (item: any) => item !== KEY_ITEMS ); - const filteredSearchQueries = searchQueries.filter((searchQuery) => - filteredLocalDataKeys.includes(searchQuery.field) - ); - if (filteredSearchQueries.length === 0) { + + if (filteredLocalDataKeys.length === 0) { return itemMatchedResult; } - for (let index = 0; index < filteredLocalDataKeys.length; index++) { - const key = filteredLocalDataKeys[index]; - const filteredResult = filteredSearchQueries.some((query: any) => { - const field = query.field; - - if (field === key) { - if (Object.prototype.hasOwnProperty.call(eventData, field)) { - return this.evaluateComparison( - query.comparatorType, - eventData[field], - query.value ? query.value : '' - ); - } - } - }); - if (filteredResult) { - return filteredResult; + + const filteredSearchQueries = searchQueries.filter( + (searchQuery) => + !searchQuery.field.startsWith(UPDATECART_ITEM_PREFIX) && + !searchQuery.field.startsWith(PURCHASE_ITEM_PREFIX) + ); + const matchResult = filteredSearchQueries.every((query: any) => { + const field = query.field; + const eventKeyItems = filteredLocalDataKeys.filter( + (keyItem) => keyItem === field + ); + if (eventKeyItems.length) { + return this.evaluateComparison( + query.comparatorType, + eventData[field], + query.value ? query.value : '' + ); } - } - return false; + return false; + }); + return matchResult; } private doesItemMatchQueries(item: any, searchQueries: any[]): boolean { diff --git a/src/constants.ts b/src/constants.ts index 8c695ed9..07d2c234 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -302,6 +302,9 @@ export const UPDATE_USER = 'user'; export const TRACK_UPDATE_CART = 'cartUpdate'; export const UPDATE_CART = 'updateCart'; +export const UPDATECART_ITEM_PREFIX = 'updateCart.updatedShoppingCartItems.'; +export const PURCHASE_ITEM_PREFIX = 'shoppingCartItems.'; + export const MERGE_SUCCESSFULL = 'MERGE_SUCCESSFULL'; export const INITIALIZE_ERROR = 'Iterable SDK must be initialized with an API key and user email/userId before calling SDK methods';