"""Unit tests for tasks for the Chartmetric Participants Ingestion Workflow.""" from unittest.mock import call from unittest.mock import MagicMock from unittest.mock import patch from freezegun import freeze_time from feed_ingestion.flows.chartmetric_participants import tasks @freeze_time('2020-01-01') def test_bootstrap_default_date(monkeypatch): """Test that bootstrap returns the default date.""" date = None expected = { 'feed_name': 'chartmetric_participants', 'date': '2019-12-31', 'reload': False, 'ingestion_started_at': '2020-01-01 00:00:00' } result = tasks.bootstrap(MagicMock(), date, None) assert result == expected @freeze_time('2020-01-01') def test_bootstrap_context_date(monkeypatch): """Test that bootstrap returns the context date.""" date = '2019-01-01' expected = { 'feed_name': 'chartmetric_participants', 'date': '2019-01-01', 'reload': True, 'ingestion_started_at': '2020-01-01 00:00:00' } result = tasks.bootstrap(MagicMock(), date, 'True') assert result == expected @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_sf_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.SnowflakeExecutor') def test_create_temp_participants_table( mock_executor_class, mock_get_sf_config): """Test create_temp_participants_table.""" mock_config = {} mock_get_sf_config.return_value = mock_config mock_executor = MagicMock() mock_executor_class.return_value.__enter__.return_value = mock_executor secrets_path = 'chartmetric_participants' tasks.create_temp_participants_table(MagicMock()) mock_get_sf_config.assert_called_once_with(secrets_path) mock_executor_class.assert_called_once_with(mock_config) mock_executor.execute_query.assert_called_once_with( 'create_temp_participants_table') @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_sf_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.SnowflakeExecutor') def test_create_main_participants_table( mock_executor_class, mock_get_sf_config): """Test create_main_participants_table.""" mock_config = {} mock_get_sf_config.return_value = mock_config mock_executor = MagicMock() mock_executor_class.return_value.__enter__.return_value = mock_executor secrets_path = 'chartmetric_participants' tasks.create_main_participants_table(MagicMock()) mock_get_sf_config.assert_called_once_with(secrets_path) mock_executor_class.assert_called_once_with(mock_config) mock_executor.execute_query.assert_called_once_with( 'create_main_participants_table') @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_sf_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.SnowflakeExecutor') @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_neo4j_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.Neo4jExecutor') def test_ingest_participants( mock_neo4j_executor_class, mock_get_neo4j_config, mock_sf_executor_class, mock_get_sf_config): """Test ingest participants.""" mock_get_neo4j_config.return_value = {} mock_get_sf_config.return_value = {'db': 'DB', 'schema': 'SCHEMA'} mock_neo4j_executor = MagicMock() mock_neo4j_executor_class.return_value.__enter__.return_value = \ mock_neo4j_executor mock_sf_executor = MagicMock() mock_sf_executor_class.return_value.__enter__.return_value = \ mock_sf_executor mock_sf_executor = MagicMock() first_batch = [{'key': 'value'}] second_batch = [] mock_sf_executor.fetchall_dict_query.side_effect = \ (first_batch, second_batch) mock_sf_executor_class.return_value.__enter__.return_value = \ mock_sf_executor feed_name = 'chartmetric_participants' get_sf_relations_query_name = 'get_participants' tasks.ingest_participants(MagicMock(), feed_name) params_expected = { 'limit': 2000, 'offset': 0, 'table_name': 'chartmetric_participants' } params_expected2 = { 'limit': 2000, 'offset': 2000, 'table_name': 'chartmetric_participants' } assert mock_sf_executor.fetchall_dict_query.call_args_list == [ call(get_sf_relations_query_name, **params_expected), call(get_sf_relations_query_name, **params_expected2), ] params_expected = {'rows': first_batch} assert mock_neo4j_executor.execute_write_query.call_args_list == [ call('ingest_participants', params_expected)] @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_sf_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.SnowflakeExecutor') @patch('feed_ingestion.flows.chartmetric_participants.tasks.get_neo4j_config') @patch('feed_ingestion.flows.chartmetric_participants.tasks.Neo4jExecutor') def test_delete_defunct_relationships( mock_neo4j_executor_class, mock_get_neo4j_config, mock_sf_executor_class, mock_get_sf_config): """Test delete defunct relationships.""" mock_get_neo4j_config.return_value = {} mock_get_sf_config.return_value = {'db': 'DB', 'schema': 'SCHEMA'} mock_neo4j_executor = MagicMock() mock_neo4j_executor_class.return_value.__enter__.return_value = \ mock_neo4j_executor mock_sf_executor = MagicMock() mock_sf_executor_class.return_value.__enter__.return_value = \ mock_sf_executor mock_sf_executor = MagicMock() first_batch = [{'key': 'value'}, {'key2': 'value'}] second_batch = [] mock_sf_executor.fetchall_dict_query.side_effect = \ (first_batch, second_batch) mock_sf_executor_class.return_value.__enter__.return_value = \ mock_sf_executor feed_name = 'chartmetric_participants' tasks.delete_defunct_relationships(MagicMock(), feed_name) assert mock_sf_executor.fetchall_dict_query.call_args_list == [ call('get_defunct_relationships', offset=0, limit=6000), call('get_defunct_relationships', offset=6000, limit=6000) ] params_expected = {'rows': first_batch} assert mock_neo4j_executor.execute_write_query.call_args_list == [ call('delete_defunct_relationships', params_expected)]