Skip to content

Commit

Permalink
Merge pull request segmentio#434 from segmentio/mp-update
Browse files Browse the repository at this point in the history
Support not setting traits on Mixpanel
  • Loading branch information
f2prateek committed Sep 22, 2015
2 parents f8c25e6 + 59a075e commit 59192c3
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 11 deletions.
68 changes: 59 additions & 9 deletions Analytics/Integrations/Mixpanel/SEGMixpanelIntegration.m
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,44 @@ - (void)identify:(NSString *)userId traits:(NSDictionary *)traits options:(NSDic
@"$name", @"name",
@"$username", @"username",
@"$phone", @"phone", nil];
NSDictionary *mappedTraits = [SEGAnalyticsIntegration map:traits withMap:map];

// Register the mapped traits.
[[self.mixpanelClass sharedInstance] registerSuperProperties:mappedTraits];
if ([self setAllTraitsByDefault]) {
NSDictionary *mappedTraits = [SEGAnalyticsIntegration map:traits withMap:map];

// Mixpanel also has a people API that works seperately, so we set the traits for it as well.
if ([(NSNumber *)[self.settings objectForKey:@"people"] boolValue]) {
// You'll notice that we could also have done: [self.mixpanelClass.sharedInstance.people set:mappedTraits];
// Using methods instead of properties directly lets us mock them in tests, which is why we use the syntax below.
[[[self.mixpanelClass sharedInstance] people] set:mappedTraits];
// Register the mapped traits.
[[self.mixpanelClass sharedInstance] registerSuperProperties:mappedTraits];

// Mixpanel also has a people API that works seperately, so we set the traits for it as well.
if ([self peopleEnabled]) {
// You'll notice that we could also have done: [self.mixpanelClass.sharedInstance.people set:mappedTraits];
// Using methods instead of properties directly lets us mock them in tests, which is why we use the syntax below.
[[[self.mixpanelClass sharedInstance] people] set:mappedTraits];
}

return;
}

NSDictionary *mixpanelOptions = [self mixpanelOptions:options];
if (!mixpanelOptions) {
return;
}

NSArray *superProperties = [mixpanelOptions objectForKey:@"superProperties"];
NSMutableDictionary *superPropertyTraits = [NSMutableDictionary dictionaryWithCapacity:superProperties.count];
for (NSString *superProperty in superProperties) {
superPropertyTraits[superProperty] = traits[superProperty];
}
NSDictionary *mappedSuperProperties = [SEGAnalyticsIntegration map:superPropertyTraits withMap:map];
[[self.mixpanelClass sharedInstance] registerSuperProperties:mappedSuperProperties];

if ([self peopleEnabled]) {
NSArray *peopleProperties = [mixpanelOptions objectForKey:@"peopleProperties"];
NSMutableDictionary *peoplePropertyTraits = [NSMutableDictionary dictionaryWithCapacity:peopleProperties.count];
for (NSString *peopleProperty in peopleProperties) {
peoplePropertyTraits[peopleProperty] = traits[peopleProperty];
}
NSDictionary *mappedPeopleProperties = [SEGAnalyticsIntegration map:peoplePropertyTraits withMap:map];
[[[self.mixpanelClass sharedInstance] people] set:mappedPeopleProperties];
}
}

Expand All @@ -99,7 +127,7 @@ - (void)track:(NSString *)event properties:(NSDictionary *)properties options:(N
[[self.mixpanelClass sharedInstance] track:event properties:properties];

// Don't go any further if Mixpanel people is disabled.
if (![(NSNumber *)[self.settings objectForKey:@"people"] boolValue]) {
if (![self peopleEnabled]) {
return;
}

Expand Down Expand Up @@ -160,6 +188,28 @@ - (BOOL)eventShouldIncrement:(NSString *)event
return NO;
}

// Return true the project has the People feature enabled.
- (BOOL)peopleEnabled
{
return [(NSNumber *)[self.settings objectForKey:@"people"] boolValue];
}

// Return true if all traits should be set by default.
- (BOOL)setAllTraitsByDefault
{
return [(NSNumber *)[self.settings objectForKey:@"setAllTraitsByDefault"] boolValue];
}

// Return true if all traits should be set by default.
- (NSDictionary *)mixpanelOptions:(NSDictionary *)options
{
NSDictionary *integrations = [options objectForKey:@"integrations"];
if (integrations) {
return [integrations objectForKey:@"Mixpanel"];
}
return nil;
}

- (void)reset
{
[[self.mixpanelClass sharedInstance] flush];
Expand Down
126 changes: 124 additions & 2 deletions iOS Tests/Integrations/Mixpanel/SEGMixpanelIntegrationTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ - (void)testFlush

- (void)testIdentify
{
[_integration setSettings:@{
@"token" : @"foo",
@"setAllTraitsByDefault" : @1
}];

[_integration identify:@"foo" traits:@{ @"bar" : @"baz" } options:@{}];

[verifyCount(_mixpanelMock, times(1)) identify:@"foo"];
Expand All @@ -89,7 +94,8 @@ - (void)testIdentifyWithPeople
{
[_integration setSettings:@{
@"token" : @"foo",
@"people" : @1
@"people" : @1,
@"setAllTraitsByDefault" : @1
}];

[_integration identify:@"foo" traits:@{ @"bar" : @"baz" } options:@{}];
Expand All @@ -99,8 +105,27 @@ - (void)testIdentifyWithPeople
[verifyCount(_mixpanelPeopleMock, times(1)) set:@{ @"bar" : @"baz" }];
}

- (void)testIdentifyWithTraits
- (void)testIdentifyWithPeopleAndWithoutSettingTraits
{
[_integration setSettings:@{
@"token" : @"foo",
@"people" : @1,
@"setAllTraitsByDefault" : @0
}];
[_integration identify:@"foo" traits:@{ @"bar" : @"baz" } options:@{}];

[verifyCount(_mixpanelMock, times(1)) identify:@"foo"];
[verifyCount(_mixpanelMock, times(0)) registerSuperProperties:anything()];
[verifyCount(_mixpanelPeopleMock, times(0)) set:anything()];
}

- (void)testIdentifyWithMappedTraits
{
[_integration setSettings:@{
@"token" : @"foo",
@"setAllTraitsByDefault" : @1
}];

[_integration identify:@"foo"
traits:@{
@"firstName" : @"bar",
Expand All @@ -127,6 +152,103 @@ - (void)testIdentifyWithTraits
}];
}

- (void)testIdentifyWithMappedPropertiesAndSuperProperties
{
[_integration setSettings:@{
@"token" : @"foo",
@"people" : @1,
@"setAllTraitsByDefault" : @0
}];

[_integration identify:@"foo"
traits:@{
@"firstName" : @"bar",
@"lastName" : @"baz",
@"createdAt" : @"qaz",
@"lastSeen" : @"foobar",
@"email" : @"barbaz",
@"name" : @"bazqaz",
@"username" : @"foobarbaz",
@"phone" : @"barbazqaz"
}
options:@{
@"integrations" : @{
@"Mixpanel" : @{
@"superProperties" : @[ @"firstName" ],
@"peopleProperties" : @[ @"lastName" ],
}
}
}];

[verifyCount(_mixpanelMock, times(1)) identify:@"foo"];
[verifyCount(_mixpanelMock, times(1)) registerSuperProperties:@{
@"$first_name" : @"bar"
}];
[verifyCount(_mixpanelPeopleMock, times(1)) set:@{
@"$last_name" : @"baz"
}];
}

- (void)testIdentifyWithoutSetAllTraitsAndNoMappedTraits
{
[_integration setSettings:@{
@"token" : @"foo",
@"people" : @1,
@"setAllTraitsByDefault" : @0
}];

[_integration identify:@"foo"
traits:@{
@"firstName" : @"bar",
@"lastName" : @"baz",
@"createdAt" : @"qaz",
@"lastSeen" : @"foobar",
@"email" : @"barbaz",
@"name" : @"bazqaz",
@"username" : @"foobarbaz",
@"phone" : @"barbazqaz"
}
options:@{
@"integrations" : @{
@"Mixpanel" : @{}
}
}];

[verifyCount(_mixpanelMock, times(1)) identify:@"foo"];
[verifyCount(_mixpanelMock, times(1)) registerSuperProperties:anything()];
[verifyCount(_mixpanelPeopleMock, times(1)) set:anything()];
}


- (void)testIdentifyWithoutSetAllTraitsAndNoMixpanelOptions
{
[_integration setSettings:@{
@"token" : @"foo",
@"people" : @1,
@"setAllTraitsByDefault" : @0
}];

[_integration identify:@"foo"
traits:@{
@"firstName" : @"bar",
@"lastName" : @"baz",
@"createdAt" : @"qaz",
@"lastSeen" : @"foobar",
@"email" : @"barbaz",
@"name" : @"bazqaz",
@"username" : @"foobarbaz",
@"phone" : @"barbazqaz"
}
options:@{
@"integrations" : @{}
}];

[verifyCount(_mixpanelMock, times(1)) identify:@"foo"];
[verifyCount(_mixpanelMock, times(0)) registerSuperProperties:anything()];
[verifyCount(_mixpanelPeopleMock, times(0)) set:anything()];
}


- (void)testTrack
{
[_integration track:@"foo" properties:@{ @"bar" : @"baz" } options:nil];
Expand Down

0 comments on commit 59192c3

Please sign in to comment.