diff --git a/CHANGELOG.md b/CHANGELOG.md index 77a43b848d74a382cab75fc85db6abb384314fd6..e75607c919fdc7fdb7ce91c8c321b391e1637d06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 entities. * Test for [caosdb-server#268](https://gitlab.com/linkahead/linkahead-server/-/issues/268): Unexpected Server Error when non-existent file shall be inserted. * test_profile for running the tests locally. +* Tests for pylib's high-level API ### Changed (for changes in existing functionality) diff --git a/tests/test_high_level.py b/tests/test_high_level.py new file mode 100644 index 0000000000000000000000000000000000000000..1b45cefbd6fb8d749fc201df049c634756ab4df5 --- /dev/null +++ b/tests/test_high_level.py @@ -0,0 +1,124 @@ +# encoding: utf-8 +# +# This file is a part of the LinkAhead Project. +# +# Copyright (C) 2025 Indiscale GmbH <info@indiscale.com> +# Copyright (C) 2025 Daniel Hornung <d.hornung@indiscale.com> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +"""Testing the high-level api. +""" + +import pytest + +import linkahead as db +from linkahead import high_level_api as hl +from linkahead import ( + Container, + Property, + Record, + RecordType, +) +from linkahead.utils.register_tests import set_test_key, clear_database + +set_test_key("_CAOSDB_PYINTTEST_SUITE") + + +@pytest.fixture(autouse=True) +def setup(clear_database): + cont = Container() + rt1 = RecordType(name="RT1") + cont.append(rt1) + rt2 = RecordType(name="RT2") + cont.append(rt2) + rt1.add_property(rt2) + prop2 = Property("comment", datatype=db.TEXT) + cont.append(prop2) + rt2.add_property(prop2) + + cont.insert() + + +def test_convert_to_py_object(): + """Basic conversion and retrieval.""" + # Create data + rec2_inserted = (Record("rec2").add_parent("RT2") + .add_property("comment", value="a nice record") + .insert()) + rec1_inserted = (Record("rec1").add_parent("RT1") + .add_property("RT2", value=rec2_inserted) + .insert()) + + # Create Record objects + rec1_offline = Record("rec1") + rec1_retrieved = db.get_entity_by_name("rec1") + + # Convert to Python objects + rec1_offl_unresolved = hl.convert_to_python_object(rec1_offline) + rec1_retrieved_unresolved = hl.convert_to_python_object(rec1_retrieved) + rec1_offl_resolved = hl.convert_to_python_object(rec1_offline, resolve_references=True) + rec1_retrieved_resolved = hl.convert_to_python_object(rec1_retrieved, resolve_references=True) + + # Also: retrieve by `query` + rec1_query_unresolved = hl.query("FIND rec1", resolve_references=False)[0] + rec1_query_resolved = hl.query("FIND rec1")[0] + + # Serialize and remove ephemeral components + json_unresolved = rec1_retrieved_unresolved.serialize() + json_resolved = rec1_retrieved_resolved.serialize() + json_query_unresolved = rec1_query_unresolved.serialize() + json_query_resolved = rec1_query_resolved.serialize() + + for data in (json_unresolved, json_resolved, json_query_unresolved, json_query_resolved): + data.pop("id") + data.pop("version") + data["properties"]["RT2"].pop("id") + data["parents"][0].pop("id") + data["metadata"]["RT2"].pop("id") + for data in (json_resolved, json_query_resolved): + data["properties"]["RT2"].pop("version") + data["properties"]["RT2"]["parents"][0].pop("id") + data["properties"]["RT2"]["metadata"]["comment"].pop("id") + + # Test against known-good serialization + assert rec1_offl_resolved.serialize() == {'role': 'Record', + 'name': 'rec1', + 'properties': {}, + 'parents': [], + 'metadata': {}} + assert rec1_offl_unresolved.serialize() == {'role': 'Record', + 'name': 'rec1', + 'properties': {}, + 'parents': [], + 'metadata': {}} + + assert json_unresolved == {'role': 'Record', + 'name': 'rec1', + 'properties': {'RT2': {'unresolved': True}}, + 'parents': [{'name': 'RT1', 'unresolved': True}], + 'metadata': {'RT2': {'datatype': 'RT2', 'importance': 'FIX'}} + } + assert json_resolved == { + 'role': 'Record', + 'name': 'rec1', + 'properties': {'RT2': {'role': 'Record', + 'name': 'rec2', + 'properties': {'comment': 'a nice record'}, + 'parents': [{'name': 'RT2', 'unresolved': True}], + 'metadata': {'comment': {'datatype': 'TEXT', + 'importance': 'FIX'}}} + }, + 'parents': [{'name': 'RT1', 'unresolved': True}], + 'metadata': {'RT2': {'datatype': 'RT2', 'importance': 'FIX'}}}