From 7e1cc04589cbeafb5849f0f40b1ae533fe778d8a Mon Sep 17 00:00:00 2001 From: Puneet Dewan Date: Thu, 20 Jul 2023 12:38:24 -0400 Subject: [PATCH] default to no array unrolling (#1362) --- .../src/trackEvent/__tests__/index.test.ts | 30 ++++++++- .../destinations/heap/src/trackEvent/index.ts | 64 ++++++++++++------- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/packages/browser-destinations/destinations/heap/src/trackEvent/__tests__/index.test.ts b/packages/browser-destinations/destinations/heap/src/trackEvent/__tests__/index.test.ts index 267fee871e..f680a5c2d9 100644 --- a/packages/browser-destinations/destinations/heap/src/trackEvent/__tests__/index.test.ts +++ b/packages/browser-destinations/destinations/heap/src/trackEvent/__tests__/index.test.ts @@ -9,6 +9,7 @@ import { import { HEAP_SEGMENT_BROWSER_LIBRARY_NAME } from '../../constants' describe('#trackEvent', () => { + let eventWithUnrolling: Plugin let event: Plugin let heapTrackSpy: jest.SpyInstance let addUserPropertiesSpy: jest.SpyInstance @@ -18,11 +19,14 @@ describe('#trackEvent', () => { mockHeapJsHttpRequest() window.heap = createMockedHeapJsSdk() - event = ( + eventWithUnrolling = ( await heapDestination({ appId: HEAP_TEST_ENV_ID, subscriptions: [trackEventSubscription], browserArrayLimit: 5 }) )[0] + await eventWithUnrolling.load(Context.system(), {} as Analytics) + event = (await heapDestination({ appId: HEAP_TEST_ENV_ID, subscriptions: [trackEventSubscription] }))[0] await event.load(Context.system(), {} as Analytics) + heapTrackSpy = jest.spyOn(window.heap, 'track') addUserPropertiesSpy = jest.spyOn(window.heap, 'addUserProperties') identifySpy = jest.spyOn(window.heap, 'identify') @@ -33,7 +37,7 @@ describe('#trackEvent', () => { }) it('sends events to heap', async () => { - await event.track?.( + await eventWithUnrolling.track?.( new Context({ type: 'track', name: 'hello!', @@ -114,7 +118,7 @@ describe('#trackEvent', () => { }) it('limits number of properties in array', async () => { - await event.track?.( + await eventWithUnrolling.track?.( new Context({ type: 'track', name: 'hello!', @@ -149,6 +153,26 @@ describe('#trackEvent', () => { }) }) + it('does not limit number of properties if browserArrayLimit is 0', async () => { + await event.track?.( + new Context({ + type: 'track', + name: 'hello!', + properties: { + testArray1: [{ val: 1 }, { val: 2 }, { val: 3 }], + testArray2: [{ val: 4 }, { val: 5 }, { val: 'N/A' }] + } + }) + ) + expect(heapTrackSpy).toHaveBeenCalledTimes(1) + + expect(heapTrackSpy).toHaveBeenCalledWith('hello!', { + testArray1: [{ val: 1 }, { val: 2 }, { val: 3 }], + testArray2: [{ val: 4 }, { val: 5 }, { val: 'N/A' }], + segment_library: HEAP_SEGMENT_BROWSER_LIBRARY_NAME + }) + }) + it('should send segment_library property if no other properties were provided', async () => { await event.track?.( new Context({ diff --git a/packages/browser-destinations/destinations/heap/src/trackEvent/index.ts b/packages/browser-destinations/destinations/heap/src/trackEvent/index.ts index 155b15ec6d..5096e82d08 100644 --- a/packages/browser-destinations/destinations/heap/src/trackEvent/index.ts +++ b/packages/browser-destinations/destinations/heap/src/trackEvent/index.ts @@ -75,38 +75,54 @@ const action: BrowserActionDefinition = { const eventName = event.payload.name const browserArrayLimit = event.settings.browserArrayLimit || 0 const browserArrayLimitSet = !!browserArrayLimit - let arrayEventsCount = 0 - for (const [key, value] of Object.entries(eventProperties)) { - if (browserArrayLimitSet && arrayEventsCount >= browserArrayLimit) { - break - } + if (browserArrayLimitSet) { + eventProperties = heapTrackArrays(heap, eventName, eventProperties, browserArrayLimit) + } - if (!Array.isArray(value)) { - continue - } + heapTrack(heap, eventName, eventProperties) + } +} - delete eventProperties[key] - eventProperties = { ...eventProperties, ...flat({ [key]: value }) } +const heapTrackArrays = ( + heap: HeapApi, + eventName: string, + properties: { + [k: string]: unknown + }, + browserArrayLimit: number +) => { + let eventProperties = Object.assign({}, properties) + let arrayEventsCount = 0 + for (const [key, value] of Object.entries(eventProperties)) { + if (arrayEventsCount >= browserArrayLimit) { + return eventProperties + } - const arrayLength = value.length - let arrayPropertyValues - // truncate in case there are multiple array properties - if (browserArrayLimitSet && arrayLength + arrayEventsCount > browserArrayLimit) { - arrayPropertyValues = value.splice(0, browserArrayLimit - arrayEventsCount) - } else { - arrayPropertyValues = value - } + if (!Array.isArray(value)) { + continue + } - arrayEventsCount += arrayLength + delete eventProperties[key] + eventProperties = { ...eventProperties, ...flat({ [key]: value }) } - arrayPropertyValues.forEach((arrayPropertyValue) => { - const arrayProperties = flattenProperties(arrayPropertyValue) - heapTrack(heap, `${eventName} ${key} item`, arrayProperties) - }) + const arrayLength = value.length + let arrayPropertyValues + // truncate in case there are multiple array properties + if (arrayLength + arrayEventsCount > browserArrayLimit) { + arrayPropertyValues = value.splice(0, browserArrayLimit - arrayEventsCount) + } else { + arrayPropertyValues = value } - heapTrack(heap, eventName, eventProperties) + + arrayEventsCount += arrayLength + + arrayPropertyValues.forEach((arrayPropertyValue) => { + const arrayProperties = flattenProperties(arrayPropertyValue) + heapTrack(heap, `${eventName} ${key} item`, arrayProperties) + }) } + return eventProperties } const heapTrack = (