Exemple #1
0
    def test_can_get_retention_week_interval(self):
        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**",
                           password="******",
                           organization=organization)

        self.client.force_login(user)

        update_or_create_person(distinct_ids=["person 1"], team_id=team.pk)
        update_or_create_person(distinct_ids=["person 2"], team_id=team.pk)

        setup_user_activity_by_day(
            daily_activity={
                "2020-01-01": {
                    "person 1": [{
                        "event": "target event"
                    }]
                },
                "2020-01-08": {
                    "person 2": [{
                        "event": "target event"
                    }]
                },
            },
            team=team,
        )

        retention = get_retention_ok(
            client=self.client,
            team_id=team.pk,
            request=RetentionRequest(
                target_entity={
                    "id": "target event",
                    "type": "events"
                },
                returning_entity={
                    "id": "target event",
                    "type": "events"
                },
                date_from="2020-01-01",
                total_intervals=2,
                date_to="2020-01-08",
                period="Week",
                retention_type="retention_first_time",
            ),
        )

        retention_by_cohort_by_period = get_by_cohort_by_period_for_response(
            client=self.client, response=retention)

        assert retention_by_cohort_by_period == {
            "Week 0": {
                "1": ["person 1"],
                "2": [],
            },
            "Week 1": {
                "1": ["person 2"]
            },
        }
Exemple #2
0
    def test_can_get_actors_and_use_percent_char_filter(self):
        """
        References https://github.com/PostHog/posthog/issues/7747

        Essentially we were performing a double string substitution, which
        causes issues if, in that case, we use a string substitution that
        includes a '%' character, and then run substitution again.

        This was the case for instance when you wanted to filter out test users
        e.g. by postgres LIKE matching '%posthog.com%'
        """
        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**", password="******", organization=organization)

        self.client.force_login(user)

        response = get_retention_people(
            client=self.client,
            team_id=team.pk,
            request=RetentionRequest(
                target_entity={"id": "target event", "type": "events"},
                returning_entity={"id": "target event", "type": "events"},
                date_from="2020-01-01",
                total_intervals=2,
                date_to="2020-01-08",
                period="Week",
                retention_type="retention_first_time",
                properties=[{"key": "email", "value": "posthog.com", "operator": "not_icontains", "type": "person"}],
            ),
        )

        assert response.status_code == 200
Exemple #3
0
    def test_can_specify_breakdown_person_property(self):
        """
        By default, we group users together by the first time they perform the
        `target_event`. However, we should also be able to specify, e.g. the
        users OS to be able to compare retention between the OSs.
        """
        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**", password="******", organization=organization)

        self.client.force_login(user)

        update_or_create_person(distinct_ids=["person 1"], team_id=team.pk, properties={"os": "Chrome"})
        update_or_create_person(distinct_ids=["person 2"], team_id=team.pk, properties={"os": "Safari"})

        setup_user_activity_by_day(
            daily_activity={
                "2020-01-01": {"person 1": [{"event": "target event"}]},
                "2020-01-02": {"person 1": [{"event": "target event"}], "person 2": [{"event": "target event"}]},
                # IMPORTANT: we include data past the end of the requested
                # window, as we want to ensure that we pick up all retention
                # periods for a user. e.g. for "person 2" we do not want to miss
                # the count from 2020-01-03 e.g. the second period, otherwise we
                # will skew results for users that didn't perform their target
                # event right at the beginning of the requested range.
                "2020-01-03": {"person 1": [{"event": "target event"}], "person 2": [{"event": "target event"}]},
            },
            team=team,
        )

        retention = get_retention_ok(
            client=self.client,
            team_id=team.pk,
            request=RetentionRequest(
                target_entity={"id": "target event", "type": "events"},
                returning_entity={"id": "target event", "type": "events"},
                date_from="2020-01-01",
                total_intervals=2,
                date_to="2020-01-02",
                period="Day",
                retention_type="retention_first_time",
                breakdowns=[Breakdown(type="person", property="os")],
                # NOTE: we need to specify breakdown_type as well, as the
                # breakdown logic currently does not support multiple differing
                # types
                breakdown_type="person",
            ),
        )

        retention_by_cohort_by_period = get_by_cohort_by_period_for_response(client=self.client, response=retention)

        assert retention_by_cohort_by_period, {
            "Chrome": {"1": ["person 1"], "2": ["person 1"]},
            "Safari": {
                "1": ["person 2"],
                "2": ["person 2"],
            },  # IMPORTANT: the "2" value is from past the requested `date_to`
        }
Exemple #4
0
    def test_can_specify_breakdown_event_property_and_retrieve_people(self):
        """
        This test is slightly different from the
        get_by_cohort_by_period_for_response based tests in that here we are
        checking a cohort/period specific people url that does not include the
        "appearances" detail.

        This is used, e.g. for the frontend retentions trend graph
        """
        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**", password="******", organization=organization)

        self.client.force_login(user)

        update_or_create_person(distinct_ids=["person 1"], team_id=team.pk)
        update_or_create_person(distinct_ids=["person 2"], team_id=team.pk)

        setup_user_activity_by_day(
            daily_activity={
                "2020-01-01": {
                    "person 1": [{"event": "target event", "properties": {"os": "Chrome"}}],
                    "person 2": [{"event": "target event", "properties": {"os": "Safari"}}],
                },
                "2020-01-02": {"person 1": [{"event": "target event"}], "person 2": [{"event": "target event"}],},
            },
            team=team,
        )

        retention = get_retention_ok(
            client=self.client,
            team_id=team.pk,
            request=RetentionRequest(
                target_entity={"id": "target event", "type": "events"},
                returning_entity={"id": "target event", "type": "events"},
                date_from="2020-01-01",
                total_intervals=2,
                date_to="2020-01-02",
                period="Day",
                retention_type="retention_first_time",
                breakdowns=[Breakdown(type="event", property="os")],
                # NOTE: we need to specify breakdown_type as well, as the
                # breakdown logic currently does not support multiple differing
                # types
                breakdown_type="event",
            ),
        )

        chrome_cohort = [cohort for cohort in retention["result"] if cohort["label"] == "Chrome"][0]
        people_url = chrome_cohort["values"][0]["people_url"]
        people_response = self.client.get(people_url)
        assert people_response.status_code == 200

        people = people_response.json()["result"]

        assert [distinct_id for person in people for distinct_id in person["distinct_ids"]] == ["person 1"]
Exemple #5
0
    def test_retention_test_account_filters(self):

        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**", password="******", organization=organization)

        self.client.force_login(user)

        team.test_account_filters = [
            {"key": "email", "type": "person", "value": "posthog.com", "operator": "not_icontains"}
        ]
        team.save()

        update_or_create_person(distinct_ids=["person 1"], team_id=team.pk, properties={"email": "posthog.com"})
        update_or_create_person(distinct_ids=["person 2"], team_id=team.pk)
        update_or_create_person(distinct_ids=["person 3"], team_id=team.pk)

        setup_user_activity_by_day(
            daily_activity={
                "2020-01-01": {"person 1": [{"event": "target event"}], "person 2": [{"event": "target event"}]},
                "2020-01-02": {"person 1": [{"event": "target event"}], "person 3": [{"event": "target event"}]},
                "2020-01-03": {"person 1": [{"event": "target event"}], "person 3": [{"event": "target event"}]},
            },
            team=team,
        )

        retention = get_retention_ok(
            client=self.client,
            team_id=team.pk,
            request=RetentionRequest(
                target_entity={"id": "target event", "type": "events"},
                returning_entity={"id": "target event", "type": "events"},
                date_from="2020-01-01",
                total_intervals=2,
                date_to="2020-01-02",
                period="Day",
                retention_type="retention_first_time",
                filter_test_accounts="true",
            ),
        )

        retention_by_cohort_by_period = get_by_cohort_by_period_for_response(client=self.client, response=retention)

        assert retention_by_cohort_by_period == {
            "Day 0": {"1": ["person 2"], "2": [],},
            "Day 1": {"1": ["person 3"]},
        }
Exemple #6
0
    def setUpTestData(cls):
        cls.organization = create_organization(name="test org")
        cls.demo_team = create_team(organization=cls.organization)
        cls.user = create_user("user", "pass", cls.organization)

        for event_definition in cls.EXPECTED_EVENT_DEFINITIONS:
            create_event_definitions(event_definition["name"],
                                     team_id=cls.demo_team.pk)
            for _ in range(event_definition["volume_30_day"]):
                capture_event(event=EventData(
                    event=event_definition["name"],
                    team_id=cls.demo_team.pk,
                    distinct_id="abc",
                    timestamp=datetime(2020, 1, 1),
                    properties={},
                ))

        # To ensure `volume_30_day` and `query_usage_30_day` are returned non
        # None, we need to call this task to have them calculated.
        calculate_event_property_usage_for_team(cls.demo_team.pk)
Exemple #7
0
    def test_retention_aggregation_by_distinct_id_and_retrieve_people(self):
        organization = create_organization(name="test")
        team = create_team(organization=organization)
        user = create_user(email="*****@*****.**",
                           password="******",
                           organization=organization)

        self.client.force_login(user)

        p1 = update_or_create_person(distinct_ids=["person 1", "another one"],
                                     team_id=team.pk)
        p2 = update_or_create_person(distinct_ids=["person 2"],
                                     team_id=team.pk)

        setup_user_activity_by_day(
            daily_activity={
                "2020-01-01": {
                    "person 1": [{
                        "event": "target event",
                    }],
                    "another one": [{
                        "event": "target event",
                    }],
                },
                "2020-01-02": {
                    "person 1": [{
                        "event": "target event"
                    }],
                    "person 2": [{
                        "event": "target event"
                    }]
                },
                "2020-01-03": {
                    "another one": [{
                        "event": "target event"
                    }],
                },
            },
            team=team,
        )

        with override_instance_config("AGGREGATE_BY_DISTINCT_IDS_TEAMS",
                                      f"{team.pk}"):
            retention = get_retention_ok(
                client=self.client,
                team_id=team.pk,
                request=RetentionRequest(
                    target_entity={
                        "id": "target event",
                        "type": "events"
                    },
                    returning_entity={
                        "id": "target event",
                        "type": "events"
                    },
                    date_from="2020-01-01",
                    total_intervals=3,
                    date_to="2020-01-03",
                    period="Day",
                    retention_type="retention_first_time",
                ),
            )

            assert retention["result"][0]["values"][0][
                "count"] == 2  #  person 1 and another one
            assert retention["result"][0]["values"][1]["count"] == 1  # person 1
            assert retention["result"][0]["values"][2][
                "count"] == 1  # another one

            #  person 2
            assert retention["result"][1]["values"][0]["count"] == 1
            assert retention["result"][1]["values"][1]["count"] == 0

            people_url = retention["result"][0]["values"][0]["people_url"]
            people_response = self.client.get(people_url)
            assert people_response.status_code == 200

            people = people_response.json()["result"]
            # person1 and another one are the same person
            assert len(people) == 1
            assert people[0]["id"] == str(p1.uuid)

            people_url = retention["result"][1]["values"][0]["people_url"]
            people_response = self.client.get(people_url)
            assert people_response.status_code == 200

            people = people_response.json()["result"]
            assert len(people) == 1
            assert people[0]["id"] == str(p2.uuid)