Skip to content

Commit

Permalink
fix(insights): Apply dashboard filters to BI nodes (#21350)
Browse files Browse the repository at this point in the history
* fix(insights): Apply dashboard filters to BI nodes

* Add tests

* Update query snapshots

* Update query snapshots

* Update query snapshots

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
Twixes and github-actions[bot] authored Apr 4, 2024
1 parent 65a1748 commit ecb2230
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
9 changes: 7 additions & 2 deletions posthog/api/insight.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
)
from posthog.hogql.errors import HogQLException
from posthog.hogql.timings import HogQLTimings
from posthog.hogql_queries.apply_dashboard_filters import DATA_TABLE_LIKE_NODE_KINDS
from posthog.hogql_queries.legacy_compatibility.feature_flag import hogql_insights_enabled
from posthog.hogql_queries.legacy_compatibility.process_insight import is_insight_with_hogql_support, process_insight
from posthog.kafka_client.topics import KAFKA_METRICS_TIME_TO_SEE_DATA
Expand Down Expand Up @@ -690,10 +691,14 @@ def _filter_request(self, request: request.Request, queryset: QuerySet) -> Query
insight = request.GET[INSIGHT]
if insight == "JSON":
queryset = queryset.filter(query__isnull=False)
queryset = queryset.exclude(query__kind="DataTableNode", query__source__kind="HogQLQuery")
queryset = queryset.exclude(
query__kind__in=DATA_TABLE_LIKE_NODE_KINDS, query__source__kind="HogQLQuery"
)
elif insight == "SQL":
queryset = queryset.filter(query__isnull=False)
queryset = queryset.filter(query__kind="DataTableNode", query__source__kind="HogQLQuery")
queryset = queryset.filter(
query__kind__in=DATA_TABLE_LIKE_NODE_KINDS, query__source__kind="HogQLQuery"
)
else:
queryset = queryset.filter(query__isnull=True)
queryset = queryset.filter(filters__insight=insight)
Expand Down
2 changes: 1 addition & 1 deletion posthog/api/test/__snapshots__/test_query.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
# ---
# name: TestQuery.test_full_hogql_query_async
'''
/* user_id:468 celery:posthog.tasks.tasks.process_query_task */
/* user_id:470 celery:posthog.tasks.tasks.process_query_task */
SELECT events.uuid AS uuid,
events.event AS event,
events.properties AS properties,
Expand Down
51 changes: 51 additions & 0 deletions posthog/api/test/test_insight.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
OrganizationMembership,
Text,
)
from posthog.schema import DataTableNode, DataVisualizationNode, DateRange, HogQLFilters, HogQLQuery
from posthog.test.base import (
APIBaseTest,
ClickhouseTestMixin,
Expand Down Expand Up @@ -1123,6 +1124,56 @@ def test_insight_refreshing(self, spy_update_insight_cache) -> None:
],
)

def test_dashboard_filters_applied_to_data_table_node(self):
dashboard_id, _ = self.dashboard_api.create_dashboard(
{"name": "the dashboard", "filters": {"date_from": "-180d"}}
)
query = DataTableNode(
source=HogQLQuery(
query="SELECT count(1) FROM events", filters=HogQLFilters(dateRange=DateRange(date_from="-3d"))
),
).model_dump()
insight_id, _ = self.dashboard_api.create_insight(
{"query": query, "name": "insight", "dashboards": [dashboard_id]}
)

response = self.client.get(f"/api/projects/{self.team.id}/insights/{insight_id}/")

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["query"], query)

response = self.client.get(
f"/api/projects/{self.team.id}/insights/{insight_id}/?refresh=true&from_dashboard={dashboard_id}"
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["query"]["source"]["filters"]["dateRange"]["date_from"], "-180d")

def test_dashboard_filters_applied_to_data_visualization_node(self):
dashboard_id, _ = self.dashboard_api.create_dashboard(
{"name": "the dashboard", "filters": {"date_from": "-180d"}}
)
query = DataVisualizationNode(
source=HogQLQuery(
query="SELECT count(1) FROM events", filters=HogQLFilters(dateRange=DateRange(date_from="-3d"))
),
).model_dump()
insight_id, _ = self.dashboard_api.create_insight(
{"query": query, "name": "insight", "dashboards": [dashboard_id]}
)

response = self.client.get(f"/api/projects/{self.team.id}/insights/{insight_id}/")

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["query"], query)

response = self.client.get(
f"/api/projects/{self.team.id}/insights/{insight_id}/?refresh=true&from_dashboard={dashboard_id}"
)

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.json()["query"]["source"]["filters"]["dateRange"]["date_from"], "-180d")

# BASIC TESTING OF ENDPOINTS. /queries as in depth testing for each insight

def test_insight_trends_basic(self) -> None:
Expand Down
6 changes: 4 additions & 2 deletions posthog/hogql_queries/apply_dashboard_filters.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from posthog.hogql_queries.query_runner import get_query_runner
from posthog.models import Team
from posthog.schema import DashboardFilter
from posthog.schema import DashboardFilter, NodeKind

DATA_TABLE_LIKE_NODE_KINDS = [NodeKind.DataTableNode, NodeKind.DataVisualizationNode]


# Apply the filters from the django-style Dashboard object
def apply_dashboard_filters(query: dict, filters: dict, team: Team) -> dict:
kind = query.get("kind", None)

if kind == "DataTableNode":
if kind in DATA_TABLE_LIKE_NODE_KINDS:
source = apply_dashboard_filters(query["source"], filters, team)
return {**query, "source": source}

Expand Down

0 comments on commit ecb2230

Please sign in to comment.