Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
63 changes: 59 additions & 4 deletions src/MixpanelEventForwarder.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,50 @@ var constructor = function () {
}
}

function onUserIdentified(user) {
var idForMixpanel;
var userIdentities = user.getUserIdentities()
function getUserIdentities(user) {
return user.getUserIdentities()
? user.getUserIdentities().userIdentities
: {};
}

function onLoginComplete(user) {
var userIdentities = getUserIdentities(user);

// When mParticle identifies a user, the user might
// actually be anonymous. We only want to send an
// identify request to Mixpanel if the user is
// actually known. Only known (logged in) users
// will have userIdentities.
if (!isEmpty(userIdentities)) {
sendIdentifyRequest(user, userIdentities);
} else {
return 'Logged in user does not have user identities and will not be sent to Mixpanel to Identify';
}
}

function onLogoutComplete() {
if (!isInitialized) {
return (
'Cannot call logout on forwarder: ' + name + ', not initialized'
);
}

try {
mixpanel.mparticle.reset();

return 'Successfully called reset on forwarder: ' + name;
} catch (e) {
return 'Cannot call reset on forwarder: ' + name + ': ' + e;
}
}

function sendIdentifyRequest(user, userIdentities) {
var idForMixpanel;

if (isEmpty(userIdentities)) {
userIdentities = getUserIdentities(user);
}

switch (forwarderSettings.userIdentificationType) {
case 'CustomerId':
idForMixpanel = userIdentities.customerid;
Expand Down Expand Up @@ -245,8 +284,20 @@ var constructor = function () {
this.process = processEvent;
this.setUserAttribute = setUserAttribute;
this.setUserIdentity = setUserIdentity;
this.onUserIdentified = onUserIdentified;
this.removeUserAttribute = removeUserAttribute;

this.onLoginComplete = onLoginComplete;

// For all Identity Requests, we run mixpanel.identify(<device_id)
// as per Mixpanel's documentation https://docs.mixpanel.com/docs/tracking-methods/identifying-users
// except when a user logs out, where we run mixpanel.reset() to
// detach the distinct_id from the device_id
this.onLogoutComplete = onLogoutComplete;

// For these two methods, we are essentially passing along the
// Identify request the same way.
this.onIdentifyComplte = sendIdentifyRequest;
this.onModifyComplete = sendIdentifyRequest;
};

function getId() {
Expand Down Expand Up @@ -283,6 +334,10 @@ function register(config) {
);
}

function isEmpty(value) {
return value == null || !(Object.keys(value) || value).length;
}

function isObject(val) {
return (
val != null && typeof val === 'object' && Array.isArray(val) === false
Expand Down
246 changes: 169 additions & 77 deletions test/src/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ describe('Mixpanel Forwarder', function () {
setCalledAttributes(data, 'identifyCalled');
};

this.mparticle.reset = function (data) {
setCalledAttributes(data, 'resetCalled');
};

this.mparticle.alias = function (data) {
setCalledAttributes(data, 'aliasCalled');
};
Expand Down Expand Up @@ -144,7 +148,30 @@ describe('Mixpanel Forwarder', function () {
}
var API_HOST = 'https://api.mixpanel.com';

before(function () {
var identificationTypes = [
{
userIdentificationType: 'CustomerId',
expectedProperty: 'cust1',
},
{
userIdentificationType: 'Other',
expectedProperty: 'other1',
},
{
userIdentificationType: 'Other2',
expectedProperty: 'other2',
},
{
userIdentificationType: 'Other3',
expectedProperty: 'other3',
},
{
userIdentificationType: 'Other4',
expectedProperty: 'other4',
},
];

beforeEach(function () {
window.mixpanel = new MPMock();
mParticle.forwarder.init(
{
Expand Down Expand Up @@ -284,15 +311,7 @@ describe('Mixpanel Forwarder', function () {
done();
});

it('should identify user (mParticle SDK v2)', function (done) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'CustomerId',
},
reportService.cb,
true
);
it('should log in a user (mParticle SDK v2)', function (done) {
var user = {
getUserIdentities: function () {
return {
Expand All @@ -310,92 +329,165 @@ describe('Mixpanel Forwarder', function () {
},
};

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'cust1');

mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'MPID',
},
reportService.cb,
true
);
identificationTypes.forEach(function (identificationType) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType:
identificationType.userIdentificationType,
},
reportService.cb,
true
);

mParticle.forwarder.onLoginComplete(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property(
'data',
identificationType.expectedProperty
);
});

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'mpid1');
done();
});

mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'Other',
it('should NOT log in a user if they do not have user identities (mParticle SDK v2)', function (done) {
var user = {
getUserIdentities: function () {
return {
userIdentities: {},
};
},
reportService.cb,
true
);
getMPID: function () {
return 'anon-mpid1';
},
};

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'other1');
identificationTypes.forEach(function (identificationType) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType:
identificationType.userIdentificationType,
},
reportService.cb,
true
);

mParticle.forwarder.onLoginComplete(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
false
);
window.mixpanel.mparticle.should.not.have.property(
'data',
identificationType.expectedProperty
);
});
done();
});

mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'Other2',
it('should identify a user (mParticle SDK v2)', function (done) {
var user = {
getUserIdentities: function () {
return {
userIdentities: {
customerid: 'cust1',
other: 'other1',
other2: 'other2',
other3: 'other3',
other4: 'other4',
},
};
},
reportService.cb,
true
);
getMPID: function () {
return 'mpid1';
},
};

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'other2');
identificationTypes.forEach(function (identificationType) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType:
identificationType.userIdentificationType,
},
reportService.cb,
true
);

mParticle.forwarder.onIdentifyComplte(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property(
'data',
identificationType.expectedProperty
);
});

mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'Other3',
done();
});

it('should modify a user identity (mParticle SDK v2)', function (done) {
var user = {
getUserIdentities: function () {
return {
userIdentities: {
customerid: 'cust1',
other: 'other1',
other2: 'other2',
other3: 'other3',
other4: 'other4',
},
};
},
reportService.cb,
true
);
getMPID: function () {
return 'mpid1';
},
};

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'other3');
identificationTypes.forEach(function (identificationType) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType:
identificationType.userIdentificationType,
},
reportService.cb,
true
);

mParticle.forwarder.onModifyComplete(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property(
'data',
identificationType.expectedProperty
);
});

done();
});

it('should log out a user (mParticle SDK v2)', function (done) {
mParticle.forwarder.init(
{
includeUserAttributes: 'True',
userIdentificationType: 'Other4',
userIdentificationType: 'MPID',
},
reportService.cb,
true
);

mParticle.forwarder.onUserIdentified(user);
window.mixpanel.mparticle.should.have.property(
'identifyCalled',
true
);
window.mixpanel.mparticle.should.have.property('data', 'other4');
mParticle.forwarder.onLogoutComplete();
window.mixpanel.mparticle.should.have.property('resetCalled', true);

done();
});
Expand Down