Skip to content

Commit

Permalink
chore: adding tests to the insight trends query runner (#18352)
Browse files Browse the repository at this point in the history
* Added the final set of aggregation functions

* Added the ability to view all chart types on trends

* WIP adding tests

* Finished adding tests

* Fix test
  • Loading branch information
Gilbert09 authored Nov 10, 2023
1 parent bc18936 commit 1d2b727
Show file tree
Hide file tree
Showing 7 changed files with 771 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ class QueryAlternator:
_group_bys: List[ast.Expr]
_select_from: ast.JoinExpr | None

def __init__(self, query: ast.SelectQuery):
def __init__(self, query: ast.SelectQuery | ast.SelectUnionQuery):
assert isinstance(query, ast.SelectQuery)

self._query = query
self._selects = []
self._group_bys = []
self._select_from = None

def build(self) -> ast.SelectQuery:
def build(self) -> ast.SelectQuery | ast.SelectUnionQuery:
if len(self._selects) > 0:
self._query.select.extend(self._selects)

Expand Down Expand Up @@ -89,7 +89,7 @@ def select_aggregation(self) -> ast.Expr:
else:
raise NotImplementedError()

return parse_expr("count(e.uuid)")
return parse_expr("count(e.uuid)") # All "count per actor" get replaced during query orchestration

def requires_query_orchestration(self) -> bool:
math_to_return_true = [
Expand Down
4 changes: 2 additions & 2 deletions posthog/hogql_queries/insights/trends/breakdown_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ def __init__(
self.histogram_bin_count = int(histogram_bin_count) if histogram_bin_count is not None else None
self.group_type_index = int(group_type_index) if group_type_index is not None else None

def get_breakdown_values(self) -> List[str]:
def get_breakdown_values(self) -> List[str | int]:
if self.breakdown_type == "cohort":
return [int(self.breakdown_field)]

if self.breakdown_type == "hogql":
select_field = ast.Alias(
alias="value",
expr=parse_expr(self.breakdown_field),
expr=parse_expr(str(self.breakdown_field)),
)
else:
select_field = ast.Alias(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
from typing import cast
from datetime import datetime
from typing import Literal, Union, cast

import pytest
from posthog.hogql import ast
from posthog.hogql.parser import parse_select
from posthog.hogql_queries.insights.trends.aggregation_operations import QueryAlternator
from posthog.hogql_queries.insights.trends.aggregation_operations import (
AggregationOperations,
QueryAlternator,
)
from posthog.hogql_queries.utils.query_date_range import QueryDateRange
from posthog.models.team.team import Team
from posthog.schema import (
BaseMathType,
CountPerActorMathType,
EventsNode,
PropertyMathType,
)


class TestQueryAlternator:
Expand Down Expand Up @@ -44,3 +58,91 @@ def test_replace_select_from(self):
query_modifier.build()

assert query.select_from.table.chain == ["groups"]


@pytest.mark.parametrize(
"math,math_property",
[
[BaseMathType.total, None],
[BaseMathType.dau, None],
[BaseMathType.weekly_active, None],
[BaseMathType.monthly_active, None],
[BaseMathType.unique_session, None],
[PropertyMathType.avg, "$browser"],
[PropertyMathType.sum, "$browser"],
[PropertyMathType.min, "$browser"],
[PropertyMathType.max, "$browser"],
[PropertyMathType.median, "$browser"],
[PropertyMathType.p90, "$browser"],
[PropertyMathType.p95, "$browser"],
[PropertyMathType.p99, "$browser"],
[CountPerActorMathType.avg_count_per_actor, None],
[CountPerActorMathType.min_count_per_actor, None],
[CountPerActorMathType.max_count_per_actor, None],
[CountPerActorMathType.median_count_per_actor, None],
[CountPerActorMathType.p90_count_per_actor, None],
[CountPerActorMathType.p95_count_per_actor, None],
[CountPerActorMathType.p99_count_per_actor, None],
["hogql", None],
],
)
def test_all_cases_return(
math: Union[
BaseMathType,
PropertyMathType,
CountPerActorMathType,
Literal["unique_group"],
Literal["hogql"],
],
math_property: str,
):
series = EventsNode(event="$pageview", math=math, math_property=math_property)
query_date_range = QueryDateRange(date_range=None, interval=None, now=datetime.now(), team=Team())

agg_ops = AggregationOperations(series, query_date_range)
res = agg_ops.select_aggregation()
assert isinstance(res, ast.Expr)


@pytest.mark.parametrize(
"math,result",
[
[BaseMathType.total, False],
[BaseMathType.dau, False],
[BaseMathType.weekly_active, True],
[BaseMathType.monthly_active, True],
[BaseMathType.unique_session, False],
[PropertyMathType.avg, False],
[PropertyMathType.sum, False],
[PropertyMathType.min, False],
[PropertyMathType.max, False],
[PropertyMathType.median, False],
[PropertyMathType.p90, False],
[PropertyMathType.p95, False],
[PropertyMathType.p99, False],
[CountPerActorMathType.avg_count_per_actor, True],
[CountPerActorMathType.min_count_per_actor, True],
[CountPerActorMathType.max_count_per_actor, True],
[CountPerActorMathType.median_count_per_actor, True],
[CountPerActorMathType.p90_count_per_actor, True],
[CountPerActorMathType.p95_count_per_actor, True],
[CountPerActorMathType.p99_count_per_actor, True],
["hogql", False],
],
)
def test_requiring_query_orchestration(
math: Union[
BaseMathType,
PropertyMathType,
CountPerActorMathType,
Literal["unique_group"],
Literal["hogql"],
],
result: bool,
):
series = EventsNode(event="$pageview", math=math)
query_date_range = QueryDateRange(date_range=None, interval=None, now=datetime.now(), team=Team())

agg_ops = AggregationOperations(series, query_date_range)
res = agg_ops.requires_query_orchestration()
assert res == result
Loading

0 comments on commit 1d2b727

Please sign in to comment.