# # This file is a part of the CaosDB Project. # # Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> # Copyright (C) 2021 Timm Fitschen <t.fitschen@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/>. # from pytest import raises import caosdb as db def setup(): teardown_module() def teardown_module(): clean = db.execute_query("FIND Test*") if len(clean) > 0: clean.delete() def test_obl_missing_error(): p = db.Property(name="TestOblProperty", datatype=db.TEXT).insert() p_dummy = db.Property(name="TestDummyProperty", datatype=db.TEXT).insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty", importance=db.OBLIGATORY) rt1.insert() # normal behaviour, should be identical to "error" level rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestDummyProperty") with raises(db.TransactionError) as exc: rt2.insert() assert exc.value.errors[0].msg == "An obligatory property is missing." # force error rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestDummyProperty") rt2.set_flag("force-missing-obligatory", "error") with raises(db.TransactionError) as exc: rt2.insert() assert exc.value.errors[0].msg == "An obligatory property is missing." # warning is treated as error because "strict" flag rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestDummyProperty") rt2.set_flag("force-missing-obligatory", "warn") with raises(db.TransactionError) as exc: rt2.insert(strict=True) assert exc.value.errors[0].msg == ( "A warning occured while processing an entity with the strict flag.") assert "An obligatory property is missing." in [ w.description for w in rt2.get_warnings()] # insert with warning rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestDummyProperty") rt2.set_flag("force-missing-obligatory", "warn") rt2.insert() assert len(rt2.get_errors()) == 0 assert (rt2.get_warnings()[0].description == "An obligatory property is missing.") # insert silently rt3 = db.RecordType(name="TestRecordType3") rt3.add_parent("TestRecordType1", inheritance=db.NONE) rt3.add_property("TestDummyProperty") rt3.set_flag("force-missing-obligatory", "ignore") rt3.insert() assert len(rt3.get_errors()) == 0 assert len(rt3.get_warnings()) == 0 def test_obl_missing_parent_in_same_container(): p = db.Property(name="TestOblProperty", datatype=db.TEXT).insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty", importance=db.OBLIGATORY) rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) c = db.Container() c.extend([rt1, rt2]) with raises(db.TransactionError) as exc: c.insert() assert exc.value.errors[0].msg == "An obligatory property is missing." def test_obl_missing_parent_in_same_container_override(): """`force-missing-obligatory` flags of entities override flags of containing containers. """ p = db.Property(name="TestOblProperty", datatype=db.TEXT).insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty", importance=db.OBLIGATORY) rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.set_flag("force-missing-obligatory", "error") c = db.Container() c.extend([rt1, rt2]) with raises(db.TransactionError) as exc: c.insert(flags={"force-missing-obligatory": "ignore"}) assert exc.value.errors[0].msg == "An obligatory property is missing." def test_sub_property_of_obl(): """If p1 <|- p2, then p2 should work for an obligatory p1. """ p1 = db.Property(name="TestOblProperty1", datatype=db.TEXT).insert() p2 = db.Property(name="TestOblProperty2", datatype=db.TEXT) p2.add_parent("TestOblProperty1") p2.insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty1", importance=db.OBLIGATORY) rt1.insert() rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) # add subtype of TestOblProperty1 rt2.add_property("TestOblProperty2") rt2.insert() # everything ok! def test_sub_property_of_obl_in_same_container(): p1 = db.Property(name="TestOblProperty1", datatype=db.TEXT).insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty1", importance=db.OBLIGATORY) rt1.insert() p2 = db.Property(name="TestOblProperty2", datatype=db.TEXT) p2.add_parent("TestOblProperty1") rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestOblProperty2") c = db.Container() c.extend([rt2, p2]) c.insert() # everything ok! def test_illegal_flag_value(): p = db.Property(name="TestOblProperty", datatype=db.TEXT).insert() p_dummy = db.Property(name="TestDummyProperty", datatype=db.TEXT).insert() rt1 = db.RecordType(name="TestRecordType1") rt1.add_property(name="TestOblProperty", importance=db.OBLIGATORY) rt1.insert() rt2 = db.RecordType(name="TestRecordType2") rt2.add_parent("TestRecordType1", inheritance=db.NONE) rt2.add_property("TestDummyProperty") rt2.set_flag("force-missing-obligatory", "illegal!!!!") with raises(db.TransactionError) as exc: rt2.insert() # default behavior + warning assert exc.value.errors[0].msg == "An obligatory property is missing." assert "Illegal value for flag 'force-missing-obligatory'." in [ w.description for w in rt2.get_warnings()]