示例#1
0
    def test_cohort_get_person_ids_by_cohort_id(self):
        user1 = _create_person(distinct_ids=["user1"],
                               team_id=self.team.pk,
                               properties={"$some_prop": "something"})
        _create_person(distinct_ids=["user2"],
                       team_id=self.team.pk,
                       properties={"$some_prop": "another"})
        user3 = _create_person(distinct_ids=["user3"],
                               team_id=self.team.pk,
                               properties={"$some_prop": "something"})
        cohort = Cohort.objects.create(
            team=self.team,
            groups=[{
                "properties": [{
                    "key": "$some_prop",
                    "value": "something",
                    "type": "person"
                }]
            }],
            name="cohort1",
        )

        results = get_person_ids_by_cohort_id(self.team, cohort.id)
        self.assertEqual(len(results), 2)
        self.assertIn(str(user1.uuid), results)
        self.assertIn(str(user3.uuid), results)
示例#2
0
 def _create_sample_data(self, num, delete=False):
     for i in range(num):
         if delete:
             person = Person.objects.create(distinct_ids=[f"user_{i}"],
                                            team=self.team)
         else:
             _create_person(distinct_ids=[f"user_{i}"], team=self.team)
         _create_event(
             event="step one",
             distinct_id=f"user_{i}",
             team=self.team,
             timestamp="2021-05-01 00:00:00",
             properties={"$browser": "Chrome"},
         )
         if i % 2 == 0:
             _create_event(
                 event="step two",
                 distinct_id=f"user_{i}",
                 team=self.team,
                 timestamp="2021-05-01 00:10:00",
                 properties={"$browser": "Chrome"},
             )
         _create_event(
             event="step three",
             distinct_id=f"user_{i}",
             team=self.team,
             timestamp="2021-05-01 00:20:00",
             properties={"$browser": "Chrome"},
         )
         if delete:
             person.delete()
示例#3
0
    def test_backwards_compatible_path_types(self):

        _create_person(team=self.team, distinct_ids=["person_1"])
        _create_event(
            properties={"$current_url": "/"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/something else"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$screen_name": "/screen1"}, distinct_id="person_1", event="$screen", team=self.team,
        )
        _create_event(
            distinct_id="person_1", event="custom1", team=self.team,
        )
        _create_event(
            distinct_id="person_1", event="custom2", team=self.team,
        )
        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path", data={"path_type": "$pageview", "insight": "PATHS",}
        ).json()
        self.assertEqual(len(response["result"]), 2)

        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path", data={"path_type": "custom_event", "insight": "PATHS"}
        ).json()
        self.assertEqual(len(response["result"]), 1)
        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path", data={"path_type": "$screen", "insight": "PATHS"}
        ).json()
        self.assertEqual(len(response["result"]), 0)
示例#4
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
示例#5
0
    def _create_sample_data(self):
        distinct_id = "user_one_{}".format(self.team.pk)
        _create_person(distinct_ids=[distinct_id], team=self.team)

        _create_event(event="viewed",
                      distinct_id=distinct_id,
                      team=self.team,
                      timestamp="2021-05-01 00:00:00")
示例#6
0
    def test_prop_cohort_multiple_groups(self):

        _create_person(distinct_ids=["some_other_id"],
                       team_id=self.team.pk,
                       properties={"$some_prop": "something"})

        _create_person(distinct_ids=["some_id"],
                       team_id=self.team.pk,
                       properties={"$another_prop": "something"})
        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_id",
            properties={"attr": "some_val"},
        )

        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_other_id",
            properties={"attr": "some_val"},
        )

        cohort1 = Cohort.objects.create(
            team=self.team,
            groups=[
                {
                    "properties": [{
                        "key": "$some_prop",
                        "value": "something",
                        "type": "person"
                    }]
                },
                {
                    "properties": [{
                        "key": "$another_prop",
                        "value": "something",
                        "type": "person"
                    }]
                },
            ],
            name="cohort1",
        )

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort1.pk,
                "type": "cohort"
            }],
        },
                        team=self.team)
        query, params = parse_prop_grouped_clauses(
            team_id=self.team.pk, property_group=filter.property_groups)
        final_query = "SELECT uuid FROM events WHERE team_id = %(team_id)s {}".format(
            query)
        result = sync_execute(final_query, {**params, "team_id": self.team.pk})
        self.assertEqual(len(result), 2)
    def test_pagination(self):
        cache.clear()

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team, event="user signed up", distinct_id=f"user_{i}", timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team, event="positively_related", distinct_id=f"user_{i}", timestamp="2020-01-03T14:00:00Z",
            )
            _create_event(
                team=self.team, event="paid", distinct_id=f"user_{i}", timestamp="2020-01-04T14:00:00Z",
            )

        request_data = {
            "events": json.dumps(
                [{"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_converted": "true",
            "funnel_correlation_person_limit": 4,
            "funnel_correlation_person_entity": json.dumps({"id": "positively_related", "type": "events"}),
        }

        response = self.client.get(f"/api/projects/{self.team.pk}/persons/funnel/correlation", data=request_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        j = response.json()

        first_person = j["results"][0]["people"][0]
        self.assertEqual(4, len(j["results"][0]["people"]))
        self.assertTrue("id" in first_person and "name" in first_person and "distinct_ids" in first_person)
        self.assertEqual(4, j["results"][0]["count"])

        next = j["next"]
        response = self.client.get(next)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        j = response.json()

        people = j["results"][0]["people"]
        next = j["next"]
        self.assertEqual(4, len(people))
        self.assertNotEqual(None, next)

        response = self.client.get(next)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        j = response.json()
        people = j["results"][0]["people"]
        next = j["next"]
        self.assertEqual(2, len(people))
        self.assertEqual(None, j["next"])
示例#8
0
    def test_insight_paths_basic(self):
        _create_person(team=self.team, distinct_ids=["person_1"])
        _create_event(
            properties={"$current_url": "/"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about"}, distinct_id="person_1", event="$pageview", team=self.team,
        )

        response = self.client.get(f"/api/projects/{self.team.id}/insights/path",).json()
        self.assertEqual(len(response["result"]), 1)
示例#9
0
    def test_prop_cohort_with_negation(self):
        team2 = Organization.objects.bootstrap(None)[2]

        _create_person(distinct_ids=["some_other_id"],
                       team_id=self.team.pk,
                       properties={"$some_prop": "something"})

        _create_person(distinct_ids=["some_id"],
                       team_id=team2.pk,
                       properties={"$another_prop": "something"})
        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_id",
            properties={"attr": "some_val"},
        )

        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_other_id",
            properties={"attr": "some_val"},
        )

        cohort1 = Cohort.objects.create(
            team=self.team,
            groups=[{
                "properties": [{
                    "type": "person",
                    "key": "$some_prop",
                    "operator": "is_not",
                    "value": "something"
                }]
            }],
            name="cohort1",
        )

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort1.pk,
                "type": "cohort"
            }],
        },
                        team=self.team)
        query, params = parse_prop_grouped_clauses(
            team_id=self.team.pk, property_group=filter.property_groups)
        final_query = "SELECT uuid FROM events WHERE team_id = %(team_id)s {}".format(
            query)
        self.assertIn("\nFROM person_distinct_id2\n", final_query)

        result = sync_execute(final_query, {**params, "team_id": self.team.pk})
        self.assertEqual(len(result), 0)
示例#10
0
    def test_insight_paths_basic_exclusions(self):
        _create_person(team=self.team, distinct_ids=["person_1"])
        _create_event(
            distinct_id="person_1", event="first event", team=self.team,
        )
        _create_event(
            distinct_id="person_1", event="second event", team=self.team,
        )
        _create_event(
            distinct_id="person_1", event="third event", team=self.team,
        )

        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path", data={"exclude_events": '["second event"]'}
        ).json()
        self.assertEqual(len(response["result"]), 1)
示例#11
0
    def test_path_groupings(self):
        _create_person(team=self.team, distinct_ids=["person_1"])
        _create_event(
            properties={"$current_url": "/about_1"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about_2"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/something else"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about3"}, distinct_id="person_1", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about4"}, distinct_id="person_1", event="$pageview", team=self.team,
        )

        _create_person(team=self.team, distinct_ids=["person_2"])
        _create_event(
            properties={"$current_url": "/about_1"}, distinct_id="person_2", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about_2"}, distinct_id="person_2", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/something else"}, distinct_id="person_2", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about3"}, distinct_id="person_2", event="$pageview", team=self.team,
        )
        _create_event(
            properties={"$current_url": "/about4"}, distinct_id="person_2", event="$pageview", team=self.team,
        )

        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path",
            data={"insight": "PATHS", "path_groupings": json.dumps(["/about*"])},
        ).json()
        self.assertEqual(len(response["result"]), 2)

        response = self.client.get(
            f"/api/projects/{self.team.id}/insights/path",
            data={"insight": "PATHS", "path_groupings": json.dumps(["/about_*"])},
        ).json()
        self.assertEqual(len(response["result"]), 3)
示例#12
0
    def test_funnel_correlation_on_properties_with_recordings(self):
        p1 = _create_person(distinct_ids=["user_1"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_1",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s2", "$window_id": "w1"},
            event_uuid="11111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="21111111-1111-1111-1111-111111111111",
        )

        _create_session_recording_event(self.team.pk, "user_1", "s2", datetime(2021, 1, 2, 0, 0, 0))

        # Success filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "True",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(results[0]["id"], p1.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now() + timedelta(minutes=3),
                            "uuid": UUID("21111111-1111-1111-1111-111111111111"),
                            "window_id": "w2",
                        }
                    ],
                    "session_id": "s2",
                }
            ],
        )
示例#13
0
def testdata(db, team):
    materialize("person", "email")
    _create_person(
        distinct_ids=["1"],
        team_id=team.pk,
        properties={
            "email": "*****@*****.**",
            "$os": "windows",
            "$browser": "chrome"
        },
    )
    _create_person(
        distinct_ids=["2"],
        team_id=team.pk,
        properties={
            "email": "*****@*****.**",
            "$os": "Mac",
            "$browser": "firefox"
        },
    )
    _create_person(
        distinct_ids=["3"],
        team_id=team.pk,
        properties={
            "email": "*****@*****.**",
            "$os": "windows",
            "$browser": "mozilla"
        },
    )
示例#14
0
    def test_strict_funnel_correlation_with_recordings(self):

        # First use that successfully completes the strict funnel
        p1 = _create_person(distinct_ids=["user_1"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_1",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s2", "$window_id": "w1"},
            event_uuid="11111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="31111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",  # Second event should not be returned
            distinct_id="user_1",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=4)),
            properties={"$session_id": "s2", "$window_id": "w2"},
            event_uuid="41111111-1111-1111-1111-111111111111",
        )
        _create_session_recording_event(self.team.pk, "user_1", "s2", datetime(2021, 1, 2, 0, 0, 0))

        # Second user with strict funnel drop off, but completed the step events for a normal funnel
        p2 = _create_person(distinct_ids=["user_2"], team=self.team, properties={"foo": "bar"})
        _create_event(
            event="$pageview",
            distinct_id="user_2",
            team=self.team,
            timestamp=timezone.now(),
            properties={"$session_id": "s3", "$window_id": "w1"},
            event_uuid="51111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight loaded",  # Interupting event
            distinct_id="user_2",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=3)),
            properties={"$session_id": "s3", "$window_id": "w2"},
            event_uuid="61111111-1111-1111-1111-111111111111",
        )
        _create_event(
            event="insight analyzed",
            distinct_id="user_2",
            team=self.team,
            timestamp=(timezone.now() + timedelta(minutes=4)),
            properties={"$session_id": "s3", "$window_id": "w2"},
            event_uuid="71111111-1111-1111-1111-111111111111",
        )
        _create_session_recording_event(self.team.pk, "user_2", "s3", datetime(2021, 1, 2, 0, 0, 0))

        # Success filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_order_type": "strict",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "True",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(len(results), 1)
        self.assertEqual(results[0]["id"], p1.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now() + timedelta(minutes=3),
                            "uuid": UUID("31111111-1111-1111-1111-111111111111"),
                            "window_id": "w2",
                        }
                    ],
                    "session_id": "s2",
                }
            ],
        )

        # Drop off filter
        filter = Filter(
            data={
                "insight": INSIGHT_FUNNELS,
                "date_from": "2021-01-01",
                "date_to": "2021-01-08",
                "funnel_order_type": "strict",
                "funnel_correlation_type": "properties",
                "events": [{"id": "$pageview", "order": 0}, {"id": "insight analyzed", "order": 1}],
                "include_recordings": "true",
                "funnel_correlation_property_values": [
                    {"key": "foo", "value": "bar", "operator": "exact", "type": "person"}
                ],
                "funnel_correlation_person_converted": "False",
            }
        )
        _, results = FunnelCorrelationActors(filter, self.team).get_actors()

        self.assertEqual(results[0]["id"], p2.uuid)
        self.assertEqual(
            results[0]["matched_recordings"],
            [
                {
                    "events": [
                        {
                            "timestamp": timezone.now(),
                            "uuid": UUID("51111111-1111-1111-1111-111111111111"),
                            "window_id": "w1",
                        }
                    ],
                    "session_id": "s3",
                }
            ],
        )
示例#15
0
    def test_prop_cohort_basic_action_days(self):

        _create_person(distinct_ids=["some_other_id"],
                       team_id=self.team.pk,
                       properties={"$some_prop": "something"})

        _create_person(
            distinct_ids=["some_id"],
            team_id=self.team.pk,
            properties={
                "$some_prop": "something",
                "$another_prop": "something"
            },
        )

        action = _create_action(team=self.team, name="$pageview")
        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_id",
            properties={"attr": "some_val"},
            timestamp=datetime.now() - timedelta(hours=22),
        )

        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_other_id",
            properties={"attr": "some_val"},
            timestamp=datetime.now() - timedelta(days=5),
        )

        cohort1 = Cohort.objects.create(
            team=self.team,
            groups=[{
                "action_id": action.pk,
                "days": 1
            }],
            name="cohort1",
        )

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort1.pk,
                "type": "cohort"
            }],
        },
                        team=self.team)
        query, params = parse_prop_grouped_clauses(
            team_id=self.team.pk,
            property_group=filter.property_groups,
            person_properties_mode=PersonPropertiesMode.DIRECT_ON_EVENTS
            if self.team.actor_on_events_querying_enabled else
            PersonPropertiesMode.USING_SUBQUERY,
        )
        final_query = "SELECT uuid FROM events WHERE team_id = %(team_id)s {}".format(
            query)
        result = sync_execute(final_query, {**params, "team_id": self.team.pk})
        self.assertEqual(len(result), 1)

        cohort2 = Cohort.objects.create(
            team=self.team,
            groups=[{
                "action_id": action.pk,
                "days": 7
            }],
            name="cohort2",
        )

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort2.pk,
                "type": "cohort"
            }],
        },
                        team=self.team)
        query, params = parse_prop_grouped_clauses(
            team_id=self.team.pk,
            property_group=filter.property_groups,
            person_properties_mode=PersonPropertiesMode.DIRECT_ON_EVENTS
            if self.team.actor_on_events_querying_enabled else
            PersonPropertiesMode.USING_SUBQUERY,
        )
        final_query = "SELECT uuid FROM events WHERE team_id = %(team_id)s {}".format(
            query)
        result = sync_execute(final_query, {**params, "team_id": self.team.pk})
        self.assertEqual(len(result), 2)
示例#16
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)
    def test_basic_format(self):
        user_a = _create_person(distinct_ids=["user a"], team=self.team)

        _create_event(event="step one",
                      distinct_id="user a",
                      team=self.team,
                      timestamp="2021-06-07 19:00:00")

        common_request_data = {
            "insight":
            INSIGHT_FUNNELS,
            "funnel_viz_type":
            FunnelVizType.TRENDS,
            "interval":
            "day",
            "date_from":
            "2021-06-07",
            "date_to":
            "2021-06-13 23:59:59",
            "funnel_window_days":
            7,
            "events":
            json.dumps([
                {
                    "id": "step one",
                    "order": 0
                },
                {
                    "id": "step two",
                    "order": 1
                },
                {
                    "id": "step three",
                    "order": 2
                },
            ]),
            "properties":
            json.dumps([]),
            "funnel_window_days":
            7,
            "new_entity":
            json.dumps([]),
        }

        # 1 user who dropped off starting 2021-06-07
        response_1 = self.client.get(
            "/api/person/funnel/",
            data={
                **common_request_data,
                "entrance_period_start": "2021-06-07",
                "drop_off": True,
            },
        )
        response_1_data = response_1.json()

        self.assertEqual(response_1.status_code, status.HTTP_200_OK)
        self.assertEqual([
            person["id"] for person in response_1_data["results"][0]["people"]
        ], [str(user_a.uuid)])

        # No users converted 2021-06-07
        response_2 = self.client.get(
            "/api/person/funnel/",
            data={
                **common_request_data,
                "entrance_period_start": "2021-06-07 00:00",
                "drop_off": False,
            },
        )
        response_2_data = response_2.json()

        self.assertEqual(response_2.status_code, status.HTTP_200_OK)
        self.assertEqual([
            person["id"] for person in response_2_data["results"][0]["people"]
        ], [])

        # No users dropped off starting 2021-06-08
        response_3 = self.client.get(
            "/api/person/funnel/",
            data={
                **common_request_data,
                "entrance_period_start": "2021-06-08",
                "drop_off": True,
            },
        )
        response_3_data = response_3.json()

        self.assertEqual(response_3.status_code, status.HTTP_200_OK)
        self.assertEqual([
            person["id"] for person in response_3_data["results"][0]["people"]
        ], [])
    def test_breakdowns(self):
        request_data = {
            "insight": INSIGHT_FUNNELS,
            "interval": "day",
            "actions": json.dumps([]),
            "properties": json.dumps([]),
            "funnel_step": 1,
            "filter_test_accounts": "false",
            "new_entity": json.dumps([]),
            "events": json.dumps(
                [{"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": "$browser",
            "funnel_step_breakdown": "Chrome",
        }

        # event
        _create_person(distinct_ids=["person1"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="sign up",
            distinct_id="person1",
            properties={"key": "val", "$browser": "Chrome"},
            timestamp="2020-01-01T12:00:00Z",
        )
        _create_event(
            team=self.team,
            event="play movie",
            distinct_id="person1",
            properties={"key": "val", "$browser": "Chrome"},
            timestamp="2020-01-01T13:00:00Z",
        )
        _create_event(
            team=self.team,
            event="buy",
            distinct_id="person1",
            properties={"key": "val", "$browser": "Chrome"},
            timestamp="2020-01-01T15:00:00Z",
        )

        _create_person(distinct_ids=["person2"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="sign up",
            distinct_id="person2",
            properties={"key": "val", "$browser": "Safari"},
            timestamp="2020-01-02T14:00:00Z",
        )
        _create_event(
            team=self.team,
            event="play movie",
            distinct_id="person2",
            properties={"key": "val", "$browser": "Safari"},
            timestamp="2020-01-02T16:00:00Z",
        )

        _create_person(distinct_ids=["person3"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="sign up",
            distinct_id="person3",
            properties={"key": "val", "$browser": "Safari"},
            timestamp="2020-01-02T14:00:00Z",
        )

        response = self.client.get("/api/person/funnel/", data=request_data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        j = response.json()

        people = j["results"][0]["people"]
        self.assertEqual(1, len(people))
        self.assertEqual(None, j["next"])

        response = self.client.get("/api/person/funnel/", data={**request_data, "funnel_step_breakdown": "Safari"})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        j = response.json()

        people = j["results"][0]["people"]
        self.assertEqual(2, len(people))
        self.assertEqual(None, j["next"])
示例#19
0
    def test_correlation_endpoint_with_properties(self):
        self.client.force_login(self.user)

        for i in range(10):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Positive"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        for i in range(10, 20):
            _create_person(distinct_ids=[f"user_{i}"],
                           team_id=self.team.pk,
                           properties={"$browser": "Negative"})
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            if i % 2 == 0:
                _create_event(
                    team=self.team,
                    event="negatively_related",
                    distinct_id=f"user_{i}",
                    timestamp="2020-01-03T14:00:00Z",
                )

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

        api_response = get_funnel_correlation_ok(
            client=self.client,
            team_id=self.team.pk,
            request=FunnelCorrelationRequest(
                events=json.dumps([
                    EventPattern(id="user signed up"),
                    EventPattern(id="paid")
                ]),
                date_to="2020-01-14",
                date_from="2020-01-01",
                funnel_correlation_type=FunnelCorrelationType.PROPERTIES,
                funnel_correlation_names=json.dumps(["$browser"]),
            ),
        )

        self.assertFalse(api_response["result"]["skewed"])

        result = api_response["result"]["events"]

        odds_ratios = [item.pop("odds_ratio") for item in result]
        expected_odds_ratios = [121, 1 / 121]

        for odds, expected_odds in zip(odds_ratios, expected_odds_ratios):
            self.assertAlmostEqual(odds, expected_odds)

        self.assertEqual(
            result,
            [
                {
                    "event": {
                        "event": "$browser::Positive",
                        "elements": [],
                        "properties": {}
                    },
                    "success_count": 10,
                    "failure_count": 0,
                    "success_people_url": ANY,
                    "failure_people_url": ANY,
                    # "odds_ratio": 121.0,
                    "correlation_type": "success",
                },
                {
                    "event": {
                        "event": "$browser::Negative",
                        "elements": [],
                        "properties": {}
                    },
                    "success_count": 0,
                    "failure_count": 10,
                    "success_people_url": ANY,
                    "failure_people_url": ANY,
                    # "odds_ratio": 1 / 121,
                    "correlation_type": "failure",
                },
            ],
        )
示例#20
0
    def test_funnel_correlation_with_event_properties_autocapture(self):
        self.client.force_login(self.user)

        # Need a minimum of 3 hits to get a correlation result
        for i in range(3):
            _create_person(distinct_ids=[f"user_{i}"], team_id=self.team.pk)
            _create_event(
                team=self.team,
                event="user signed up",
                distinct_id=f"user_{i}",
                timestamp="2020-01-02T14:00:00Z",
            )
            _create_event(
                team=self.team,
                event="$autocapture",
                distinct_id=f"user_{i}",
                elements=[
                    Element(nth_of_type=1,
                            nth_child=0,
                            tag_name="a",
                            href="/movie")
                ],
                timestamp="2020-01-03T14:00:00Z",
                properties={
                    "signup_source": "email",
                    "$event_type": "click"
                },
            )
            _create_event(
                team=self.team,
                event="paid",
                distinct_id=f"user_{i}",
                timestamp="2020-01-04T14:00:00Z",
            )

        # Atleast one person that fails, to ensure we get results
        _create_person(distinct_ids=[f"user_fail"], team_id=self.team.pk)
        _create_event(
            team=self.team,
            event="user signed up",
            distinct_id=f"user_fail",
            timestamp="2020-01-02T14:00:00Z",
        )

        with freeze_time("2020-01-01"):
            response = get_funnel_correlation_ok(
                client=self.client,
                team_id=self.team.pk,
                request=FunnelCorrelationRequest(
                    events=json.dumps([
                        EventPattern(id="user signed up"),
                        EventPattern(id="paid")
                    ]),
                    date_to="2020-01-14",
                    date_from="2020-01-01",
                    funnel_correlation_type=FunnelCorrelationType.
                    EVENT_WITH_PROPERTIES,
                    funnel_correlation_event_names=json.dumps(["$autocapture"
                                                               ]),
                ),
            )

        assert response == {
            "result": {
                "events": [
                    {
                        "success_count": 3,
                        "failure_count": 0,
                        "success_people_url": ANY,
                        "failure_people_url": ANY,
                        "odds_ratio": 8.0,
                        "correlation_type": "success",
                        "event": {
                            "event":
                            '$autocapture::elements_chain::click__~~__a:href="/movie"nth-child="0"nth-of-type="1"',
                            "properties": {
                                "$event_type": "click"
                            },
                            "elements": [{
                                "event": None,
                                "text": None,
                                "tag_name": "a",
                                "attr_class": None,
                                "href": "/movie",
                                "attr_id": None,
                                "nth_child": 0,
                                "nth_of_type": 1,
                                "attributes": {},
                                "order": 0,
                            }],
                        },
                    },
                ],
                "skewed":
                False,
            },
            "last_refresh": "2020-01-01T00:00:00Z",
            "is_cached": False,
        }

        assert get_people_for_correlation_ok(
            client=self.client,
            correlation=response["result"]["events"][0]) == {
                "success": ["user_0", "user_1", "user_2"],
                "failure": [],
            }