Example #1
0
    def test_get_insight_items(self):

        filter_dict = {
            "events": [{
                "id": "$pageview"
            }],
            "properties": [{
                "key": "$browser",
                "value": "Mac OS X"
            }],
        }

        DashboardItem.objects.create(
            filters=Filter(data=filter_dict).to_dict(),
            team=self.team,
            created_by=self.user)

        # create without user
        DashboardItem.objects.create(
            filters=Filter(data=filter_dict).to_dict(), team=self.team)

        response = self.client.get("/api/insight/", data={
            "user": "******"
        }).json()

        self.assertEqual(len(response["results"]), 1)
Example #2
0
    def test_breakdown_by_person_property(self):
        person1, person2, person3, person4 = self._create_multiple_people()
        action = _create_action(name="watched movie", team=self.team)

        with freeze_time("2020-01-04T13:01:01Z"):
            action_response = ClickhouseTrends().run(
                Filter(
                    data={
                        "date_from":
                        "-14d",
                        "breakdown":
                        "name",
                        "breakdown_type":
                        "person",
                        "actions": [{
                            "id": action.pk,
                            "type": "actions",
                            "order": 0
                        }],
                    }),
                self.team,
            )
            event_response = ClickhouseTrends().run(
                Filter(
                    data={
                        "date_from":
                        "-14d",
                        "breakdown":
                        "name",
                        "breakdown_type":
                        "person",
                        "events": [{
                            "id": "watched movie",
                            "name": "watched movie",
                            "type": "events",
                            "order": 0,
                        }],
                    }),
                self.team,
            )

        self.assertListEqual(
            [res["breakdown_value"] for res in event_response],
            ["person1", "person2", "person3"])

        for response in event_response:
            if response["breakdown_value"] == "person1":
                self.assertEqual(response["count"], 1)
                self.assertEqual(response["label"], "watched movie - person1")
            if response["breakdown_value"] == "person2":
                self.assertEqual(response["count"], 3)
            if response["breakdown_value"] == "person3":
                self.assertEqual(response["count"], 3)

        self.assertTrue(
            self._compare_entity_response(
                event_response,
                action_response,
            ))
Example #3
0
    def test_dau_with_breakdown_filtering_with_prop_filter(self):
        sign_up_action, _ = self._create_events()
        with freeze_time("2020-01-02T13:01:01Z"):
            _create_event(
                team=self.team,
                event="sign up",
                distinct_id="blabla",
                properties={
                    "$some_property": "other_value",
                    "$os": "Windows"
                },
            )
        with freeze_time("2020-01-04T13:01:01Z"):
            action_response = ClickhouseTrends().run(
                Filter(
                    data={
                        "breakdown": "$some_property",
                        "actions": [{
                            "id": sign_up_action.id,
                            "math": "dau"
                        }],
                        "properties": [{
                            "key": "$os",
                            "value": "Windows"
                        }],
                    }),
                self.team,
            )
            event_response = ClickhouseTrends().run(
                Filter(
                    data={
                        "breakdown": "$some_property",
                        "events": [{
                            "id": "sign up",
                            "math": "dau"
                        }],
                        "properties": [{
                            "key": "$os",
                            "value": "Windows"
                        }],
                    }),
                self.team,
            )

        self.assertEqual(event_response[0]["label"], "sign up - value")
        self.assertEqual(event_response[1]["label"], "sign up - other_value")

        self.assertEqual(sum(event_response[1]["data"]), 1)
        self.assertEqual(event_response[1]["data"][5],
                         1)  # property not defined

        self.assertTrue(
            self._compare_entity_response(action_response, event_response))
Example #4
0
    def test_prop_cohort_basic(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"
            },
        )
        _create_person(distinct_ids=["no_match"], team_id=self.team.pk)
        _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": {
                    "$some_prop": "something",
                    "$another_prop": "something"
                }
            }],
            name="cohort1",
        )

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort1.pk,
                "type": "cohort"
            }],
        })
        query, params = parse_prop_clauses(filter.properties, self.team)
        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)

        feature_flag = FeatureFlag.objects.create(filters=filter.to_dict(),
                                                  created_by=self.user,
                                                  name="test",
                                                  key="test",
                                                  team=self.team)
        self.assertTrue(feature_flag.distinct_id_matches("some_id"))
        self.assertFalse(feature_flag.distinct_id_matches("no_match"))
Example #5
0
    def path(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = request.user.team
        assert team is not None
        filter = Filter(request=request)
        resp = ClickhousePaths().run(filter=filter, team=team)
        return Response(resp)
Example #6
0
    def test_prop_event(self):

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

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

        filter = Filter(data={
            "properties": [{
                "key": "attr",
                "value": "some_val"
            }],
        })
        query, params = parse_prop_clauses(filter.properties, self.team.pk)
        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)
Example #7
0
    def test_breakdown_filtering(self):
        self._create_events()
        # test breakdown filtering
        with freeze_time("2020-01-04T13:01:01Z"):
            response = ClickhouseTrends().run(
                Filter(
                    data={
                        "date_from": "-14d",
                        "breakdown": "$some_property",
                        "events": [
                            {"id": "sign up", "name": "sign up", "type": "events", "order": 0,},
                            {"id": "no events"},
                        ],
                    }
                ),
                self.team,
            )

        self.assertEqual(response[0]["label"], 'sign up - "value"')
        self.assertEqual(response[1]["label"], 'sign up - "other_value"')
        self.assertEqual(response[2]["label"], 'no events - "value"')
        self.assertEqual(response[3]["label"], 'no events - "other_value"')

        self.assertEqual(sum(response[0]["data"]), 2)
        self.assertEqual(response[0]["breakdown_value"], '"value"')

        self.assertEqual(sum(response[1]["data"]), 1)
        self.assertEqual(response[1]["breakdown_value"], '"other_value"')
Example #8
0
    def retention(self, request: Request, *args: Any,
                  **kwargs: Any) -> Response:

        team = request.user.team
        filter = Filter(request=request)
        result = ClickhouseRetention().run(filter, team)
        return Response({"data": result})
Example #9
0
    def test_retention_period(self):
        Person.objects.create(
            team=self.team, distinct_ids=["person1", "alias1"], properties={"email": "*****@*****.**"},
        )
        Person.objects.create(
            team=self.team, distinct_ids=["person2"], properties={"email": "*****@*****.**"},
        )

        self._create_pageviews(
            [
                ("person1", self._date(0)),
                ("person1", self._date(1)),
                ("person1", self._date(2, month=1)),
                ("person1", self._date(10, month=1)),
                ("person1", self._date(15)),
                ("person1", self._date(18)),
                ("person2", self._date(13)),
            ]
        )

        filter = Filter(data={"date_from": self._date(0, hour=0), "period": "Week"})

        result = ClickhouseRetention().run(filter, self.team, total_intervals=7)

        self.assertEqual(
            self.pluck(result, "values", "count"),
            [[1, 0, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 0], [2, 1, 0, 1, 1], [1, 0, 1, 1], [0, 0, 0], [1, 1], [1],],
        )
Example #10
0
    def funnel(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = request.user.team
        assert team is not None
        filter = Filter(request=request)
        response = ClickhouseFunnel(team=team, filter=filter).run()
        return Response(response)
Example #11
0
    def test_prop_person(self):

        _create_person(distinct_ids=["some_other_id"],
                       team_id=self.team.pk,
                       properties={"email": "*****@*****.**"})

        _create_person(distinct_ids=["some_id"],
                       team_id=self.team.pk,
                       properties={"email": "*****@*****.**"})

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

        filter = Filter(
            data={
                "properties": [{
                    "key": "email",
                    "value": "*****@*****.**",
                    "type": "person"
                }],
            })
        query, params = parse_prop_clauses(filter.properties, self.team.pk)

        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)
Example #12
0
    def stats(self, request: request.Request) -> response.Response:
        filter = Filter(request=request)
        team = request.user.team
        assert team is not None

        date_from, date_to = parse_timestamps(filter)

        prop_filters, prop_filter_params = parse_prop_clauses(
            filter.properties, team.pk)
        result = sync_execute(
            GET_ELEMENTS.format(date_from=date_from,
                                date_to=date_to,
                                query=prop_filters),
            {
                "team_id": team.id,
                **prop_filter_params
            },
        )
        return response.Response([{
            "count":
            elements[1],
            "hash":
            None,
            "elements": [
                ElementSerializer(element).data
                for element in chain_to_elements(elements[0])
            ],
        } for elements in result])
Example #13
0
    def session(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = request.user.team
        filter = Filter(request=request)

        limit = int(request.GET.get("limit", SESSIONS_LIST_DEFAULT_LIMIT))
        offset = int(request.GET.get("offset", 0))

        response = ClickhouseSessions().run(team=team,
                                            filter=filter,
                                            limit=limit + 1,
                                            offset=offset)

        if "distinct_id" in request.GET and request.GET["distinct_id"]:
            try:
                person_ids = get_persons_by_distinct_ids(
                    team.pk, [request.GET["distinct_id"]])[0].distinct_ids
                response = [
                    session for i, session in enumerate(response)
                    if response[i]["distinct_id"] in person_ids
                ]
            except IndexError:
                response = []

        if len(response) > limit:
            response.pop()
            return Response({"result": response, "offset": offset + limit})
        else:
            return Response({
                "result": response,
            })
Example #14
0
    def people(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = request.user.team
        filter = Filter(request=request)
        shown_as = request.GET.get("shown_as")

        if len(filter.entities) >= 1:
            entity = filter.entities[0]
        else:
            entity = Entity({
                "id": request.GET["entityId"],
                "type": request.GET["type"]
            })

        # adhoc date handling. parsed differently with django orm
        date_from = filter.date_from or timezone.now()
        if filter.interval == "month":
            filter._date_to = (date_from + relativedelta(months=1) -
                               timedelta(days=1)).strftime("%Y-%m-%d %H:%M:%S")
        elif filter.interval == "week":
            filter._date_to = date_from + timedelta(weeks=1)
        elif filter.interval == "hour":
            filter._date_to = date_from + timedelta(hours=1)
        elif filter.interval == "minute":
            filter._date_to = date_from + timedelta(minutes=1)

        current_url = request.get_full_path()

        if shown_as is not None and shown_as == "Stickiness":
            stickiness_day = int(request.GET["stickiness_days"])
            serialized_people = self._calculate_stickiness_entity_people(
                team, entity, filter, stickiness_day)

        else:
            serialized_people = self._calculate_entity_people(
                team, entity, filter)

        current_url = request.get_full_path()
        next_url: Optional[str] = request.get_full_path()
        offset = filter.offset
        if len(serialized_people) > 100 and next_url:
            if "offset" in next_url:
                next_url = next_url[1:]
                next_url = next_url.replace("offset=" + str(offset),
                                            "offset=" + str(offset + 100))
            else:
                next_url = request.build_absolute_uri("{}{}offset={}".format(
                    next_url, "&" if "?" in next_url else "?", offset + 100))
        else:
            next_url = None
        return Response({
            "results": [{
                "people": serialized_people[0:100],
                "count": len(serialized_people[0:99])
            }],
            "next":
            next_url,
            "previous":
            current_url[1:],
        })
Example #15
0
    def funnel(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_FUNNEL_ENDPOINT, request.user.distinct_id):
            result = super().calculate_funnel(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        response = ClickhouseFunnel(team=team, filter=filter).run()
        return Response(response)
Example #16
0
    def path(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_PATH_ENDPOINT, request.user.distinct_id):
            result = super().calculate_path(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)
        resp = ClickhousePaths().run(filter=filter, team=team)
        return Response(resp)
Example #17
0
    def test_person_cohort_properties(self):
        person1_distinct_id = "person1"
        person1 = Person.objects.create(
            team=self.team, distinct_ids=[person1_distinct_id], properties={"$some_prop": "something"}
        )

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

        person2_distinct_id = "person2"
        person2 = Person.objects.create(
            team=self.team, distinct_ids=[person2_distinct_id], properties={"$some_prop": "different"}
        )
        cohort2 = Cohort.objects.create(
            team=self.team, groups=[{"properties": {"$some_prop__is_not": "something"}}], name="cohort2"
        )

        filter = Filter(data={"properties": [{"key": "id", "value": cohort1.pk, "type": "cohort"}],})

        prop_clause, prop_clause_params = parse_prop_clauses("uuid", filter.properties, self.team)
        query = """
        SELECT * FROM person_distinct_id WHERE team_id = %(team_id)s {prop_clause}
        """.format(
            prop_clause=prop_clause
        )
        # get distinct_id column of result
        result = sync_execute(query, {"team_id": self.team.pk, **prop_clause_params})[0][1]
        self.assertEqual(result, person1_distinct_id)

        # test cohort2 with negation
        filter = Filter(data={"properties": [{"key": "id", "value": cohort2.pk, "type": "cohort"}],})
        prop_clause, prop_clause_params = parse_prop_clauses("uuid", filter.properties, self.team)
        query = """
        SELECT * FROM person_distinct_id WHERE team_id = %(team_id)s {prop_clause}
        """.format(
            prop_clause=prop_clause
        )
        # get distinct_id column of result
        result = sync_execute(query, {"team_id": self.team.pk, **prop_clause_params})[0][1]

        self.assertEqual(result, person2_distinct_id)
Example #18
0
        def _single_step_funnel(self, properties=None, filters=None):
            if filters is None:
                filters = {
                    "events": [{"id": "user signed up", "type": "events", "order": 0},],
                }

            if properties is not None:
                filters.update({"properties": properties})

            filter = Filter(data=filters)
            return Funnel(filter=filter, team=self.team)
Example #19
0
    def retention(self, request: Request, *args: Any,
                  **kwargs: Any) -> Response:

        if not endpoint_enabled(CH_RETENTION_ENDPOINT,
                                request.user.distinct_id):
            result = super().calculate_retention(request)
            return Response({"data": result})

        team = request.user.team
        filter = Filter(request=request)
        result = ClickhouseRetention().run(filter, team)
        return Response({"data": result})
Example #20
0
    def trend(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = request.user.team
        filter = Filter(request=request)

        if filter.shown_as == TRENDS_STICKINESS:
            result = ClickhouseStickiness().run(filter, team)
        else:
            result = ClickhouseTrends().run(filter, team)

        self._refresh_dashboard(request=request)

        return Response(result)
Example #21
0
    def test_prop_cohort_basic_action(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"
            },
        )
        _create_person(distinct_ids=["no_match"], team_id=self.team.pk)

        action = _create_action(team=self.team, name="$pageview")
        _create_event(
            event="$pageview",
            team=self.team,
            distinct_id="some_id",
            properties={"attr": "some_val"},
        )

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

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

        filter = Filter(data={
            "properties": [{
                "key": "id",
                "value": cohort1.pk,
                "type": "cohort"
            }],
        })
        query, params = parse_prop_clauses(filter.properties, self.team.pk)
        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)
Example #22
0
    def trend(self, request: Request, *args: Any, **kwargs: Any) -> Response:
        if not endpoint_enabled(CH_TREND_ENDPOINT, request.user.distinct_id):
            result = super().calculate_trends(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)

        if filter.shown_as == TRENDS_STICKINESS:
            result = ClickhouseStickiness().run(filter, team)
        else:
            result = ClickhouseTrends().run(filter, team)

        self._refresh_dashboard(request=request)

        return Response(result)
Example #23
0
        def _basic_funnel(self, properties=None, filters=None):
            action_credit_card = Action.objects.create(team=self.team,
                                                       name="paid")
            ActionStep.objects.create(action=action_credit_card,
                                      event="$autocapture",
                                      tag_name="button",
                                      text="Pay $10")
            action_play_movie = Action.objects.create(team=self.team,
                                                      name="watched movie")
            ActionStep.objects.create(action=action_play_movie,
                                      event="$autocapture",
                                      tag_name="a",
                                      href="/movie")

            if filters is None:
                filters = {
                    "events": [
                        {
                            "id": "user signed up",
                            "type": "events",
                            "order": 0
                        },
                    ],
                    "actions": [
                        {
                            "id": action_credit_card.pk,
                            "type": "actions",
                            "order": 1
                        },
                        {
                            "id": action_play_movie.pk,
                            "type": "actions",
                            "order": 2
                        },
                    ],
                }

            if properties is not None:
                filters.update({"properties": properties})

            filter = Filter(data=filters)
            return Funnel(filter=filter, team=self.team)
Example #24
0
    def list(self, request):

        team = request.user.team
        filter = Filter(request=request)
        limit = "LIMIT 100" if not filter._date_from and not filter._date_to else ""
        conditions, condition_params = determine_event_conditions(request.GET)
        prop_filters, prop_filter_params = parse_filter(filter.properties)

        if prop_filters:
            query_result = sync_execute(
                SELECT_EVENT_WITH_PROP_SQL.format(conditions=conditions, limit=limit, filters=prop_filters),
                {"team_id": team.pk, **condition_params, **prop_filter_params},
            )
        else:
            query_result = sync_execute(
                SELECT_EVENT_WITH_ARRAY_PROPS_SQL.format(conditions=conditions, limit=limit),
                {"team_id": team.pk, **condition_params},
            )

        result = ClickhouseEventSerializer(query_result, many=True, context={"elements": None, "people": None}).data

        return Response({"next": None, "results": result})
Example #25
0
    def session(self, request: Request, *args: Any, **kwargs: Any) -> Response:
        if not endpoint_enabled(CH_SESSION_ENDPOINT, request.user.distinct_id):
            result = super().calculate_session(request)
            return Response(result)

        team = request.user.team
        filter = Filter(request=request)

        limit = int(request.GET.get("limit", SESSIONS_LIST_DEFAULT_LIMIT))
        offset = int(request.GET.get("offset", 0))

        response = ClickhouseSessions().run(team=team,
                                            filter=filter,
                                            limit=limit + 1,
                                            offset=offset)

        if len(response) > limit:
            response.pop()
            return Response({"result": response, "offset": offset + limit})
        else:
            return Response({
                "result": response,
            })
Example #26
0
    def path(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = self.team
        filter = Filter(request=request)
        resp = ClickhousePaths().run(filter=filter, team=team)
        return Response(resp)
Example #27
0
    def test_retention_period_weekly(self):
        Person.objects.create(
            team=self.team,
            distinct_ids=["person1", "alias1"],
            properties={"email": "*****@*****.**"},
        )
        Person.objects.create(
            team=self.team,
            distinct_ids=["person2"],
            properties={"email": "*****@*****.**"},
        )

        self._create_pageviews([
            ("person1", self._date(0)),
            ("person2", self._date(0)),
            ("person1", self._date(1)),
            ("person2", self._date(1)),
            ("person1", self._date(7)),
            ("person2", self._date(7)),
            ("person1", self._date(14)),
            ("person1", self._date(month=1, day=-6)),
            ("person2", self._date(month=1, day=-6)),
            ("person2", self._date(month=1, day=1)),
            ("person1", self._date(month=1, day=1)),
            ("person2", self._date(month=1, day=15)),
        ])

        filter = Filter(data={
            "date_to": self._date(10, month=1, hour=0),
            "period": "Week"
        })

        result = ClickhouseRetention().run(filter,
                                           self.team,
                                           total_intervals=7)

        self.assertEqual(
            self.pluck(result, "label"),
            [
                "Week 0", "Week 1", "Week 2", "Week 3", "Week 4", "Week 5",
                "Week 6"
            ],
        )

        self.assertEqual(
            self.pluck(result, "values", "count"),
            [
                [2, 2, 1, 2, 2, 0, 1],
                [2, 1, 2, 2, 0, 1],
                [1, 1, 1, 0, 0],
                [2, 2, 0, 1],
                [2, 0, 1],
                [0, 0],
                [1],
            ],
        )

        self.assertEqual(
            self.pluck(result, "date"),
            [
                datetime(2020, 6, 7, 0, tzinfo=pytz.UTC),
                datetime(2020, 6, 14, 0, tzinfo=pytz.UTC),
                datetime(2020, 6, 21, 0, tzinfo=pytz.UTC),
                datetime(2020, 6, 28, 0, tzinfo=pytz.UTC),
                datetime(2020, 7, 5, 0, tzinfo=pytz.UTC),
                datetime(2020, 7, 12, 0, tzinfo=pytz.UTC),
                datetime(2020, 7, 19, 0, tzinfo=pytz.UTC),
            ],
        )
Example #28
0
    def test_breakdown_filtering_with_properties(self):
        with freeze_time("2020-01-03T13:01:01Z"):
            _create_event(
                team=self.team,
                event="sign up",
                distinct_id="blabla",
                properties={
                    "$current_url": "first url",
                    "$browser": "Firefox",
                    "$os": "Mac"
                },
            )
            _create_event(
                team=self.team,
                event="sign up",
                distinct_id="blabla",
                properties={
                    "$current_url": "first url",
                    "$browser": "Chrome",
                    "$os": "Windows"
                },
            )
        with freeze_time("2020-01-04T13:01:01Z"):
            _create_event(
                team=self.team,
                event="sign up",
                distinct_id="blabla",
                properties={
                    "$current_url": "second url",
                    "$browser": "Firefox",
                    "$os": "Mac"
                },
            )
            _create_event(
                team=self.team,
                event="sign up",
                distinct_id="blabla",
                properties={
                    "$current_url": "second url",
                    "$browser": "Chrome",
                    "$os": "Windows"
                },
            )

        with freeze_time("2020-01-05T13:01:01Z"):
            response = ClickhouseTrends().run(
                Filter(
                    data={
                        "date_from":
                        "-14d",
                        "breakdown":
                        "$current_url",
                        "events": [
                            {
                                "id": "sign up",
                                "name": "sign up",
                                "type": "events",
                                "order": 0,
                                "properties": [{
                                    "key": "$os",
                                    "value": "Mac"
                                }],
                            },
                        ],
                        "properties": [{
                            "key": "$browser",
                            "value": "Firefox"
                        }],
                    }),
                self.team,
            )

        self.assertEqual(response[0]["label"], "sign up - second url")
        self.assertEqual(response[1]["label"], "sign up - first url")

        self.assertEqual(sum(response[0]["data"]), 1)
        self.assertEqual(response[0]["breakdown_value"], "second url")

        self.assertEqual(sum(response[1]["data"]), 1)
        self.assertEqual(response[1]["breakdown_value"], "first url")
Example #29
0
def dashboard_item_saved(sender, instance: DashboardItem, **kwargs):
    if instance.filters and instance.filters != {}:
        filter = Filter(data=instance.filters)
        instance.filters_hash = generate_cache_key("{}_{}".format(filter.toJSON(), instance.team_id))
Example #30
0
    def funnel(self, request: Request, *args: Any, **kwargs: Any) -> Response:

        team = self.team
        filter = Filter(request=request)
        response = ClickhouseFunnel(team=team, filter=filter).run()
        return Response(response)