"""Unit tests for Spotify Track Metrics tasks workflow.""" from unittest.mock import MagicMock from unittest.mock import patch import pytest from feed_ingestion.flows.spotify_track_metrics import tasks _date = '2023-01-09' @pytest.fixture def expected_bootstrap_response(): """Response for bootstrap task.""" return { 'archive_bucket': 'dev-cucumbers', 'archive_path': 'spotify_track_metrics/playlist_atc/2023-01-09/', 'date': '2023-01-09', 'feed_name': 'spotify_track_metrics_playlist_atc', 'report': 'playlist_atc', 's3_dir_path': 's3://dev-cucumbers/spotify_track_metrics/' 'playlist_atc/2023-01-09/', 'secrets_path': 'swf-spotify-track-metrics', 'staging_raw_table': 'staging_raw_spotify_playlist_atc' } @pytest.fixture def mock_get_overall_status(): """Yield get overall status.""" overall_status_path = ( 'feed_ingestion.flows.spotify_track_metrics.tasks.garcon_feed_status.' 'get_overall_status') with patch(overall_status_path) as overall_status: yield overall_status @pytest.fixture def mock_set_overall_status(): """Yield overall status.""" overall_status_path = ( 'feed_ingestion.flows.spotify_track_metrics.tasks.garcon_feed_status.' 'set_overall_status') with patch(overall_status_path) as overall_status: yield overall_status @pytest.fixture def mock_delete_status(): """Yield delete overall status.""" overall_status_path = ( 'feed_ingestion.flows.spotify_track_metrics.tasks.garcon_feed_status.' 'delete_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 def test_bootstrap_reload( expected_bootstrap_response, mock_get_overall_status, mock_delete_status): """Test bootstrap task when reload = True.""" result = tasks.bootstrap( MagicMock(), _date, report='playlist_atc', reload='True') assert result == expected_bootstrap_response mock_delete_status.assert_called_with( 'spotify_track_metrics_playlist_atc', '2023-01-09') def test_bootstrap( expected_bootstrap_response, mock_get_overall_status, mock_delete_status): """Test bootstrap task.""" result = tasks.bootstrap( MagicMock(), _date, report='playlist_atc', reload='') assert result == expected_bootstrap_response mock_delete_status.assert_not_called() @pytest.fixture def mock_athena(): """Yield athena mock.""" with patch.object(tasks, 'athena') as mock: yield mock @pytest.fixture def mock_s3_tasks(): """Yield athena mock.""" with patch.object(tasks, 's3_tasks') as mock: yield mock def test_fetch_from_athena_file_is_available( mock_task_status, mock_set_overall_status, mock_athena, mock_s3_tasks): """Test fetch_from_athena_file when a file is available.""" result = tasks.fetch_from_athena( MagicMock(), date=_date, report='playlist_atc', feed_name='spotify_track_metrics_playlist_atc', destination_s3_bucket='dev-cucumbers', destination_s3_path='spotify_track_metrics/playlist_atc/2023-01-09/', ) assert result == mock_s3_tasks.source_files.return_value mock_set_overall_status.assert_called_with( 'spotify_track_metrics_playlist_atc', '2023-01-09', 'DOWNLOADED') def test_fetch_from_athena_file_is_not_available( mock_task_status, mock_set_overall_status, mock_athena, mock_s3_tasks): """Test fetch_from_athena_file when a file is not available.""" mock_s3_tasks.source_files.side_effect = ValueError dest_s3_path = 'spotify_track_metrics/playlist_atc/2023-01-09/' message = ( f'Empty dataset. ' f'No parquet data files were found in {dest_s3_path}') result = tasks.fetch_from_athena( MagicMock(), date=_date, report='playlist_atc', feed_name='spotify_track_metrics_playlist_atc', destination_s3_bucket='dev-cucumbers', destination_s3_path=dest_s3_path, ) assert result == {'stop': True, 'message': message} mock_set_overall_status.assert_called_with( 'spotify_track_metrics_playlist_atc', '2023-01-09', 'NOT_AVAILABLE')