def _validate_options(data: Dict[str, Any]) -> Dict[str, Any]: """ Looks up the exporter_type from the data, selects the correct export options serializer based on the exporter_type and finally validates the data using that serializer. :param data: A dict of data to serialize using an exporter options serializer. :return: validated export options data """ option_serializers = table_exporter_registry.get_option_serializer_map() validated_exporter_type = validate_data(BaseExporterOptionsSerializer, data) serializer = option_serializers[validated_exporter_type["exporter_type"]] return validate_data(serializer, data)
def post(self, request, table_id): """ Creates a new row for the given table_id. Also the post data is validated according to the tables field types. """ table = TableHandler().get_table(table_id) TokenHandler().check_table_permissions(request, 'create', table, False) model = table.get_model() validation_serializer = get_row_serializer_class(model) data = validate_data(validation_serializer, request.data) before_id = request.GET.get('before') before = (RowHandler().get_row(request.user, table, before_id, model) if before_id else None) row = RowHandler().create_row(request.user, table, data, model, before=before) serializer_class = get_row_serializer_class(model, RowSerializer, is_response=True) serializer = serializer_class(row) return Response(serializer.data)
def patch(self, request, table_id, row_id): """ Updates the row with the given row_id for the table with the given table_id. Also the post data is validated according to the tables field types. """ table = TableHandler().get_table(request.user, table_id) TokenHandler().check_table_permissions(request, 'update', table, False) # Small side effect of generating the model for only the fields that need to # change is that the response it not going to contain the other fields. It is # however much faster because it doesn't need to get the specific version of # all the field objects. field_ids = RowHandler().extract_field_ids_from_dict(request.data) model = table.get_model(field_ids=field_ids) validation_serializer = get_row_serializer_class(model) data = validate_data(validation_serializer, request.data) row = RowHandler().update_row(request.user, table, row_id, data, model) serializer_class = get_row_serializer_class(model, RowSerializer, is_response=True) serializer = serializer_class(row) return Response(serializer.data)
def test_validate_data(): with pytest.raises(APIException) as api_exception_1: validate_data(TemporarySerializer, {'field_1': 'test'}) assert api_exception_1.value.detail[ 'error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert api_exception_1.value.detail['detail']['field_2'][0]['error'] == \ 'This field is required.' assert api_exception_1.value.detail['detail']['field_2'][0][ 'code'] == 'required' assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST with pytest.raises(APIException) as api_exception_2: validate_data(TemporarySerializer, { 'field_1': 'test', 'field_2': 'wrong' }) assert api_exception_2.value.detail[ 'error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert api_exception_2.value.detail['detail']['field_2'][0]['error'] == \ '"wrong" is not a valid choice.' assert api_exception_2.value.detail['detail']['field_2'][0]['code'] == \ 'invalid_choice' assert api_exception_2.value.status_code == status.HTTP_400_BAD_REQUEST validated_data = validate_data(TemporarySerializer, { 'field_1': 'test', 'field_2': 'choice_1' }) assert validated_data['field_1'] == 'test' assert validated_data['field_2'] == 'choice_1' assert len(validated_data.items()) == 2 with pytest.raises(APIException) as api_exception_1: validate_data(TemporarySerializerWithList, { 'field_3': 'aaa', 'field_4': ['a', 'b'] }) assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST assert api_exception_1.value.detail[ 'error'] == 'ERROR_REQUEST_BODY_VALIDATION' assert api_exception_1.value.detail['detail']['field_3'][0]['error'] == \ 'A valid integer is required.' assert api_exception_1.value.detail['detail']['field_3'][0][ 'code'] == 'invalid' assert len(api_exception_1.value.detail['detail']['field_4']) == 2 assert api_exception_1.value.detail['detail']['field_4'][0][0]['error'] == \ 'A valid integer is required.' assert api_exception_1.value.detail['detail']['field_4'][0][0]['code'] == \ 'invalid' assert api_exception_1.value.detail['detail']['field_4'][1][0]['error'] == \ 'A valid integer is required.' assert api_exception_1.value.detail['detail']['field_4'][1][0]['code'] == \ 'invalid'
def post(self, request, table_id): """ Creates a new row for the given table_id. Also the post data is validated according to the tables field types. """ table = TableHandler().get_table(request.user, table_id) model = table.get_model() validation_serializer = get_row_serializer_class(model) data = validate_data(validation_serializer, request.data) row = RowHandler().create_row(request.user, table, data, model) serializer_class = get_row_serializer_class(model, RowSerializer) serializer = serializer_class(row) return Response(serializer.data)
def patch(self, request, table_id, row_id): """ Updates the row with the given row_id for the table with the given table_id. Also the post data is validated according to the tables field types. """ table = TableHandler().get_table(table_id) TokenHandler().check_table_permissions(request, "update", table, False) field_ids = RowHandler().extract_field_ids_from_dict(request.data) model = table.get_model() validation_serializer = get_row_serializer_class(model, field_ids=field_ids) data = validate_data(validation_serializer, request.data) row = RowHandler().update_row(request.user, table, row_id, data, model) serializer_class = get_row_serializer_class( model, RowSerializer, is_response=True ) serializer = serializer_class(row) return Response(serializer.data)
def test_validate_data(): with pytest.raises(APIException) as api_exception_1: validate_data(TemporarySerializer, {"field_1": "test"}) assert api_exception_1.value.detail[ "error"] == "ERROR_REQUEST_BODY_VALIDATION" assert api_exception_1.value.detail["detail"]["field_2"][0]["error"] == ( "This field is required.") assert api_exception_1.value.detail["detail"]["field_2"][0][ "code"] == "required" assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST with pytest.raises(APIException) as api_exception_2: validate_data(TemporarySerializer, { "field_1": "test", "field_2": "wrong" }) assert api_exception_2.value.detail[ "error"] == "ERROR_REQUEST_BODY_VALIDATION" assert api_exception_2.value.detail["detail"]["field_2"][0]["error"] == ( '"wrong" is not a valid choice.') assert api_exception_2.value.detail["detail"]["field_2"][0]["code"] == ( "invalid_choice") assert api_exception_2.value.status_code == status.HTTP_400_BAD_REQUEST validated_data = validate_data(TemporarySerializer, { "field_1": "test", "field_2": "choice_1" }) assert validated_data["field_1"] == "test" assert validated_data["field_2"] == "choice_1" assert len(validated_data.items()) == 2 with pytest.raises(APIException) as api_exception_1: validate_data(TemporarySerializerWithList, { "field_3": "aaa", "field_4": ["a", "b"] }) assert api_exception_1.value.status_code == status.HTTP_400_BAD_REQUEST assert api_exception_1.value.detail[ "error"] == "ERROR_REQUEST_BODY_VALIDATION" assert api_exception_1.value.detail["detail"]["field_3"][0]["error"] == ( "A valid integer is required.") assert api_exception_1.value.detail["detail"]["field_3"][0][ "code"] == "invalid" assert len(api_exception_1.value.detail["detail"]["field_4"]) == 2 assert api_exception_1.value.detail["detail"]["field_4"][0][0][ "error"] == ("A valid integer is required.") assert api_exception_1.value.detail["detail"]["field_4"][0][0]["code"] == ( "invalid") assert api_exception_1.value.detail["detail"]["field_4"][1][0][ "error"] == ("A valid integer is required.") assert api_exception_1.value.detail["detail"]["field_4"][1][0]["code"] == ( "invalid") with pytest.raises(APIException) as api_exception_3: validate_data(TemporaryListSerializer, [{"something": "nothing"}]) assert api_exception_3.value.status_code == status.HTTP_400_BAD_REQUEST assert api_exception_3.value.detail[ "error"] == "ERROR_REQUEST_BODY_VALIDATION" assert len(api_exception_3.value.detail["detail"]) == 1 assert api_exception_3.value.detail["detail"][0]["field_1"][0][ "code"] == "required" assert api_exception_3.value.detail["detail"][0]["field_2"][0][ "code"] == "required"