diff --git a/unittests/test_error_handling.py b/unittests/test_error_handling.py new file mode 100644 index 0000000000000000000000000000000000000000..7a6b415252d6719b603951c158fbe519c6ba018b --- /dev/null +++ b/unittests/test_error_handling.py @@ -0,0 +1,146 @@ +# -*- encoding: utf-8 -*- +# +# ** header v3.0 +# This file is a part of the CaosDB Project. +# +# Copyright (C) 2020 Indiscale GmbH <info@indiscale.com> +# Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@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/>. +# +# ** end header +# +"""Test the new (as of June 2020) error handling. All errors should +be TransactionErrors at first which may have one or more level of +children. + +""" +import caosdb as db +from caosdb.common.models import raise_errors +# TODO: Import the relevant error classes once they have been finalized. +from caosdb.exceptions import (EntityDoesNotExistError, + EntityHasNoDatatypeError, + TransactionError) + +from pytest import raises + + +# #################### Single Error Tests #################### + + +def _add_error_message_to_entity(entity, code, description="Error message"): + """Attach error message with code and description to entity""" + message = db.Message(type="Error", code=code, + description=description) + entity.add_message(message) + + return enetity + + +def test_has_no_datatype_error(): + """Code 110; property without datatype""" + code = 110 + prop = _add_error_message_to_entity(db.Property(name="TestProp"), + code) + with raises(TransactionError) as e: + raise_errors(prop) + # There should be exactly one child + assert len(e.errors) == 1 + err = e.errors[0] + # check type and entity of only child + assert isinstance(err, EntityHasNoDatatypeError) + assert err.entity.name == prop.name + + +def test_entity_does_not_exist_error(): + """Code 101; entity does not exist""" + code = 101 + ent = _add_error_message_to_entity(db.Entity(name="TestEnt"), + code) + + db.Property(name="TestProp"), + code) + with raises(TransactionError) as e: + raise_errors(ent) + # There should be exactly one child + assert len(e.errors) == 1 + err = e.errors[0] + # check type and entity of only child + assert isinstance(err, EntityDoesNotExistError) + assert err.entity.name == ent.name + +# TODO: remaining single error tests +def test_entity_error(): + """Code 0; most basic.""" + + +def test_unique_names_error(): + """Code 152; name is not unique""" + + +def test_authorization_exception(): + """Code 403; transaction not allowed""" + + +# #################### Children with children #################### + + +def test_unqualified_parents_error(): + """Code 116; parent does not exist""" + code = 116 + entity_does_not_exist_code = 101 + parent = _add_error_message_to_entity( + db.RecordType(name="TestParent"), + entity_does_not_exist_code) + rec = _add_error_message_to_entity(db.Record(name="TestRecord"), + code) + rec.add_parent(parent) + with raises(TransactionError) as e: + raise_errors(rec) + # TODO: Both direct and indirect children should be in the errors + # list, the only direct child is the UnqualifiedParentsError with + # entity rec and one child of its own; the EntityDoesNotExistError + # with entity parent. + + +def test_unqualified_properties_error(): + """Code 114; properties do not exist or have wrong data types or + values. + + """ + code = 114 + # TODO: One record with two properties; one doesn't exist (code + # 101), the other has a wrong value (EntityError, code 0). Then + # check whether all levels are in order. + + +# #################### Multiple errors #################### + + +def test_parent_and_properties_errors(): + """Record with UnqualifiedParentsError and UnqualifiedPropertiesError, + and corresponding parent and properties with their errors as + above. Test whether all levels are in order. + + """ + # TODO: record with code 114 and 116, properties with 101 and 0, + # parent with 101 + + +def test_container_with_faulty_elements(): + """Container with valid and invalid entities. All faulty entities have + to be reflected correctly in the errors list of the + TransactionError raised by the container. + + """