"""Unit tests for YouTube Facts Snowflake SQL executor.""" from unittest.mock import MagicMock from unittest.mock import patch import pytest from snowflake import connector from feed_ingestion.flows import \ YouTubeFactsAssetSme, YouTubeFactsAssetTheOrchard, \ YouTubeFactsVideoSme, YouTubeFactsVideoTheOrchard from tests.conftest import SubstringMatcher @pytest.fixture def mock_sql_loader(): """Return sql_loader mock.""" sql_loader_path = ( 'feed_ingestion.flows.youtube_facts.snowflake_executor.sql_loader') with patch(sql_loader_path) as sql_loader: yield sql_loader @pytest.fixture(params=[ (YouTubeFactsAssetTheOrchard, 'asset', 'theorchard'), (YouTubeFactsAssetSme, 'asset', 'sme'), (YouTubeFactsVideoTheOrchard, 'video', 'theorchard'), (YouTubeFactsVideoSme, 'video', 'sme'), ]) def mock_executor_and_params(request, sf_config_mock, monkeypatch): """Yield executor, expected_report_type, expected_licensor.""" connect_mock = MagicMock() monkeypatch.setattr(connector, 'connect', connect_mock) executor_class = request.param[0] expected_report_type = request.param[1] expected_licensor = request.param[2] executor = executor_class(sf_config_mock) with patch.object(executor, 'execute', wraps=executor.execute) as \ executor.ex_mock: executor.fetchall = MagicMock() with patch.object(executor, 'fetchone', wraps=executor.fetchone) as \ executor.fetchone_mock: yield executor, expected_report_type, expected_licensor def test_load_staging_fact_table(mock_executor_and_params): """Test load_staging_fact_table method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.load_staging_fact_table('2019-11-01') assert mock_executor.ex_mock.call_count == 1 mock_executor.ex_mock.assert_any_call( SubstringMatcher( containing=[ 'test_db.test_schema.staging_fact_analytics_' 'youtube_facts_{}_{}_20191101'.format( report_type, licensor ), 'prod', 'yt_reports_api']), params={'reportdate': '2019-11-01', 'storeid': 453, 'feedid': 38, 'licensor': licensor}) def test_delete_from_fact_table(mock_executor_and_params): """Test delete_from_fact_table method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.delete_from_fact_table('2019-11-01') assert mock_executor.fetchone_mock.call_count == 1 mock_executor.fetchone_mock.assert_any_call( SubstringMatcher( containing=[ 'DELETE FROM', 'test_db.test_schema.fact_youtube_{}_analytics'.format( report_type) ]), params={'reportdate': '2019-11-01', 'storeid': 453, 'feedid': 38}) def test_delete_from_demographics_table(mock_executor_and_params): """Test test_delete_from_demographics_table method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.delete_from_demographics_table('2019-11-01') assert mock_executor.fetchone_mock.call_count == 1 mock_executor.fetchone_mock.assert_any_call( SubstringMatcher( containing=[ 'DELETE FROM', 'test_db.test_schema.fact_youtube_{}_demographics'.format( report_type) ]), params={'reportdate': '2019-11-01', 'storeid': 453, 'feedid': 38}) def test_load_fact_data(mock_executor_and_params): """Test load_fact_data method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.load_fact_data('2019-11-01') assert mock_executor.ex_mock.call_count == 1 mock_executor.ex_mock.assert_any_call( SubstringMatcher( containing=[ 'INSERT INTO', 'test_db.test_schema.fact_youtube_{}_analytics'.format( report_type), 'test_db.test_schema.staging_fact' '_analytics_youtube_facts_{}_{}_20191101'.format( report_type, licensor)]), params={'reportdate': '2019-11-01'}) def test_load_fact_error_data(mock_executor_and_params): """Test load_fact_error_data method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.load_fact_error_data('2019-11-01') if report_type == 'video': # Video report doesn't have analytics_error assert mock_executor.ex_mock.call_count == 0 else: assert mock_executor.ex_mock.call_count == 1 mock_executor.ex_mock.assert_any_call( SubstringMatcher( containing=[ 'INSERT INTO', 'test_db.test_schema.fact_youtube_{}_analytics_error' .format(report_type), 'test_db.test_schema.staging_fact' '_analytics_youtube_facts_{}_{}_20191101'.format( report_type, licensor)]), params={'reportdate': '2019-11-01'}) def test_load_demographics_data(mock_executor_and_params): """Test load_staging_fact_table method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.load_demographics_data('2019-11-01') assert mock_executor.ex_mock.call_count == 1 mock_executor.ex_mock.assert_any_call( SubstringMatcher( containing=[ 'test_db.test_schema.fact_youtube_{}_demographics'.format( report_type), 'prod', 'yt_reports_api']), params={'reportdate': '2019-11-01', 'storeid': 453, 'feedid': 38}) def test_load_youtube_video_asset_type_mapping(mock_executor_and_params): """Test load_youtube_video_asset_type_mapping method.""" mock_executor, report_type, licensor = mock_executor_and_params mock_executor.load_youtube_video_asset_type_mapping('2019-11-01') assert mock_executor.ex_mock.call_count == 1 mock_executor.ex_mock.assert_any_call( SubstringMatcher( containing=[ 'MERGE INTO', 'test_db.test_schema.staging_fact' '_analytics_youtube_facts_{}_{}_20191101'.format( report_type, licensor)]), params={'reportdate': '2019-11-01'})