"""Unit tests for Chartmetric Charts Decider.""" from unittest import mock from unittest.mock import MagicMock from garcon.activity import Activity from feed_ingestion.flows.chartmetric_charts.flow import Flow ACTIVITIES = { 'bootstrap', 'clear_log_table', 'create_staging_fact', 'find_unchanged_charts', 'insert_into_log_table', 'load_fact_data', 'update_globalsoundrecording_relations_kafka', 'update_soundrecording_noisrc_nodes_kafka', 'update_trackandparticipant_relations_kafka', 'update_productandlabel_relations_kafka', 'load_staging_fact', 'update_position_change', 'update_isrc_to_label_participant_mapping', 'update_upc_to_label_participant_mapping', 'refresh_aggregated_table', 'update_dim_tables', 'update_staging_fact_sound_recording', 'update_staging_fact_public_product', 'update_dim_chart_latest_chart_date', 'ows_charts_cache_prime', 'set_overall_status_ingested', } def test_decider_kafka(): """Test decider method.""" activity_statuses = MagicMock() activity_statuses.result = { 'bootstrap.reload_from_s3': False, 'bootstrap.platform_names': ['spotify', 'deezer'] } schedule = MagicMock(return_value=activity_statuses) # test activities are called flow = Flow() context = {'kafka': 'True'} flow.decider(schedule, context) scheduled_activities = set() activities = ACTIVITIES for (name, activity), _ in schedule.call_args_list: assert name in activities assert isinstance(activity, Activity) scheduled_activities.add(name) assert scheduled_activities == activities def test_chartmetric_charts(): """Test normal decider execution.""" flow = Flow() activity_statuses = MagicMock() activity_statuses.result = { 'bootstrap.reload_from_s3': False, 'bootstrap.platform_names': ['spotify', 'deezer'] } schedule = MagicMock(return_value=activity_statuses) flow.decider(schedule, {'platform_names': 'spotify,tiktok', 'kafka': 'True', 'wait_until_complete': 'True', 'days_back': '3' }) schedule.assert_has_calls([ mock.call('bootstrap', mock.ANY), mock.call('clear_log_table', mock.ANY, requires=[mock.ANY]), mock.call('create_staging_fact', mock.ANY, requires=[mock.ANY]), mock.call('find_unchanged_charts', mock.ANY, requires=[mock.ANY]), mock.call('load_staging_fact', mock.ANY, requires=[mock.ANY]), mock.call('update_isrc_to_label_participant_mapping', mock.ANY, requires=[mock.ANY]), mock.call('update_upc_to_label_participant_mapping', mock.ANY, requires=[mock.ANY]), mock.call('update_globalsoundrecording_relations_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_soundrecording_noisrc_nodes_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_trackandparticipant_relations_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_productandlabel_relations_kafka', mock.ANY, requires=[mock.ANY], input={'productandlabel_platforms_to_skip': ['tiktok', 'recochoku', 'linemusic', 'soundcloud', 'youtube']}), mock.call('update_staging_fact_sound_recording', mock.ANY, requires=[mock.ANY]), mock.call('update_staging_fact_public_product', mock.ANY, requires=[mock.ANY]), mock.call('update_dim_tables', mock.ANY, requires=[mock.ANY]), mock.call('load_fact_data', mock.ANY, requires=[mock.ANY]), mock.call('update_position_change', mock.ANY, requires=[mock.ANY]), mock.call('refresh_aggregated_table', mock.ANY, requires=[mock.ANY]), mock.call('update_dim_chart_latest_chart_date', mock.ANY, requires=[mock.ANY]), mock.call('ows_charts_cache_prime', mock.ANY, requires=[mock.ANY]), mock.call('insert_into_log_table', mock.ANY, requires=[mock.ANY]), mock.call('set_overall_status_ingested', mock.ANY, requires=[mock.ANY], input={'status': 'INGESTED'}) ]) def test_chartmetric_charts_without_find_unchanged_charts(): """Test normal decider execution.""" flow = Flow() activity_statuses = MagicMock() activity_statuses.result = { 'bootstrap.reload_from_s3': False, 'bootstrap.platform_names': ['spotify', 'tiktok'] } schedule = MagicMock(return_value=activity_statuses) flow.decider(schedule, {'platform_names': 'spotify,tiktok', 'kafka': 'True', 'wait_until_complete': 'True', 'days_back': '3' }) schedule.assert_has_calls([ mock.call('bootstrap', mock.ANY), mock.call('clear_log_table', mock.ANY, requires=[mock.ANY]), mock.call('create_staging_fact', mock.ANY, requires=[mock.ANY]), mock.call('load_staging_fact', mock.ANY, requires=[mock.ANY]), mock.call('update_isrc_to_label_participant_mapping', mock.ANY, requires=[mock.ANY]), mock.call('update_upc_to_label_participant_mapping', mock.ANY, requires=[mock.ANY]), mock.call('update_globalsoundrecording_relations_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_soundrecording_noisrc_nodes_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_trackandparticipant_relations_kafka', mock.ANY, requires=[mock.ANY]), mock.call('update_productandlabel_relations_kafka', mock.ANY, requires=[mock.ANY], input={'productandlabel_platforms_to_skip': ['tiktok', 'recochoku', 'linemusic', 'soundcloud', 'youtube']}), mock.call('update_staging_fact_sound_recording', mock.ANY, requires=[mock.ANY]), mock.call('update_staging_fact_public_product', mock.ANY, requires=[mock.ANY]), mock.call('update_dim_tables', mock.ANY, requires=[mock.ANY]), mock.call('load_fact_data', mock.ANY, requires=[mock.ANY]), mock.call('update_position_change', mock.ANY, requires=[mock.ANY]), mock.call('refresh_aggregated_table', mock.ANY, requires=[mock.ANY]), mock.call('update_dim_chart_latest_chart_date', mock.ANY, requires=[mock.ANY]), mock.call('ows_charts_cache_prime', mock.ANY, requires=[mock.ANY]), mock.call('insert_into_log_table', mock.ANY, requires=[mock.ANY]), mock.call('set_overall_status_ingested', mock.ANY, requires=[mock.ANY], input={'status': 'INGESTED'}) ])