Esempio n. 1
0
    def _setup_basic_test(self):
        filters = {
            "events": [
                {"id": "user signed up", "type": "events", "order": 0},
                {"id": "paid", "type": "events", "order": 1},
            ],
            "insight": INSIGHT_FUNNELS,
            "date_from": "2020-01-01",
            "date_to": "2020-01-14",
            "funnel_correlation_type": "events",
        }

        filter = Filter(data=filters)

        success_target_persons = []
        failure_target_persons = []
        events_by_person = {}
        for i in range(10):
            person_id = f"user_{i}"
            person = _create_person(distinct_ids=[person_id], team_id=self.team.pk)
            events_by_person[person_id] = [{"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)}]

            if i % 2 == 0:
                events_by_person[person_id].append(
                    {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)}
                )

                success_target_persons.append(str(person.uuid))

            events_by_person[person_id].append({"event": "paid", "timestamp": datetime(2020, 1, 4, 14)})

        for i in range(10, 20):
            person_id = f"user_{i}"
            person = _create_person(distinct_ids=[person_id], team_id=self.team.pk)
            events_by_person[person_id] = [{"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)}]
            if i % 2 == 0:
                events_by_person[person_id].append(
                    {"event": "negatively_related", "timestamp": datetime(2020, 1, 3, 14)}
                )
                failure_target_persons.append(str(person.uuid))

        # One positively_related as failure
        person_fail_id = f"user_fail"
        person_fail = _create_person(distinct_ids=[person_fail_id], team_id=self.team.pk)
        events_by_person[person_fail_id] = [
            {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)},
            {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)},
        ]

        # One negatively_related as success
        person_success_id = f"user_succ"
        person_succ = _create_person(distinct_ids=[person_success_id], team_id=self.team.pk)
        events_by_person[person_success_id] = [
            {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)},
            {"event": "negatively_related", "timestamp": datetime(2020, 1, 3, 14)},
            {"event": "paid", "timestamp": datetime(2020, 1, 4, 14)},
        ]
        journeys_for(events_by_person, self.team)

        return filter, success_target_persons, failure_target_persons, person_fail, person_succ
Esempio n. 2
0
    def test_breakdown_by_group_props(self):
        self._create_groups()

        journey = {
            "person1": [
                {
                    "event": "sign up",
                    "timestamp": datetime(2020, 1, 2, 12),
                    "properties": {"$group_0": "org:5"},
                    "group0_properties": {"industry": "finance"},
                },
                {
                    "event": "sign up",
                    "timestamp": datetime(2020, 1, 2, 13),
                    "properties": {"$group_0": "org:6"},
                    "group0_properties": {"industry": "technology"},
                },
                {
                    "event": "sign up",
                    "timestamp": datetime(2020, 1, 2, 15),
                    "properties": {"$group_0": "org:7", "$group_1": "company:10"},
                    "group0_properties": {"industry": "finance"},
                    "group1_properties": {"industry": "finance"},
                },
            ],
        }

        journeys_for(events_by_person=journey, team=self.team)

        filter = Filter(
            data={
                "date_from": "2020-01-01T00:00:00Z",
                "date_to": "2020-01-12",
                "breakdown": "industry",
                "breakdown_type": "group",
                "breakdown_group_type_index": 0,
                "events": [{"id": "sign up", "name": "sign up", "type": "events", "order": 0,}],
            }
        )
        response = Trends().run(filter, self.team,)

        self.assertEqual(len(response), 2)
        self.assertEqual(response[0]["breakdown_value"], "finance")
        self.assertEqual(response[0]["count"], 2)
        self.assertEqual(response[1]["breakdown_value"], "technology")
        self.assertEqual(response[1]["count"], 1)

        filter = filter.with_data(
            {"breakdown_value": "technology", "date_from": "2020-01-02T00:00:00Z", "date_to": "2020-01-03"}
        )
        entity = Entity({"id": "sign up", "name": "sign up", "type": "events", "order": 0,})
        res = self._get_trend_people(filter, entity)

        self.assertEqual(res[0]["distinct_ids"], ["person1"])
Esempio n. 3
0
    def test_test_account_filters_with_groups(self):
        self.team.test_account_filters = [
            {"key": "key", "type": "group", "value": "value", "group_type_index": 0},
        ]
        self.team.save()

        GroupTypeMapping.objects.create(team=self.team, group_type="organization", group_type_index=0)
        create_group(self.team.pk, group_type_index=0, group_key="in", properties={"key": "value"})
        create_group(self.team.pk, group_type_index=0, group_key="out", properties={"key": "othervalue"})

        with freeze_time("2020-01-11T12:00:00Z"):
            Person.objects.create(distinct_ids=["person1"], team_id=self.team.pk)

        with freeze_time("2020-01-09T12:00:00Z"):
            Person.objects.create(distinct_ids=["person2"], team_id=self.team.pk)

        journeys_for(
            {
                "person1": [
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 11, 12), "properties": {"$group_0": "out"},},
                ],
                "person2": [
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 9, 12), "properties": {"$group_0": "in"},},
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 12, 12), "properties": {"$group_0": "in"},},
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 15, 12), "properties": {"$group_0": "in"},},
                ],
            },
            self.team,
        )

        result = Trends().run(
            Filter(
                data={
                    "date_from": "2020-01-12T00:00:00Z",
                    "date_to": "2020-01-19T00:00:00Z",
                    "events": [{"id": "$pageview", "type": "events", "order": 0}],
                    "shown_as": TRENDS_LIFECYCLE,
                    FILTER_TEST_ACCOUNTS: True,
                },
                team=self.team,
            ),
            self.team,
        )

        self.assertLifecycleResults(
            result,
            [
                {"status": "dormant", "data": [0, -1, 0, 0, -1, 0, 0, 0]},
                {"status": "new", "data": [0, 0, 0, 0, 0, 0, 0, 0]},
                {"status": "resurrecting", "data": [1, 0, 0, 1, 0, 0, 0, 0]},
                {"status": "returning", "data": [0, 0, 0, 0, 0, 0, 0, 0]},
            ],
        )
    def test_unordered_funnel_with_groups(self):
        GroupTypeMapping.objects.create(team=self.team, group_type="organization", group_type_index=0)
        GroupTypeMapping.objects.create(team=self.team, group_type="company", group_type_index=1)

        create_group(team_id=self.team.pk, group_type_index=0, group_key="org:5", properties={"industry": "finance"})
        create_group(team_id=self.team.pk, group_type_index=0, group_key="org:6", properties={"industry": "technology"})

        create_group(team_id=self.team.pk, group_type_index=1, group_key="company:1", properties={})
        create_group(team_id=self.team.pk, group_type_index=1, group_key="company:2", properties={})

        events_by_person = {
            "user_1": [
                {"event": "user signed up", "timestamp": datetime(2020, 1, 3, 14), "properties": {"$group_0": "org:5"}},
                {  # same person, different group, so should count as different step 1 in funnel
                    "event": "user signed up",
                    "timestamp": datetime(2020, 1, 10, 14),
                    "properties": {"$group_0": "org:6"},
                },
            ],
            "user_2": [
                {  # different person, same group, so should count as step two in funnel
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 2, 14),
                    "properties": {"$group_0": "org:5"},
                }
            ],
        }
        journeys_for(events_by_person, self.team)

        params = FunnelRequest(
            events=json.dumps(
                [
                    EventPattern(id="user signed up", type="events", order=0),
                    EventPattern(id="paid", type="events", order=1),
                ]
            ),
            date_from="2020-01-01",
            date_to="2020-01-14",
            aggregation_group_type_index=0,
            funnel_order_type="unordered",
            insight=INSIGHT_FUNNELS,
        )

        result = get_funnel_ok(self.client, self.team.pk, params)

        assert result["user signed up"]["count"] == 2
        assert result["paid"]["count"] == 1
        assert result["paid"]["average_conversion_time"] == 86400

        actors = get_funnel_actors_ok(self.client, result["user signed up"]["converted_people_url"])
        assert len(actors) == 2
Esempio n. 5
0
    def _setup_returning_lifecycle_data(self, days):
        with freeze_time("2019-01-01T12:00:00Z"):
            Person.objects.create(distinct_ids=["person1"], team_id=self.team.pk)

        journeys_for(
            {
                "person1": [
                    {"event": "$pageview", "timestamp": (now() - timedelta(days=n)).strftime("%Y-%m-%d %H:%M:%S.%f")}
                    for n in range(days)
                ],
            },
            self.team,
            create_people=False,
        )
    def test_timezones(self, patch_feature_enabled):
        journeys_for(
            {
                "person1": [
                    {
                        "event": "$pageview",
                        "timestamp": datetime(2021, 5, 2, 1),
                    },  # this time will fall on 5/1 in US Pacific
                    {"event": "$pageview", "timestamp": datetime(2021, 5, 2, 9)},
                    {"event": "$pageview", "timestamp": datetime(2021, 5, 4, 3)},
                ],
            },
            self.team,
        )

        data = ClickhouseStickiness().run(
            filter=StickinessFilter(
                data={
                    "shown_as": "Stickiness",
                    "date_from": "2021-05-01",
                    "date_to": "2021-05-15",
                    "events": [{"id": "$pageview"}],
                },
                team=self.team,
            ),
            team=self.team,
        )

        self.assertEqual(data[0]["days"], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
        self.assertEqual(data[0]["data"], [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

        self.team.timezone = "US/Pacific"
        self.team.save()

        data_pacific = ClickhouseStickiness().run(
            filter=StickinessFilter(
                data={
                    "shown_as": "Stickiness",
                    "date_from": "2021-05-01",
                    "date_to": "2021-05-15",
                    "events": [{"id": "$pageview"}],
                },
                team=self.team,
            ),
            team=self.team,
        )

        self.assertEqual(data_pacific[0]["days"], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
        self.assertEqual(data_pacific[0]["data"], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
Esempio n. 7
0
    def test_funnel_group_aggregation_with_groups_entity_filtering(self):
        self._create_groups()

        events_by_person = {
            "user_1": [
                {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14), "properties": {"$group_0": "org:5"}}
            ],
            "user_2": [
                {  # different person, same group, so should count as step two in funnel
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {"$group_0": "org:5"},
                },
            ],
            "user_3": [
                {  # different person, different group, so should be discarded from step 1 in funnel
                    "event": "user signed up",
                    "timestamp": datetime(2020, 1, 10, 14),
                    "properties": {"$group_0": "org:6"},
                },
            ],
        }
        journeys_for(events_by_person, self.team)

        params = FunnelRequest(
            events=json.dumps([
                EventPattern(id="user signed up",
                             type="events",
                             order=0,
                             properties={"$group_0": "org:5"}),
                EventPattern(id="paid", type="events", order=1),
            ]),
            date_from="2020-01-01",
            date_to="2020-01-14",
            aggregation_group_type_index=0,
            insight=INSIGHT_FUNNELS,
        )

        result = get_funnel_ok(self.client, self.team.pk, params)

        assert result["user signed up"]["count"] == 1
        assert result["paid"]["count"] == 1
        assert result["paid"]["average_conversion_time"] == 86400

        actors = get_funnel_actors_ok(
            self.client, result["user signed up"]["converted_people_url"])
        actor_ids = [str(val["id"]) for val in actors]
        assert actor_ids == ["org:5"]
Esempio n. 8
0
    def test_people_arent_returned_multiple_times(self):

        people = journeys_for(
            {
                "user_1": [
                    {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14)},
                    {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)},
                    # duplicate event
                    {"event": "positively_related", "timestamp": datetime(2020, 1, 3, 14)},
                    {"event": "paid", "timestamp": datetime(2020, 1, 4, 14)},
                ]
            },
            self.team,
        )

        filter = Filter(
            data={
                "events": [
                    {"id": "user signed up", "type": "events", "order": 0},
                    {"id": "paid", "type": "events", "order": 1},
                ],
                "insight": INSIGHT_FUNNELS,
                "date_from": "2020-01-01",
                "date_to": "2020-01-14",
                "funnel_correlation_type": "events",
                "funnel_correlation_person_entity": {"id": "positively_related", "type": "events"},
                "funnel_correlation_person_converted": "TrUe",
            }
        )
        _, serialized_actors = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertCountEqual([str(val["id"]) for val in serialized_actors], [str(people["user_1"].uuid)])
Esempio n. 9
0
    def test_lifecycle_edge_cases(self):
        # This test tests behavior when created_at is different from first matching event and dormant/resurrecting/returning logic
        with freeze_time("2020-01-11T12:00:00Z"):
            Person.objects.create(distinct_ids=["person1"], team_id=self.team.pk)

        journeys_for(
            {
                "person1": [
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 12, 12),},
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 13, 12),},
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 15, 12),},
                    {"event": "$pageview", "timestamp": datetime(2020, 1, 16, 12),},
                ],
            },
            self.team,
        )

        result = Trends().run(
            Filter(
                data={
                    "date_from": "2020-01-11T00:00:00Z",
                    "date_to": "2020-01-18T00:00:00Z",
                    "events": [{"id": "$pageview", "type": "events", "order": 0}],
                    "shown_as": TRENDS_LIFECYCLE,
                },
                team=self.team,
            ),
            self.team,
        )

        self.assertLifecycleResults(
            result,
            [
                {"status": "dormant", "data": [0, 0, 0, -1, 0, 0, -1, 0]},
                {"status": "new", "data": [0, 0, 0, 0, 0, 0, 0, 0]},
                {"status": "resurrecting", "data": [0, 1, 0, 0, 1, 0, 0, 0]},
                {"status": "returning", "data": [0, 0, 1, 0, 0, 1, 0, 0]},
            ],
        )
Esempio n. 10
0
    def test_event_correlation_endpoint_does_not_include_funnel_steps(self):
        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            # Add Person1 with only the funnel steps involved

            events = {
                "Person 1": [
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "some waypoint",
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                # We need atleast 1 success and failure to return a result
                "Person 2": [
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "some waypoint",
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }
            # '' is a weird event name to have, but if it exists, our duty to report it

            journeys_for(events_by_person=events, team=self.team)

            # We need to make sure we clear the cache other tests that have run
            # done interfere with this test
            cache.clear()

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="some waypoint"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

        assert odds == {
            "is_cached": False,
            "last_refresh": "2020-01-01T00:00:00Z",
            "result": {
                "events": [{
                    "correlation_type": "failure",
                    "event": {
                        "event": "",
                        "elements": [],
                        "properties": {}
                    },
                    "failure_count": 1,
                    "odds_ratio": 1 / 4,
                    "success_count": 0,
                    "success_people_url": ANY,
                    "failure_people_url": ANY,
                }],
                "skewed":
                False,
            },
        }
Esempio n. 11
0
    def test_funnel_aggregation_with_groups_with_cohort_filtering(self):

        GroupTypeMapping.objects.create(team=self.team,
                                        group_type="organization",
                                        group_type_index=0)
        GroupTypeMapping.objects.create(team=self.team,
                                        group_type="company",
                                        group_type_index=1)

        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:5",
                     properties={"industry": "finance"})
        create_group(team_id=self.team.pk,
                     group_type_index=0,
                     group_key="org:6",
                     properties={"industry": "technology"})

        create_group(team_id=self.team.pk,
                     group_type_index=1,
                     group_key="company:1",
                     properties={})
        create_group(team_id=self.team.pk,
                     group_type_index=1,
                     group_key="company:2",
                     properties={})

        _create_person(distinct_ids=[f"user_1"],
                       team=self.team,
                       properties={"email": "*****@*****.**"})
        _create_person(distinct_ids=[f"user_2"],
                       team=self.team,
                       properties={"email": "*****@*****.**"})
        _create_person(distinct_ids=[f"user_3"],
                       team=self.team,
                       properties={"email": "*****@*****.**"})

        action1 = Action.objects.create(team=self.team, name="action1")
        ActionStep.objects.create(
            event="$pageview",
            action=action1,
        )

        cohort = Cohort.objects.create(
            team=self.team,
            groups=[{
                "properties": [{
                    "key": "email",
                    "operator": "icontains",
                    "value": "*****@*****.**",
                    "type": "person"
                }]
            }],
        )

        events_by_person = {
            "user_1": [
                {"event": "$pageview", "timestamp": datetime(2020, 1, 2, 14), "properties": {"$group_0": "org:5"}},
                {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14), "properties": {"$group_0": "org:5"}},
                {
                    "event": "user signed up",  # same person, different group, so should count as different step 1 in funnel
                    "timestamp": datetime(2020, 1, 10, 14),
                    "properties": {"$group_0": "org:6"},
                },
            ],
            "user_2": [
                {  # different person, same group, so should count as step two in funnel
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {"$group_0": "org:5"},
                },
            ],
            "user_3": [
                {"event": "user signed up", "timestamp": datetime(2020, 1, 2, 14), "properties": {"$group_0": "org:7"}},
                {  # person not in cohort so should be filtered out
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {"$group_0": "org:7"},
                },
            ],
        }
        journeys_for(events_by_person, self.team)
        cohort.calculate_people_ch(pending_version=0)

        filters = {
            "events": [
                {
                    "id":
                    "user signed up",
                    "type":
                    "events",
                    "order":
                    0,
                    "properties": [{
                        "type": "precalculated-cohort",
                        "key": "id",
                        "value": cohort.pk
                    }],
                },
                {
                    "id": "paid",
                    "type": "events",
                    "order": 1
                },
            ],
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-14",
            "aggregation_group_type_index":
            0,
        }

        filter = Filter(data=filters)
        funnel = ClickhouseFunnel(filter, self.team)
        result = funnel.run()

        self.assertEqual(result[0]["name"], "user signed up")
        self.assertEqual(result[0]["count"], 2)

        self.assertEqual(result[1]["name"], "paid")
        self.assertEqual(result[1]["count"], 1)
Esempio n. 12
0
    def test_basic_secondary_metric_results(self):
        journeys_for(
            {
                # For a trend pageview metric
                "person1": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person2": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                "person3": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                # doesn't have feature set
                "person_out_of_control": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                    },
                ],
                "person_out_of_end_date": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-08-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                # for a funnel conversion metric
                "person1_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                    {
                        "event": "$pageleave_funnel",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person2_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                    {
                        "event": "$pageleave_funnel",
                        "timestamp": "2020-01-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                "person3_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                    {
                        "event": "$pageleave_funnel",
                        "timestamp": "2020-01-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                # doesn't have feature set
                "person_out_of_control_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-03",
                    },
                    {
                        "event": "$pageleave_funnel",
                        "timestamp": "2020-01-05",
                    },
                ],
                "person_out_of_end_date_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-08-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                    {
                        "event": "$pageleave_funnel",
                        "timestamp": "2020-08-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                # non-converters with FF
                "person4_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person5_funnel": [
                    {
                        "event": "$pageview_funnel",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
            },
            self.team,
        )

        ff_key = "a-b-test"
        # generates the FF which should result in the above events^
        creation_response = self.client.post(
            f"/api/projects/{self.team.id}/experiments/",
            {
                "name":
                "Test Experiment",
                "description":
                "",
                "start_date":
                "2020-01-01T00:00",
                "end_date":
                "2020-01-06T00:00",
                "feature_flag_key":
                ff_key,
                "parameters": {},
                "secondary_metrics": [
                    {
                        "name": "trends whatever",
                        "filters": {
                            "insight":
                            "trends",
                            "events": [{
                                "order": 0,
                                "id": "$pageview"
                            }],
                            "properties":
                            [{
                                "key": "$geoip_country_name",
                                "type": "person",
                                "value": ["france"],
                                "operator": "exact",
                            }
                             # properties superceded by FF breakdown
                             ],
                        },
                    },
                    {
                        "name": "funnels whatever",
                        "filters": {
                            "insight":
                            "funnels",
                            "events": [{
                                "order": 0,
                                "id": "$pageview_funnel"
                            }, {
                                "order": 1,
                                "id": "$pageleave_funnel"
                            }],
                            "properties": [
                                {
                                    "key": "$geoip_country_name",
                                    "type": "person",
                                    "value": ["france"],
                                    "operator": "exact",
                                }
                                # properties superceded by FF breakdown
                            ],
                        },
                    },
                ],
                # target metric insignificant since we're testing secondaries right now
                "filters": {
                    "insight": "trends",
                    "events": [{
                        "order": 0,
                        "id": "whatever"
                    }],
                },
            },
        )

        id = creation_response.json()["id"]

        response = self.client.get(
            f"/api/projects/{self.team.id}/experiments/{id}/secondary_results?id=0"
        )
        self.assertEqual(200, response.status_code)

        response_data = response.json()

        self.assertEqual(len(response_data["result"].items()), 2)

        self.assertEqual(response_data["result"]["control"], 3)
        self.assertEqual(response_data["result"]["test"], 1)

        response = self.client.get(
            f"/api/projects/{self.team.id}/experiments/{id}/secondary_results?id=1"
        )
        self.assertEqual(200, response.status_code)

        response_data = response.json()

        self.assertEqual(len(response_data["result"].items()), 2)

        self.assertAlmostEqual(response_data["result"]["control"], 1)
        self.assertEqual(response_data["result"]["test"], round(1 / 3, 3))
Esempio n. 13
0
    def test_funnel_with_groups_global_filtering(self):
        self._create_groups()

        events_by_person = {
            "user_1": [
                {
                    "event": "user signed up",
                    "timestamp": datetime(2020, 1, 2, 14),
                    "properties": {
                        "$group_0": "org:5"
                    }
                },
                {
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {
                        "$group_0": "org:6"
                    },  # second event belongs to different group, so shouldn't complete funnel
                },
            ],
            "user_2": [
                {
                    "event":
                    "user signed up",  # event belongs to different group, so shouldn't enter funnel
                    "timestamp": datetime(2020, 1, 2, 14),
                    "properties": {
                        "$group_0": "org:6"
                    },
                },
                {
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {
                        "$group_0": "org:5"
                    },  # same group, but different person, so not in funnel
                },
            ],
        }
        created_people = journeys_for(events_by_person, self.team)

        params = FunnelRequest(
            events=json.dumps([
                EventPattern(id="user signed up", type="events", order=0),
                EventPattern(id="paid", type="events", order=1),
            ]),
            date_from="2020-01-01",
            date_to="2020-01-14",
            insight=INSIGHT_FUNNELS,
            properties=json.dumps([{
                "key": "industry",
                "value": "finance",
                "type": "group",
                "group_type_index": 0
            }]),
        )

        result = get_funnel_ok(self.client, self.team.pk, params)

        assert result["user signed up"]["count"] == 1
        assert result["paid"]["count"] == 0

        actors = get_funnel_actors_ok(
            self.client, result["user signed up"]["converted_people_url"])
        actor_ids = [str(val["id"]) for val in actors]

        assert actor_ids == sorted([str(created_people["user_1"].uuid)])
Esempio n. 14
0
    def test_funnel_with_groups_entity_filtering(self):
        self._create_groups()

        events_by_person = {
            "user_1": [
                {
                    "event": "user signed up",
                    "timestamp": datetime(2020, 1, 2, 14),
                    "properties": {
                        "$group_0": "org:5"
                    }
                },
                {
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {
                        "$group_0": "org:6"
                    },  # different group, but doesn't matter since not aggregating by groups
                },
                {
                    "event":
                    "user signed up",  # event belongs to different group, so shouldn't enter funnel
                    "timestamp": datetime(2020, 1, 2, 14),
                    "properties": {
                        "$group_0": "org:6"
                    },
                },
                {
                    "event": "paid",
                    "timestamp": datetime(2020, 1, 3, 14),
                    "properties": {
                        "$group_0": "org:6"
                    },  # event belongs to different group, so shouldn't enter funnel
                },
            ],
        }
        created_people = journeys_for(events_by_person, self.team)

        params = FunnelRequest(
            events=json.dumps([
                EventPattern(id="user signed up",
                             type="events",
                             order=0,
                             properties={"$group_0": "org:5"}),
                EventPattern(id="paid", type="events", order=1),
            ]),
            date_from="2020-01-01",
            date_to="2020-01-14",
            insight=INSIGHT_FUNNELS,
        )

        result = get_funnel_ok(self.client, self.team.pk, params)

        assert result["user signed up"]["count"] == 1
        assert result["paid"]["count"] == 1
        assert result["paid"]["average_conversion_time"] == 86400

        actors = get_funnel_actors_ok(
            self.client, result["user signed up"]["converted_people_url"])
        actor_ids = [str(val["id"]) for val in actors]

        assert actor_ids == sorted([str(created_people["user_1"].uuid)])
Esempio n. 15
0
    def test_secondary_metric_results_for_multiple_variants(self):
        journeys_for(
            {
                # trend metric first
                "person1_2_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_2"
                        },
                    },
                ],
                "person1_1_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                ],
                "person2_1_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                ],
                "person2_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                "person3_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                "person4_trend": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                # doesn't have feature set
                "person_out_of_control": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-01-03",
                    },
                ],
                "person_out_of_end_date": [
                    {
                        "event": "$pageview_trend",
                        "timestamp": "2020-08-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        },
                    },
                ],
                # funnel metric second
                "person1_2": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_2"
                        },
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test_2"
                        },
                    },
                ],
                "person1_1": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                ],
                "person2_1": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                ],
                "person1": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person2": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                "person3": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                # doesn't have feature set
                "person_out_of_control": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-01-05",
                    },
                ],
                "person_out_of_end_date": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-08-03",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                    {
                        "event": "$pageleave",
                        "timestamp": "2020-08-05",
                        "properties": {
                            "$feature/a-b-test": "control"
                        }
                    },
                ],
                # non-converters with FF
                "person4": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-03",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person5": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-04",
                        "properties": {
                            "$feature/a-b-test": "test"
                        },
                    },
                ],
                "person6_1": [
                    {
                        "event": "$pageview",
                        "timestamp": "2020-01-02",
                        "properties": {
                            "$feature/a-b-test": "test_1"
                        },
                    },
                ],
            },
            self.team,
        )

        ff_key = "a-b-test"
        # generates the FF which should result in the above events^
        creation_response = self.client.post(
            f"/api/projects/{self.team.id}/experiments/",
            {
                "name":
                "Test Experiment",
                "description":
                "",
                "start_date":
                "2020-01-01T00:00",
                "end_date":
                "2020-01-06T00:00",
                "feature_flag_key":
                ff_key,
                "parameters": {
                    "feature_flag_variants": [
                        {
                            "key": "control",
                            "name": "Control Group",
                            "rollout_percentage": 25
                        },
                        {
                            "key": "test_1",
                            "name": "Test Variant 1",
                            "rollout_percentage": 25
                        },
                        {
                            "key": "test_2",
                            "name": "Test Variant 2",
                            "rollout_percentage": 25
                        },
                        {
                            "key": "test",
                            "name": "Test Variant 3",
                            "rollout_percentage": 25
                        },
                    ],
                },
                "secondary_metrics": [
                    {
                        "name": "secondary metric",
                        "filters": {
                            "insight": "trends",
                            "events": [{
                                "order": 0,
                                "id": "$pageview_trend"
                            }]
                        },
                    },
                    {
                        "name": "funnel metric",
                        "filters": {
                            "insight":
                            "funnels",
                            "events": [{
                                "order": 0,
                                "id": "$pageview"
                            }, {
                                "order": 1,
                                "id": "$pageleave"
                            }],
                        },
                    },
                ],
                # target metric insignificant since we're testing secondaries right now
                "filters": {
                    "insight": "trends",
                    "events": [{
                        "order": 0,
                        "id": "whatever"
                    }],
                },
            },
        )

        id = creation_response.json()["id"]

        response = self.client.get(
            f"/api/projects/{self.team.id}/experiments/{id}/secondary_results?id=0"
        )
        self.assertEqual(200, response.status_code)

        response_data = response.json()

        # trend missing 'test' variant, so it's not in the results
        self.assertEqual(len(response_data["result"].items()), 3)

        self.assertEqual(response_data["result"]["control"], 3)
        self.assertEqual(response_data["result"]["test_1"], 2)
        self.assertEqual(response_data["result"]["test_2"], 1)

        response = self.client.get(
            f"/api/projects/{self.team.id}/experiments/{id}/secondary_results?id=1"
        )
        self.assertEqual(200, response.status_code)

        response_data = response.json()

        # funnel not missing 'test' variant, so it's in the results
        self.assertEqual(len(response_data["result"].items()), 4)

        self.assertAlmostEqual(response_data["result"]["control"], 1)
        self.assertAlmostEqual(response_data["result"]["test"],
                               round(1 / 3, 3))
        self.assertAlmostEqual(response_data["result"]["test_1"],
                               round(2 / 3, 3))
        self.assertAlmostEqual(response_data["result"]["test_2"], 1)
Esempio n. 16
0
    def test_properties_correlation_endpoint_provides_people_drill_down_urls(
            self):
        """
        Here we are setting up three users, two with a specified property but
        differing values, and one with this property absent. We expect to be
        able to use the correlation people drill down urls to retrieve the
        associated people for each.
        """

        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            update_or_create_person(distinct_ids=["Person 1"],
                                    team_id=self.team.pk,
                                    properties={"$browser": "1"})
            update_or_create_person(distinct_ids=["Person 2"],
                                    team_id=self.team.pk,
                                    properties={"$browser": "1"})

            events = {
                "Person 1": [
                    # Failure / $browser::1
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                ],
                "Person 2": [
                    # Success / $browser::1
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                "Person 3": [
                    # Success / $browser not set
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                    funnel_correlation_type=FunnelCorrelationType.PROPERTIES,
                    funnel_correlation_names=json.dumps(["$browser"]),
                ),
            )

            (browser_correlation, ) = [
                correlation for correlation in odds["result"]["events"]
                if correlation["event"]["event"] == "$browser::1"
            ]

            (notset_correlation, ) = [
                correlation for correlation in odds["result"]["events"]
                if correlation["event"]["event"] == "$browser::"
            ]

            assert get_people_for_correlation_ok(
                client=self.client, correlation=browser_correlation) == {
                    "success": ["Person 2"],
                    "failure": ["Person 1"],
                }

            assert get_people_for_correlation_ok(
                client=self.client, correlation=notset_correlation) == {
                    "success": ["Person 3"],
                    "failure": [],
                }
Esempio n. 17
0
    def test_events_with_properties_correlation_endpoint_provides_people_drill_down_urls(
            self):
        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            events = {
                "Person 1": [
                    # Failure / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "properties": {
                            "$browser": "1"
                        },
                        "timestamp": datetime(2020, 1, 2)
                    },
                ],
                "Person 2": [
                    # Success / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "properties": {
                            "$browser": "1"
                        },
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                "Person 3": [
                    # Success / watched. We need to have three event instances
                    # for this test otherwise the endpoint doesn't return results
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "properties": {
                            "$browser": "1"
                        },
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                "Person 4": [
                    # Success / didn't watch. Want to use this user to verify
                    # that we don't pull in unrelated users erroneously
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    funnel_correlation_type=FunnelCorrelationType.
                    EVENT_WITH_PROPERTIES,
                    funnel_correlation_event_names=json.dumps(
                        ["watched video"]),
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

            assert odds["result"]["events"][0]["event"][
                "event"] == "watched video::$browser::1"
            watched_video_correlation = odds["result"]["events"][0]

            assert get_people_for_correlation_ok(
                client=self.client, correlation=watched_video_correlation) == {
                    "success": ["Person 2", "Person 3"],
                    "failure": ["Person 1"],
                }
Esempio n. 18
0
    def test_event_correlation_endpoint_picks_up_events_for_odds_ratios(self):
        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            # Add in two people:
            #
            # Person 1 - a single signup event
            # Person 2 - a signup event and a view insights event
            #
            # Both of them have a "watched video" event
            #
            # We then create Person 3, one successful, the other
            # not. Both have not watched the video.
            #
            # So our contingency table for "watched video" should be
            #
            # |                  | success  | failure  | total    |
            # | ---------------- | -------- | -------- | -------- |
            # | watched          | 1        | 1        | 2        |
            # | did not watched  | 1        | 0        | 1        |
            # | total            | 2        | 1        | 3        |
            #
            # For Calculating Odds Ratio, we add a prior count of 1 to everything
            #
            # So our odds ratio should be
            #  (success + prior / failure + prior) * (failure_total - failure + prior / success_total - success + prior)
            # = ( 1 + 1 / 1 + 1) * ( 1 - 1 + 1 / 2 - 1 + 1)
            # = 1 / 2

            events = {
                "Person 1": [
                    #  Failure / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "timestamp": datetime(2020, 1, 2)
                    },
                ],
                "Person 2": [
                    #  Success / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                "Person 3": [
                    # Success / did not watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

        assert odds == {
            "is_cached": False,
            "last_refresh": "2020-01-01T00:00:00Z",
            "result": {
                "events": [
                    {
                        "event": {
                            "event": "watched video",
                            "elements": [],
                            "properties": {}
                        },
                        "failure_count": 1,
                        "success_count": 1,
                        "success_people_url": ANY,
                        "failure_people_url": ANY,
                        "odds_ratio": 1 / 2,
                        "correlation_type": "failure",
                    },
                ],
                "skewed":
                False,
            },
        }
Esempio n. 19
0
        def test_funnel_breakdown_group(self):
            self._create_groups()

            people = journeys_for(
                {
                    "person1": [
                        {
                            "event": "sign up",
                            "timestamp": datetime(2020, 1, 1, 12),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                        {
                            "event": "play movie",
                            "timestamp": datetime(2020, 1, 1, 13),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                        {
                            "event": "buy",
                            "timestamp": datetime(2020, 1, 1, 15),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                    ],
                    "person2": [
                        {
                            "event": "sign up",
                            "timestamp": datetime(2020, 1, 2, 14),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                        {
                            "event": "play movie",
                            "timestamp": datetime(2020, 1, 2, 16),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                    ],
                    "person3": [
                        {
                            "event": "sign up",
                            "timestamp": datetime(2020, 1, 2, 14),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                    ],
                },
                self.team,
            )

            filters = {
                "events": [{
                    "id": "sign up",
                    "order": 0
                }, {
                    "id": "play movie",
                    "order": 1
                }, {
                    "id": "buy",
                    "order": 2
                }],
                "insight":
                INSIGHT_FUNNELS,
                "date_from":
                "2020-01-01",
                "date_to":
                "2020-01-08",
                "funnel_window_days":
                7,
                "breakdown":
                "industry",
                "breakdown_type":
                "group",
                "breakdown_group_type_index":
                0,
            }

            filter = Filter(data=filters, team=self.team)
            result = Funnel(filter, self.team).run()

            assert_funnel_breakdown_result_is_correct(
                result[0],
                [
                    FunnelStepResult(
                        name="sign up", breakdown="finance", count=1),
                    FunnelStepResult(
                        name="play movie",
                        breakdown="finance",
                        count=1,
                        average_conversion_time=3600.0,
                        median_conversion_time=3600.0,
                    ),
                    FunnelStepResult(
                        name="buy",
                        breakdown="finance",
                        count=1,
                        average_conversion_time=7200.0,
                        median_conversion_time=7200.0,
                    ),
                ],
            )

            # Querying persons when aggregating by persons should be ok, despite group breakdown
            self.assertCountEqual(
                self._get_actor_ids_at_step(filter, 1, "finance"),
                [people["person1"].uuid])
            self.assertCountEqual(
                self._get_actor_ids_at_step(filter, 2, "finance"),
                [people["person1"].uuid])

            assert_funnel_breakdown_result_is_correct(
                result[1],
                [
                    FunnelStepResult(
                        name="sign up", breakdown="technology", count=2),
                    FunnelStepResult(
                        name="play movie",
                        breakdown="technology",
                        count=1,
                        average_conversion_time=7200.0,
                        median_conversion_time=7200.0,
                    ),
                    FunnelStepResult(
                        name="buy", breakdown="technology", count=0),
                ],
            )

            self.assertCountEqual(
                self._get_actor_ids_at_step(filter, 1, "technology"),
                [people["person2"].uuid, people["person3"].uuid])
            self.assertCountEqual(
                self._get_actor_ids_at_step(filter, 2, "technology"),
                [people["person2"].uuid])
Esempio n. 20
0
    def test_event_correlation_endpoint_does_not_include_historical_events(
            self):
        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            # Add in two people:
            #
            # Person 1 - a single signup event
            # Person 2 - a signup event and a view insights event
            #
            # Both of them have a "watched video" event but they are before the
            # signup event

            events = {
                "Person 1": [
                    {
                        "event": "watched video",
                        "timestamp": datetime(2019, 1, 2)
                    },
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                ],
                "Person 2": [
                    {
                        "event": "watched video",
                        "timestamp": datetime(2019, 1, 2)
                    },
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            # We need to make sure we clear the cache other tests that have run
            # done interfere with this test
            cache.clear()

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

        assert odds == {
            "is_cached": False,
            "last_refresh": "2020-01-01T00:00:00Z",
            "result": {
                "events": [],
                "skewed": False
            },
        }
Esempio n. 21
0
    def test_event_correlation_is_partitioned_by_team(self):
        """
        Ensure there's no crosstalk between teams

        We check this by:

         1. loading events into team 1
         2. checking correlation for team 1
         3. loading events into team 2
         4. checking correlation for team 1 again, they should be the same

        """
        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            events = {
                "Person 1": [
                    {
                        "event": "watched video",
                        "timestamp": datetime(2019, 1, 2)
                    },
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                ],
                "Person 2": [
                    {
                        "event": "watched video",
                        "timestamp": datetime(2019, 1, 2)
                    },
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            odds_before = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

            other_team = create_team(organization=self.organization)
            journeys_for(events_by_person=events, team=other_team)

            # We need to make sure we clear the cache so we get the same results again
            cache.clear()

            odds_after = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

            assert odds_before == odds_after
Esempio n. 22
0
    def test_events_correlation_endpoint_provides_people_drill_down_urls(self):
        """
        Here we are setting up three users, and looking to retrieve one
        correlation for watched video, with a url we can use to retrieve people
        that successfully completed the funnel AND watched the video, and
        another for people that did not complete the funnel but also watched the
        video.
        """

        with freeze_time("2020-01-01"):
            self.client.force_login(self.user)

            events = {
                "Person 1": [
                    # Failure / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "timestamp": datetime(2020, 1, 2)
                    },
                ],
                "Person 2": [
                    # Success / watched
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "watched video",
                        "timestamp": datetime(2020, 1, 2)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
                "Person 3": [
                    # Success / did not watched. We don't expect to retrieve
                    # this one as part of the
                    {
                        "event": "signup",
                        "timestamp": datetime(2020, 1, 1)
                    },
                    {
                        "event": "view insights",
                        "timestamp": datetime(2020, 1, 3)
                    },
                ],
            }

            journeys_for(events_by_person=events, team=self.team)

            odds = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="signup"),
                        EventPattern(id="view insights")
                    ]),
                    date_to="2020-04-04",
                ),
            )

            assert odds["result"]["events"][0]["event"][
                "event"] == "watched video"
            watched_video_correlation = odds["result"]["events"][0]

            assert get_people_for_correlation_ok(
                client=self.client, correlation=watched_video_correlation) == {
                    "success": ["Person 2"],
                    "failure": ["Person 1"],
                }
Esempio n. 23
0
        def test_funnel_aggregate_by_groups_breakdown_group(self):
            self._create_groups()

            journeys_for(
                {
                    "person1": [
                        {
                            "event": "sign up",
                            "timestamp": datetime(2020, 1, 1, 12),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                        {
                            "event": "play movie",
                            "timestamp": datetime(2020, 1, 1, 13),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                        {
                            "event": "buy",
                            "timestamp": datetime(2020, 1, 1, 15),
                            "properties": {
                                "$group_0": "org:5",
                                "$browser": "Chrome"
                            },
                        },
                    ],
                    "person2": [
                        {
                            "event": "sign up",
                            "timestamp": datetime(2020, 1, 2, 14),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                        {
                            "event": "play movie",
                            "timestamp": datetime(2020, 1, 2, 16),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                    ],
                    "person3": [
                        {
                            "event": "buy",
                            "timestamp": datetime(2020, 1, 2, 18),
                            "properties": {
                                "$group_0": "org:6",
                                "$browser": "Safari"
                            },
                        },
                    ],
                },
                self.team,
            )

            filters = {
                "events": [{
                    "id": "sign up",
                    "order": 0
                }, {
                    "id": "play movie",
                    "order": 1
                }, {
                    "id": "buy",
                    "order": 2
                }],
                "insight":
                INSIGHT_FUNNELS,
                "date_from":
                "2020-01-01",
                "date_to":
                "2020-01-08",
                "funnel_window_days":
                7,
                "breakdown":
                "industry",
                "breakdown_type":
                "group",
                "breakdown_group_type_index":
                0,
                "aggregation_group_type_index":
                0,
            }

            result = Funnel(Filter(data=filters, team=self.team),
                            self.team).run()

            assert_funnel_breakdown_result_is_correct(
                result[0],
                [
                    FunnelStepResult(
                        name="sign up", breakdown="finance", count=1),
                    FunnelStepResult(
                        name="play movie",
                        breakdown="finance",
                        count=1,
                        average_conversion_time=3600.0,
                        median_conversion_time=3600.0,
                    ),
                    FunnelStepResult(
                        name="buy",
                        breakdown="finance",
                        count=1,
                        average_conversion_time=7200.0,
                        median_conversion_time=7200.0,
                    ),
                ],
            )

            assert_funnel_breakdown_result_is_correct(
                result[1],
                [
                    FunnelStepResult(
                        name="sign up", breakdown="technology", count=1),
                    FunnelStepResult(
                        name="play movie",
                        breakdown="technology",
                        count=1,
                        average_conversion_time=7200.0,
                        median_conversion_time=7200.0,
                    ),
                    FunnelStepResult(
                        name="buy",
                        breakdown="technology",
                        count=1,
                        average_conversion_time=7200.0,
                        median_conversion_time=7200.0,
                    ),
                ],
            )