"""User journey regressions: accurate counts, one approval/one plan, then review.""" from __future__ import annotations from server.aps_domain.folder_pack import analyze_work_dir from server.aps_domain.guidance import build_guidance from server.state.seed import empty_world from tests.golden.test_folder_schedule_security import _approve, _stage from tests.golden.test_folder_schedule_security import ( folder_env as folder_env, # noqa: PLC0414 - register pytest fixture ) def test_mixed_workbook_counts_each_business_category_once(tmp_path, monkeypatch): (tmp_path / "设备与订单.xlsx").write_bytes(b"test workbook") class Projects: def snapshot(self, include_messages=False): return {"projects": [{"id": "p", "workDir": str(tmp_path)}], "sessions": [{"id": "s", "projectId": "p"}]} batches = [{"sheet": kind, "kind": kind, "okCount": count, "okRows": [{"code": f"{kind}-{i}"} for i in range(count)]} for kind, count in [("orders", 6), ("materials", 87), ("routing", 15), ("equipment", 57)]] monkeypatch.setattr("server.state.projects.get_project_store", lambda: Projects()) monkeypatch.setattr("server.aps_domain.folder_pack.preview_file", lambda *_args, **_kwargs: {"batches": batches}) report = analyze_work_dir(empty_world(), "s") assert report["totalOk"] == 165 assert report["kindCounts"] == {"orders": 6, "materials": 87, "routing": 15, "equipment": 57} assert {item["key"]: item["count"] for item in report["coverageDetail"]}["equipment"] == 57 def test_existing_flex_plan_never_prompts_first_schedule(): world = empty_world() world["flexScheduleVersions"] = [{"id": 42, "versionNo": "V42", "status": "DRAFT", "trialOnly": True, "productionReady": False, "conflictCount": 0}] result = build_guidance(world) ids = {item["id"] for item in result["suggestions"]} assert {"view_schedule", "export_schedule"} <= ids assert not {"run_delivery", "flex_run", "publish"} & ids assert not any(item["id"] == "no_version" for item in result["signals"]) assert "尚未下发" in result["hint"] assert next(item for item in result["suggestions"] if item["id"] == "view_schedule")["command"] == "查看排产结果" def test_fixed_plan_view_and_blocked_publish(): world = empty_world() world["scheduleVersions"] = [{"id": 1, "versionNo": "V1", "status": "DRAFT", "conflictCount": 4}] result = build_guidance(world) assert not any(item["id"] == "publish" for item in result["suggestions"]) assert result["suggestions"][0]["id"] == "view_conflicts" def test_one_confirmation_runs_solver_once_and_reviews_the_committed_version(folder_env, monkeypatch): from server.aps_domain import flex store, identity, _approvals, _checkpoints, _path = folder_env original = flex.run_flex_schedule calls = [] def counted(*args, **kwargs): result = original(*args, **kwargs) calls.append(result) return result monkeypatch.setattr(flex, "run_flex_schedule", counted) confirm_id, reply = _stage(store, identity) assert "尚未生成方案" in reply.text assert calls == [] message = _approve(store, identity, confirm_id) assert len(calls) == 1 assert len(store.data["flexScheduleVersions"]) == 1 version = store.data["flexScheduleVersions"][0] assert version["trialOnly"] is True and version["productionReady"] is False assert version["versionNo"] in message and "尚未下发" in message assert "根据这些数据排产" not in message _approve(store, identity, confirm_id) assert len(calls) == 1