"""Unit tests for the top video metrics logic layer.""" import datetime from unittest.mock import patch import pytest from analytics.api import app from analytics.logic import top_video_metrics VIDEO_SOURCES = [{"id": 100, "name": "YouTube"}] @pytest.fixture(autouse=True) def mock_request_context(): with app.test_request_context(): yield @pytest.fixture(autouse=True) def no_cache(): with patch("analytics.connectors.redis.client.get") as get: get.return_value = None yield get @pytest.fixture(autouse=True) def mock_environment(mocker): mocker.patch( "analytics.logic.top_video_metrics.store_availability.get_query_store_ids", return_value=[100], ) mocker.patch( "analytics.logic.top_video_metrics.store_availability.get_video_sources", return_value=VIDEO_SOURCES, ) mocker.patch( "analytics.logic.top_video_metrics.add_outage_error_to_stores", return_value=VIDEO_SOURCES, ) mocker.patch( "analytics.logic.top_video_metrics.get_videos_max_available_date", return_value=datetime.date(2024, 6, 15), ) @pytest.fixture def permissions(): return { "permission_label_ids": [7123], "permission_artist_ids": None, "permission_subaccount_ids": None, "permission_label_participant_ids": None, "permission_feed_ids": [1, 2], } @pytest.fixture def query_params(): return { "distributors": ["theorchard", "sme", "awal"], "countries": [], "store_ids": [], "label_ids": [], "subaccount_ids": [], "global_participant_ids": [], "channel_ids": [], "track_types": ["video"], "order_by": "views_1_month_back", "order_dir": "DESC", "limit": 25, "offset": 0, } @pytest.fixture def query_rows(): return [ { "video_id": "ipbukl6oFoQ", "channel_id": "UCFg7-w47VVA3ozhvnR6P0YQ", "subscriber_count": 13100, "total_views": 198980, "total_estimated_gross_revenue": 347.05400, "average_view_duration_seconds": 192.93, "views_1_month_back": 6880, "growth_2_to_1_months_back": -0.04, "views_2_months_back": 7185, "growth_3_to_2_months_back": -0.20, "views_3_months_back": 9058, "growth_4_to_3_months_back": -0.33, "views_last_28_days": 4823, "views_last_7_days": 1047, "total_results": 1, } ] class TestGetTopVideoMetrics: def test_succeeds(self, mocker, permissions, query_params, query_rows): mocker.patch( "analytics.logic.top_video_metrics.TopVideoMetrics.execute", return_value=query_rows, ) response = top_video_metrics.get_top_video_metrics(query_params, permissions) assert response.status == 200 assert response.message["total_results"] == 1 assert response.message["sources"] == VIDEO_SOURCES assert response.message["items"][0]["video_id"] == "ipbukl6oFoQ" def test_invalid_order_by_raises(self, permissions, query_params): params = {**query_params, "order_by": "bogus"} with pytest.raises(Exception): top_video_metrics.get_top_video_metrics(params, permissions) def test_invalid_order_dir_raises(self, permissions, query_params): params = {**query_params, "order_dir": "INVALID"} with pytest.raises(Exception): top_video_metrics.get_top_video_metrics(params, permissions) def test_no_video_stores_returns_empty(self, mocker, permissions, query_params): mocker.patch( "analytics.logic.top_video_metrics.store_availability.get_query_store_ids", return_value=[], ) execute = mocker.patch( "analytics.logic.top_video_metrics.TopVideoMetrics.execute" ) response = top_video_metrics.get_top_video_metrics(query_params, permissions) assert response.status == 200 assert response.message["items"] == [] assert response.message["total_results"] == 0 execute.assert_not_called() def test_label_ids_auto_populates_from_permissions( self, mocker, permissions, query_params, query_rows ): MockQuery = mocker.patch("analytics.logic.top_video_metrics.TopVideoMetrics") MockQuery.return_value.execute.return_value = query_rows top_video_metrics.get_top_video_metrics(query_params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["label_ids"] == [7123] assert query_input["subaccount_ids"] == [] def test_caller_label_ids_override_permissions( self, mocker, permissions, query_params, query_rows ): MockQuery = mocker.patch("analytics.logic.top_video_metrics.TopVideoMetrics") MockQuery.return_value.execute.return_value = query_rows params = {**query_params, "label_ids": [9999]} top_video_metrics.get_top_video_metrics(params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["label_ids"] == [9999] def test_combined_grant_does_not_intersect(self, mocker, query_rows): permissions = { "permission_label_ids": [7123], "permission_artist_ids": None, "permission_subaccount_ids": [46189], "permission_label_participant_ids": None, "permission_feed_ids": [1, 2], } params = { "distributors": ["theorchard"], "countries": [], "store_ids": [], "label_ids": [], "subaccount_ids": [], "global_participant_ids": [], "channel_ids": [], "track_types": ["video"], "order_by": "views_1_month_back", "order_dir": "DESC", "limit": 25, "offset": 0, } MockQuery = mocker.patch("analytics.logic.top_video_metrics.TopVideoMetrics") MockQuery.return_value.execute.return_value = query_rows top_video_metrics.get_top_video_metrics(params, permissions) query_input = MockQuery.call_args[0][0] assert query_input["label_ids"] == [7123] # subaccount_ids must NOT be auto-populated when label_ids is set assert query_input["subaccount_ids"] == []