"""Unit tests for Proper Music Distribution Ingestion Workflow.""" import datetime from unittest import mock from unittest.mock import MagicMock import pytest from feed_ingestion.flows.proper_incoming import config from feed_ingestion.flows.proper_incoming.flow import Flow @pytest.fixture def run_date(): """Fixture returning run date.""" return '2016-08-27' @pytest.fixture(params=[ config.FEED_TYPE_STOCK, config.FEED_TYPE_GOODSIN, config.FEED_TYPE_SALES, config.FEED_TYPE_SHORTAGES]) def proper_feed_type(request): """Fixture returns acceptable proper feed types.""" return request.param def test_proper_flow_get_proper_run_params_from_context( run_date, proper_feed_type): """Test Flow class _get_proper_run_params_from_context method. (Normal execution). """ proper_flow = Flow() context = { 'context_date': run_date, 'proper_feed_type': proper_feed_type } response_date, response_feed_type = ( proper_flow._get_proper_run_params_from_context(context)) assert response_date == run_date assert response_feed_type == proper_feed_type def test_proper_flow_get_proper_run_params_from_context_no_date( proper_feed_type): """Test Flow class _get_proper_run_params_from_context method. (Without passed context_date). """ proper_flow = Flow() context = { 'proper_feed_type': proper_feed_type } response_date, response_feed_type = ( proper_flow._get_proper_run_params_from_context(context)) assert response_date == datetime.datetime.today().strftime('%Y-%m-%d') assert response_feed_type == proper_feed_type def test_proper_flow_get_proper_run_params_from_context_no_feed_type(): """Test Flow class _get_proper_run_params_from_context method. (Without passed proper_feed_type). """ proper_flow = Flow() context = {} with pytest.raises(KeyError): proper_flow._get_proper_run_params_from_context(context) def test_proper_flow_get_proper_run_params_from_context_incorrect_feed_type(): """Test Flow class _get_proper_run_params_from_context method. (With incorrect proper_feed_type). """ proper_flow = Flow() context = { 'proper_feed_type': 'incorrect_type' } with pytest.raises(ValueError): proper_flow._get_proper_run_params_from_context(context) def test_proper_flow_workflow_id(monkeypatch, proper_feed_type, run_date): """Test normal execution of Flow class workflow_id method.""" proper_flow = Flow() get_proper_run_params_from_context_mock = MagicMock() monkeypatch.setattr( proper_flow, '_get_proper_run_params_from_context', value=get_proper_run_params_from_context_mock) get_proper_run_params_from_context_mock.return_value = ( run_date, proper_feed_type) context = { 'context_date': run_date, 'proper_feed_type': proper_feed_type } exec_workflow_id = proper_flow.workflow_id(context) expected_workflow_id = '{}-{}'.format(proper_feed_type, run_date) assert exec_workflow_id == expected_workflow_id def test_proper_flow_decider_stock(monkeypatch, proper_feed_type, run_date): """Test normal decider execution for stock feed type.""" proper_flow = Flow() schedule = MagicMock() schedule_result_object = MagicMock() schedule_result_object.result = {} schedule.return_value = schedule_result_object get_proper_run_params_from_context_mock = MagicMock() monkeypatch.setattr( proper_flow, '_get_proper_run_params_from_context', value=get_proper_run_params_from_context_mock) get_proper_run_params_from_context_mock.return_value = ( run_date, proper_feed_type) context = { 'context_date': run_date, 'proper_feed_type': proper_feed_type } proper_flow.decider(schedule, context) schedule.assert_any_call('bootstrap', mock.ANY) schedule.assert_any_call( 'fetch_from_drop_location', mock.ANY, requires=mock.ANY) if proper_feed_type == config.FEED_TYPE_STOCK: schedule.assert_any_call( 'transform_csv_file_stock', mock.ANY, requires=mock.ANY) schedule.assert_any_call('validate_csv_file', mock.ANY, requires=mock.ANY) if proper_feed_type == config.FEED_TYPE_STOCK: schedule.assert_any_call( 'ingest_stock_data_into_mysql_table', mock.ANY, requires=mock.ANY) schedule.assert_any_call( 'set_overall_status_to_ingested', mock.ANY, requires=mock.ANY) with pytest.raises(AssertionError): schedule.assert_any_call( 'transform_csv_file', mock.ANY, requires=mock.ANY) schedule.assert_any_call( 'purge_old_data_from_snowflake', mock.ANY, requires=mock.ANY) schedule.assert_any_call('set_overall_status_to_ingested', mock.ANY, requires=mock.ANY) elif proper_feed_type in [config.FEED_TYPE_GOODSIN, config.FEED_TYPE_SHORTAGES]: schedule.assert_any_call('transform_csv_file', mock.ANY, requires=mock.ANY) schedule.assert_any_call('purge_old_data_from_snowflake', mock.ANY, requires=mock.ANY) elif proper_feed_type == config.FEED_TYPE_SALES: schedule.assert_any_call('set_overall_status_to_ingested', mock.ANY, requires=mock.ANY) def test_proper_flow_decider_stopped(monkeypatch, run_date): """Test decider execution when it must be stopped.""" proper_flow = Flow() schedule = MagicMock() schedule_result_object = MagicMock() schedule_result_object.result = { 'fetch_from_drop_location.stop': True } schedule.return_value = schedule_result_object feed_with_schema = config.FEED_TYPE_STOCK get_proper_run_params_from_context_mock = MagicMock() monkeypatch.setattr( proper_flow, '_get_proper_run_params_from_context', value=get_proper_run_params_from_context_mock) get_proper_run_params_from_context_mock.return_value = ( run_date, feed_with_schema) context = { 'context_date': run_date, 'proper_feed_type': feed_with_schema } proper_flow.decider(schedule, context) schedule.assert_any_call('bootstrap', mock.ANY) schedule.assert_any_call( 'fetch_from_drop_location', mock.ANY, requires=mock.ANY) with pytest.raises(AssertionError): schedule.assert_any_call( 'validate_csv_file', mock.ANY, requires=mock.ANY) schedule.assert_any_call( 'transform_csv_file_stock', mock.ANY, requires=mock.ANY) schedule.assert_any_call( 'ingest_stock_data_into_mysql_table', mock.ANY, requires=mock.ANY) schedule.assert_any_call( 'set_overall_status_to_ingested', mock.ANY, requires=mock.ANY)