From 9cf5714d874099578d65b5cac8758d9d4e5a6f69 Mon Sep 17 00:00:00 2001 From: Prateek Srivastava Date: Mon, 6 Nov 2017 13:27:52 -0800 Subject: [PATCH] Support schema defaults for new events. If an event is not present in the tracking plan, we'll now lookup the schema defaults for the project. If the event is disabled in the schema default, it will only be sent to the Segment integration (i.e. api.segment.io). If the event is enabled in the schema default, it will be sent to all integrations. Ref: https://paper.dropbox.com/doc/Schema-Client-Side-Defaults-DufdS8Ej43mnFXvvMqm1b --- .../analytics/IntegrationOperation.java | 24 ++- .../analytics/IntegrationOperationTest.java | 137 +++++++++++++++++- 2 files changed, 158 insertions(+), 3 deletions(-) diff --git a/analytics/src/main/java/com/segment/analytics/IntegrationOperation.java b/analytics/src/main/java/com/segment/analytics/IntegrationOperation.java index 003c82623..90848e80c 100644 --- a/analytics/src/main/java/com/segment/analytics/IntegrationOperation.java +++ b/analytics/src/main/java/com/segment/analytics/IntegrationOperation.java @@ -179,12 +179,32 @@ public void run(String key, Integration integration, ProjectSettings projectS } String event = trackPayload.event(); + ValueMap eventPlan = trackingPlan.getValueMap(event); if (isNullOrEmpty(eventPlan)) { - // No event plan, use options provided. - if (isIntegrationEnabled(integrationOptions, key)) { + if (!isNullOrEmpty(integrationOptions)) { + // No event plan, use options provided. + if (isIntegrationEnabled(integrationOptions, key)) { + integration.track(trackPayload); + } + return; + } + + // Use schema defaults if no options are provided. + ValueMap defaultPlan = trackingPlan.getValueMap("__default"); + + // No defaults, send the event. + if (isNullOrEmpty(defaultPlan)) { + integration.track(trackPayload); + return; + } + + // Send the event if new events are enabled or if this is the Segment integration. + boolean defaultEventsEnabled = defaultPlan.getBoolean("enabled", true); + if (defaultEventsEnabled || SegmentIntegration.SEGMENT_KEY.equals(key)) { integration.track(trackPayload); } + return; } diff --git a/analytics/src/test/java/com/segment/analytics/IntegrationOperationTest.java b/analytics/src/test/java/com/segment/analytics/IntegrationOperationTest.java index 15b897280..350c0942b 100644 --- a/analytics/src/test/java/com/segment/analytics/IntegrationOperationTest.java +++ b/analytics/src/test/java/com/segment/analytics/IntegrationOperationTest.java @@ -88,7 +88,7 @@ public void trackAllDisabledInOptionsButIntegrationEnabledWithOptions() { } @Test - public void trackNoEventPlan() throws IOException { + public void trackPlanForEvent() throws IOException { TrackPayload payload = new TrackPayload.Builder() .event("Install Attributed") .userId("userId") @@ -107,6 +107,50 @@ public void trackNoEventPlan() throws IOException { verify(integration).track(payload); } + + @Test + public void trackWithOptionsAndWithoutEventPlan() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .integrations(ImmutableMap.of("Mixpanel", false)) + .build(); + track( + payload, + "Mixpanel", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"Completed Order\": {}\n" + + " }\n" + + " }\n" + + "}")); + verify(integration, never()).track(payload); + } + + + @Test + public void trackPlanForEventWithOptions() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .integrations(Collections.singletonMap("All", false)) + .build(); + track( + payload, + "Mixpanel", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"Completed Order\": {}\n" + + " }\n" + + " }\n" + + "}")); + verify(integration, never()).track(payload); + } + @Test public void trackPlanDisabledEvent() throws IOException { TrackPayload payload = new TrackPayload.Builder() @@ -222,4 +266,95 @@ public void ignoresSegment() throws IOException { + "}")); verify(integration).track(payload); } + + @Test + public void defaultNewEventsEnabled() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .build(); + track( + payload, + "Segment.io", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"__default\": {\n" + + " \"enabled\": true\n" + + " }\n" + + " }\n" + + " }\n" + + "}")); + verify(integration).track(payload); + } + + @Test + public void defaultNewEventsDisabled() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .build(); + track( + payload, + "Mixpanel", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"__default\": {\n" + + " \"enabled\": false\n" + + " }\n" + + " }\n" + + " }\n" + + "}")); + verify(integration, never()).track(payload); + } + + @Test + public void defaultNewEventsDisabledSendToSegment() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .build(); + track( + payload, + "Segment.io", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"__default\": {\n" + + " \"enabled\": false\n" + + " }\n" + + " }\n" + + " }\n" + + "}")); + verify(integration).track(payload); + } + + @Test + public void eventPlanOverridesSchemaDefault() throws IOException { + TrackPayload payload = new TrackPayload.Builder() + .event("Install Attributed") + .userId("userId") + .build(); + track( + payload, + "Mixpanel", + Cartographer.INSTANCE.fromJson( + "{\n" + + " \"plan\": {\n" + + " \"track\": {\n" + + " \"__default\": {\n" + + " \"enabled\": true\n" + + " },\n" + + " \"Install Attributed\": {\n" + + " \"enabled\": false\n" + + " }\n" + + " }\n" + + " }\n" + + "}")); + verify(integration, never()).track(payload); + } }