Skip to content

Commit

Permalink
feat: user attribute, identity, and custom event processing with unit…
Browse files Browse the repository at this point in the history
… tests (#6)

* Add UA, identity, and custom event processing with unit tests

* Update method of checking ignored events for readability

* Update onSetUserIdentity for increased compatibility

* Restore ignored filed

* Restore settings file to previous

* Update to include all user attributes from mParticleUser

* remove cached dist/ files

* Fix failing unit tests
  • Loading branch information
SbDove authored Jun 24, 2024
1 parent f74eb21 commit b47736c
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 1,587 deletions.
779 changes: 0 additions & 779 deletions dist/HeapKit.common.js

This file was deleted.

782 changes: 0 additions & 782 deletions dist/HeapKit.iife.js

This file was deleted.

14 changes: 13 additions & 1 deletion src/event-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,19 @@ A non-ecommerce event has the following schema:
function EventHandler(common) {
this.common = common || {};
}
EventHandler.prototype.logEvent = function(event) {};
EventHandler.prototype.logEvent = function(event) {
var ignoredEvents = [
'click',
'change',
'submit'
];

if (ignoredEvents.includes(event.EventName.toLowerCase())) {
return;
}

window.heap.track(event.EventName, event.EventAttributes);
};
EventHandler.prototype.logError = function(event) {
// The schema for a logError event is the same, but noteworthy differences are as follows:
// {
Expand Down
23 changes: 20 additions & 3 deletions src/identity-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,18 @@ For more userIdentity types, see https://docs.mparticle.com/developers/sdk/web/i
function IdentityHandler(common) {
this.common = common || {};
}
IdentityHandler.prototype.onUserIdentified = function(mParticleUser) {};
IdentityHandler.prototype.onUserIdentified = function(mParticleUser) {
if (!mParticleUser && !mParticleUser.getUserIdentities()) {
return;
}

var identitiesObject = mParticleUser.getUserIdentities();
var identity = identitiesObject.userIdentities[this.common.userIdentificationType];

if (identity) {
window.heap.identify(identity);
}
};
IdentityHandler.prototype.onIdentifyComplete = function(
mParticleUser,
identityApiRequest
Expand All @@ -33,7 +44,9 @@ IdentityHandler.prototype.onLoginComplete = function(
IdentityHandler.prototype.onLogoutComplete = function(
mParticleUser,
identityApiRequest
) {};
) {
window.heap.resetIdentity();
};
IdentityHandler.prototype.onModifyComplete = function(
mParticleUser,
identityApiRequest
Expand All @@ -47,6 +60,10 @@ IdentityHandler.prototype.onSetUserIdentity = function(
forwarderSettings,
id,
type
) {};
) {
if (this.common.userIdentificationType === type) {
window.heap.identify(id);
}
};

module.exports = IdentityHandler;
2 changes: 2 additions & 0 deletions src/initialization.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ var initialization = {
/* Load your Web SDK here using a variant of your snippet from your readme that your customers would generally put into their <head> tags
Generally, our integrations create script tags and append them to the <head>. Please follow the following format as a guide:
*/
common.userIdentificationType = forwarderSettings.userIdentificationType

var forwardWebRequestsServerSide = forwarderSettings.forwardWebRequestsServerSide === 'True';
common.forwardWebRequestsServerSide = forwardWebRequestsServerSide;
if (!forwardWebRequestsServerSide) {
Expand Down
14 changes: 12 additions & 2 deletions src/user-attribute-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,22 @@ function UserAttributeHandler(common) {
UserAttributeHandler.prototype.onRemoveUserAttribute = function(
key,
mParticleUser
) {};
) {
delete this.common.userAttributes[key];
window.heap.addUserProperties(this.common.userAttributes);
};
UserAttributeHandler.prototype.onSetUserAttribute = function(
key,
value,
mParticleUser
) {};
) {
if (!this.common.userAttributes) {
this.common.userAttributes = {};
}

this.common.userAttributes[key] = value;
window.heap.addUserProperties(this.common.userAttributes);
};
UserAttributeHandler.prototype.onConsentStateUpdated = function(
oldState,
newState,
Expand Down
1 change: 1 addition & 0 deletions test/end-to-end-testapp/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var SDKsettings = {
into the src/initialization.js file as the
*/
appId: 'testAppId',
userIdentificationType: 'customerid',
};

// Do not edit below:
Expand Down
149 changes: 129 additions & 20 deletions test/tests.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable no-undef*/
describe('XYZ Forwarder', function () {
describe('Heap Forwarder', function () {
// -------------------DO NOT EDIT ANYTHING BELOW THIS LINE-----------------------
var MessageType = {
SessionStart: 1,
Expand Down Expand Up @@ -83,22 +83,25 @@ describe('XYZ Forwarder', function () {
},
};
// -------------------START EDITING BELOW:-----------------------
var MockXYZForwarder = function () {
var MockHeapForwarder = function () {
var self = this;

// create properties for each type of event you want tracked, see below for examples
this.trackCustomEventCalled = false;
this.trackCalled = false;
this.logPurchaseEventCalled = false;
this.addUserPropertiesCalled = false;
this.loadCalled = false;
this.identifyCalled = false;
this.initializeCalled = false;

this.trackCustomName = null;
this.logPurchaseName = null;
this.apiKey = null;
this.appId = null;
this.userId = null;
this.appid = null;
this.identity = null;
this.userAttributes = {};
this.userIdField = null;

this.events = [];
this.eventProperties = [];
this.purchaseEventProperties = [];

Expand All @@ -109,6 +112,27 @@ describe('XYZ Forwarder', function () {
self.appId = appId;
};

this.load = function (appId) {
self.loadCalled = true;
self.appid = appId;
};

this.identify = function (identity) {
self.identity = identity;
self.identifyCalled = true;
};

this.addUserProperties = function(properties) {
self.addUserPropertiesCalled = true;
self.userAttributes = properties;
};

this.track = function (eventName, eventAttributes) {
this.trackCalled = true;
this.events.push(eventName);
this.eventProperties.push(eventAttributes);
};

this.stubbedTrackingMethod = function (name, eventProperties) {
self.trackCustomEventCalled = true;
self.trackCustomName = name;
Expand Down Expand Up @@ -139,11 +163,12 @@ describe('XYZ Forwarder', function () {
before(function () {});

beforeEach(function () {
window.MockXYZForwarder = new MockXYZForwarder();
window.MockHeapForwarder = new MockHeapForwarder();
// Include any specific settings that is required for initializing your SDK here
var sdkSettings = {
clientKey: '123456',
appId: 'test-app-id',
userIdentificationType: 'customerid',
};

// You may require userAttributes or userIdentities to be passed into initialization
Expand Down Expand Up @@ -186,21 +211,105 @@ describe('XYZ Forwarder', function () {
done();
});

it('should log event', function (done) {
// mParticle.forwarder.process({
// EventDataType: MessageType.PageEvent,
// EventName: 'Test Event',
// EventAttributes: {
// label: 'label',
// value: 200,
// category: 'category'
// }
// });
describe('UserIdentification', function () {
it('should log the correct identity to heap based on the forwarder settings', function (done) {
window.heap = new MockHeapForwarder();

// window.MockXYZForwarder.eventProperties[0].label.should.equal('label');
// window.MockXYZForwarder.eventProperties[0].value.should.equal(200);
mParticle.forwarder.init({
appId: 'test-app-id',
userIdentificationType: 'customerid'
});

done();
var user = {
getUserIdentities: function () {
return {
userIdentities: {
customerid: 'cid123'
}
}
}
}
mParticle.forwarder.onUserIdentified(user);

window.heap.should.be.defined;
window.heap.identity.should.equal('cid123');
done();
});

it('should return a null identity on logout', function (done) {
mParticle.forwarder.init({
appId: 'test-app-id',
userIdentificationType: 'customerid'
});

var user = {
getUserIdentities: function () {
return {
userIdentities: {
customerid: 'cid123'
}
}
}
}
mParticle.forwarder.onUserIdentified(user);

window.heap.should.be.defined;
window.heap.identity.should.equal('cid123');

mParticle.forwarder.onLogoutComplete();

window.heap.identity.should.not.exist;
done();
});
});

describe('UserAttributeProcessing', function () {
it('Should log all user attributes when one is added', function (done) {
mParticle.forwarder.setUserAttribute("newKey", "newValue");

window.heap.addUserPropertiesCalled.should.equal(true);
done();
});

it('Should log user attributes when one is removed', function(done){
mParticle.forwarder.setUserAttribute("newKey2", "newValue2");

window.heap.userAttributes.newKey2.should.exist;
window.heap.userAttributes.newKey.should.exist;

mParticle.forwarder.removeUserAttribute("newKey");

Object.keys(window.heap.userAttributes).length.should.equal(1);
window.heap.addUserPropertiesCalled.should.equal(true);
done();
});
});

describe('EventProcessing', function () {
it('should log event', function (done) {
window.heap = new MockHeapForwarder();
mParticle.forwarder.init({
appId: 'test-app-id'
});

mParticle.forwarder.process({
EventDataType: MessageType.PageEvent,
EventName: 'Test Event',
EventAttributes: {
label: 'label',
value: 200,
category: 'category'
}
});

window.heap.trackCalled.should.equal(true);
window.heap.events.length.should.equal(1);
window.heap.events[0].should.equal('Test Event');
window.heap.eventProperties[0].label.should.equal('label');
window.heap.eventProperties[0].value.should.equal(200);
window.heap.eventProperties[0].category.should.equal('category');
done();
});
});

it('should log page view', function (done) {
Expand Down

0 comments on commit b47736c

Please sign in to comment.