"""Unit tests for NetEase tasks workflow.""" from unittest.mock import MagicMock from unittest.mock import patch from garcon_contrib.dynamo_feed_status import garcon_feed_status import pytest from feed_ingestion.flows.netease import tasks _date = '2025-03-26' @pytest.fixture def feed_name(): """Feed name value.""" return 'netease' @pytest.fixture def source_filename(): """Source filename.""" return 'QC43_20250326_20250326_SME_ORCHARD.txt' @pytest.fixture def source_key_name(): """Source key.""" return 'netease/in/QC43_20250326_20250326_SME_ORCHARD.txt' @pytest.fixture def expected_bootstrap_response(): """Response for bootstrap task.""" return { 'feed_name': 'netease', 'date': '2025-03-26', 'source_key_name': 'netease/in/QC43_20250326_20250326_SME_ORCHARD.txt', 'destination_key_name': ( 'NetEase/archives/2025-03-26/' 'QC43_20250326_20250326_SME_ORCHARD.txt'), 'key_dir': ( 's3://dev-cucumbers/NetEase/archives/' '2025-03-26/QC43_20250326_20250326_SME_ORCHARD.txt'), 'secrets_path': 'swf-netease', 'staging_raw_table': 'staging_raw_netease', 'temp_staging_raw_table': 'temp_staging_raw_netease_2025_03_26' } def test_bootstrap(expected_bootstrap_response): """Test bootstrap.""" result = tasks.bootstrap(MagicMock(), _date, reload=False) assert result == expected_bootstrap_response @pytest.fixture def mock_task_status(): """Yield task status.""" task_status_path = 'feed_ingestion.tasks.task_status' with patch(task_status_path) as task_status: task_status.is_completed_task.return_value = False task_status.mark_completed_task = MagicMock() yield task_status @pytest.fixture def mock_set_overall_status(): """Yield overall status.""" overall_status_path = ( 'feed_ingestion.flows.netease.tasks.garcon_feed_status.' 'set_overall_status') with patch(overall_status_path) as overall_status: yield overall_status @pytest.fixture def mock_set_delete_status(): """Yield delete status.""" delete_status_path = ( 'feed_ingestion.flows.netease.tasks.garcon_feed_status.' 'delete_status') with patch(delete_status_path) as delete_status: yield delete_status @pytest.fixture def mock_set_missing_files(): """Yield set_missing_files.""" path = ( 'feed_ingestion.flows.netease.tasks.garcon_feed_status.' 'set_missing_files') with patch(path) as mock_set_missing: yield mock_set_missing @pytest.fixture def mock_s3_tasks(): """Yield overall status.""" path = 'feed_ingestion.flows.netease.tasks.s3_tasks' with patch(path) as mock_s3: yield mock_s3 def test_grab_drop_files( mock_s3_tasks, mock_set_overall_status, mock_task_status, mock_set_delete_status, source_key_name, source_filename ): """Test grab_drop_files.""" activity = MagicMock() result = tasks.grab_drop_files( activity=activity, feed_name='netease', date=_date, source_key_name=source_key_name, destination_key_name='destination_key_name') assert result != {'stop': True} mock_s3_tasks.copy_file_from_sme_s3_to_theocrhard.assert_called_once() def test_grab_drop_files_no_file( mock_s3_tasks, mock_set_overall_status, mock_task_status, mock_set_delete_status, source_key_name ): """Test grab_drop_files if there is no file.""" mock_s3_tasks.copy_file_from_sme_s3_to_theocrhard.return_value = {} activity = MagicMock() result = tasks.grab_drop_files( activity=activity, feed_name='netease', date=_date, source_key_name=source_key_name, destination_key_name='destination_key_name') assert result == {'stop': True} mock_s3_tasks.copy_file_from_sme_s3_to_theocrhard.assert_called_once() mock_set_overall_status.assert_called_once_with( 'netease', _date, garcon_feed_status.STATUS_NOT_AVAILABLE)