"""UiPath migration helper tests and pilot output structure checks.""" from __future__ import annotations import json from datetime import datetime from pathlib import Path import pytest ROOT = Path(__file__).resolve().parent.parent UIPATH = ROOT / "uipath" / "MISF_Planner_Download" HELPERS_CS = UIPATH / "Helpers" def _read_cs(name: str) -> str: return (HELPERS_CS / name).read_text(encoding="utf-8") class TestUiPathProjectStructure: def test_project_json_exists(self): assert (UIPATH / "project.json").is_file() def test_main_workflows_exist(self): for name in ( "Main.xaml", "01_ReadConfig.xaml", "02_LoginPlanner.xaml", "03_ProcessFacility.xaml", "04_DownloadTaskAttachments.xaml", "05_SetTaskInProgress.xaml", "06_WriteSummary.xaml", ): assert (UIPATH / name).is_file(), f"missing {name}" def test_helpers_exist(self): assert (UIPATH / "Helpers" / "GenerateTotp.xaml").is_file() assert (UIPATH / "Helpers" / "SanitizeFolderName.xaml").is_file() assert (UIPATH / "Helpers" / "TotpGenerator.cs").is_file() def test_selectors_documented(self): assert (UIPATH / "Selectors" / "PlannerSelectors.json").is_file() assert (UIPATH / "Selectors" / "IFRAME_SETUP.md").is_file() data = json.loads((UIPATH / "Selectors" / "PlannerSelectors.json").read_text()) assert "planner_iframe" in data assert "my_plans" in data["planner_iframe"] class TestHelperLogicMirrorsPython: def test_sanitize_folder_name(self): src = _read_cs("MisfHelpers.cs") assert "SanitizeFolderName" in src assert "InvalidFolderChars" in src def test_totp_sanitize_matches_python(self): src = _read_cs("MisfHelpers.cs") assert 'Replace("0", "O")' in src assert 'Replace("1", "I")' in src def test_download_url_transform(self): src = _read_cs("MisfHelpers.cs") assert "web=1" in src assert "download=1" in src def test_default_planner_url(self): src = _read_cs("MisfConstants.cs") assert "planner.cloud.microsoft" in src assert "0c15ad2c-19dd-4ded-9cd1-20d344386414" in src class TestPilotOutputLayout: """Compare output folder layout with Python bot expectations.""" @pytest.fixture def today_iso(self) -> str: return datetime.now().strftime("%Y-%m-%d") def test_output_directories_can_be_created(self, today_iso: str, tmp_path: Path): original = tmp_path / "Output" / today_iso / "Original" / "Test_Facility" workable = tmp_path / "Output" / today_iso / "Workable" summary = tmp_path / "Output" / today_iso / "Summary" for d in (original, workable, summary): d.mkdir(parents=True, exist_ok=True) assert original.is_dir() assert workable.is_dir() assert summary.is_dir() def test_checkpoint_json_shape(self, tmp_path: Path): ckpt = { "last_completed_index": 2, "last_facility": "Amaya", "completed_facilities": ["Amaya", "Brighton Place San Diego"], } path = tmp_path / "checkpoint.json" path.write_text(json.dumps(ckpt), encoding="utf-8") loaded = json.loads(path.read_text()) assert loaded["last_completed_index"] == 2 assert isinstance(loaded["completed_facilities"], list) class TestMainXamlExpressions: def test_main_has_facility_limit_argument(self): main = (UIPATH / "Main.xaml").read_text(encoding="utf-8") assert "in_FacilityLimit" in main assert "FilterFacilities" in main def test_login_invokes_generate_totp(self): login = (UIPATH / "02_LoginPlanner.xaml").read_text(encoding="utf-8") assert "GenerateTotp.xaml" in login assert "loginfmt" in login def test_iframe_prefix_in_process_facility(self): proc = (UIPATH / "03_ProcessFacility.xaml").read_text(encoding="utf-8") assert "IFRAME" in proc assert "My plans" in proc def test_attachments_tab_download_flow(self): py = (ROOT / "src" / "onedrive_planner.py").read_text(encoding="utf-8") assert "_open_attachments_view" in py assert "_ensure_board_scan_context" in py assert "attachment-indicator" in py assert "_card_has_attachment" in py assert "_task_is_not_started" in py assert "_open_task_via_attachment" in py assert "_click_exact_attachment_name" in py assert "_collect_attachment_hrefs" in py assert "_collect_attachment_download_urls" in py assert "_download_href_via_http" in py assert "_download_attachment_row" in py assert "_list_attachment_rows" in py assert "_close_extra_download_tabs" in py assert "_download_href_with_fallback" in py assert "_download_one_href_browser_new_tab" in py assert "HTTP only last" in py or "HTTP last" in py assert "configure_http_download_proxy" in py assert "_url_from_attachment_element" in py assert "_scroll_attachments_panel" in py dl = (UIPATH / "04_DownloadTaskAttachments.xaml").read_text(encoding="utf-8") assert "Attachments" in dl assert "sharepoint" in dl.lower() def test_in_progress_task_details_only(self): proc = (UIPATH / "05_SetTaskInProgress.xaml").read_text(encoding="utf-8") assert "Task details" in proc assert "In progress" in proc py = (ROOT / "src" / "onedrive_planner.py").read_text(encoding="utf-8") assert "_set_task_in_progress_from_task_details" in py assert "_mark_task_in_progress" in py assert "task details only" in py assert "_set_task_in_progress_from_board(driver, card" not in py