Enforce task session binding for authoring apply
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-16 19:59:14 +03:00
parent f37d45066d
commit cca24d0e7e
2 changed files with 133 additions and 0 deletions
+60
View File
@@ -10,6 +10,21 @@ from api_server.main import app
from one_c_normalizer import ConfigurationRoot, MetadataGroup, MetadataObject, Module, NormalizedProject
def create_authoring_session(client: TestClient, project_id: str, task_id: str, session_id: str, user_id: str = "dev.ivan") -> None:
user = client.post("/collaboration/users", json={"user_id": user_id, "display_name": user_id})
assert user.status_code == 200
task = client.post(
"/collaboration/tasks",
json={"task_id": task_id, "project_id": project_id, "title": f"Authoring {task_id}", "assignee_user_id": user_id},
)
assert task.status_code == 200
session = client.post(
"/collaboration/sessions",
json={"session": {"session_id": session_id, "task_id": task_id, "user_id": user_id}},
)
assert session.status_code == 200
def test_cors_allows_lan_panel_origin():
client = TestClient(app)
response = client.options(
@@ -1931,6 +1946,8 @@ def test_authoring_context_and_completion_preview(tmp_path: Path):
indexed = client.post("/projects/index", json={"path": str(tmp_path), "project_id": project_id})
assert indexed.status_code == 200
create_authoring_session(client, project_id, "task.authoring", "session.authoring")
create_authoring_session(client, project_id, "task.rollback", "session.rollback")
context = client.post(
f"/projects/{project_id}/authoring/context",
@@ -1993,6 +2010,7 @@ def test_authoring_context_and_completion_preview(tmp_path: Path):
assert diff_payload["target"]["name"] == "Проведение"
assert diff_payload["version_preview"]["task_id"] == "task.authoring"
assert diff_payload["version_preview"]["apply_available"] is False
assert any(row["name"] == "task-session" and row["status"] == "OK" for row in diff_payload["checks"])
assert any(row["name"] == "apply" and row["status"] == "BLOCKED" for row in diff_payload["checks"])
apply_response = client.post(
@@ -2093,6 +2111,45 @@ def test_authoring_context_and_completion_preview(tmp_path: Path):
assert production_apply.status_code == 403
def test_authoring_apply_requires_active_task_session(tmp_path: Path):
project_id = f"authoring-guard-{uuid4()}"
module = tmp_path / "guard_module.bsl"
source_text = "Процедура Проверить()\nКонецПроцедуры\n"
module.write_text(source_text, encoding="utf-8")
client = TestClient(app)
indexed = client.post("/projects/index", json={"path": str(tmp_path), "project_id": project_id})
assert indexed.status_code == 200
preview = client.post(
f"/projects/{project_id}/authoring/semantic-diff-preview",
json={
"routine_name": "Проверить",
"source_path": str(module),
"original_text": source_text,
"proposed_text": source_text.replace("КонецПроцедуры", " Возврат;\nКонецПроцедуры"),
},
)
assert preview.status_code == 200
preview_payload = preview.json()
assert any(check["name"] == "task-session" and check["status"] == "BLOCKED" for check in preview_payload["checks"])
apply_response = client.post(
f"/projects/{project_id}/authoring/apply-change-set",
json={
"routine_name": "Проверить",
"source_path": str(module),
"original_text": source_text,
"proposed_text": source_text.replace("КонецПроцедуры", " Возврат;\nКонецПроцедуры"),
"expected_next_version_id": preview_payload["version_preview"]["next_version_id"],
"approved_by": "dev.ivan",
},
)
assert apply_response.status_code == 409
blocked = apply_response.json()["detail"]["blocked_checks"]
assert blocked[0]["name"] == "task-session"
def test_authoring_metadata_object_preview_and_apply(tmp_path: Path):
project_id = f"metadata-authoring-api-{uuid4()}"
(tmp_path / "metadata.xml").write_text(
@@ -2107,6 +2164,8 @@ def test_authoring_metadata_object_preview_and_apply(tmp_path: Path):
client = TestClient(app)
indexed = client.post("/projects/index", json={"path": str(tmp_path), "project_id": project_id})
assert indexed.status_code == 200
create_authoring_session(client, project_id, "task.metadata", "session.metadata")
create_authoring_session(client, project_id, "task.metadata.rollback", "session.metadata.rollback")
draft = {
"object_kind": "DOCUMENT",
@@ -2136,6 +2195,7 @@ def test_authoring_metadata_object_preview_and_apply(tmp_path: Path):
assert preview_payload["target"]["qualified_name"] == "Документ.ЗаявкаНаЗакупку"
assert preview_payload["changed"] is True
assert preview_payload["version_preview"]["apply_available"] is True
assert any(check["name"] == "task-session" and check["status"] == "OK" for check in preview_payload["checks"])
assert any("Реквизит.Контрагент" in row["text"] for row in preview_payload["semantic_diff"])
assert any("ТабличнаяЧасть.Товары" in row["text"] for row in preview_payload["semantic_diff"])
assert any("Команда.Заполнить" in row["text"] for row in preview_payload["semantic_diff"])