Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Rokt-Kit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,13 +886,16 @@ class RoktKit implements KitInterface {
mp() && mp().sessionManager && typeof mp().sessionManager!.getSession === 'function'
? mp().sessionManager!.getSession()
: undefined;
const userIdentities = this.returnUserIdentities(filteredUser);

return {
event_type: eventType,
data: {
timestamp_unixtime_ms: Date.now(),
session_uuid: sessionUuid ?? undefined,
mpid,
user_identities: userIdentities,
user_attributes: this.userAttributes,
},
} as unknown as BaseEvent;
}
Expand Down
104 changes: 104 additions & 0 deletions test/src/tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5661,6 +5661,8 @@ describe('Rokt Forwarder', () => {
expect(pending.length).toBe(1);
expect(pending[0].event_type).toBe('login');
expect(pending[0].data.timestamp_unixtime_ms).toBeTypeOf('number');
expect(pending[0].data.user_identities).toEqual({});
expect(pending[0].data.user_attributes).toEqual({});
});

it('should add an identity event to pendingIdentityEvents on onLogoutComplete', () => {
Expand All @@ -5676,6 +5678,8 @@ describe('Rokt Forwarder', () => {
expect(pending.length).toBe(1);
expect(pending[0].event_type).toBe('logout');
expect(pending[0].data.timestamp_unixtime_ms).toBeTypeOf('number');
expect(pending[0].data.user_identities).toEqual({});
expect(pending[0].data.user_attributes).toEqual({});
});

it('should add identity events to pendingIdentityEvents on onModifyComplete and onUserIdentified', () => {
Expand All @@ -5694,6 +5698,104 @@ describe('Rokt Forwarder', () => {
expect(pending[1].event_type).toBe('identify');
});

it('should include user_identities inside data of the identity event payload', () => {
const mockUser = {
getMPID: () => '123',
getAllUserAttributes: () => ({}),
getUserIdentities: () => ({
userIdentities: {
email: 'user@example.com',
customerid: 'cust-456',
},
}),
};

(window as any).mParticle.forwarder.onLoginComplete(mockUser, null);

const pending = (window as any).mParticle.forwarder.pendingIdentityEvents;
expect(pending.length).toBe(1);
expect(pending[0].data.user_identities).toEqual({
email: 'user@example.com',
customerid: 'cust-456',
});
});

it('should apply emailsha256 mapping to user_identities inside data of the identity event payload', () => {
(window as any).mParticle.forwarder._mappedEmailSha256Key = 'other';

const mockUser = {
getMPID: () => '123',
getAllUserAttributes: () => ({}),
getUserIdentities: () => ({
userIdentities: {
customerid: 'cust-789',
other: 'abc123hashedemail',
},
}),
};

(window as any).mParticle.forwarder.onLoginComplete(mockUser, null);

const pending = (window as any).mParticle.forwarder.pendingIdentityEvents;
expect(pending.length).toBe(1);
expect(pending[0].data.user_identities).toEqual({
customerid: 'cust-789',
emailsha256: 'abc123hashedemail',
});
expect(pending[0].data.user_identities.other).toBeUndefined();
});

it('should include user_attributes inside data of the identity event payload', () => {
const mockUser = {
getMPID: () => '123',
getAllUserAttributes: () => ({ plan: 'premium', region: 'us' }),
getUserIdentities: () => ({ userIdentities: {} }),
};

(window as any).mParticle.forwarder.onLoginComplete(mockUser, null);

const pending = (window as any).mParticle.forwarder.pendingIdentityEvents;
expect(pending.length).toBe(1);
expect(pending[0].data.user_attributes).toEqual({ plan: 'premium', region: 'us' });
});

it('should snapshot user_attributes from the user at event build time', () => {
const mockUserAtLogin = {
getMPID: () => '123',
getAllUserAttributes: () => ({ role: 'admin' }),
getUserIdentities: () => ({ userIdentities: {} }),
};
const mockUserAtModify = {
getMPID: () => '123',
getAllUserAttributes: () => ({ role: 'viewer' }),
getUserIdentities: () => ({ userIdentities: {} }),
};

(window as any).mParticle.forwarder.onLoginComplete(mockUserAtLogin, null);
(window as any).mParticle.forwarder.onModifyComplete(mockUserAtModify, null);

const pending = (window as any).mParticle.forwarder.pendingIdentityEvents;
expect(pending.length).toBe(2);
expect(pending[0].data.user_attributes).toEqual({ role: 'admin' });
expect(pending[1].data.user_attributes).toEqual({ role: 'viewer' });
});

it('should include empty user_attributes inside data on logout for an anonymous session', () => {
const anonymousUser = {
getMPID: () => '-1234567890',
getAllUserAttributes: () => ({}),
getUserIdentities: () => ({ userIdentities: {} }),
};

(window as any).mParticle.forwarder.onLogoutComplete(anonymousUser, null);

const pending = (window as any).mParticle.forwarder.pendingIdentityEvents;
expect(pending.length).toBe(1);
expect(pending[0].event_type).toBe('logout');
expect(pending[0].data.user_identities).toEqual({});
expect(pending[0].data.user_attributes).toEqual({});
});

it('should merge pendingIdentityEvents into the outgoing batch and clear the queue', async () => {
const receivedBatches: any[] = [];
(window as any).Rokt.__batch_stream__ = function (payload: any) {
Expand All @@ -5719,6 +5821,8 @@ describe('Rokt Forwarder', () => {
expect(receivedBatches[0].events.length).toBe(2);
expect(receivedBatches[0].events[1].event_type).toBe('login');
expect(receivedBatches[0].events[1].data.timestamp_unixtime_ms).toBeTypeOf('number');
expect(receivedBatches[0].events[1].data.user_identities).toEqual({});
expect(receivedBatches[0].events[1].data.user_attributes).toEqual({});
// Queue should be cleared after flush
expect((window as any).mParticle.forwarder.pendingIdentityEvents.length).toBe(0);
});
Expand Down
Loading