"""Unit tests for the tasks of the Apple id mapping SME ingestion workflow.""" from unittest.mock import call from unittest.mock import MagicMock from unittest.mock import patch import pytest from feed_ingestion.flows.apple_id_mapping_sme import config from feed_ingestion.flows.apple_id_mapping_sme import tasks @pytest.fixture def mock_reports_info(): """Response for bootstrap task.""" return { 'album': { 'filename': 'album_mapping_20200501.txt.gz', 'temp_table': 'apple_id_mapping_sme_album_20200501', 's3_download_path': ('sme_max/album_mapping/v1/report_date=2020-05-01/' 'report_licensor=sme/')}, 'track': { 'filename': 'track_mapping_20200501.txt.gz', 'temp_table': 'apple_id_mapping_sme_track_20200501', 's3_download_path': ( 'sme_max/track_mapping/v1/report_date=2020-05-01/' 'report_licensor=sme/')}} def test_bootstrap(mock_reports_info): """Check that bootstrap returns expected results.""" context = { 'activity': MagicMock(), 'date': '2020-05-01', 'snowflake_error_limit': None} # expected response expected = { 'date': '2020-05-01', 'feed_name': config.feed_name, 'secrets_path': config.secrets_path, 's3_archive_path': 'AppleMusicStreams/apple_id_mapping_sme/2020-05-01/', 'reports': mock_reports_info, 'snowflake_error_limit': 1} # check response result = tasks.bootstrap(**context) assert result == expected def test_bootstrap_incorrect_snowflake_error_limit(mock_reports_info): """Check that bootstrap returns expected results.""" context = { 'activity': MagicMock(), 'date': '2020-05-01', 'snowflake_error_limit': 'False'} # expected response expected = { 'stop': True, 'error': 'snowflake_error_limit should be integer'} # check response result = tasks.bootstrap(**context) assert result == expected @pytest.fixture def mock_set_overall_status(): """Yield overall status.""" overall_status_path = ( 'feed_ingestion.flows.apple_id_mapping_sme.tasks.garcon_feed_status.' 'set_overall_status') with patch(overall_status_path) as overall_status: yield overall_status @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 @patch('feed_ingestion.flows.apple_id_mapping_sme.tasks.' '_get_sme_s3_client_assume_role') def test_fetch_from_drop_location( mock_get_sme_s3_client_assume_role, mock_reports_info, mock_task_status): """Test test_fetch_from_drop_location.""" tasks.fetch_from_drop_location( MagicMock(), config.feed_name, '2020-05-01', 'AppleMusicStreams/apple_id_mapping_sme/2020-05-01/', mock_reports_info) mock_get_sme_s3_client_assume_role.assert_called_once_with(config.role_arn) mock_get_sme_s3_client_assume_role.return_value.copy.assert_has_calls([ call( { 'Bucket': 'dev-feed-drop', 'Key': 'sme_max/album_mapping/v1/report_date=2020-05-01/' 'report_licensor=sme/album_mapping_20200501.txt.gz' }, 'dev-cucumbers', 'AppleMusicStreams/apple_id_mapping_sme/2020-05-01/' 'album_mapping_20200501.txt.gz'), call( { 'Bucket': 'dev-feed-drop', 'Key': 'sme_max/track_mapping/v1/report_date=2020-05-01/' 'report_licensor=sme/track_mapping_20200501.txt.gz'}, 'dev-cucumbers', 'AppleMusicStreams/apple_id_mapping_sme/2020-05-01/' 'track_mapping_20200501.txt.gz') ] ) @pytest.fixture def mock_boto3(): """Mock boto3.""" boto3_path = 'feed_ingestion.flows.apple_id_mapping_sme.tasks.boto3' with patch(boto3_path) as boto3: mock_client = MagicMock() boto3.client.return_value = mock_client yield boto3 def test_get_sme_s3_client_assume_role(mock_boto3): """Test _get_sme_s3_client_assume_role.""" tasks._get_sme_s3_client_assume_role('test_role') mock_boto3.client.return_value.assume_role.assert_any_call( RoleArn='test_role', RoleSessionName='feed_ingestion') @pytest.fixture def mock_executor_context(): """Yield executor context.""" sf_executor_class_path = ( 'feed_ingestion.flows.apple_id_mapping_sme.tasks.AppleIDMapping') with patch(sf_executor_class_path) as sf_executor: mock_executor_context = sf_executor.return_value.__enter__.return_value yield mock_executor_context def test_update_apple_id_mapping(mock_executor_context, mock_task_status): """Test update_apple_id_mapping task.""" tasks.update_apple_id_mapping( MagicMock(), '2020-05-01', 'feed_name', config.secrets_path) mock_executor_context.update_sony_apple_id_mapping.assert_called_with()