from __future__ import annotations import pytest from tests.data_research.test_ontology_validation import base_graph def test_json_and_owl_round_trip_preserve_stable_uids_and_hashes(): from app.core.data_research.ontology.exchange import OntologyExchange from app.core.data_research.ontology.repository import canonical_graph_hash exchange = OntologyExchange(max_import_bytes=100_000) graph = base_graph() json_bytes = exchange.export_json("ontology-1", 3, graph) owl_bytes = exchange.export_owl("ontology-1", 3, graph) imported_json = exchange.import_json(json_bytes) imported_owl = exchange.import_owl(owl_bytes) assert imported_json["ontology_uid"] == "ontology-1" assert imported_owl["ontology_uid"] == "ontology-1" assert imported_owl["graph_document"] == graph assert canonical_graph_hash(imported_json["graph_document"]) == canonical_graph_hash(graph) assert canonical_graph_hash(imported_owl["graph_document"]) == canonical_graph_hash(graph) def test_owl_import_rejects_unsafe_xml_and_size_limits(): from app.core.data_research.ontology.exchange import ExchangeInvalid, OntologyExchange exchange = OntologyExchange(max_import_bytes=80) with pytest.raises(ExchangeInvalid, match="unsafe XML"): exchange.import_owl(b']>&e;') with pytest.raises(ExchangeInvalid, match="size limit"): exchange.import_json(b"{" + b" " * 100 + b"}") def test_exports_redact_secret_like_fields_deterministically(): from app.core.data_research.ontology.exchange import OntologyExchange graph = base_graph() graph["classes"][0]["password"] = "must-not-export" first = OntologyExchange().export_json("ontology-1", 1, graph) second = OntologyExchange().export_json("ontology-1", 1, graph) assert first == second assert b"must-not-export" not in first assert b"[redacted]" in first