From dec6747e718e90e461d16606e388ff2922554ea5 Mon Sep 17 00:00:00 2001 From: Cris Ryan Tan Date: Wed, 25 Mar 2026 13:34:15 +1100 Subject: [PATCH] feat: enrich event stream with Kit-managed userAttributes Merge self.userAttributes onto events before forwarding to __event_stream__ so the downstream SDK always receives fresh, Kit-filtered user attributes regardless of event queuing state. Made-with: Cursor --- src/Rokt-Kit.js | 5 +- test/src/tests.js | 128 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 131 insertions(+), 2 deletions(-) diff --git a/src/Rokt-Kit.js b/src/Rokt-Kit.js index a3b7fa8..f8d40ab 100644 --- a/src/Rokt-Kit.js +++ b/src/Rokt-Kit.js @@ -553,7 +553,10 @@ var constructor = function () { function _sendEventStream(event) { if (window.Rokt && typeof window.Rokt.__event_stream__ === 'function') { - window.Rokt.__event_stream__(event); + var enrichedEvent = mergeObjects({}, event, { + UserAttributes: self.userAttributes, + }); + window.Rokt.__event_stream__(enrichedEvent); } } diff --git a/test/src/tests.js b/test/src/tests.js index 80a3db2..8bcedda 100644 --- a/test/src/tests.js +++ b/test/src/tests.js @@ -4647,7 +4647,11 @@ describe('Rokt Forwarder', () => { window.mParticle.forwarder.process(testEvent); receivedEvents.length.should.equal(1); - receivedEvents[0].should.deepEqual(testEvent); + receivedEvents[0].EventName.should.equal('Test Event'); + receivedEvents[0].EventCategory.should.equal(EventType.Other); + receivedEvents[0].EventDataType.should.equal( + MessageType.PageEvent + ); }); it('should not throw when window.Rokt.__event_stream__ is not defined', async () => { @@ -4833,6 +4837,128 @@ describe('Rokt Forwarder', () => { 'foo-mapped-flag': true, }); }); + + it('should enrich event with Kit userAttributes before forwarding', async () => { + var receivedEvents = []; + window.Rokt.__event_stream__ = function (event) { + receivedEvents.push(event); + }; + + await window.mParticle.forwarder.init( + { accountId: '123456' }, + reportService.cb, + true, + null, + {} + ); + + await waitForCondition(() => window.mParticle.Rokt.attachKitCalled); + + window.mParticle.forwarder.setUserAttribute('email', 'test@example.com'); + window.mParticle.forwarder.setUserAttribute('plan', 'premium'); + + window.mParticle.forwarder.process({ + EventName: 'Page View', + EventCategory: EventType.Navigation, + EventDataType: MessageType.PageView, + }); + + receivedEvents.length.should.equal(1); + receivedEvents[0].UserAttributes.should.deepEqual({ + email: 'test@example.com', + plan: 'premium', + }); + receivedEvents[0].EventName.should.equal('Page View'); + }); + + it('should use Kit userAttributes over event-level UserAttributes', async () => { + var receivedEvents = []; + window.Rokt.__event_stream__ = function (event) { + receivedEvents.push(event); + }; + + await window.mParticle.forwarder.init( + { accountId: '123456' }, + reportService.cb, + true, + null, + {} + ); + + await waitForCondition(() => window.mParticle.Rokt.attachKitCalled); + + window.mParticle.forwarder.setUserAttribute('email', 'fresh@example.com'); + + window.mParticle.forwarder.process({ + EventName: 'Test', + EventCategory: EventType.Other, + EventDataType: MessageType.PageEvent, + UserAttributes: { email: 'stale@example.com' }, + }); + + receivedEvents.length.should.equal(1); + receivedEvents[0].UserAttributes.email.should.equal( + 'fresh@example.com' + ); + }); + + it('should not mutate the original event object', async () => { + var receivedEvents = []; + window.Rokt.__event_stream__ = function (event) { + receivedEvents.push(event); + }; + + await window.mParticle.forwarder.init( + { accountId: '123456' }, + reportService.cb, + true, + null, + {} + ); + + await waitForCondition(() => window.mParticle.Rokt.attachKitCalled); + + window.mParticle.forwarder.setUserAttribute('key', 'value'); + + var originalEvent = { + EventName: 'Original', + EventCategory: EventType.Other, + EventDataType: MessageType.PageEvent, + }; + + window.mParticle.forwarder.process(originalEvent); + + (originalEvent.UserAttributes === undefined).should.equal(true); + receivedEvents[0].UserAttributes.should.deepEqual({ key: 'value' }); + }); + + it('should send empty UserAttributes when Kit has no user attributes', async () => { + var receivedEvents = []; + window.Rokt.__event_stream__ = function (event) { + receivedEvents.push(event); + }; + + await window.mParticle.forwarder.init( + { accountId: '123456' }, + reportService.cb, + true, + null, + {} + ); + + await waitForCondition(() => window.mParticle.Rokt.attachKitCalled); + + window.mParticle.forwarder.userAttributes = {}; + + window.mParticle.forwarder.process({ + EventName: 'Test', + EventCategory: EventType.Other, + EventDataType: MessageType.PageEvent, + }); + + receivedEvents.length.should.equal(1); + receivedEvents[0].UserAttributes.should.deepEqual({}); + }); }); describe('#_setRoktSessionId', () => {