"""Test for Features.""" from unittest.mock import MagicMock, Mock, patch import pytest from flask import g from pythonfeatures.constants import split as split_constants from playlist import api from playlist.features import ( _check_feature_flag, is_disable_playlists_cache_enabled, is_filter_incorrect_playlists_enabled, is_insights_playlist_page_hourly_playlists_enabled, is_insights_playlist_v2_current_past_enabled, is_insights_primary_playlist_type_enabled, is_insights_transfer_product_ownership_enabled, is_show_sme_data_enabled, ) from playlist.queries.constants import ( INSIGHTS_DISABLE_PLAYLISTS_CACHE, INSIGHTS_FILTER_INCORRECT_PLAYLISTS, INSIGHTS_PLAYLIST_PAGE_HOURLY_PLAYLISTS, INSIGHTS_PLAYLIST_V2_CURRENT_PAST, INSIGHTS_PRIMARY_PLAYLIST_TYPE, INSIGHTS_TRANSFER_PRODUCT_OWNERSHIP, SHOW_SME_DATA, ) class TestCheckFeatureFlag: """Tests for _check_feature_flag function.""" @patch("playlist.features.config.ENVIRONMENT", "test") @patch("playlist.features.pythonfeatures.get_single_feature") def test_check_feature_flag_enabled(self, mock_get_single_feature): """Test that feature flag returns True when enabled.""" with api.app.app_context(): mock_response = Mock() mock_response.message = split_constants.FEATURE_ENABLED mock_get_single_feature.return_value = mock_response g.request_context = Mock() result = _check_feature_flag("test_feature") assert result is True mock_get_single_feature.assert_called_once_with( "test_feature", g.request_context ) @patch("playlist.features.config.ENVIRONMENT", "test") @patch("playlist.features.pythonfeatures.get_single_feature") def test_check_feature_flag_disabled(self, mock_get_single_feature): """Test that feature flag returns False when disabled.""" with api.app.app_context(): mock_response = Mock() mock_response.message = "disabled" mock_get_single_feature.return_value = mock_response g.request_context = Mock() result = _check_feature_flag("test_feature") assert result is False mock_get_single_feature.assert_called_once_with( "test_feature", g.request_context ) class TestIsShowSmeDataEnabled: """Tests for is_show_sme_data_enabled function.""" def test_show_sme_data_enabled_for_sme_brand(self): """Test that SME brand bypasses feature flag check.""" with api.app.app_context(): mock_request_context = Mock() mock_request_context.brand = "sme" g.request_context = mock_request_context result = is_show_sme_data_enabled() assert result is True @patch("playlist.features._check_feature_flag") def test_show_sme_data_enabled_non_sme_brand_flag_enabled( self, mock_check_feature_flag ): """Test with non-SME brand when feature flag is enabled.""" with api.app.app_context(): mock_request_context = Mock() mock_request_context.brand = "other" g.request_context = mock_request_context mock_check_feature_flag.return_value = True result = is_show_sme_data_enabled() assert result is True mock_check_feature_flag.assert_called_once_with(SHOW_SME_DATA) @patch("playlist.features._check_feature_flag") def test_show_sme_data_disabled_non_sme_brand(self, mock_check_feature_flag): """Test with non-SME brand when feature flag is disabled.""" with api.app.app_context(): mock_request_context = Mock() mock_request_context.brand = "other" g.request_context = mock_request_context mock_check_feature_flag.return_value = False result = is_show_sme_data_enabled() assert result is False mock_check_feature_flag.assert_called_once_with(SHOW_SME_DATA) @patch("playlist.features._check_feature_flag") def test_show_sme_data_no_brand_attribute(self, mock_check_feature_flag): """Test when request_context has no brand attribute.""" with api.app.app_context(): mock_request_context = Mock(spec=[]) # No brand attribute g.request_context = mock_request_context mock_check_feature_flag.return_value = False result = is_show_sme_data_enabled() assert result is False mock_check_feature_flag.assert_called_once_with(SHOW_SME_DATA) @patch("playlist.features._check_feature_flag") def test_show_sme_data_brand_none(self, mock_check_feature_flag): """Test when brand is None.""" with api.app.app_context(): mock_request_context = Mock() mock_request_context.brand = None g.request_context = mock_request_context mock_check_feature_flag.return_value = False result = is_show_sme_data_enabled() assert result is False mock_check_feature_flag.assert_called_once_with(SHOW_SME_DATA) class TestInsightsPlaylistV2CurrentPast: """Tests for is_insights_playlist_v2_current_past_enabled.""" @patch("playlist.features._check_feature_flag") def test_insights_playlist_v2_enabled(self, mock_check_feature_flag): """Test when insights_playlist_v2_current_past is enabled.""" mock_check_feature_flag.return_value = True result = is_insights_playlist_v2_current_past_enabled() assert result is True mock_check_feature_flag.assert_called_once_with( INSIGHTS_PLAYLIST_V2_CURRENT_PAST ) @patch("playlist.features._check_feature_flag") def test_insights_playlist_v2_disabled(self, mock_check_feature_flag): """Test when insights_playlist_v2_current_past is disabled.""" mock_check_feature_flag.return_value = False result = is_insights_playlist_v2_current_past_enabled() assert result is False mock_check_feature_flag.assert_called_once_with( INSIGHTS_PLAYLIST_V2_CURRENT_PAST ) class TestInsightsPrimaryPlaylistType: """Tests for is_insights_primary_playlist_type_enabled.""" @patch("playlist.features._check_feature_flag") def test_insights_primary_playlist_type_enabled(self, mock_check_feature_flag): """Test when insights_primary_playlist_type is enabled.""" mock_check_feature_flag.return_value = True result = is_insights_primary_playlist_type_enabled() assert result is True mock_check_feature_flag.assert_called_once_with(INSIGHTS_PRIMARY_PLAYLIST_TYPE) @patch("playlist.features._check_feature_flag") def test_insights_primary_playlist_type_disabled(self, mock_check_feature_flag): """Test when insights_primary_playlist_type is disabled.""" mock_check_feature_flag.return_value = False result = is_insights_primary_playlist_type_enabled() assert result is False mock_check_feature_flag.assert_called_once_with(INSIGHTS_PRIMARY_PLAYLIST_TYPE) class TestInsightsTransferProductOwnership: """Tests for is_insights_transfer_product_ownership_enabled.""" @patch("playlist.features._check_feature_flag") def test_insights_transfer_product_ownership_enabled(self, mock_check_feature_flag): """Test when insights_transfer_product_ownership is enabled.""" mock_check_feature_flag.return_value = True result = is_insights_transfer_product_ownership_enabled() assert result is True mock_check_feature_flag.assert_called_once_with( INSIGHTS_TRANSFER_PRODUCT_OWNERSHIP ) @patch("playlist.features._check_feature_flag") def test_insights_transfer_product_ownership_disabled( self, mock_check_feature_flag ): """Test when insights_transfer_product_ownership is disabled.""" mock_check_feature_flag.return_value = False result = is_insights_transfer_product_ownership_enabled() assert result is False mock_check_feature_flag.assert_called_once_with( INSIGHTS_TRANSFER_PRODUCT_OWNERSHIP ) class TestFilterIncorrectPlaylists: """Tests for is_filter_incorrect_playlists_enabled.""" @patch("playlist.features._check_feature_flag") def test_filter_incorrect_playlists_enabled(self, mock_check_feature_flag): """Test when insights_filter_incorrect_playlists is enabled.""" mock_check_feature_flag.return_value = True result = is_filter_incorrect_playlists_enabled() assert result is True mock_check_feature_flag.assert_called_once_with( INSIGHTS_FILTER_INCORRECT_PLAYLISTS ) @patch("playlist.features._check_feature_flag") def test_filter_incorrect_playlists_disabled(self, mock_check_feature_flag): """Test when insights_filter_incorrect_playlists is disabled.""" mock_check_feature_flag.return_value = False result = is_filter_incorrect_playlists_enabled() assert result is False mock_check_feature_flag.assert_called_once_with( INSIGHTS_FILTER_INCORRECT_PLAYLISTS ) class TestDisablePlaylistsCache: """Tests for is_disable_playlists_cache_enabled.""" @patch("playlist.features._check_feature_flag") def test_disable_playlists_cache_enabled(self, mock_check_feature_flag): """Test when insights_disable_playlists_cache is enabled.""" mock_check_feature_flag.return_value = True result = is_disable_playlists_cache_enabled() assert result is True mock_check_feature_flag.assert_called_once_with( INSIGHTS_DISABLE_PLAYLISTS_CACHE ) @patch("playlist.features._check_feature_flag") def test_disable_playlists_cache_disabled(self, mock_check_feature_flag): """Test when insights_disable_playlists_cache is disabled.""" mock_check_feature_flag.return_value = False result = is_disable_playlists_cache_enabled() assert result is False mock_check_feature_flag.assert_called_once_with( INSIGHTS_DISABLE_PLAYLISTS_CACHE ) class TestInsightsPlaylistPageHourlyPlaylists: """Tests for is_insights_playlist_page_hourly_playlists_enabled.""" @patch("playlist.features._check_feature_flag") def test_hourly_playlists_enabled(self, mock_check_feature_flag): """Test when insights_playlist_page_hourly_playlists is enabled.""" mock_check_feature_flag.return_value = True result = is_insights_playlist_page_hourly_playlists_enabled() assert result is True mock_check_feature_flag.assert_called_once_with( INSIGHTS_PLAYLIST_PAGE_HOURLY_PLAYLISTS ) @patch("playlist.features._check_feature_flag") def test_hourly_playlists_disabled(self, mock_check_feature_flag): """Test when insights_playlist_page_hourly_playlists is disabled.""" mock_check_feature_flag.return_value = False result = is_insights_playlist_page_hourly_playlists_enabled() assert result is False mock_check_feature_flag.assert_called_once_with( INSIGHTS_PLAYLIST_PAGE_HOURLY_PLAYLISTS )