"""Unit tests for Meta Daily flow decider logic.""" from unittest import mock from unittest.mock import MagicMock import pytest from feed_ingestion.flows.meta_daily.flow import Flow class TestWorkflowId: """Tests for workflow ID generation.""" def test_workflow_id_with_context_date(self): flow = Flow() context = {'report': 'consumption', 'context_date': '2026-04-17'} assert flow.workflow_id(context) == ( 'meta_daily-consumption-2026-04-17' ) def test_workflow_id_without_context_date_uses_today(self): flow = Flow() context = {'report': 'production'} wf_id = flow.workflow_id(context) assert wf_id.startswith('meta_daily-production-') # Should be a valid date format YYYY-MM-DD date_part = wf_id.split('-', 2)[2] assert len(date_part) == 10 @pytest.mark.parametrize('report', ['consumption', 'production']) def test_contextified_feed_name(self, report): flow = Flow() context = {'report': report} assert flow.contextified_feed_name(context) == (f'meta_daily-{report}') class TestDecider: """Tests for the DAG decider logic.""" def test_decider_normal_execution(self): """All activities are scheduled in the normal run.""" flow = Flow() schedule = MagicMock() schedule_result = MagicMock() schedule_result.result = {} schedule.return_value = schedule_result flow.decider(schedule) schedule.assert_has_calls( [ mock.call('bootstrap', mock.ANY), mock.call( 'grab_available_files', mock.ANY, requires=[mock.ANY] ), mock.call('load_staging_raw', mock.ANY, requires=[mock.ANY]), mock.call( 'set_overall_status_if_complete', mock.ANY, requires=[mock.ANY], ), ] ) def test_decider_stops_when_bootstrap_returns_stop(self): """No further activities are scheduled after bootstrap stop.""" flow = Flow() schedule = MagicMock() schedule_result = MagicMock() schedule_result.result = {'bootstrap.stop': True} schedule.return_value = schedule_result flow.decider(schedule) schedule.assert_called_once_with('bootstrap', mock.ANY) with pytest.raises(AssertionError): schedule.assert_any_call( 'grab_available_files', mock.ANY, requires=mock.ANY ) def test_decider_stops_when_grab_files_returns_stop(self): """No load/status activities when no files are available.""" flow = Flow() schedule = MagicMock() schedule_result = MagicMock() schedule_result.result = {'grab_available_files.stop': True} schedule.return_value = schedule_result flow.decider(schedule) schedule.assert_any_call('bootstrap', mock.ANY) schedule.assert_any_call( 'grab_available_files', mock.ANY, requires=[mock.ANY] ) with pytest.raises(AssertionError): schedule.assert_any_call( 'load_staging_raw', mock.ANY, requires=mock.ANY ) with pytest.raises(AssertionError): schedule.assert_any_call( 'set_overall_status_if_complete', mock.ANY, requires=mock.ANY )