Complete name-first MCP write-plan composition
This commit is contained in:
@@ -21449,6 +21449,63 @@ def test_metadata_write_plan_allows_concrete_module_saved_state_reference() -> N
|
||||
assert result["route"]["apply_payload_hint"]["ready_for_apply_method"] is True
|
||||
|
||||
|
||||
def test_metadata_write_plan_resolves_public_module_selector_internally(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
seen: dict[str, Any] = {}
|
||||
|
||||
def fake_search(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
seen.update(payload)
|
||||
return {
|
||||
"schema": "onec_saved_state_module_search.v1",
|
||||
"status": "ok",
|
||||
"modules": [
|
||||
{
|
||||
"owner": {"kind": "Catalog", "name": "Контрагенты"},
|
||||
"module": {"kind": "manager_module", "name": "Модуль менеджера"},
|
||||
"qualified_name": "Контрагенты.Модуль менеджера",
|
||||
"payload": {"sha1": "saved-payload-sha1"},
|
||||
"streams": [
|
||||
{
|
||||
"module_ref": "ConfigSave:object-guid.3#stream:0",
|
||||
"module": {"kind": "manager_module", "name": "Модуль менеджера"},
|
||||
"qualified_name": "Контрагенты.Модуль менеджера",
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
monkeypatch.setattr(adapter_server, "metadata_saved_state_modules_search", fake_search)
|
||||
|
||||
result = adapter_server.metadata_write_plan(
|
||||
{
|
||||
"base_id": "upo_test",
|
||||
"target": {
|
||||
"kind": "module",
|
||||
"ref": "Catalog.Контрагенты",
|
||||
"module": "Модуль менеджера",
|
||||
"qualified_name": "Контрагенты.Модуль менеджера",
|
||||
"stream_ordinal": 1,
|
||||
},
|
||||
"intent": {
|
||||
"operation": "replace_with_control",
|
||||
"control_fragment": "Процедура Тест()",
|
||||
"new": "Процедура Тест()\nКонецПроцедуры",
|
||||
},
|
||||
"resolve_origin": False,
|
||||
}
|
||||
)
|
||||
|
||||
assert seen["ref"] == "Catalog.Контрагенты"
|
||||
assert seen["include_storage"] is True
|
||||
assert result["allowed"] is True
|
||||
assert result["route"]["name_resolution"]["status"] == "resolved"
|
||||
assert result["route"]["name_resolution"]["selector"]["ref"] == "Catalog.Контрагенты"
|
||||
hint = result["route"]["apply_payload_hint"]
|
||||
assert hint["ready_for_apply_method"] is True
|
||||
assert hint["payload"]["module_ref"] == "ConfigSave:object-guid.3#stream:0"
|
||||
assert hint["payload"]["expected_sha1"] == "saved-payload-sha1"
|
||||
|
||||
|
||||
def test_metadata_write_preflight_verifies_concrete_saved_state(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
def fake_diff(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
assert payload["module_ref"] == "ConfigCASSave:object-guid__module-guid.0#stream:4"
|
||||
@@ -24393,6 +24450,14 @@ def test_public_saved_state_module_search_row_is_name_first() -> None:
|
||||
"qualified_name": "test2.t_Форма.Модуль формы",
|
||||
}
|
||||
assert public["streams"][0]["match"] == {"query": "Команда", "in_text": True, "in_name": False}
|
||||
assert public["streams"][0]["write_plan_target"] == {
|
||||
"kind": "module",
|
||||
"ref": "Catalog.test2",
|
||||
"form": "t_Форма",
|
||||
"module": "Модуль формы",
|
||||
"qualified_name": "test2.t_Форма.Модуль формы",
|
||||
"stream_ordinal": 1,
|
||||
}
|
||||
for storage_marker in (
|
||||
"ConfigCASSave",
|
||||
"extension-guid",
|
||||
@@ -24400,7 +24465,6 @@ def test_public_saved_state_module_search_row_is_name_first() -> None:
|
||||
"owner-guid",
|
||||
"module_ref",
|
||||
"file_name",
|
||||
"write_plan_target",
|
||||
"sha1",
|
||||
):
|
||||
assert storage_marker not in str(public)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
import scripts.plan_1c_saved_state_copy as copy_plan
|
||||
import scripts.smoke_1c_code_write_saved_state as code_write_smoke
|
||||
|
||||
|
||||
def test_resolve_object_uses_name_first_object_get(monkeypatch) -> None:
|
||||
calls: list[tuple[str, dict[str, Any]]] = []
|
||||
|
||||
def fake_rpc(base_url: str, method: str, payload: dict[str, Any], timeout: float) -> dict[str, Any]:
|
||||
calls.append((method, payload))
|
||||
assert method == "metadata.object.get"
|
||||
return {
|
||||
"status": "ok",
|
||||
"object": {
|
||||
"guid": "40045984-a54c-42bd-8ea8-1c10672f40ec",
|
||||
"kind": "Catalog",
|
||||
"name": "АвансовыйОтчетПрисоединенныеФайлы",
|
||||
},
|
||||
}
|
||||
|
||||
monkeypatch.setattr(copy_plan, "rpc", fake_rpc)
|
||||
selector = {
|
||||
"base_id": "upo_test",
|
||||
"ref": "Catalog.АвансовыйОтчетПрисоединенныеФайлы",
|
||||
"include_storage": True,
|
||||
"table": "Config",
|
||||
}
|
||||
|
||||
result = copy_plan.resolve_object("http://adapter.example", selector, "Config", 1)
|
||||
|
||||
assert result["kind"] == "Catalog"
|
||||
assert result["name"] == "АвансовыйОтчетПрисоединенныеФайлы"
|
||||
assert calls == [("metadata.object.get", selector)]
|
||||
|
||||
|
||||
def test_optional_code_write_smoke_skips_only_policy_gate() -> None:
|
||||
assert code_write_smoke.is_optional_write_gate_block(
|
||||
{"status": "blocked", "error": "needs_repository_lock"}
|
||||
)
|
||||
assert not code_write_smoke.is_optional_write_gate_block(
|
||||
{"status": "blocked", "error": "write_plan_blocked"}
|
||||
)
|
||||
assert not code_write_smoke.is_optional_write_gate_block(
|
||||
{"status": "error", "error": "needs_repository_lock"}
|
||||
)
|
||||
Reference in New Issue
Block a user