From 06c55d9ea933c2234a2535d08a9e618b3be021a9 Mon Sep 17 00:00:00 2001 From: hardikmashru <150107929+hardikmashru@users.noreply.github.com> Date: Fri, 12 Jul 2024 21:43:46 +0530 Subject: [PATCH] Isset purchase update fix (#416) * Fixed single item matches code * Fixed comments * added more unit tests, bug fixes * Not combinator implemented * evaluateEvent added not combinator * minMatch changes revert * minMatch implemented * complex criteria tests, not combinator, evaluateFieldLogic fix * Isset fix and unit tests * update cart and custom event fix, unit tests * little changes * doesItemMatchQueries fix * isset fail & min-max tests, * Replace for loop with array methods * added sampleTest1 * Set type annotations for issetCheck --------- Co-authored-by: hardikmashru --- .../criteriaCompletionChecker.ts | 58 +- .../tests/complexCriteria.test.ts | 1599 +++++++++++++++++ .../tests/criteriaCompletionChecker.test.ts | 723 ++++++++ src/constants.ts | 3 +- 4 files changed, 2374 insertions(+), 9 deletions(-) create mode 100644 src/anonymousUserTracking/tests/complexCriteria.test.ts diff --git a/src/anonymousUserTracking/criteriaCompletionChecker.ts b/src/anonymousUserTracking/criteriaCompletionChecker.ts index 11f18401..9b70a283 100644 --- a/src/anonymousUserTracking/criteriaCompletionChecker.ts +++ b/src/anonymousUserTracking/criteriaCompletionChecker.ts @@ -8,7 +8,8 @@ import { UPDATE_USER, KEY_EVENT_NAME, UPDATECART_ITEM_PREFIX, - PURCHASE_ITEM_PREFIX + PURCHASE_ITEM_PREFIX, + PURCHASE_ITEM } from '../constants'; interface SearchQuery { @@ -99,7 +100,7 @@ class CriteriaCompletionChecker { }); return updatItem; }); - updatedItem[KEY_ITEMS] = items; + updatedItem[PURCHASE_ITEM] = items; } if (localEventData.dataFields) { @@ -277,9 +278,16 @@ class CriteriaCompletionChecker { private evaluateFieldLogic(searchQueries: any[], eventData: any): boolean { const localDataKeys = Object.keys(eventData); let itemMatchedResult = false; + let key_item = null; if (localDataKeys.includes(KEY_ITEMS)) { + key_item = KEY_ITEMS; + } else if (localDataKeys.includes(PURCHASE_ITEM)) { + key_item = PURCHASE_ITEM; + } + + if (key_item !== null) { // scenario of items inside purchase and updateCart Events - const items = eventData[KEY_ITEMS]; + const items = eventData[key_item]; const result = items.some((item: any) => { return this.doesItemMatchQueries(item, searchQueries); }); @@ -307,6 +315,19 @@ class CriteriaCompletionChecker { } const matchResult = filteredSearchQueries.every((query: any) => { const field = query.field; + if ( + query.dataType === TRACK_EVENT && + query.fieldType === 'object' && + query.comparatorType === 'IsSet' + ) { + const eventName = eventData[KEY_EVENT_NAME]; + if (eventName === UPDATE_CART && field === eventName) { + return true; + } + if (field === eventName) { + return true; + } + } const eventKeyItems = filteredLocalDataKeys.filter( (keyItem) => keyItem === field ); @@ -323,10 +344,21 @@ class CriteriaCompletionChecker { } private doesItemMatchQueries(item: any, searchQueries: any[]): boolean { - const filteredSearchQueries = searchQueries.filter((searchQuery) => - Object.keys(item).includes(searchQuery.field) - ); - if (filteredSearchQueries.length === 0) { + let shouldReturn = false; + const filteredSearchQueries = searchQueries.filter((searchQuery) => { + if ( + searchQuery.field.startsWith(UPDATECART_ITEM_PREFIX) || + searchQuery.field.startsWith(PURCHASE_ITEM_PREFIX) + ) { + if (!Object.keys(item).includes(searchQuery.field)) { + shouldReturn = true; + return false; + } + return true; + } + return false; + }); + if (filteredSearchQueries.length === 0 || shouldReturn) { return false; } return filteredSearchQueries.every((query: any) => { @@ -356,7 +388,7 @@ class CriteriaCompletionChecker { case 'DoesNotEquals': return !this.compareValueEquality(matchObj, valueToCompare); case 'IsSet': - return matchObj !== ''; + return this.issetCheck(matchObj); case 'GreaterThan': case 'LessThan': case 'GreaterThanOrEqualTo': @@ -439,6 +471,16 @@ class CriteriaCompletionChecker { } } + private issetCheck(matchObj: string | object | any[]): boolean { + if (Array.isArray(matchObj)) { + return matchObj.length > 0; + } else if (typeof matchObj === 'object' && matchObj !== null) { + return Object.keys(matchObj).length > 0; + } else { + return matchObj !== ''; + } + } + private handleException(e: any) { console.error('Exception occurred', e.toString()); } diff --git a/src/anonymousUserTracking/tests/complexCriteria.test.ts b/src/anonymousUserTracking/tests/complexCriteria.test.ts new file mode 100644 index 00000000..ed7c6876 --- /dev/null +++ b/src/anonymousUserTracking/tests/complexCriteria.test.ts @@ -0,0 +1,1599 @@ +import { SHARED_PREFS_EVENT_LIST_KEY } from '../../constants'; +import CriteriaCompletionChecker from '../criteriaCompletionChecker'; + +const localStorageMock = { + getItem: jest.fn(), + setItem: jest.fn(), + removeItem: jest.fn() +}; + +describe('complexCriteria', () => { + beforeEach(() => { + (global as any).localStorage = localStorageMock; + }); + + // complex criteria + it('should return criteriaId 98 (complex criteria 1)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { + id: '12', + name: 'monitor', + price: 50, + quantity: 10 + } + ], + total: 50, + eventType: 'purchase' + }, + { + dataFields: { + preferred_car_models: 'Honda', + country: 'Japan' + }, + eventType: 'user' + } + ]); + } + 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: '98', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 23, + value: 'button.clicked' + }, + { + field: 'button-clicked.animal', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 25, + value: 'giraffe' + } + ] + } + }, + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 28, + value: '120' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 29, + valueLong: 100, + value: '100' + } + ] + } + } + ] + }, + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 31, + value: 'monitor' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 32, + valueLong: 5, + value: '5' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 34, + value: 'Japan' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 36, + value: 'Honda' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('98'); + }); + + it('should return null (complex criteria 1 fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { + id: '12', + name: 'monitor', + price: 50, + quantity: 10 + } + ], + total: 50, + eventType: 'purchase' + }, + { + dataFields: { + preferred_car_models: 'Honda' + }, + eventType: 'user' + } + ]); + } + 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: '98', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'Or', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 23, + value: 'button.clicked' + }, + { + field: 'button-clicked.animal', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 25, + value: 'giraffe' + } + ] + } + }, + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 28, + value: '120' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 29, + valueLong: 100, + value: '100' + } + ] + } + } + ] + }, + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 31, + value: 'monitor' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 32, + valueLong: 5, + value: '5' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 34, + value: 'Japan' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 36, + value: 'Honda' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 99 (complex criteria 2)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + { + dataFields: { + preferred_car_models: 'Subaru', + country: 'USA' + }, + eventType: 'user' + } + ]); + } + 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: '99', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 2, + value: 'button-clicked' + }, + { + field: 'button-clicked.lastPageViewed', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 4, + value: 'welcome page' + } + ] + } + }, + { + dataType: 'customEvent', + minMatch: 2, + maxMatch: 3, + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 6, + value: '85' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 7, + valueLong: 50, + value: '50' + } + ] + } + } + ] + }, + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 16, + isFiltering: false, + value: 'coffee' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 17, + valueLong: 2, + value: '2' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 19, + value: 'USA' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 21, + value: 'Subaru' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('99'); + }); + + it('should return null (complex criteria 2 fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + { + dataFields: { + preferred_car_models: 'Subaru', + country: 'USA' + }, + eventType: 'user' + } + ]); + } + 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: '99', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 2, + value: 'button-clicked' + }, + { + field: 'button-clicked.lastPageViewed', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 4, + value: 'welcome page' + } + ] + } + }, + { + dataType: 'customEvent', + minMatch: 2, + maxMatch: 3, + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 6, + value: '85' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 7, + valueLong: 50, + value: '50' + } + ] + } + } + ] + }, + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 16, + isFiltering: false, + value: 'coffee' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 17, + valueLong: 2, + value: '2' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 19, + value: 'USA' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 21, + value: 'Subaru' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 100 (complex criteria 3)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + + { + dataFields: { + preferred_car_models: 'Subaru', + country: 'USA' + }, + eventType: 'user' + }, + { + eventName: 'button-clicked', + dataFields: { + 'button-clicked.lastPageViewed': 'welcome page' + }, + eventType: 'customEvent' + }, + { + items: [ + { + id: '12', + name: 'coffee', + price: 10, + quantity: 5 + } + ], + total: 2, + 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: '100', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 2, + value: 'button-clicked' + }, + { + field: 'button-clicked.lastPageViewed', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 4, + value: 'welcome page' + } + ] + } + }, + { + dataType: 'customEvent', + minMatch: 2, + maxMatch: 3, + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 6, + value: '85' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 7, + valueLong: 50, + value: '50' + } + ] + } + }, + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 9, + value: 'coffee' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 10, + valueLong: 2, + value: '2' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 12, + value: 'USA' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 14, + value: 'Subaru' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('100'); + }); + + it('should return null (complex criteria 3 fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + { + items: [{ id: '12', name: 'Mocha', price: 90, quantity: 50 }], + total: 50, + eventType: 'cartUpdate' + }, + + { + dataFields: { + preferred_car_models: 'Subaru', + country: 'USA' + }, + eventType: 'user' + }, + { + eventName: 'button-clicked', + dataFields: { + 'button-clicked.lastPageViewed': 'welcome page' + }, + eventType: 'customEvent' + } + ]); + } + 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: '100', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'eventName', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 2, + value: 'button-clicked' + }, + { + field: 'button-clicked.lastPageViewed', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'customEvent', + id: 4, + value: 'welcome page' + } + ] + } + }, + { + dataType: 'customEvent', + minMatch: 2, + maxMatch: 3, + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'updateCart.updatedShoppingCartItems.price', + fieldType: 'double', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 6, + value: '85' + }, + { + field: + 'updateCart.updatedShoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'customEvent', + id: 7, + valueLong: 50, + value: '50' + } + ] + } + }, + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'purchase', + id: 9, + value: 'coffee' + }, + { + field: 'shoppingCartItems.quantity', + fieldType: 'long', + comparatorType: 'GreaterThanOrEqualTo', + dataType: 'purchase', + id: 10, + valueLong: 2, + value: '2' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'Equals', + dataType: 'user', + id: 12, + value: 'USA' + }, + { + field: 'preferred_car_models', + fieldType: 'string', + comparatorType: 'Contains', + dataType: 'user', + id: 14, + value: 'Subaru' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 101 (complex criteria 4)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { id: '12', name: 'sneakers', price: 10, quantity: 5 }, + { id: '13', name: 'slippers', price: 10, quantity: 3 } + ], + total: 2, + 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: '101', + name: 'Complex Criteria 4: (NOT 9) AND 10', + createdAt: 1719328083918, + updatedAt: 1719328083918, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Not', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'sneakers', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'LessThanOrEqualTo', + value: '3', + fieldType: 'long' + } + ] + } + } + ] + }, + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'slippers', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'GreaterThanOrEqualTo', + value: '3', + fieldType: 'long' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('101'); + }); + + it('should return null (complex criteria 4 fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { id: '12', name: 'sneakers', price: 10, quantity: 2 }, + { id: '13', name: 'slippers', price: 10, quantity: 3 } + ], + total: 2, + 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: '101', + name: 'Complex Criteria 4: (NOT 9) AND 10', + createdAt: 1719328083918, + updatedAt: 1719328083918, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Not', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'sneakers', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'LessThanOrEqualTo', + value: '3', + fieldType: 'long' + } + ] + } + } + ] + }, + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'slippers', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'GreaterThanOrEqualTo', + value: '3', + fieldType: 'long' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 134 (Min-Max 2)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 50, quantity: 50 }], + eventType: 'cartUpdate' + }, + { + items: [{ id: '12', name: 'Mocha', price: 50.0, quantity: 50 }], + eventType: 'cartUpdate' + }, + { + dataFields: { + preferred_car_models: 'Honda' + }, + eventType: 'user' + } + ]); + } + 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: '134', + name: 'Min-Max 2', + createdAt: 1719336370734, + updatedAt: 1719337067199, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'Equals', + value: '50.0', + fieldType: 'double' + } + ] + }, + minMatch: 2, + maxMatch: 3 + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'user', + field: 'preferred_car_models', + comparatorType: 'Equals', + value: 'Honda', + fieldType: 'string' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('134'); + }); + + it('should return criteriaId 151 (sampleTest1)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + dataFields: { + 'animal-found.type': 'cat', + 'animal-found.count': 4 + }, + eventType: 'customEvent' + }, + { + items: [{ id: '12', name: 'Caramel', price: 3, quantity: 5 }], + total: 2, + 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: '151', + name: 'test criteria', + createdAt: 1719336370734, + updatedAt: 1719337067199, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'animal-found.type', + comparatorType: 'Equals', + value: 'cat', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'animal-found.count', + comparatorType: 'LessThan', + value: '5', + fieldType: 'long' + } + ] + } + }, + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '500', + fieldType: 'double' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'LessThan', + value: '20', + fieldType: 'double' + } + ] + } + } + ] + }, + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'Caramel', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'GreaterThanOrEqualTo', + value: '2', + fieldType: 'long' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'user', + field: 'country', + comparatorType: 'Equals', + value: 'UK', + fieldType: 'string' + }, + { + dataType: 'user', + field: 'likes_boba', + comparatorType: 'Equals', + value: 'false', + fieldType: 'boolean' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('151'); + }); + + it('should return null (sampleTest1 fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + dataFields: { + 'animal-found.type': 'dog', + 'animal-found.count': 4 + }, + eventType: 'customEvent' + }, + { + items: [{ id: '12', name: 'Caramel', price: 3, quantity: 5 }], + total: 2, + 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: '151', + name: 'test criteria', + createdAt: 1719336370734, + updatedAt: 1719337067199, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'animal-found.type', + comparatorType: 'Equals', + value: 'cat', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'animal-found.count', + comparatorType: 'LessThan', + value: '5', + fieldType: 'long' + } + ] + } + }, + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'GreaterThanOrEqualTo', + value: '500', + fieldType: 'double' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'LessThan', + value: '20', + fieldType: 'double' + } + ] + } + } + ] + }, + { + combinator: 'Or', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + field: 'shoppingCartItems.name', + comparatorType: 'Equals', + value: 'Caramel', + fieldType: 'string' + }, + { + dataType: 'purchase', + field: 'shoppingCartItems.quantity', + comparatorType: 'GreaterThanOrEqualTo', + value: '2', + fieldType: 'long' + } + ] + } + }, + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'user', + field: 'country', + comparatorType: 'Equals', + value: 'UK', + fieldType: 'string' + }, + { + dataType: 'user', + field: 'likes_boba', + comparatorType: 'Equals', + value: 'false', + fieldType: 'boolean' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); +}); diff --git a/src/anonymousUserTracking/tests/criteriaCompletionChecker.test.ts b/src/anonymousUserTracking/tests/criteriaCompletionChecker.test.ts index f8e866ff..b0396563 100644 --- a/src/anonymousUserTracking/tests/criteriaCompletionChecker.test.ts +++ b/src/anonymousUserTracking/tests/criteriaCompletionChecker.test.ts @@ -722,4 +722,727 @@ describe('CriteriaCompletionChecker', () => { ); expect(result).toEqual('6'); }); + + // isSet criteria + it('should return criteriaId 97 if isset user criteria is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + dataFields: { + country: 'UK', + eventTimeStamp: 10, + phoneNumberDetails: '99999999', + 'shoppingCartItems.price': 50.5 + }, + eventType: 'user' + } + ]); + } + 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: '97', + name: 'User', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'user', + id: 25, + value: '' + }, + { + field: 'eventTimeStamp', + fieldType: 'long', + comparatorType: 'IsSet', + dataType: 'user', + id: 26, + valueLong: null, + value: '' + }, + { + field: 'phoneNumberDetails', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'user', + id: 28, + value: '' + }, + { + field: 'shoppingCartItems.price', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'user', + id: 30, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('97'); + }); + + it('should return null (isset user criteria fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + dataFields: { + eventTimeStamp: 10, + phoneNumberDetails: '99999999', + 'shoppingCartItems.price': 50.5 + }, + eventType: 'user' + } + ]); + } + 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: '97', + name: 'User', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'user', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'country', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'user', + id: 25, + value: '' + }, + { + field: 'eventTimeStamp', + fieldType: 'long', + comparatorType: 'IsSet', + dataType: 'user', + id: 26, + valueLong: null, + value: '' + }, + { + field: 'phoneNumberDetails', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'user', + id: 28, + value: '' + }, + { + field: 'shoppingCartItems.price', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'user', + id: 30, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 94 if isset customEvent criteria is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + eventName: 'button-clicked', + dataFields: { + 'button-clicked': 'signup page', + 'button-clicked.animal': 'test page', + 'button-clicked.clickCount': '2', + total: 3 + }, + createdAt: 1700071052507, + eventType: 'customEvent' + } + ]); + } + 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: '94', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'button-clicked', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 2, + value: '' + }, + { + field: 'button-clicked.animal', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 4, + value: '' + }, + { + field: 'button-clicked.clickCount', + fieldType: 'long', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 5, + valueLong: null, + value: '' + }, + { + field: 'total', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 9, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('94'); + }); + + it('should return null (isset customEvent criteria fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + eventName: 'button-clicked', + dataFields: { + 'button-clicked.animal': 'test page', + total: 3 + }, + createdAt: 1700071052507, + eventType: 'customEvent' + } + ]); + } + 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: '94', + name: 'Custom Event', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'button-clicked', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 2, + value: '' + }, + { + field: 'button-clicked.animal', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 4, + value: '' + }, + { + field: 'button-clicked.clickCount', + fieldType: 'long', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 5, + valueLong: null, + value: '' + }, + { + field: 'total', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'customEvent', + id: 9, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 96 if isset purchase criteria is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { + id: '12', + name: 'monitor', + price: 10, + quantity: 10 + } + ], + total: 50, + 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: '96', + name: 'Purchase', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 1, + value: '' + }, + { + field: 'shoppingCartItems.price', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 3, + value: '' + }, + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 5, + value: '' + }, + { + field: 'total', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 7, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('96'); + }); + + it('should return null (isset purchase criteria fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [ + { + id: '12', + name: 'monitor', + quantity: 10 + } + ], + total: 50, + 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: '96', + name: 'Purchase', + createdAt: 1716560453973, + updatedAt: 1716560453973, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'purchase', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + field: 'shoppingCartItems', + fieldType: 'object', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 1, + value: '' + }, + { + field: 'shoppingCartItems.price', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 3, + value: '' + }, + { + field: 'shoppingCartItems.name', + fieldType: 'string', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 5, + value: '' + }, + { + field: 'total', + fieldType: 'double', + comparatorType: 'IsSet', + dataType: 'purchase', + id: 7, + value: '' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); + + it('should return criteriaId 95 if isset updateCart criteria is matched', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', price: 50, quantity: 50 }], + 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: '95', + name: 'UpdateCart: isSet Comparator', + createdAt: 1719328291857, + updatedAt: 1719328291857, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'updateCart', + comparatorType: 'IsSet', + value: '', + fieldType: 'object' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.name', + comparatorType: 'IsSet', + value: '', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'IsSet', + value: '', + fieldType: 'double' + }, + { + dataType: 'customEvent', + field: + 'updateCart.updatedShoppingCartItems.quantity', + comparatorType: 'IsSet', + value: '', + fieldType: 'long' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual('95'); + }); + + it('should return null (isset updateCart criteria fail)', () => { + (localStorage.getItem as jest.Mock).mockImplementation((key) => { + if (key === SHARED_PREFS_EVENT_LIST_KEY) { + return JSON.stringify([ + { + items: [{ id: '12', name: 'Mocha', quantity: 50 }], + 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: '95', + name: 'UpdateCart: isSet Comparator', + createdAt: 1719328291857, + updatedAt: 1719328291857, + searchQuery: { + combinator: 'And', + searchQueries: [ + { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + searchCombo: { + combinator: 'And', + searchQueries: [ + { + dataType: 'customEvent', + field: 'updateCart', + comparatorType: 'IsSet', + value: '', + fieldType: 'object' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.name', + comparatorType: 'IsSet', + value: '', + fieldType: 'string' + }, + { + dataType: 'customEvent', + field: 'updateCart.updatedShoppingCartItems.price', + comparatorType: 'IsSet', + value: '', + fieldType: 'double' + }, + { + dataType: 'customEvent', + field: + 'updateCart.updatedShoppingCartItems.quantity', + comparatorType: 'IsSet', + value: '', + fieldType: 'long' + } + ] + } + } + ] + } + ] + } + } + ] + }) + ); + expect(result).toEqual(null); + }); }); diff --git a/src/constants.ts b/src/constants.ts index 18823f5d..38c59eca 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -299,8 +299,9 @@ export const UPDATE_USER = 'user'; export const TRACK_UPDATE_CART = 'cartUpdate'; export const UPDATE_CART = 'updateCart'; +export const PURCHASE_ITEM = 'shoppingCartItems'; export const UPDATECART_ITEM_PREFIX = 'updateCart.updatedShoppingCartItems.'; -export const PURCHASE_ITEM_PREFIX = 'shoppingCartItems.'; +export const PURCHASE_ITEM_PREFIX = PURCHASE_ITEM + '.'; export const MERGE_SUCCESSFULL = 'MERGE_SUCCESSFULL'; export const INITIALIZE_ERROR =