"""Tests for comma-separated ``country_code`` on the catalog-filter endpoints. ``/top-metrics``, ``/product-metrics`` and ``/participant-metrics`` take their country filter as a repeated query-string param (``?country_code=US&...``). With ~249 countries the GET URL grows large enough to be dropped at the edge (502) before app code runs. The handlers now also accept the comma-separated form (``?country_code=US,GB,DE``) — a much shorter URL — while the repeated form keeps working unchanged (backward compatible). These tests mock the logic layer (no live Snowflake) and assert, per endpoint, that the comma-separated, repeated, and mixed forms all parse into the same ``country_ids`` and that the two forms are equivalent. """ from unittest.mock import patch import pytest from oto import response as oto_response from analytics import config MOCK_PERMISSIONS = { "permission_label_ids": [], "permission_artist_ids": [], "permission_subaccount_ids": [], "permission_label_participant_ids": [], "permission_feed_ids": [1, 2, 38], } INSIGHTS_HEADERS = { "Orchard-Profile-Id": "36135", "Orchard-Profile-Type": "InsightsProfile", } class TestTopMetricsCountryCsv: """GET /top-metrics accepts comma-separated and repeated country_code.""" @pytest.fixture def top_metrics_mock(self): with patch("analytics.handlers.top_metrics.get_top_metrics") as mock: mock.return_value = oto_response.Response({"items": []}) yield mock @pytest.fixture def mock_permissions(self): with patch( "analytics.handlers.get_permission_values", return_value=MOCK_PERMISSIONS ): yield MOCK_PERMISSIONS def _get(self, client, qs): return client.get(config.TOP_METRICS_PATH + qs, headers=INSIGHTS_HEADERS) def test_comma_separated(self, client, top_metrics_mock, mock_permissions): self._get(client, "?country_code=US,MX,GB") assert top_metrics_mock.call_args.args[0]["country_ids"] == ["US", "MX", "GB"] def test_repeated_keys(self, client, top_metrics_mock, mock_permissions): self._get(client, "?country_code=US&country_code=MX") assert top_metrics_mock.call_args.args[0]["country_ids"] == ["US", "MX"] def test_mixed_repeated_and_comma(self, client, top_metrics_mock, mock_permissions): self._get(client, "?country_code=US,MX&country_code=GB") assert top_metrics_mock.call_args.args[0]["country_ids"] == ["US", "MX", "GB"] def test_comma_and_repeated_are_equivalent( self, client, top_metrics_mock, mock_permissions ): self._get(client, "?country_code=US&country_code=MX&country_code=GB") self._get(client, "?country_code=US,MX,GB") assert top_metrics_mock.call_args_list[0] == top_metrics_mock.call_args_list[1] class TestProductMetricsCountryCsv: """GET /product-metrics accepts comma-separated and repeated country_code.""" @pytest.fixture def product_metrics_mock(self): with patch("analytics.handlers.product_metrics.get_product_metrics") as mock: mock.return_value = oto_response.Response({"items": []}) yield mock @pytest.fixture def mock_permissions(self): with patch( "analytics.handlers.get_permission_values", return_value=MOCK_PERMISSIONS ): yield MOCK_PERMISSIONS def _get(self, client, qs): return client.get(config.PRODUCT_METRICS_PATH + qs, headers=INSIGHTS_HEADERS) def test_comma_separated(self, client, product_metrics_mock, mock_permissions): self._get(client, "?country_code=US,MX,GB") assert product_metrics_mock.call_args.args[0]["country_ids"] == [ "US", "MX", "GB", ] def test_repeated_keys(self, client, product_metrics_mock, mock_permissions): self._get(client, "?country_code=US&country_code=MX") assert product_metrics_mock.call_args.args[0]["country_ids"] == ["US", "MX"] def test_mixed_repeated_and_comma( self, client, product_metrics_mock, mock_permissions ): self._get(client, "?country_code=US,MX&country_code=GB") assert product_metrics_mock.call_args.args[0]["country_ids"] == [ "US", "MX", "GB", ] def test_comma_and_repeated_are_equivalent( self, client, product_metrics_mock, mock_permissions ): self._get(client, "?country_code=US&country_code=MX&country_code=GB") self._get(client, "?country_code=US,MX,GB") assert ( product_metrics_mock.call_args_list[0] == product_metrics_mock.call_args_list[1] ) class TestParticipantMetricsCountryCsv: """GET /participant-metrics accepts comma-separated and repeated country_code.""" @pytest.fixture def participant_metrics_mock(self): with patch( "analytics.logic.participant_metrics.get_participant_metrics" ) as mock: mock.return_value = oto_response.Response({"items": []}) yield mock @pytest.fixture def mock_permissions(self): with patch( "analytics.participant_handlers.get_permission_values", return_value=MOCK_PERMISSIONS, ): yield MOCK_PERMISSIONS def _get(self, client, qs): return client.get( config.PARTICIPANT_METRICS_PATH + qs, headers=INSIGHTS_HEADERS ) def test_comma_separated(self, client, participant_metrics_mock, mock_permissions): self._get(client, "?country_code=US,MX,GB") assert participant_metrics_mock.call_args.args[0]["country_ids"] == [ "US", "MX", "GB", ] def test_repeated_keys(self, client, participant_metrics_mock, mock_permissions): self._get(client, "?country_code=US&country_code=MX") assert participant_metrics_mock.call_args.args[0]["country_ids"] == ["US", "MX"] def test_mixed_repeated_and_comma( self, client, participant_metrics_mock, mock_permissions ): self._get(client, "?country_code=US,MX&country_code=GB") assert participant_metrics_mock.call_args.args[0]["country_ids"] == [ "US", "MX", "GB", ] def test_comma_and_repeated_are_equivalent( self, client, participant_metrics_mock, mock_permissions ): self._get(client, "?country_code=US&country_code=MX&country_code=GB") self._get(client, "?country_code=US,MX,GB") assert ( participant_metrics_mock.call_args_list[0] == participant_metrics_mock.call_args_list[1] )