diff --git a/src/server/BreCal/validators/input_validation_shipcall.py b/src/server/BreCal/validators/input_validation_shipcall.py index 729a896..59b8b35 100644 --- a/src/server/BreCal/validators/input_validation_shipcall.py +++ b/src/server/BreCal/validators/input_validation_shipcall.py @@ -123,6 +123,9 @@ class InputValidationShipcall(): # time values must use future-dates InputValidationShipcall.check_times_are_in_future(loadedModel, content) + # the type of a shipcall may not be changed. It can only be set with the initial POST-request. + InputValidationShipcall.check_shipcall_type_is_unchanged(loadedModel) + # some arguments must not be provided InputValidationShipcall.check_forbidden_arguments(content, forbidden_keys=forbidden_keys) return @@ -247,6 +250,16 @@ class InputValidationShipcall(): if not valid_participant_types: # #TODO: according to Daniel, there may eventually be multi-assignment of participants for the same role raise ValidationError(f"every participant id and type should be listed only once. Found multiple entries for one of the participants.") + @staticmethod + def check_shipcall_type_is_unchanged(loadedModel:dict): + # the type of a shipcall may only be set on POST requests. Afterwards, shipcall types may not be changed. + query = SQLQuery.get_shipcall_by_id() + shipcall = execute_sql_query_standalone(query=query, model=Shipcall, param={"id":loadedModel.get("id")}, command_type="single") + + if int(loadedModel["type"]) != int(shipcall.type): + raise ValidationError(f"The shipcall type may only be set in the initial POST-request. Afterwards, changing the shipcall type is not allowed.") # @pytest.raises + return + @staticmethod def check_forbidden_arguments(content:dict, forbidden_keys=["evaluation", "evaluation_message"]): """ diff --git a/src/server/tests/validators/test_input_validation_shipcall.py b/src/server/tests/validators/test_input_validation_shipcall.py index df41f1f..87b3b7f 100644 --- a/src/server/tests/validators/test_input_validation_shipcall.py +++ b/src/server/tests/validators/test_input_validation_shipcall.py @@ -901,3 +901,35 @@ def test_post_data_with_valid_data(get_stub_token): assert response.status_code==201 return +def test_input_validation_shipcall_put_fails_when_type_differs(): + from marshmallow import ValidationError + from BreCal.stubs.shipcall import get_stub_valid_shipcall_arrival + from BreCal.schemas import model + from BreCal.database.sql_queries import SQLQuery + from BreCal.database.sql_handler import execute_sql_query_standalone + + from BreCal.validators.input_validation_shipcall import InputValidationShipcall + + # stub data + put_data = get_stub_valid_shipcall_arrival() + put_data["id"] = 3 + loadedModel = model.ShipcallSchema().load(data=put_data, many=False, partial=True) + + # load data from DB + shipcall_id = loadedModel.get("id") + query = SQLQuery.get_shipcall_by_id() + shipcall = execute_sql_query_standalone(query=query, model=model.Shipcall, param={"id":shipcall_id}, command_type="single") + + # create failure case. Ensures that the type is not the same as in the loaded shipcall from the DB + failure_case = 1 if shipcall.type==2 else 2 + loadedModel["type"] = model.ShipcallType(failure_case) + + # should fail: different 'type' + with pytest.raises(ValidationError, match="The shipcall type may only be set in the initial POST-request. Afterwards, changing the shipcall type is not allowed"): + InputValidationShipcall.check_shipcall_type_is_unchanged(loadedModel) + + # should pass: same 'type' + loadedModel["type"] = shipcall.type + InputValidationShipcall.check_shipcall_type_is_unchanged(loadedModel) + return +