From 18ca9a9731b37320a8d2673e01309fab9e17d887 Mon Sep 17 00:00:00 2001 From: Rafa Audibert Date: Thu, 12 Dec 2024 18:19:24 -0300 Subject: [PATCH] test: Add missing tests for comparison --- .../web_analytics/stats_table.py | 3 - .../web_analytics/test/test_web_overview.py | 47 ++++++++ .../test/test_web_stats_table.py | 103 +++++++++++------- 3 files changed, 111 insertions(+), 42 deletions(-) diff --git a/posthog/hogql_queries/web_analytics/stats_table.py b/posthog/hogql_queries/web_analytics/stats_table.py index d9fe98c4678f9b..7135934bc66257 100644 --- a/posthog/hogql_queries/web_analytics/stats_table.py +++ b/posthog/hogql_queries/web_analytics/stats_table.py @@ -242,9 +242,6 @@ def to_path_bounce_query(self) -> ast.SelectQuery: with self.timings.measure("stats_table_scroll_query"): query = parse_select( """ -WITH - start_timestamp >= {current_date_range_start} AND start_timestamp < {current_date_range_end} AS current_period_segment, - start_timestamp >= {previous_date_range_start} AND start_timestamp < {previous_date_range_end} AS previous_period_segment SELECT counts.breakdown_value AS "context.columns.breakdown_value", tuple(counts.visitors, counts.previous_visitors) AS "context.columns.visitors", diff --git a/posthog/hogql_queries/web_analytics/test/test_web_overview.py b/posthog/hogql_queries/web_analytics/test/test_web_overview.py index 5ae981afdba469..3a5c421cb890a1 100644 --- a/posthog/hogql_queries/web_analytics/test/test_web_overview.py +++ b/posthog/hogql_queries/web_analytics/test/test_web_overview.py @@ -232,6 +232,53 @@ def test_all_time(self): self.assertEqual(None, bounce.previous) self.assertEqual(None, bounce.changeFromPreviousPct) + def test_comparison(self): + s1a = str(uuid7("2023-12-02")) + s1b = str(uuid7("2023-12-12")) + s2 = str(uuid7("2023-12-11")) + self._create_events( + [ + ("p1", [("2023-12-02", s1a), ("2023-12-03", s1a), ("2023-12-12", s1b)]), + ("p2", [("2023-12-11", s2)]), + ] + ) + + results = self._run_web_overview_query( + "2023-12-06", + "2023-12-13", + compare=True, + ).results + + visitors = results[0] + self.assertEqual("visitors", visitors.key) + self.assertEqual(2, visitors.value) + self.assertEqual(1, visitors.previous) + self.assertEqual(100, visitors.changeFromPreviousPct) + + views = results[1] + self.assertEqual("views", views.key) + self.assertEqual(2, views.value) + self.assertEqual(2, views.previous) + self.assertEqual(0, views.changeFromPreviousPct) + + sessions = results[2] + self.assertEqual("sessions", sessions.key) + self.assertEqual(2, sessions.value) + self.assertEqual(1, sessions.previous) + self.assertEqual(100, sessions.changeFromPreviousPct) + + duration_s = results[3] + self.assertEqual("session duration", duration_s.key) + self.assertEqual(0, duration_s.value) + self.assertEqual(60 * 60 * 24, duration_s.previous) + self.assertEqual(-100, duration_s.changeFromPreviousPct) + + bounce = results[4] + self.assertEqual("bounce rate", bounce.key) + self.assertAlmostEqual(100, bounce.value) + self.assertEqual(0, bounce.previous) + self.assertEqual(None, bounce.changeFromPreviousPct) + def test_filter_test_accounts(self): s1 = str(uuid7("2023-12-02")) # Create 1 test account diff --git a/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py b/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py index f59c95931dd07e..74c12e30586cf5 100644 --- a/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py +++ b/posthog/hogql_queries/web_analytics/test/test_web_stats_table.py @@ -7,6 +7,7 @@ from posthog.models.utils import uuid7 from posthog.schema import ( DateRange, + CompareFilter, WebStatsTableQuery, WebStatsBreakdown, EventPropertyFilter, @@ -123,6 +124,7 @@ def _run_web_stats_table_query( include_bounce_rate=False, include_scroll_depth=False, properties=None, + compare_filter=None, action: Optional[Action] = None, custom_event: Optional[str] = None, session_table_version: SessionTableVersion = SessionTableVersion.V2, @@ -137,6 +139,7 @@ def _run_web_stats_table_query( doPathCleaning=bool(path_cleaning_filters), includeBounceRate=include_bounce_rate, includeScrollDepth=include_scroll_depth, + compareFilter=compare_filter, conversionGoal=ActionConversionGoal(actionId=action.id) if action else CustomEventConversionGoal(customEventName=custom_event) @@ -170,8 +173,8 @@ def test_increase_in_users(self): self.assertEqual( [ - ["/", (2, 0), (2, 0)], - ["/login", (1, 0), (1, 0)], + ["/", (2, None), (2, None)], + ["/login", (1, None), (1, None)], ], results, ) @@ -191,9 +194,33 @@ def test_all_time(self): self.assertEqual( [ - ["/", (2, 0), (2, 0)], + ["/", (2, None), (2, None)], + ["/docs", (1, None), (1, None)], + ["/login", (1, None), (1, None)], + ], + results, + ) + + def test_comparison(self): + s1a = str(uuid7("2023-12-02")) + s1b = str(uuid7("2023-12-13")) + s2 = str(uuid7("2023-12-10")) + self._create_events( + [ + ("p1", [("2023-12-02", s1a, "/"), ("2023-12-03", s1a, "/login"), ("2023-12-13", s1b, "/docs")]), + ("p2", [("2023-12-10", s2, "/")]), + ] + ) + + results = self._run_web_stats_table_query( + "2023-12-06", "2023-12-13", compare_filter=CompareFilter(compare=True) + ).results + + self.assertEqual( + [ + ["/", (1, 1), (1, 1)], ["/docs", (1, 0), (1, 0)], - ["/login", (1, 0), (1, 0)], + ["/login", (0, 1), (0, 1)], ], results, ) @@ -218,7 +245,7 @@ def test_dont_filter_test_accounts(self): results = self._run_web_stats_table_query("2023-12-01", "2023-12-03", filter_test_accounts=False).results self.assertEqual( - [["/", (1, 0), (1, 0)], ["/login", (1, 0), (1, 0)]], + [["/", (1, None), (1, None)], ["/login", (1, None), (1, None)]], results, ) @@ -258,7 +285,7 @@ def test_limit(self): response_1 = self._run_web_stats_table_query("all", "2023-12-15", limit=1) self.assertEqual( [ - ["/", (2, 0), (2, 0)], + ["/", (2, None), (2, None)], ], response_1.results, ) @@ -267,8 +294,8 @@ def test_limit(self): response_2 = self._run_web_stats_table_query("all", "2023-12-15", limit=2) self.assertEqual( [ - ["/", (2, 0), (2, 0)], - ["/login", (1, 0), (1, 0)], + ["/", (2, None), (2, None)], + ["/login", (1, None), (1, None)], ], response_2.results, ) @@ -303,10 +330,10 @@ def test_path_filters(self): self.assertEqual( [ - ["/cleaned/:id", (2, 0), (2, 0)], - ["/cleaned/:id/path/:id", (1, 0), (1, 0)], - ["/not-cleaned", (1, 0), (1, 0)], - ["/thing_c", (1, 0), (1, 0)], + ["/cleaned/:id", (2, None), (2, None)], + ["/cleaned/:id/path/:id", (1, None), (1, None)], + ["/not-cleaned", (1, None), (1, None)], + ["/thing_c", (1, None), (1, None)], ], results, ) @@ -610,7 +637,7 @@ def test_entry_bounce_rate_one_user(self): self.assertEqual( [ - ["/a", (1, 0), (3, 0), (0, None)], + ["/a", (1, None), (3, None), (0, None)], ], results, ) @@ -649,7 +676,7 @@ def test_entry_bounce_rate(self): self.assertEqual( [ - ["/a", (3, 0), (8, 0), (1 / 3, None)], + ["/a", (3, None), (8, None), (1 / 3, None)], ], results, ) @@ -689,7 +716,7 @@ def test_entry_bounce_rate_with_property(self): self.assertEqual( [ - ["/a", (3, 0), (4, 0), (1 / 3, None)], + ["/a", (3, None), (4, None), (1 / 3, None)], ], results, ) @@ -718,7 +745,7 @@ def test_entry_bounce_rate_path_cleaning(self): self.assertEqual( [ - ["/a/:id", (1, 0), (3, 0), (0, None)], + ["/a/:id", (1, None), (3, None), (0, None)], ], results, ) @@ -767,8 +794,8 @@ def test_source_medium_campaign(self): self.assertEqual( [ - ["google / (none) / (none)", (1, 0), (1, 0)], - ["news.ycombinator.com / referral / (none)", (1, 0), (1, 0)], + ["google / (none) / (none)", (1, None), (1, None)], + ["news.ycombinator.com / referral / (none)", (1, None), (1, None)], ], results, ) @@ -818,7 +845,7 @@ def test_null_in_utm_tags(self): ).results self.assertEqual( - [["google", (1, 0), (1, 0)], [None, (1, 0), (1, 0)]], + [["google", (1, None), (1, None)], [None, (1, None), (1, None)]], results, ) @@ -868,7 +895,7 @@ def test_is_not_set_filter(self): ).results self.assertEqual( - [[None, (1, 0), (1, 0)]], + [[None, (1, None), (1, None)]], results, ) @@ -904,7 +931,7 @@ def test_same_user_multiple_sessions(self): "2024-07-31", breakdown_by=WebStatsBreakdown.INITIAL_UTM_SOURCE, ).results - assert [["google", (1, 0), (2, 0)]] == results_session + assert [["google", (1, None), (2, None)]] == results_session # Try this with a query that uses event properties results_event = self._run_web_stats_table_query( @@ -912,7 +939,7 @@ def test_same_user_multiple_sessions(self): "2024-07-31", breakdown_by=WebStatsBreakdown.PAGE, ).results - assert [["/path", (1, 0), (2, 0)]] == results_event + assert [["/path", (1, None), (2, None)]] == results_event # Try this with a query using the bounce rate results_event = self._run_web_stats_table_query( @@ -961,16 +988,14 @@ def test_no_session_id(self): ).results assert [] == results - # Do show event property breakdowns of events with no session id - # but it will return 0 views because we depend on session.$start_timestamp - # to figure out the previous/current values + # Show event property breakdowns of page view events even without session id results = self._run_web_stats_table_query( "all", "2024-07-31", breakdown_by=WebStatsBreakdown.PAGE, ).results - assert [["/path", (0, 0), (0, 0)]] == results + assert [["/path", (1, None), (1, None)]] == results def test_cohort_test_filters(self): d1 = "d1" @@ -1032,7 +1057,7 @@ def test_cohort_test_filters(self): breakdown_by=WebStatsBreakdown.PAGE, ).results - assert results == [["/path1", (1, 0), (1, 0)]] + assert results == [["/path1", (1, None), (1, None)]] def test_language_filter(self): d1, s1 = "d1", str(uuid7("2024-07-30")) @@ -1158,10 +1183,10 @@ def test_timezone_filter_general(self): # Brasilia UTC-3, New York UTC-4, Calcutta UTC+5:30, UTC assert results == [ - [-3, (1, 1), (4, 1)], - [-4, (1, 1), (3, 1)], - [5.5, (1, 1), (2, 1)], - [0, (1, 1), (1, 1)], + [-3, (1, None), (4, None)], + [-4, (1, None), (3, None)], + [5.5, (1, None), (2, None)], + [0, (1, None), (1, None)], ] def test_timezone_filter_dst_change(self): @@ -1191,7 +1216,7 @@ def test_timezone_filter_dst_change(self): ).results # Change from UTC-2 to UTC-3 in the middle of the night - assert results == [[-3, (1, 0), (4, 0)], [-2, (1, 0), (2, 0)]] + assert results == [[-3, (1, None), (4, None)], [-2, (1, None), (2, None)]] def test_timezone_filter_with_invalid_timezone(self): date = "2024-07-30" @@ -1297,7 +1322,7 @@ def test_conversion_goal_no_conversions(self): "2023-12-01", "2023-12-03", breakdown_by=WebStatsBreakdown.PAGE, action=action ) - assert [["https://www.example.com/foo", (1, 0), (0, 0), (0, 0), (0, None)]] == response.results + assert [["https://www.example.com/foo", (1, None), (0, None), (0, None), (0, None)]] == response.results assert [ "context.columns.breakdown_value", "context.columns.visitors", @@ -1334,7 +1359,7 @@ def test_conversion_goal_one_pageview_conversion(self): "2023-12-01", "2023-12-03", breakdown_by=WebStatsBreakdown.PAGE, action=action ) - assert [["https://www.example.com/foo", (1, 0), (1, 0), (1, 0), (1, None)]] == response.results + assert [["https://www.example.com/foo", (1, None), (1, None), (1, None), (1, None)]] == response.results assert [ "context.columns.breakdown_value", "context.columns.visitors", @@ -1359,7 +1384,7 @@ def test_conversion_goal_one_custom_event_conversion(self): custom_event="custom_event", ) - assert [[None, (1, 0), (1, 0), (1, 0), (1, None)]] == response.results + assert [[None, (1, None), (1, None), (1, None), (1, None)]] == response.results assert [ "context.columns.breakdown_value", "context.columns.visitors", @@ -1394,7 +1419,7 @@ def test_conversion_goal_one_custom_action_conversion(self): action=action, ) - assert [[None, (1, 0), (1, 0), (1, 0), (1, None)]] == response.results + assert [[None, (1, None), (1, None), (1, None), (1, None)]] == response.results assert [ "context.columns.breakdown_value", "context.columns.visitors", @@ -1431,7 +1456,7 @@ def test_conversion_goal_one_autocapture_conversion(self): action=action, ) - assert [[None, (1, 0), (1, 0), (1, 0), (1, None)]] == response.results + assert [[None, (1, None), (1, None), (1, None), (1, None)]] == response.results assert [ "context.columns.breakdown_value", "context.columns.visitors", @@ -1482,8 +1507,8 @@ def test_conversion_rate(self): ) assert [ - ["https://www.example.com/foo", (2, 0), (3, 0), (2, 0), (1, None)], - ["https://www.example.com/bar", (2, 0), (0, 0), (0, 0), (0, None)], + ["https://www.example.com/foo", (2, None), (3, None), (2, None), (1, None)], + ["https://www.example.com/bar", (2, None), (0, None), (0, None), (0, None)], ] == response.results assert [ "context.columns.breakdown_value",