Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
150 lines
5.7 KiB
Python
150 lines
5.7 KiB
Python
"""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
|