73 lines
3.7 KiB
Python
73 lines
3.7 KiB
Python
"""Custom profiles and configuration drift must use the actual confirmation API."""
|
|
from __future__ import annotations
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from tests.auth_provider import install_test_auth
|
|
from tests.golden.test_ruiyang_intake_workflow import _chat, _confirm
|
|
from tests.golden.test_workbook_profiles import _alternative, _config, _write
|
|
from tests.pi_primary_adapter import install_fake_pi_tool_adapter
|
|
from tests.workbook_acceptance import load_expectations, source_for_test
|
|
|
|
|
|
def _client(monkeypatch):
|
|
monkeypatch.setenv("APS_SEED_DEMO", "0")
|
|
install_test_auth(monkeypatch, "configured-intake-test")
|
|
install_fake_pi_tool_adapter(monkeypatch)
|
|
from server.gateway.app import create_app
|
|
return TestClient(create_app())
|
|
|
|
|
|
def _upload(client, raw):
|
|
assert client.post("/api/auth/login", json={"username": "planner", "password": "test"}).status_code == 200
|
|
project = client.post("/api/projects", json={"name": "另一个工厂"}).json()
|
|
pid, sid = project["project"]["id"], project["session"]["id"]
|
|
result = client.post(f"/api/projects/{pid}/files/upload", files=[("files", ("different-name.xlsx", raw))])
|
|
assert result.status_code == 200, result.text
|
|
return pid, sid
|
|
|
|
|
|
def test_alternative_profile_uses_same_upload_adoption_and_review_flow(tmp_path, monkeypatch):
|
|
expected = load_expectations()
|
|
raw, config, changed_codes = _alternative(source_for_test().read_bytes(), _config())
|
|
directory = tmp_path / "profiles"
|
|
_write(directory, config)
|
|
monkeypatch.setenv("APS_WORKBOOK_PROFILE_DIR", str(directory))
|
|
with _client(monkeypatch) as client:
|
|
pid, sid = _upload(client, raw)
|
|
blocks, text = _chat(client, pid, sid, "分析一下数据文件")
|
|
assert len(blocks) == 2, text
|
|
review = blocks[0]["props"]
|
|
assert review["profile"] == config["id"]
|
|
assert review["summary"] == expected["reviewCounts"]
|
|
assert client.get("/api/master").json()["materials"] == []
|
|
applied = _confirm(client, sid, blocks[1])
|
|
assert applied["refresh"] is True and "资料已采用" in applied["message"], applied
|
|
assert len(client.get("/api/master").json()["materials"]) == expected["entityCounts"]["materials"]
|
|
formal = client.get("/api/flex/world").json()["orders"]
|
|
assert {row["orderNo"] for row in formal} == {changed_codes[code] for code in expected["formalOrderNos"]}
|
|
again, text = _chat(client, pid, sid, "分析一下数据文件")
|
|
assert not any(block["type"] == "confirm-card" for block in again), text
|
|
result, text = _chat(client, pid, sid, "根据这些数据排产")
|
|
plan = next(block for block in result if block["type"] == "flex-schedule")
|
|
assert plan["props"]["trialOnly"] is True
|
|
assert plan["props"]["stats"]["orderCount"] == expected["entityCounts"]["orders"]
|
|
|
|
|
|
def test_changed_mapping_is_a_readable_rejection_not_an_http_error(tmp_path, monkeypatch):
|
|
config = _config()
|
|
directory = tmp_path / "profiles"
|
|
_write(directory, config)
|
|
monkeypatch.setenv("APS_WORKBOOK_PROFILE_DIR", str(directory))
|
|
with _client(monkeypatch) as client:
|
|
pid, sid = _upload(client, source_for_test().read_bytes())
|
|
blocks, _ = _chat(client, pid, sid, "分析一下数据文件")
|
|
card = next(block for block in blocks if block["type"] == "confirm-card")
|
|
config["planning"]["timeZone"] = "Europe/Berlin"
|
|
_write(directory, config)
|
|
response = _confirm(client, sid, card)
|
|
assert response["refresh"] is False
|
|
assert response["errorCode"] == "INTAKE_REVIEW_REQUIRED"
|
|
assert "重新检查" in response["message"]
|
|
assert client.get("/api/master").json()["materials"] == []
|