feat: complete production workflow migration
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from gyxx_flow.adapters import WORKFLOW_ACCEPTANCE_RECIPIENT_OPEN_ID
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def acceptance_environment(
|
||||
tmp_path: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> Path:
|
||||
evidence = tmp_path / "evidence.jsonl"
|
||||
monkeypatch.setenv("GYXX_WORKFLOW_ACCEPTANCE", "1")
|
||||
monkeypatch.setenv("GYXX_FEISHU_TABLE_WRITE_DISABLED", "1")
|
||||
monkeypatch.setenv("GYXX_COOKIE_INVALID_SKIP", "1")
|
||||
monkeypatch.setenv(
|
||||
"GYXX_NOTIFICATION_RECIPIENT_OPEN_ID",
|
||||
WORKFLOW_ACCEPTANCE_RECIPIENT_OPEN_ID,
|
||||
)
|
||||
monkeypatch.setenv("GYXX_ACCEPTANCE_EVIDENCE_FILE", str(evidence))
|
||||
return evidence
|
||||
|
||||
|
||||
def test_replenishment_bitable_run_is_physically_skipped(
|
||||
tmp_path: Path,
|
||||
acceptance_environment: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
module = importlib.import_module(
|
||||
"gyxx_flow.modules.supply_chain.orchestrator.scripts."
|
||||
"insert_replenishment_bitable"
|
||||
)
|
||||
pending = tmp_path / "pending_insert.json"
|
||||
pending.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"pending_count": 2,
|
||||
"records": [
|
||||
{"商品编号": "SKU1"},
|
||||
{"商品编号": "SKU2"},
|
||||
],
|
||||
},
|
||||
ensure_ascii=False,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
module,
|
||||
"_search_record_id_by_sku",
|
||||
lambda *_args, **_kwargs: pytest.fail("must not access Feishu"),
|
||||
)
|
||||
|
||||
result = module.run(pending)
|
||||
|
||||
assert result == {
|
||||
"inserted": 0,
|
||||
"updated": 0,
|
||||
"skipped": 2,
|
||||
"record_ids": [],
|
||||
"errors": [],
|
||||
"skipped_by_policy": True,
|
||||
}
|
||||
assert "feishu_write_skipped" in acceptance_environment.read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
|
||||
def test_supply_card_sender_forces_only_wang_yunlong(
|
||||
acceptance_environment: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
module = importlib.import_module(
|
||||
"gyxx_flow.modules.supply_chain.orchestrator.scripts."
|
||||
"send_card_notification"
|
||||
)
|
||||
sent: list[str] = []
|
||||
monkeypatch.setattr(module, "_get_tenant_token", lambda: "test-token")
|
||||
monkeypatch.setattr(
|
||||
module,
|
||||
"_send_card",
|
||||
lambda _token, open_id, _card: sent.append(open_id) or "mid-1",
|
||||
)
|
||||
|
||||
result = module.run(["ou_other", "oc_group"], {"elements": []})
|
||||
|
||||
assert sent == [WORKFLOW_ACCEPTANCE_RECIPIENT_OPEN_ID]
|
||||
assert result == {"message_ids": ["mid-1"], "errors": []}
|
||||
|
||||
|
||||
def test_supply_config_uses_the_two_local_hermes_api_servers(
|
||||
acceptance_environment: Path,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setenv(
|
||||
"COLLECTOR_API_SERVER_URL",
|
||||
"http://127.0.0.1:8643/v1/chat/completions",
|
||||
)
|
||||
monkeypatch.setenv(
|
||||
"ANALYZER_API_SERVER_URL",
|
||||
"http://127.0.0.1:8642/v1/chat/completions",
|
||||
)
|
||||
module = importlib.import_module(
|
||||
"gyxx_flow.modules.supply_chain.orchestrator.config"
|
||||
)
|
||||
module = importlib.reload(module)
|
||||
|
||||
assert module.HERMES_GATEWAYS["collector"]["url"] == "http://127.0.0.1:8643/v1"
|
||||
assert module.HERMES_GATEWAYS["collector"]["model"] == "data-collector"
|
||||
assert module.HERMES_GATEWAYS["analyzer"]["url"] == "http://127.0.0.1:8642/v1"
|
||||
assert module.HERMES_GATEWAYS["analyzer"]["model"] == "data-analyzer"
|
||||
for targets in module.FEISHU_CONFIG["notification_targets"].values():
|
||||
assert targets == [WORKFLOW_ACCEPTANCE_RECIPIENT_OPEN_ID]
|
||||
|
||||
|
||||
def test_purchase_order_update_is_blocked_before_erp_mutation(
|
||||
acceptance_environment: Path,
|
||||
) -> None:
|
||||
module = importlib.import_module(
|
||||
"gyxx_flow.modules.supply_chain.orchestrator.mcp_workflow"
|
||||
)
|
||||
module = importlib.reload(module)
|
||||
|
||||
result = module.run_mcp_workflow(
|
||||
"purchase-order-update",
|
||||
"acceptance-purchase-order-update",
|
||||
)
|
||||
|
||||
assert result["status"] == "blocked_business_mutation"
|
||||
assert "approved test task/SKU fixture" in result["error"]
|
||||
assert "business_mutation_blocked" in acceptance_environment.read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
Reference in New Issue
Block a user