Files
llm/tests/1c/test_sql_base_access_policy.py
T

127 lines
5.0 KiB
Python

from __future__ import annotations
import importlib.util
from pathlib import Path
import yaml
ROOT = Path(__file__).resolve().parents[2]
CONNECTOR = ROOT / "plugins" / "1c" / "connector"
def load_adapter():
path = CONNECTOR / "adapter_1c_server.py"
spec = importlib.util.spec_from_file_location("adapter_1c_policy_test", path)
assert spec and spec.loader
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def test_sql_base_access_policy_contract() -> None:
policy = yaml.safe_load((CONNECTOR / "policies" / "sql-base-access-policy.yaml").read_text(encoding="utf-8"))
assert policy["status"] == "active"
assert policy["base_settings"]["selector"] == "base_id"
assert set(policy["base_settings"]["required_fields"]) == {"server", "database", "user"}
assert policy["read_scope"]["application_data"] == "read_only"
assert policy["read_scope"]["metadata_structure"] == "read_only"
assert set(policy["write_scope"]["allowed"].values()) == {"ConfigSave", "ConfigCASSave"}
assert policy["sql_identity_management"]["mode"] == "forbidden"
def test_xml_is_offline_decoder_evidence_and_runtime_is_sql_only() -> None:
policy = yaml.safe_load((CONNECTOR / "policies" / "xml-decoding-reference-policy.yaml").read_text(encoding="utf-8"))
service = yaml.safe_load((CONNECTOR / "service.yaml").read_text(encoding="utf-8"))
assert policy["status"] == "active"
assert policy["offline_analysis"]["allowed"] is True
assert policy["runtime"]["source"] == "sql_only"
assert policy["runtime"]["xml_mount_required"] is False
assert "policies/xml-decoding-reference-policy.yaml" in service["contracts"]["policies"]
def test_designer_sql_decoding_policy_keeps_adapter_read_only() -> None:
policy = yaml.safe_load((CONNECTOR / "policies" / "designer-sql-decoding-policy.yaml").read_text(encoding="utf-8"))
service = yaml.safe_load((CONNECTOR / "service.yaml").read_text(encoding="utf-8"))
assert policy["scope"]["default_base_id"] == "upo_test"
assert policy["scope"]["adapter_role"] == "sql_observer_and_decoder"
assert policy["credentials"]["persistence"] == "forbidden_in_repository"
assert policy["sql_observation"]["adapter_access"] == "read_only"
assert "direct_application_data_write" in policy["sql_observation"]["forbidden"]
assert policy["xml"]["role"] == "offline_schema_reference_only"
assert "policies/designer-sql-decoding-policy.yaml" in service["contracts"]["policies"]
def test_runtime_rejects_xml_sources_at_any_payload_depth() -> None:
adapter = load_adapter()
direct = adapter.call_method_impl(
"metadata.object.get",
{"base_id": "upo_test", "ref": "Catalog.Test", "xml_path": "Configuration.xml"},
)
nested = adapter.call_method_impl(
"metadata.write.plan",
{"base_id": "upo_test", "target": {"form_xml_path": "Forms/Test/Ext/Form.xml"}},
)
assert direct["status"] == "invalid_argument"
assert direct["argument"] == "payload.xml_path"
assert nested["status"] == "invalid_argument"
assert nested["argument"] == "payload.target.form_xml_path"
assert "SQL-only" in direct["diagnostics"]["message"]
def test_adapter_has_no_xml_runtime_environment_configuration() -> None:
source = (CONNECTOR / "adapter_1c_server.py").read_text(encoding="utf-8")
assert "ONEC_XML" not in source
def test_sql_connection_requires_explicit_base_entry(monkeypatch) -> None:
adapter = load_adapter()
for name in (
"ONEC_SQL_BASES_JSON",
"ONEC_SQL_CONNECTIONS_JSON",
"ONEC_SQL_BASES_JSON_FILE",
"ONEC_SQL_CONNECTIONS_JSON_FILE",
):
monkeypatch.delenv(name, raising=False)
monkeypatch.setenv("ONEC_SQL_SERVER", "must-not-be-used")
monkeypatch.setenv("ONEC_SQL_USER", "must-not-be-used")
monkeypatch.setenv("ONEC_SQL_PASSWORD", "must-not-be-used")
config, error = adapter.sql_config_for_base("upo_test")
assert config is None
assert error and error["status"] == "not_configured"
def test_sql_connection_does_not_infer_database_name(monkeypatch) -> None:
adapter = load_adapter()
monkeypatch.setenv(
"ONEC_SQL_BASES_JSON",
'{"upo_test":{"server":"sql-host","user":"login","password":"secret"}}',
)
config, error = adapter.sql_config_for_base("upo_test")
assert config is None
assert error and "database" in error["message"]
def test_sql_connection_ignores_legacy_connection_map(monkeypatch) -> None:
adapter = load_adapter()
monkeypatch.delenv("ONEC_SQL_BASES_JSON", raising=False)
monkeypatch.delenv("ONEC_SQL_BASES_JSON_FILE", raising=False)
monkeypatch.setenv(
"ONEC_SQL_CONNECTIONS_JSON",
'{"upo_test":{"server":"must-not-be-used","database":"must-not-be-used","user":"must-not-be-used","password":"must-not-be-used"}}',
)
config, error = adapter.sql_config_for_base("upo_test")
assert config is None
assert error and error["status"] == "not_configured"
assert adapter.sql_configured_base_ids() == []