From 15c79d48a2a4f9c44a0edd6e893cd68c5c988a66 Mon Sep 17 00:00:00 2001 From: Tim Yiu <137842098+tyiuhc@users.noreply.github.com> Date: Thu, 2 Oct 2025 16:27:35 -0700 Subject: [PATCH 1/3] fix: Allow timestamp override for experiment events --- packages/analytics-browser/src/browser-client.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/analytics-browser/src/browser-client.ts b/packages/analytics-browser/src/browser-client.ts index fa2b17a8c..230caa9ba 100644 --- a/packages/analytics-browser/src/browser-client.ts +++ b/packages/analytics-browser/src/browser-client.ts @@ -241,7 +241,9 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient, An // Step 7: Add the event receiver after running remaining queued functions. connector.eventBridge.setEventReceiver((event) => { - void this.track(event.eventType, event.eventProperties); + const { time, ...cleanEventProperties } = event.eventProperties || {}; + const eventOptions = (typeof time === 'number') ? { time } : undefined; + void this.track(event.eventType, cleanEventProperties, eventOptions); }); } From d2396d627dc26a1a6238402a504a17557f1a0139 Mon Sep 17 00:00:00 2001 From: Tim Yiu <137842098+tyiuhc@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:19:23 -0700 Subject: [PATCH 2/3] increase test coverage --- .../test/browser-client.test.ts | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/packages/analytics-browser/test/browser-client.test.ts b/packages/analytics-browser/test/browser-client.test.ts index 469b270c7..cd6bbba8c 100644 --- a/packages/analytics-browser/test/browser-client.test.ts +++ b/packages/analytics-browser/test/browser-client.test.ts @@ -387,6 +387,102 @@ describe('browser-client', () => { expect(track).toHaveBeenCalledTimes(1); }); + test('should handle event bridge events with time property in eventProperties', async () => { + await client.init(apiKey, userId, { + optOut: false, + defaultTracking, + }).promise; + const track = jest.spyOn(client, 'track').mockReturnValueOnce({ + promise: Promise.resolve({ + code: 200, + message: '', + event: { + event_type: 'custom_event', + }, + }), + }); + + const customTime = 12345; + getAnalyticsConnector().eventBridge.logEvent({ + eventType: 'custom_event', + eventProperties: { + property1: 'value1', + property2: 123, + time: customTime, + property3: true, + }, + }); + + expect(track).toHaveBeenCalledTimes(1); + expect(track).toHaveBeenCalledWith( + 'custom_event', + { + property1: 'value1', + property2: 123, + property3: true, + }, + { time: customTime } + ); + }); + + test('should handle event bridge events with null time property', async () => { + await client.init(apiKey, userId, { + optOut: false, + defaultTracking, + }).promise; + const track = jest.spyOn(client, 'track').mockReturnValueOnce({ + promise: Promise.resolve({ + code: 200, + message: '', + event: { + event_type: 'null_time_event', + }, + }), + }); + + getAnalyticsConnector().eventBridge.logEvent({ + eventType: 'null_time_event', + eventProperties: { + property1: 'value1', + time: null, + property2: 'value2', + }, + }); + + expect(track).toHaveBeenCalledTimes(1); + expect(track).toHaveBeenCalledWith( + 'null_time_event', + { + property1: 'value1', + property2: 'value2', + }, + undefined + ); + }); + + test('should handle event bridge events with no eventProperties', async () => { + await client.init(apiKey, userId, { + optOut: false, + defaultTracking, + }).promise; + const track = jest.spyOn(client, 'track').mockReturnValueOnce({ + promise: Promise.resolve({ + code: 200, + message: '', + event: { + event_type: 'no_props_event', + }, + }), + }); + + getAnalyticsConnector().eventBridge.logEvent({ + eventType: 'no_props_event', + }); + + expect(track).toHaveBeenCalledTimes(1); + expect(track).toHaveBeenCalledWith('no_props_event', {}, undefined); + }); + test('should add file download and form interaction tracking plugins', async () => { const fileDownloadTrackingPlugin = jest.spyOn(fileDownloadTracking, 'fileDownloadTracking'); const formInteractionTrackingPlugin = jest.spyOn(formInteractionTracking, 'formInteractionTracking'); From cc58b8ffd0059099c76bf65dd3c9eb87295b7cb9 Mon Sep 17 00:00:00 2001 From: Tim Yiu <137842098+tyiuhc@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:45:59 -0700 Subject: [PATCH 3/3] fix lint --- packages/analytics-browser/src/browser-client.ts | 2 +- packages/analytics-browser/test/browser-client.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/analytics-browser/src/browser-client.ts b/packages/analytics-browser/src/browser-client.ts index dc1284fab..3c95589d5 100644 --- a/packages/analytics-browser/src/browser-client.ts +++ b/packages/analytics-browser/src/browser-client.ts @@ -240,7 +240,7 @@ export class AmplitudeBrowser extends AmplitudeCore implements BrowserClient, An // Step 7: Add the event receiver after running remaining queued functions. connector.eventBridge.setEventReceiver((event) => { const { time, ...cleanEventProperties } = event.eventProperties || {}; - const eventOptions = (typeof time === 'number') ? { time } : undefined; + const eventOptions = typeof time === 'number' ? { time } : undefined; void this.track(event.eventType, cleanEventProperties, eventOptions); }); } diff --git a/packages/analytics-browser/test/browser-client.test.ts b/packages/analytics-browser/test/browser-client.test.ts index cd6bbba8c..667cd61e2 100644 --- a/packages/analytics-browser/test/browser-client.test.ts +++ b/packages/analytics-browser/test/browser-client.test.ts @@ -421,7 +421,7 @@ describe('browser-client', () => { property2: 123, property3: true, }, - { time: customTime } + { time: customTime }, ); }); @@ -456,7 +456,7 @@ describe('browser-client', () => { property1: 'value1', property2: 'value2', }, - undefined + undefined, ); });