"""Music Analytics Report Flow tasks.""" from unittest import TestCase from unittest.mock import MagicMock, patch import pytest import feed_ingestion.flows.music_analytics_reports.tasks as tasks _date = '2022-12-07' @pytest.fixture def mock_executor_context(): """Yield executor context.""" sf_executor_class_path = \ 'feed_ingestion.flows.music_analytics_in_review.' \ 'snowflake_executor.MusicAnalyticsReportsSE' with patch(sf_executor_class_path) as sf_executor: mock_executor_context = sf_executor.return_value.__enter__.return_value yield mock_executor_context class TestMusicAnalyticsTasks(TestCase): """MusicAnalytics Tasks Test class.""" activity = MagicMock() @pytest.fixture(autouse=True) def set_bootstrap_response(self): """Response for bootstrap task.""" self.bootstrap_response = { 'date': '2022-12-07', 'errors_table': 'music_analytics_in_review_errors', 'feed_name': 'music_analytics_reports', 'reload': 'False', 'report_type': 'in_review', 'secrets_path': 'music_analytics_reports', 'staging_raw_table': 'staging_raw_music_analytics_in_review', 'temp_errors_table': 'temp_music_analytics_in_review_errors_20221207', 'temp_staging_raw_table': 'temp_staging_raw_music_analytics_in_review_20221207'} @pytest.fixture(autouse=True) def set_report(self): """Set report content.""" self.report = \ 'song_id\tartist_name\tcontent_name\tstorefront\t' \ 'subscription_type\tsubscription_mode\tchannel_partner\t' \ 'device_type\tdevice_os\tsource_of_stream\t' \ 'container_sub_type\tcontainer_id\tcontainer_name\t' \ 'end_reason_type\taudio_format\tgender\tage_bucket\t' \ 'streams\trptg_date\n9058038335\tTest\tTest Artist\t' \ 'GB\tINDIVIDUAL_MONTHLY\tPAID\tNone\tMOBILE\tIOS\t' \ 'LIBRARY\tALBUM\t9058033852\tNone\tSKIP\t' \ f'COMPRESSED_AUDIO\tMALE\tAGE_35_TO_44\t1\t{_date}\n' @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.garcon_feed_status') def test_bootstrap(self, status_mock): """Test bootstrap.""" context = { 'activity': MagicMock(), 'date': _date, 'reload': 'False', 'report_type': 'in_review', } result = tasks.bootstrap(**context) self.assertEqual(result, self.bootstrap_response) self.assertEqual(result, self.bootstrap_response) @patch('builtins.open', read_data='data') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.MusicAnalyticsUtils') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.MusicAnalyticsAPI.get_in_review_report') def test_get_report_file(self, report_mock, utils_mock, mock_open): """Test get_report_file method.""" mock_open().name = 'AMAnalytics_InReviewReport_2022-12-07.csv' report_mock.return_value = self.report context = { 'activity': MagicMock(), 'date': _date, 'report_type': 'in_review', } result = tasks.get_report_file(**context) self.assertEqual(result.get('file'), { 'report': 'AMAnalytics_InReviewReport_2022-12-07.csv'}) @patch('builtins.open', read_data='data') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.MusicAnalyticsUtils') @patch('feed_ingestion.util.apple_music_analytics.requests') def test_get_empty_report_file( self, requests_mock, utils_mock, mock_open): """Test get_report_file if report is empty.""" context = { 'activity': MagicMock(), 'date': '2000-01-01', 'report_type': 'in_review', } response_mock = MagicMock() response_mock.text = '' requests_mock.get = MagicMock(return_value=response_mock) result = tasks.get_report_file(**context) self.assertEqual(result, {'stop': True}) @patch('os.remove') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks._upload_to_s3') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.garcon_feed_status') def test_load_report_to_s3( self, status_mock, upload_to_s3_mock, os_remove_mock): """Test load_report_to_s3 method.""" upload_to_s3_mock.return_value = True file = {'report': 'report.csv'} context = { 'activity': MagicMock(), 'file': file, 'date': _date, 'feed_name': 'music_analytics_reports', 'report_type': 'in_review', } result = tasks.load_report_to_s3(**context) expected = { 'full_s3_path': {'report': 's3://dev-cucumbers/MusicAnalytics/InReview/' 'archives/2022-12-07/' + file['report']}, 'failed': False} self.assertEqual(result, expected) @patch('os.remove') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks._upload_to_s3') @patch('feed_ingestion.flows.music_analytics_reports.' 'tasks.garcon_feed_status') def test_load_report_and_errors_to_s3( self, status_mock, upload_to_s3_mock, os_remove_mock): """Test load_report_to_s3 method with errors files..""" upload_to_s3_mock.return_value = True file = {'report': 'report.csv', 'errors': 'errors.csv'} context = { 'activity': MagicMock(), 'file': file, 'date': _date, 'feed_name': 'music_analytics_reports', 'report_type': 'in_review', } result = tasks.load_report_to_s3(**context) expected = { 'full_s3_path': {'report': 's3://dev-cucumbers/MusicAnalytics/InReview/' 'archives/2022-12-07/' + file['report'], 'errors': 's3://dev-cucumbers/MusicAnalytics/InReview/' 'processed/2022-12-07/' + file['errors']}, 'failed': False} self.assertEqual(result, expected) self.assertEqual(upload_to_s3_mock.call_count, 2)