import copy import json import unittest from pathlib import Path from automation.planning import PAGE_ORDER, TaskPlanner ROOT = Path(__file__).resolve().parents[1] class PlanningTests(unittest.TestCase): def setUp(self): self.data = json.loads((ROOT / 'workflows/page_map.json').read_text()) self.planner = TaskPlanner(self.data, ROOT) def test_map_and_task_references_are_valid(self): self.assertTrue(self.planner.audit()['valid'], self.planner.audit()['issues']) def test_disabled_ancestor_and_cycles_are_rejected(self): data = copy.deepcopy(self.data) page = next(p for p in data['pages'] if p['id'] == 'guild.store') page['automation'] = {'enabled': False} issues = TaskPlanner(data, ROOT).audit()['issues'] self.assertTrue(any('disabled ancestor guild.store' in issue for issue in issues)) page['parent'] = 'guild.store.contribution' self.assertTrue(any('cyclic parent' in issue for issue in TaskPlanner(data, ROOT).audit()['issues'])) data['planned_tasks'][0]['group_page'] = 'missing_group' self.assertTrue(any('unknown group page missing_group' in issue for issue in TaskPlanner(data, ROOT).audit()['issues'])) def test_manual_and_deferred_tasks_are_not_in_default_plan(self): plan = self.planner.plan() ids = {row['id'] for row in plan['tasks']} self.assertNotIn('sweep', ids) self.assertNotIn('wall_command_build', ids) self.assertNotIn('movie_daily_rewards', ids) expanded = self.planner.plan(True, True) self.assertTrue({'sweep', 'wall_command_build', 'movie_daily_rewards'} <= {r['id'] for r in expanded['tasks']}) def test_shared_store_keeps_two_tasks_and_legacy_home_contract(self): plan = self.planner.plan() hub = next(group for group in plan['visit_groups'] if group['hub'] == 'guild.store') self.assertEqual(set(hub['tasks']), {'guild_contribution_store_purchases', 'guild_dragon_scale_store_purchases'}) legacy = next(row for row in plan['tasks'] if row['id'] == 'recruit') self.assertEqual(legacy['script_start'], 'home') self.assertEqual(legacy['navigation_mode'], 'legacy_script_owns_navigation') def test_page_order_blockers_and_config_are_preserved(self): before = copy.deepcopy(self.data) rows = self.planner.plan()['tasks'] groups = [PAGE_ORDER.index(row['group_page']) for row in rows] self.assertEqual(groups, sorted(groups)) self.assertTrue(all('任务执行器尚未实现' in row['blockers'] for row in rows if row['implementation'] == 'planned')) self.assertEqual(self.data, before) self.assertTrue(all(r['group_page'] == 'guild' for r in self.planner.plan(group_page='guild')['tasks'])) if __name__ == '__main__': unittest.main()