diff --git a/posthog/api/decide.py b/posthog/api/decide.py index 2b6ebf418674b..820179f93aa4c 100644 --- a/posthog/api/decide.py +++ b/posthog/api/decide.py @@ -391,7 +391,10 @@ def _session_recording_config_response(request: HttpRequest, team: Team) -> bool try: if team.session_recording_opt_in and not _session_recording_domain_not_allowed(team, request): capture_console_logs = True if team.capture_console_log_opt_in else False - sample_rate = str(team.session_recording_sample_rate) if team.session_recording_sample_rate else None + sample_rate = ( + str(team.session_recording_sample_rate) if team.session_recording_sample_rate is not None else None + ) + if sample_rate == "1.00": sample_rate = None diff --git a/posthog/api/test/__snapshots__/test_decide.ambr b/posthog/api/test/__snapshots__/test_decide.ambr index 78ed20c78730a..1a90a48a5ebb5 100644 --- a/posthog/api/test/__snapshots__/test_decide.ambr +++ b/posthog/api/test/__snapshots__/test_decide.ambr @@ -1858,47 +1858,6 @@ LIMIT 21 ''' # --- -# name: TestDecide.test_flag_with_behavioural_cohorts.22 - ''' - SELECT "posthog_cohort"."id", - "posthog_cohort"."name", - "posthog_cohort"."description", - "posthog_cohort"."team_id", - "posthog_cohort"."deleted", - "posthog_cohort"."filters", - "posthog_cohort"."query", - "posthog_cohort"."version", - "posthog_cohort"."pending_version", - "posthog_cohort"."count", - "posthog_cohort"."created_by_id", - "posthog_cohort"."created_at", - "posthog_cohort"."is_calculating", - "posthog_cohort"."last_calculation", - "posthog_cohort"."errors_calculating", - "posthog_cohort"."last_error_at", - "posthog_cohort"."is_static", - "posthog_cohort"."groups" - FROM "posthog_cohort" - WHERE (NOT "posthog_cohort"."deleted" - AND "posthog_cohort"."team_id" = 99999) - ''' -# --- -# name: TestDecide.test_flag_with_behavioural_cohorts.23 - ''' - SELECT "posthog_group"."id", - "posthog_group"."team_id", - "posthog_group"."group_key", - "posthog_group"."group_type_index", - "posthog_group"."group_properties", - "posthog_group"."created_at", - "posthog_group"."properties_last_updated_at", - "posthog_group"."properties_last_operation", - "posthog_group"."version" - FROM "posthog_group" - WHERE "posthog_group"."team_id" = 99999 - LIMIT 21 - ''' -# --- # name: TestDecide.test_flag_with_behavioural_cohorts.3 ''' SELECT "posthog_team"."id", @@ -2936,43 +2895,6 @@ AND "posthog_person"."team_id" = 99999) ''' # --- -# name: TestDecide.test_flag_with_regular_cohorts.22 - ''' - SELECT "posthog_cohort"."id", - "posthog_cohort"."name", - "posthog_cohort"."description", - "posthog_cohort"."team_id", - "posthog_cohort"."deleted", - "posthog_cohort"."filters", - "posthog_cohort"."query", - "posthog_cohort"."version", - "posthog_cohort"."pending_version", - "posthog_cohort"."count", - "posthog_cohort"."created_by_id", - "posthog_cohort"."created_at", - "posthog_cohort"."is_calculating", - "posthog_cohort"."last_calculation", - "posthog_cohort"."errors_calculating", - "posthog_cohort"."last_error_at", - "posthog_cohort"."is_static", - "posthog_cohort"."groups" - FROM "posthog_cohort" - WHERE (NOT "posthog_cohort"."deleted" - AND "posthog_cohort"."team_id" = 99999) - ''' -# --- -# name: TestDecide.test_flag_with_regular_cohorts.23 - ''' - SELECT (("posthog_person"."properties" -> '$some_prop_1') = '"something_1"'::jsonb - AND "posthog_person"."properties" ? '$some_prop_1' - AND NOT (("posthog_person"."properties" -> '$some_prop_1') = 'null'::jsonb)) AS "flag_X_condition_0" - FROM "posthog_person" - INNER JOIN "posthog_persondistinctid" ON ("posthog_person"."id" = "posthog_persondistinctid"."person_id") - WHERE ("posthog_persondistinctid"."distinct_id" = 'another_id' - AND "posthog_persondistinctid"."team_id" = 99999 - AND "posthog_person"."team_id" = 99999) - ''' -# --- # name: TestDecide.test_flag_with_regular_cohorts.3 ''' SELECT "posthog_team"."id", @@ -4007,38 +3929,6 @@ AND "posthog_pluginconfig"."team_id" = 99999) ''' # --- -# name: TestDecide.test_web_app_queries.22 - ''' - SELECT "posthog_pluginconfig"."id", - "posthog_pluginconfig"."web_token", - "posthog_pluginsourcefile"."updated_at", - "posthog_plugin"."updated_at", - "posthog_pluginconfig"."updated_at" - FROM "posthog_pluginconfig" - INNER JOIN "posthog_plugin" ON ("posthog_pluginconfig"."plugin_id" = "posthog_plugin"."id") - INNER JOIN "posthog_pluginsourcefile" ON ("posthog_plugin"."id" = "posthog_pluginsourcefile"."plugin_id") - WHERE ("posthog_pluginconfig"."enabled" - AND "posthog_pluginsourcefile"."filename" = 'site.ts' - AND "posthog_pluginsourcefile"."status" = 'TRANSPILED' - AND "posthog_pluginconfig"."team_id" = 99999) - ''' -# --- -# name: TestDecide.test_web_app_queries.23 - ''' - SELECT "posthog_pluginconfig"."id", - "posthog_pluginconfig"."web_token", - "posthog_pluginsourcefile"."updated_at", - "posthog_plugin"."updated_at", - "posthog_pluginconfig"."updated_at" - FROM "posthog_pluginconfig" - INNER JOIN "posthog_plugin" ON ("posthog_pluginconfig"."plugin_id" = "posthog_plugin"."id") - INNER JOIN "posthog_pluginsourcefile" ON ("posthog_plugin"."id" = "posthog_pluginsourcefile"."plugin_id") - WHERE ("posthog_pluginconfig"."enabled" - AND "posthog_pluginsourcefile"."filename" = 'site.ts' - AND "posthog_pluginsourcefile"."status" = 'TRANSPILED' - AND "posthog_pluginconfig"."team_id" = 99999) - ''' -# --- # name: TestDecide.test_web_app_queries.3 ''' SELECT "posthog_hogfunction"."id", @@ -6070,36 +5960,6 @@ 'site_app')) ''' # --- -# name: TestDecideRemoteConfig.test_decide_doesnt_error_out_when_database_is_down.48 - ''' - SELECT "posthog_hogfunction"."id", - "posthog_hogfunction"."team_id", - "posthog_hogfunction"."name", - "posthog_hogfunction"."description", - "posthog_hogfunction"."created_at", - "posthog_hogfunction"."created_by_id", - "posthog_hogfunction"."deleted", - "posthog_hogfunction"."updated_at", - "posthog_hogfunction"."enabled", - "posthog_hogfunction"."type", - "posthog_hogfunction"."icon_url", - "posthog_hogfunction"."hog", - "posthog_hogfunction"."bytecode", - "posthog_hogfunction"."transpiled", - "posthog_hogfunction"."inputs_schema", - "posthog_hogfunction"."inputs", - "posthog_hogfunction"."encrypted_inputs", - "posthog_hogfunction"."filters", - "posthog_hogfunction"."mappings", - "posthog_hogfunction"."masking", - "posthog_hogfunction"."template_id" - FROM "posthog_hogfunction" - WHERE ("posthog_hogfunction"."enabled" - AND "posthog_hogfunction"."team_id" = 99999 - AND "posthog_hogfunction"."type" IN ('site_destination', - 'site_app')) - ''' -# --- # name: TestDecideRemoteConfig.test_decide_doesnt_error_out_when_database_is_down.5 ''' SELECT "posthog_organizationmembership"."id", @@ -7579,108 +7439,6 @@ LIMIT 21 ''' # --- -# name: TestDecideRemoteConfig.test_flag_with_behavioural_cohorts.34 - ''' - SELECT "posthog_hogfunction"."id", - "posthog_hogfunction"."team_id", - "posthog_hogfunction"."name", - "posthog_hogfunction"."description", - "posthog_hogfunction"."created_at", - "posthog_hogfunction"."created_by_id", - "posthog_hogfunction"."deleted", - "posthog_hogfunction"."updated_at", - "posthog_hogfunction"."enabled", - "posthog_hogfunction"."type", - "posthog_hogfunction"."icon_url", - "posthog_hogfunction"."hog", - "posthog_hogfunction"."bytecode", - "posthog_hogfunction"."transpiled", - "posthog_hogfunction"."inputs_schema", - "posthog_hogfunction"."inputs", - "posthog_hogfunction"."encrypted_inputs", - "posthog_hogfunction"."filters", - "posthog_hogfunction"."mappings", - "posthog_hogfunction"."masking", - "posthog_hogfunction"."template_id" - FROM "posthog_hogfunction" - WHERE ("posthog_hogfunction"."enabled" - AND "posthog_hogfunction"."team_id" = 99999 - AND "posthog_hogfunction"."type" IN ('site_destination', - 'site_app')) - LIMIT 21 - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_behavioural_cohorts.35 - ''' - SELECT "posthog_hogfunction"."id", - "posthog_hogfunction"."team_id", - "posthog_hogfunction"."name", - "posthog_hogfunction"."description", - "posthog_hogfunction"."created_at", - "posthog_hogfunction"."created_by_id", - "posthog_hogfunction"."deleted", - "posthog_hogfunction"."updated_at", - "posthog_hogfunction"."enabled", - "posthog_hogfunction"."type", - "posthog_hogfunction"."icon_url", - "posthog_hogfunction"."hog", - "posthog_hogfunction"."bytecode", - "posthog_hogfunction"."transpiled", - "posthog_hogfunction"."inputs_schema", - "posthog_hogfunction"."inputs", - "posthog_hogfunction"."encrypted_inputs", - "posthog_hogfunction"."filters", - "posthog_hogfunction"."mappings", - "posthog_hogfunction"."masking", - "posthog_hogfunction"."template_id" - FROM "posthog_hogfunction" - WHERE ("posthog_hogfunction"."enabled" - AND "posthog_hogfunction"."team_id" = 99999 - AND "posthog_hogfunction"."type" IN ('site_destination', - 'site_app')) - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_behavioural_cohorts.36 - ''' - SELECT "posthog_cohort"."id", - "posthog_cohort"."name", - "posthog_cohort"."description", - "posthog_cohort"."team_id", - "posthog_cohort"."deleted", - "posthog_cohort"."filters", - "posthog_cohort"."query", - "posthog_cohort"."version", - "posthog_cohort"."pending_version", - "posthog_cohort"."count", - "posthog_cohort"."created_by_id", - "posthog_cohort"."created_at", - "posthog_cohort"."is_calculating", - "posthog_cohort"."last_calculation", - "posthog_cohort"."errors_calculating", - "posthog_cohort"."last_error_at", - "posthog_cohort"."is_static", - "posthog_cohort"."groups" - FROM "posthog_cohort" - WHERE (NOT "posthog_cohort"."deleted" - AND "posthog_cohort"."team_id" = 99999) - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_behavioural_cohorts.37 - ''' - SELECT "posthog_group"."id", - "posthog_group"."team_id", - "posthog_group"."group_key", - "posthog_group"."group_type_index", - "posthog_group"."group_properties", - "posthog_group"."created_at", - "posthog_group"."properties_last_updated_at", - "posthog_group"."properties_last_operation", - "posthog_group"."version" - FROM "posthog_group" - WHERE "posthog_group"."team_id" = 99999 - LIMIT 21 - ''' -# --- # name: TestDecideRemoteConfig.test_flag_with_behavioural_cohorts.4 ''' SELECT COUNT(*) AS "__count" @@ -9316,104 +9074,6 @@ AND "posthog_person"."team_id" = 99999) ''' # --- -# name: TestDecideRemoteConfig.test_flag_with_regular_cohorts.34 - ''' - SELECT "posthog_hogfunction"."id", - "posthog_hogfunction"."team_id", - "posthog_hogfunction"."name", - "posthog_hogfunction"."description", - "posthog_hogfunction"."created_at", - "posthog_hogfunction"."created_by_id", - "posthog_hogfunction"."deleted", - "posthog_hogfunction"."updated_at", - "posthog_hogfunction"."enabled", - "posthog_hogfunction"."type", - "posthog_hogfunction"."icon_url", - "posthog_hogfunction"."hog", - "posthog_hogfunction"."bytecode", - "posthog_hogfunction"."transpiled", - "posthog_hogfunction"."inputs_schema", - "posthog_hogfunction"."inputs", - "posthog_hogfunction"."encrypted_inputs", - "posthog_hogfunction"."filters", - "posthog_hogfunction"."mappings", - "posthog_hogfunction"."masking", - "posthog_hogfunction"."template_id" - FROM "posthog_hogfunction" - WHERE ("posthog_hogfunction"."enabled" - AND "posthog_hogfunction"."team_id" = 99999 - AND "posthog_hogfunction"."type" IN ('site_destination', - 'site_app')) - LIMIT 21 - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_regular_cohorts.35 - ''' - SELECT "posthog_hogfunction"."id", - "posthog_hogfunction"."team_id", - "posthog_hogfunction"."name", - "posthog_hogfunction"."description", - "posthog_hogfunction"."created_at", - "posthog_hogfunction"."created_by_id", - "posthog_hogfunction"."deleted", - "posthog_hogfunction"."updated_at", - "posthog_hogfunction"."enabled", - "posthog_hogfunction"."type", - "posthog_hogfunction"."icon_url", - "posthog_hogfunction"."hog", - "posthog_hogfunction"."bytecode", - "posthog_hogfunction"."transpiled", - "posthog_hogfunction"."inputs_schema", - "posthog_hogfunction"."inputs", - "posthog_hogfunction"."encrypted_inputs", - "posthog_hogfunction"."filters", - "posthog_hogfunction"."mappings", - "posthog_hogfunction"."masking", - "posthog_hogfunction"."template_id" - FROM "posthog_hogfunction" - WHERE ("posthog_hogfunction"."enabled" - AND "posthog_hogfunction"."team_id" = 99999 - AND "posthog_hogfunction"."type" IN ('site_destination', - 'site_app')) - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_regular_cohorts.36 - ''' - SELECT "posthog_cohort"."id", - "posthog_cohort"."name", - "posthog_cohort"."description", - "posthog_cohort"."team_id", - "posthog_cohort"."deleted", - "posthog_cohort"."filters", - "posthog_cohort"."query", - "posthog_cohort"."version", - "posthog_cohort"."pending_version", - "posthog_cohort"."count", - "posthog_cohort"."created_by_id", - "posthog_cohort"."created_at", - "posthog_cohort"."is_calculating", - "posthog_cohort"."last_calculation", - "posthog_cohort"."errors_calculating", - "posthog_cohort"."last_error_at", - "posthog_cohort"."is_static", - "posthog_cohort"."groups" - FROM "posthog_cohort" - WHERE (NOT "posthog_cohort"."deleted" - AND "posthog_cohort"."team_id" = 99999) - ''' -# --- -# name: TestDecideRemoteConfig.test_flag_with_regular_cohorts.37 - ''' - SELECT (("posthog_person"."properties" -> '$some_prop_1') = '"something_1"'::jsonb - AND "posthog_person"."properties" ? '$some_prop_1' - AND NOT (("posthog_person"."properties" -> '$some_prop_1') = 'null'::jsonb)) AS "flag_X_condition_0" - FROM "posthog_person" - INNER JOIN "posthog_persondistinctid" ON ("posthog_person"."id" = "posthog_persondistinctid"."person_id") - WHERE ("posthog_persondistinctid"."distinct_id" = 'another_id' - AND "posthog_persondistinctid"."team_id" = 99999 - AND "posthog_person"."team_id" = 99999) - ''' -# --- # name: TestDecideRemoteConfig.test_flag_with_regular_cohorts.4 ''' SELECT COUNT(*) AS "__count" diff --git a/posthog/api/test/test_decide.py b/posthog/api/test/test_decide.py index d8629d6d88ea5..aaf75d8a18be9 100644 --- a/posthog/api/test/test_decide.py +++ b/posthog/api/test/test_decide.py @@ -260,6 +260,23 @@ def test_session_recording_sample_rate(self, *args): response = self._post_decide().json() self.assertEqual(response["sessionRecording"]["sampleRate"], "0.80") + def test_session_recording_sample_rate_of_0_is_not_treated_as_no_sampling(self, *args): + # :TRICKY: Test for regression around caching + + self._update_team( + { + "session_recording_opt_in": True, + } + ) + + response = self._post_decide().json() + assert response["sessionRecording"]["sampleRate"] is None + + self._update_team({"session_recording_sample_rate": 0.0}) + + response = self._post_decide().json() + self.assertEqual(response["sessionRecording"]["sampleRate"], "0.00") + def test_session_recording_sample_rate_of_1_is_treated_as_no_sampling(self, *args): # :TRICKY: Test for regression around caching diff --git a/posthog/models/remote_config.py b/posthog/models/remote_config.py index 427b3df7ec2de..a3ea8800adc8a 100644 --- a/posthog/models/remote_config.py +++ b/posthog/models/remote_config.py @@ -152,7 +152,9 @@ def build_config(self): # TODO: Support the domain based check for recordings (maybe do it client side)? if team.session_recording_opt_in: capture_console_logs = True if team.capture_console_log_opt_in else False - sample_rate = str(team.session_recording_sample_rate) if team.session_recording_sample_rate else None + sample_rate = ( + str(team.session_recording_sample_rate) if team.session_recording_sample_rate is not None else None + ) if sample_rate == "1.00": sample_rate = None diff --git a/posthog/models/test/test_remote_config.py b/posthog/models/test/test_remote_config.py index ddcd23aca2a73..34d394e11e5ba 100644 --- a/posthog/models/test/test_remote_config.py +++ b/posthog/models/test/test_remote_config.py @@ -1,5 +1,7 @@ from decimal import Decimal from unittest.mock import patch + +from parameterized import parameterized from django.test import RequestFactory from inline_snapshot import snapshot import pytest @@ -124,12 +126,13 @@ def test_autocapture_exceptions_toggle(self): self.remote_config.refresh_from_db() assert self.remote_config.config["autocaptureExceptions"] == {"endpoint": "/e/"} - def test_session_recording_sample_rate(self): + @parameterized.expand([["1.00", None], ["0.95", "0.95"], ["0.50", "0.50"], ["0.00", "0.00"], [None, None]]) + def test_session_recording_sample_rate(self, value: str | None, expected: str | None) -> None: self.team.session_recording_opt_in = True - self.team.session_recording_sample_rate = Decimal("0.5") + self.team.session_recording_sample_rate = Decimal(value) if value else None self.team.save() self.remote_config.refresh_from_db() - assert self.remote_config.config["sessionRecording"]["sampleRate"] == "0.50" + assert self.remote_config.config["sessionRecording"]["sampleRate"] == expected def test_session_recording_domains(self): self.team.session_recording_opt_in = True