Пример #1
0
    def test_basic_offset(self):
        self._create_sample_data()
        data = {
            "insight": INSIGHT_FUNNELS,
            "interval": "day",
            "date_from": "2021-05-01 00:00:00",
            "date_to": "2021-05-07 00:00:00",
            "funnel_window_days": 7,
            "funnel_step": 1,
            "events": [
                {"id": "step one", "order": 0},
                {"id": "step two", "order": 1},
                {"id": "step three", "order": 2},
            ],
        }

        filter = Filter(data=data)
        results = ClickhouseFunnelPersons(filter, self.team)._exec_query()
        self.assertEqual(100, len(results))

        filter_offset = Filter(data={**data, "offset": 100,})
        results = ClickhouseFunnelPersons(filter_offset, self.team).run()
        self.assertEqual(100, len(results))

        filter_offset = Filter(data={**data, "offset": 200,})
        results = ClickhouseFunnelPersons(filter_offset, self.team).run()
        self.assertEqual(50, len(results))
Пример #2
0
    def test_first_step_breakdowns(self):
        person1, person2 = self._create_browser_breakdown_events()
        filter = Filter(
            data={
                "insight":
                INSIGHT_FUNNELS,
                "date_from":
                "2020-01-01",
                "date_to":
                "2020-01-08",
                "interval":
                "day",
                "funnel_window_days":
                7,
                "funnel_step":
                1,
                "events": [
                    {
                        "id": "sign up",
                        "order": 0
                    },
                    {
                        "id": "play movie",
                        "order": 1
                    },
                    {
                        "id": "buy",
                        "order": 2
                    },
                ],
                "breakdown_type":
                "event",
                "breakdown":
                "$browser",
            })
        results = ClickhouseFunnelPersons(filter, self.team)._exec_query()

        self.assertCountEqual([val[0] for val in results],
                              [person1.uuid, person2.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Chrome"}),
            self.team)._exec_query()

        self.assertCountEqual([val[0] for val in results], [person1.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Safari"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results], [person2.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Safari, Chrome"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results],
                              [person2.uuid, person1.uuid])
Пример #3
0
    def test_steps_with_custom_steps_parameter_are_equivalent_to_funnel_step(
            self):
        self._create_sample_data_multiple_dropoffs()
        data = {
            "insight":
            INSIGHT_FUNNELS,
            "interval":
            "day",
            "date_from":
            "2021-05-01 00:00:00",
            "date_to":
            "2021-05-07 00:00:00",
            "funnel_window_days":
            7,
            "events": [
                {
                    "id": "step one",
                    "order": 0
                },
                {
                    "id": "step two",
                    "order": 1
                },
                {
                    "id": "step three",
                    "order": 2
                },
            ],
        }
        base_filter = Filter(data=data)

        parameters = [
            #  funnel_step,  custom_steps, expected_results
            (1, [1, 2, 3], 35),
            (2, [2, 3], 15),
            (3, [3], 5),
            (-2, [1], 20),
            (-3, [2], 10),
        ]

        for funnel_step, custom_steps, expected_count in parameters:
            filter = base_filter.with_data({"funnel_step": funnel_step})
            results = ClickhouseFunnelPersons(filter, self.team)._exec_query()

            new_filter = base_filter.with_data(
                {"funnel_custom_steps": custom_steps})
            new_results = ClickhouseFunnelPersons(new_filter,
                                                  self.team)._exec_query()

            self.assertEqual(new_results, results)
            self.assertEqual(len(results), expected_count)
Пример #4
0
 def test_last_step_dropoff(self):
     self._create_sample_data_multiple_dropoffs()
     data = {
         "insight":
         INSIGHT_FUNNELS,
         "interval":
         "day",
         "date_from":
         "2021-05-01 00:00:00",
         "date_to":
         "2021-05-07 00:00:00",
         "funnel_window_days":
         7,
         "funnel_step":
         -3,
         "events": [
             {
                 "id": "step one",
                 "order": 0
             },
             {
                 "id": "step two",
                 "order": 1
             },
             {
                 "id": "step three",
                 "order": 2
             },
         ],
     }
     filter = Filter(data=data)
     results = ClickhouseFunnelPersons(filter, self.team)._exec_query()
     self.assertEqual(10, len(results))
Пример #5
0
 def _get_people_at_step(self, filter, funnel_step, breakdown_value=None):
     person_filter = filter.with_data({
         "funnel_step":
         funnel_step,
         "funnel_step_breakdown":
         breakdown_value
     })
     result = ClickhouseFunnelPersons(person_filter,
                                      self.team)._exec_query()
     return [row[0] for row in result]
Пример #6
0
 def test_funnel_cohort_breakdown_persons(self):
     person = _create_person(distinct_ids=[f"person1"],
                             team_id=self.team.pk,
                             properties={"key": "value"})
     _create_event(
         team=self.team,
         event="sign up",
         distinct_id=f"person1",
         properties={},
         timestamp="2020-01-02T12:00:00Z",
     )
     cohort = Cohort.objects.create(
         team=self.team,
         name="test_cohort",
         groups=[{
             "properties": [{
                 "key": "key",
                 "value": "value",
                 "type": "person"
             }]
         }],
     )
     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,
         "funnel_step":
         1,
         "breakdown_type":
         "cohort",
         "breakdown": [cohort.pk],
     }
     filter = Filter(data=filters)
     results = ClickhouseFunnelPersons(filter, self.team)._exec_query()
     self.assertEqual(results[0][0], person.uuid)
Пример #7
0
    def funnel(self, request: request.Request, **kwargs) -> response.Response:
        if request.user.is_anonymous or not request.user.team:
            return response.Response(data=[])

        filter = Filter(request=request)
        team = request.user.team
        results = ClickhouseFunnelPersons(filter, team).run()

        next_url = format_next_absolute_url(request, filter.offset,
                                            100) if len(results) > 99 else None
        return response.Response(data={"results": results, "next": next_url})
Пример #8
0
    def test_steps_with_custom_steps_parameter_where_funnel_step_equivalence_isnt_possible(
            self):
        self._create_sample_data_multiple_dropoffs()
        data = {
            "insight":
            INSIGHT_FUNNELS,
            "interval":
            "day",
            "date_from":
            "2021-05-01 00:00:00",
            "date_to":
            "2021-05-07 00:00:00",
            "funnel_window_days":
            7,
            "events": [
                {
                    "id": "step one",
                    "order": 0
                },
                {
                    "id": "step two",
                    "order": 1
                },
                {
                    "id": "step three",
                    "order": 2
                },
            ],
        }
        base_filter = Filter(data=data)

        parameters = [
            # custom_steps, expected_results
            ([1, 2], 30),
            ([1, 3], 25),
            ([3, 1], 25),
            ([1, 3, 3, 1], 25),
        ]

        for custom_steps, expected_count in parameters:
            new_filter = base_filter.with_data(
                {"funnel_custom_steps": custom_steps})
            new_results = ClickhouseFunnelPersons(new_filter,
                                                  self.team)._exec_query()

            self.assertEqual(len(new_results), expected_count)
Пример #9
0
 def get_path_query_funnel_cte(self, funnel_filter: Filter):
     funnel_persons_generator = ClickhouseFunnelPersons(
         funnel_filter,
         self._team,
         include_timestamp=bool(self._filter.funnel_paths),
         include_preceding_timestamp=self._filter.funnel_paths ==
         FUNNEL_PATH_BETWEEN_STEPS,
         no_person_limit=True,
     )
     funnel_persons_query = funnel_persons_generator.get_query()
     funnel_persons_query_new_params = funnel_persons_query.replace(
         "%(", "%(funnel_")
     funnel_persons_param = funnel_persons_generator.params
     new_funnel_params = {
         "funnel_" + str(key): val
         for key, val in funnel_persons_param.items()
     }
     self.params.update(new_funnel_params)
     return f"""
Пример #10
0
    def __init__(self, filter: Filter, team: Team) -> None:
        self._filter = filter
        self._team = team

        if self._filter.funnel_step is None:
            self._filter = self._filter.with_data({"funnel_step": 1})
            # Funnel Step by default set to 1, to give us all people who entered the funnel

        # Used for generating the funnel persons cte
        self._funnel_persons_generator = ClickhouseFunnelPersons(
            self._filter,
            self._team,
            # NOTE: we want to include the latest timestamp of the `target_step`,
            # from this we can deduce if the person reached the end of the funnel,
            # i.e. successful
            include_timestamp=True,
            # NOTE: we don't need these as we have all the information we need to
            # deduce if the person was successful or not
            include_preceding_timestamp=False,
            no_person_limit=True,
        )
Пример #11
0
    def test_steps_with_custom_steps_parameter_overrides_funnel_step(self):
        self._create_sample_data_multiple_dropoffs()
        data = {
            "insight":
            INSIGHT_FUNNELS,
            "interval":
            "day",
            "date_from":
            "2021-05-01 00:00:00",
            "date_to":
            "2021-05-07 00:00:00",
            "funnel_window_days":
            7,
            "funnel_step":
            1,  # means custom steps = [1,2,3]
            "funnel_custom_steps": [3],
            "events": [
                {
                    "id": "step one",
                    "order": 0
                },
                {
                    "id": "step two",
                    "order": 1
                },
                {
                    "id": "step three",
                    "order": 2
                },
            ],
        }

        results = ClickhouseFunnelPersons(Filter(data=data),
                                          self.team)._exec_query()

        self.assertEqual(len(results), 5)
Пример #12
0
    def test_first_step_breakdown_person(self):
        person1, person2 = self._create_browser_breakdown_events()
        filter = Filter(
            data={
                "insight":
                INSIGHT_FUNNELS,
                "date_from":
                "2020-01-01",
                "date_to":
                "2020-01-08",
                "interval":
                "day",
                "funnel_window_days":
                7,
                "funnel_step":
                1,
                "events": [
                    {
                        "id": "sign up",
                        "order": 0
                    },
                    {
                        "id": "play movie",
                        "order": 1
                    },
                    {
                        "id": "buy",
                        "order": 2
                    },
                ],
                "breakdown_type":
                "person",
                "breakdown":
                "$country",
            })

        results = ClickhouseFunnelPersons(filter, self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results],
                              [person1.uuid, person2.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "EE"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results], [person2.uuid])

        # Check custom_steps give same answers for breakdowns
        custom_step_results = ClickhouseFunnelPersons(
            filter.with_data({
                "funnel_step_breakdown": "EE",
                "funnel_custom_steps": [1, 2, 3]
            }), self.team)._exec_query()
        self.assertEqual(results, custom_step_results)

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "PL"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results], [person1.uuid])

        # Check custom_steps give same answers for breakdowns
        custom_step_results = ClickhouseFunnelPersons(
            filter.with_data({
                "funnel_step_breakdown": "PL",
                "funnel_custom_steps": [1, 2, 3]
            }), self.team)._exec_query()
        self.assertEqual(results, custom_step_results)
Пример #13
0
    def test_first_step_breakdowns(self):

        person1 = _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",
        )

        person2 = _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",
        )

        data = {
            "insight":
            INSIGHT_FUNNELS,
            "date_from":
            "2020-01-01",
            "date_to":
            "2020-01-08",
            "interval":
            "day",
            "funnel_window_days":
            7,
            "funnel_step":
            1,
            "events": [
                {
                    "id": "sign up",
                    "order": 0
                },
                {
                    "id": "play movie",
                    "order": 1
                },
                {
                    "id": "buy",
                    "order": 2
                },
            ],
            "breakdown_type":
            "event",
            "breakdown":
            "$browser",
        }
        filter = Filter(data=data)
        results = ClickhouseFunnelPersons(filter, self.team)._exec_query()

        self.assertCountEqual([val[0] for val in results],
                              [person1.uuid, person2.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Chrome"}),
            self.team)._exec_query()
        print(results)
        self.assertCountEqual([val[0] for val in results], [person1.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Safari"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results], [person2.uuid])

        results = ClickhouseFunnelPersons(
            filter.with_data({"funnel_step_breakdown": "Safari, Chrome"}),
            self.team)._exec_query()
        self.assertCountEqual([val[0] for val in results],
                              [person2.uuid, person1.uuid])