From 6c529b25fffdef1a3171ad74c36064a8b31c0413 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Mon, 21 Jan 2019 13:51:03 +0545 Subject: [PATCH 1/6] - Validator Base creation --- core/validator/build.gradle | 5 + .../nubeiot/core/validator/Validation.java | 103 ++++++++++++ .../core/validator/ValidationResult.java | 49 ++++++ .../core/validator/ValidationSupplier.java | 9 + .../core/validator/enums/ValidationState.java | 5 + .../validator/validations/Alternative.java | 40 +++++ .../core/validator/validations/Any.java | 24 +++ .../validator/validations/Composition.java | 44 +++++ .../core/validator/validations/Dbl.java | 26 +++ .../core/validator/validations/Exist.java | 29 ++++ .../core/validator/validations/Forbidden.java | 28 +++ .../core/validator/validations/Int.java | 26 +++ .../core/validator/validations/Items.java | 42 +++++ .../core/validator/validations/JArray.java | 27 +++ .../core/validator/validations/JObject.java | 27 +++ .../core/validator/validations/KeyLoop.java | 32 ++++ .../core/validator/validations/Loop.java | 40 +++++ .../core/validator/validations/Max.java | 40 +++++ .../core/validator/validations/Min.java | 23 +++ .../core/validator/validations/Numeric.java | 24 +++ .../validations/NumericOrString.java | 23 +++ .../core/validator/validations/Ptrn.java | 35 ++++ .../core/validator/validations/Range.java | 38 +++++ .../core/validator/validations/Required.java | 32 ++++ .../core/validator/validations/Str.java | 26 +++ .../core/validator/validations/When.java | 47 ++++++ .../core/validator/ValidationResultTest.java | 28 +++ .../core/validator/ValidationTest.java | 159 ++++++++++++++++++ .../validations/AlternativeTest.java | 40 +++++ .../core/validator/validations/AnyTest.java | 15 ++ .../validations/CompositionTest.java | 39 +++++ .../core/validator/validations/DblTest.java | 23 +++ .../core/validator/validations/ExistTest.java | 28 +++ .../validator/validations/ForbiddenTest.java | 15 ++ .../core/validator/validations/IntTest.java | 23 +++ .../core/validator/validations/ItemsTest.java | 41 +++++ .../validator/validations/JArrayTest.java | 35 ++++ .../validator/validations/JObjectTest.java | 31 ++++ .../core/validator/validations/MaxTest.java | 23 +++ .../validations/MinValidationTest.java | 23 +++ .../validations/NumericOrStringTest.java | 34 ++++ .../validator/validations/NumericTest.java | 32 ++++ .../core/validator/validations/PtrnTest.java | 21 +++ .../core/validator/validations/RangeTest.java | 36 ++++ .../validator/validations/RequiredTest.java | 30 ++++ .../core/validator/validations/StrTest.java | 21 +++ .../core/validator/validations/WhenTest.java | 58 +++++++ .../validator/src/test/resources/example.json | 28 +++ settings.gradle | 1 + 49 files changed, 1628 insertions(+) create mode 100644 core/validator/build.gradle create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/Validation.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java create mode 100644 core/validator/src/test/resources/example.json diff --git a/core/validator/build.gradle b/core/validator/build.gradle new file mode 100644 index 000000000..9ded852ab --- /dev/null +++ b/core/validator/build.gradle @@ -0,0 +1,5 @@ +dependencies { + compile project(':core:base') + + testCompile project(':core:base').sourceSets.test.output +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java new file mode 100644 index 000000000..2d14f5257 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java @@ -0,0 +1,103 @@ +package com.nubeiot.core.validator; + +import com.nubeiot.core.utils.Strings; + +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; + +public abstract class Validation { + + protected String parentField = ""; + protected String field = ""; + protected Object defaultValue = null; + protected String errorType = "ValidationError"; + + public abstract Single> validate(T s); + + protected abstract String getErrorMessage(); + + public Validation registerField(String field) { + this.field = field; + return this; + } + + public Validation registerParentField(String parentField) { + this.parentField = parentField; + return this; + } + + public Validation registerDefaultValue(Object defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + /** + * @param jsonObject : JSON object to be passed to extract value + * @param field : JSON field on String format like "thing.features.points.UI1.value" + * @return : Resulted value on ValidationResult form + *

+ * Basically this will works as a mediator for parsing JSON value and sending it to actual business logic of + * validation + */ + public final Single> validate(JsonObject jsonObject, String field) { + this.field = field; + if (Strings.isBlank(field)) { + return validate((T) jsonObject); + } + + T value; + String[] fields = field.split("\\."); + + JsonObject object = jsonObject; + try { + for (int i = 0; i < fields.length - 1; i++) { + if (object.getJsonObject(fields[i]) == null && this.defaultValue != null) { + object.put(fields[i], new JsonObject()); + } + object = object.getJsonObject(fields[i]); + } + } catch (NullPointerException ignored) { + } + value = (T) object.getValue(fields[fields.length - 1]); + + if (value == null) { + if (this.defaultValue != null) { + object.put(fields[fields.length - 1], defaultValue); + } + + if (this.passNullCase()) { + return new ValidationResult().asyncSuccess(); + } + } + + return validate(value); + } + + protected boolean passNullCase() { + return true; + } + + public final Single> validate(Object s, String parentField, String field) { + this.field = field; + this.parentField = parentField; + + if (s instanceof JsonObject) { + return validate((JsonObject) s, field); + } + + if (this.passNullCase() && s == null) { + return new ValidationResult().asyncSuccess(); + } + + return validate((T) s); + } + + protected final String getAbsoluteField() { + if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) { + return parentField + "." + this.field; + } else { + return this.parentField + this.field; + } + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java new file mode 100644 index 000000000..62b228f50 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java @@ -0,0 +1,49 @@ +package com.nubeiot.core.validator; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.enums.ValidationState; + +import io.reactivex.Single; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ValidationResult { + + private ValidationState validity; + private String reason; + private T data; + + public ValidationResult success(T data) { + this.validity = ValidationState.VALID; + this.reason = null; + this.data = data; + return this; + } + + public ValidationResult success() { + return success(null); + } + + public NubeException invalid(String reason) { + return new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason); + } + + public Single> asyncSuccess(T data) { + return Single.just(success(data)); + } + + public Single> asyncSuccess() { + return Single.just(success()); + } + + public Single> asyncInvalid(String reason) { + return Single.error(new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason)); + } + + public Single> asyncInvalid(NubeException.ErrorCode errorCode, String reason) { + return Single.error(new NubeException(errorCode, reason)); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java new file mode 100644 index 000000000..d092d5d8a --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java @@ -0,0 +1,9 @@ +package com.nubeiot.core.validator; + +import io.reactivex.Single; + +public interface ValidationSupplier { + + Single> get(T s, String parentField); + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java b/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java new file mode 100644 index 000000000..a3dab4a45 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java @@ -0,0 +1,5 @@ +package com.nubeiot.core.validator.enums; + +public enum ValidationState { + VALID, INVALID +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java new file mode 100644 index 000000000..1b80e679a --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java @@ -0,0 +1,40 @@ +package com.nubeiot.core.validator.validations; + +import java.util.ArrayList; +import java.util.List; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Alternative extends Validation { + + private final List> validations; + + @Override + public Single> validate(T s) { + final List exception = new ArrayList<>(); + return Single.create(source -> { + for (Validation validation : validations) { + + validation.registerField(field).registerParentField(parentField).validate(s) + .subscribe(validationResult -> source.onSuccess((ValidationResult) validationResult), + error -> exception.add((NubeException) error)); + } + + if (exception.size() == validations.size()) { + source.onError(exception.get(0)); + } + }); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java new file mode 100644 index 000000000..af6d1dd14 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java @@ -0,0 +1,24 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; + +public class Any extends Validation { + + public Single> validate() { + return this.validate(null); + } + + @Override + public Single> validate(Object s) { + return new ValidationResult<>().asyncSuccess(); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java new file mode 100644 index 000000000..e1f6fa7b8 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java @@ -0,0 +1,44 @@ +package com.nubeiot.core.validator.validations; + +import java.util.ArrayList; +import java.util.List; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Observable; +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Composition extends Validation> { + + private final List> validations; + + @Override + public Single>> validate(T s) { + + return Observable.fromIterable(validations) + .flatMapSingle( + validation -> validation.registerField(field).registerParentField(parentField).validate(s)) + .toList() + .map(outputs -> { + List list = new ArrayList<>(); + for (ValidationResult output : outputs) { + list.add(output.getData()); + } + return new ValidationResult>().success(list); + }); + } + + @Override + protected boolean passNullCase() { + return false; + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java new file mode 100644 index 000000000..037e717e1 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java @@ -0,0 +1,26 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class Dbl extends Validation { + + @Override + public Single> validate(T s) { + if (s instanceof Double) { + return new ValidationResult().asyncSuccess((Double) s); + } + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not the type of Double", errorType, getAbsoluteField()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java new file mode 100644 index 000000000..3e0c96f6d --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java @@ -0,0 +1,29 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; + +public class Exist extends Validation { + + @Override + public Single> validate(T s) { + if (s != null) { + return new ValidationResult<>().asyncSuccess(); + } + return new ValidationResult<>().asyncInvalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is required", errorType, getAbsoluteField()); + } + + @Override + protected boolean passNullCase() { + return false; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java new file mode 100644 index 000000000..f6b7770e4 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java @@ -0,0 +1,28 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; + +public class Forbidden extends Validation { + + public static String FORBIDDEN_MESSAGE = "Forbidden: you are not authorized to post this value"; + + public Single> validate() { + return this.validate(null); + } + + @Override + public Single> validate(T s) { + return new ValidationResult<>().asyncInvalid(NubeException.ErrorCode.INSUFFICIENT_PERMISSION_ERROR, + getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return FORBIDDEN_MESSAGE; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java new file mode 100644 index 000000000..e71ead87a --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java @@ -0,0 +1,26 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class Int extends Validation { + + @Override + public Single> validate(T s) { + if (s instanceof Integer) { + return new ValidationResult().asyncSuccess((Integer) s); + } + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + public String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not the type of Integer", errorType, getAbsoluteField()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java new file mode 100644 index 000000000..51a7497f6 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java @@ -0,0 +1,42 @@ +package com.nubeiot.core.validator.validations; + +import java.util.List; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Items extends Validation { + + private final List items; + + @Override + public Single> validate(T s) { + boolean contains = true; + if (s instanceof JsonArray) { + for (Object o : (JsonArray) s) { + if (!items.contains(o)) { + contains = false; + break; + } + } + } else { + contains = items.contains(s); + } + return contains + ? new ValidationResult().asyncSuccess(s) + : new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value does not fall on the items {2}", errorType, getAbsoluteField(), + items); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java new file mode 100644 index 000000000..22248b6c3 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java @@ -0,0 +1,27 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class JArray extends Validation { + + @Override + public Single> validate(T s) { + if (s instanceof JsonArray) { + return new ValidationResult().asyncSuccess((JsonArray) s); + } + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not the type of JsonArray", errorType, getAbsoluteField()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java new file mode 100644 index 000000000..82ceb9567 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java @@ -0,0 +1,27 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class JObject extends Validation { + + @Override + public Single> validate(T s) { + if (s instanceof JsonObject) { + return new ValidationResult().asyncSuccess((JsonObject) s); + } + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not the type of JsonObject", errorType, getAbsoluteField()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java new file mode 100644 index 000000000..32f44fde9 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java @@ -0,0 +1,32 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.ValidationSupplier; + +import io.reactivex.Observable; +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class KeyLoop extends Validation { + + private final ValidationSupplier supplier; + private final String parentField; + + @Override + public Single> validate(JsonObject s) { + + return Observable.fromIterable(s) + .flatMapSingle(o -> supplier.get(o.getValue(), parentField + "." + o.getKey())) + .toList() + .flatMap(r -> new ValidationResult().asyncSuccess(s)); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java new file mode 100644 index 000000000..9660c3bf9 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java @@ -0,0 +1,40 @@ +package com.nubeiot.core.validator.validations; + +import java.util.ArrayList; +import java.util.List; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.ValidationSupplier; + +import io.reactivex.Observable; +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Loop extends Validation { + + private final ValidationSupplier supplier; + private final String parentField; + + @Override + public Single> validate(JsonArray s) { + final List objects = new ArrayList<>(); + // When isRequired is false then parsed JsonArray value will be of size 0 + if (s.size() == 0) { + return new ValidationResult().asyncSuccess(s); + } + return Observable.fromIterable(s).flatMapSingle(o -> { + Single> output = supplier.get(o, this.parentField + "[" + objects.size() + "]"); + objects.add(o); + return output; + }).toList().flatMap(r -> new ValidationResult().asyncSuccess(s)); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java new file mode 100644 index 000000000..4671a019e --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java @@ -0,0 +1,40 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Max extends Validation { + + private final Double value; + + @Override + public Single> validate(T s) { + if (s instanceof Double || s instanceof Integer || s instanceof Long || s instanceof Float) { + Double d = Double.parseDouble(s.toString()); + if (condition(d)) { + return new ValidationResult().asyncSuccess(d); + } else { + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + } else { + return new ValidationResult().asyncInvalid( + Strings.format("ClassCastException: \"{0}\" field value is not parsable to Number", + getAbsoluteField())); + } + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not less than {2}", errorType, getAbsoluteField(), value); + } + + protected boolean condition(Double d) { + return value >= d; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java new file mode 100644 index 000000000..115cf02a3 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java @@ -0,0 +1,23 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; + +public class Min extends Max { + + private final Double value; + + public Min(Double value) { + super(value); + this.value = value; + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not greater than {2}", errorType, getAbsoluteField(), value); + } + + protected boolean condition(Double d) { + return value <= d; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java new file mode 100644 index 000000000..53329189d --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java @@ -0,0 +1,24 @@ +package com.nubeiot.core.validator.validations; + +import java.util.Arrays; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; + +public class Numeric extends Validation { + + @Override + public Single> validate(T s) { + return new Alternative<>(Arrays.asList(new Int<>(), new Dbl<>())).registerField(field) + .registerParentField(parentField) + .validate(s); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java new file mode 100644 index 000000000..9250f6078 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java @@ -0,0 +1,23 @@ +package com.nubeiot.core.validator.validations; + +import java.util.Arrays; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; + +public class NumericOrString extends Validation { + + @Override + public Single> validate(T s) { + return new Alternative<>(Arrays.asList(new Int<>(), new Dbl<>(), new Str<>())).registerField( + field).registerParentField(parentField).validate(s); + } + + @Override + protected String getErrorMessage() { + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java new file mode 100644 index 000000000..f885dcadb --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java @@ -0,0 +1,35 @@ +package com.nubeiot.core.validator.validations; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Ptrn extends Validation { + + private final String regex; + + @Override + public Single> validate(String s) { + Pattern pattern = java.util.regex.Pattern.compile(regex); + Matcher matcher = pattern.matcher(s); + boolean isValid = matcher.matches(); + + return isValid + ? new ValidationResult().asyncSuccess((s)) + : new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + public String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value does not match with the pattern \"{2}\"", errorType, + getAbsoluteField(), regex); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java new file mode 100644 index 000000000..86bce199d --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java @@ -0,0 +1,38 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Range extends Validation { + + private final Double minValue; + private final Double maxValue; + + @Override + public Single> validate(T s) { + if (s instanceof Double || s instanceof Integer || s instanceof Long || s instanceof Float) { + Double d = Double.parseDouble(s.toString()); + if (minValue <= d && d <= maxValue) { + return new ValidationResult().asyncSuccess(d); + } else { + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + } else { + return new ValidationResult().asyncInvalid( + Strings.format("ClassCastException: \"{0}\" field value is not parsable to Number", + getAbsoluteField())); + } + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value should be on range {2}-{3}", errorType, getAbsoluteField(), + minValue, maxValue); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java new file mode 100644 index 000000000..ece87df62 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java @@ -0,0 +1,32 @@ +package com.nubeiot.core.validator.validations; + +import java.util.Arrays; +import java.util.List; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Required extends Validation> { + + private final Validation validation; + + @Override + public Single>> validate(T s) { + return new Composition<>(Arrays.asList(validation, new Exist<>())).registerParentField( + parentField).registerField(field).validate(s); + } + + @Override + protected String getErrorMessage() { + return null; + } + + protected boolean passNullCase() { + return false; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java new file mode 100644 index 000000000..a2b34c03e --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java @@ -0,0 +1,26 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Str extends Validation { + + @Override + public Single> validate(T s) { + if (s instanceof String) { + return new ValidationResult().asyncSuccess((String) s); + } + return new ValidationResult().asyncInvalid(getErrorMessage()); + } + + @Override + public String getErrorMessage() { + return Strings.format("{0}: \"{1}\" field value is not the type of String", errorType, getAbsoluteField()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java new file mode 100644 index 000000000..ccd5babdc --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java @@ -0,0 +1,47 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class When>> extends Validation { + + private Single> is; + private Single> then; + private T otherwise; + + public Single> validate() { + return this.validate(null); + } + + @Override + public Single> validate(T s) { + return Single.create( + source -> this.is.subscribe(ignored -> this.then.subscribe(source::onSuccess, source::onError), + error -> otherwise.subscribe(source::onSuccess, source::onError))); + } + + @Override + protected String getErrorMessage() { + return null; + } + + public When registerIs(Single> is) { + this.is = is; + return this; + } + + public When registerThen(Single> then) { + this.then = then; + return this; + } + + public When registerOtherwise(T otherwise) { + this.otherwise = otherwise; + return this; + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java new file mode 100644 index 000000000..fce3b03b6 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java @@ -0,0 +1,28 @@ +package core.nubeiot.core.validator; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.enums.ValidationState; + +public class ValidationResultTest { + + @Test + public void test_success() { + String output = "succeeded"; + ValidationResult validationResult = new ValidationResult().success(output); + Assert.assertEquals(validationResult.getData(), output); + Assert.assertEquals(validationResult.getValidity(), ValidationState.VALID); + Assert.assertNull(validationResult.getReason()); + } + + @Test + public void test_invalid() { + String reason = "invalid"; + NubeException nubeException = new ValidationResult().invalid(reason); + Assert.assertEquals(nubeException.getMessage(), reason); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java new file mode 100644 index 000000000..aa6c603d3 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java @@ -0,0 +1,159 @@ +package core.nubeiot.core.validator; + +import java.net.URL; +import java.util.Arrays; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.utils.FileUtils; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.ValidationSupplier; +import com.nubeiot.core.validator.validations.Composition; +import com.nubeiot.core.validator.validations.Exist; +import com.nubeiot.core.validator.validations.Int; +import com.nubeiot.core.validator.validations.JArray; +import com.nubeiot.core.validator.validations.JObject; +import com.nubeiot.core.validator.validations.KeyLoop; +import com.nubeiot.core.validator.validations.Loop; +import com.nubeiot.core.validator.validations.Str; + +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; +import lombok.NoArgsConstructor; + +public class ValidationTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(ValidationTest.class); + + private JsonObject object = new JsonObject().put("first_name", "Binod") + .put("last_name", "Rai") + .put("details", new JsonObject().put("age", 26.2)); + + @Test + public void test_fieldDoesNotExistWhenIsRequiredTrue() { + Validation sv = new Str<>(); + Validation iv = new Int<>(); + Validation ev = new Exist<>(); + + sv.validate(object, "first_name") + .flatMap(ignore -> sv.validate(object, "last_name")) + .flatMap(ignore -> new Composition<>(Arrays.asList(iv, ev)).validate(object, "details.xyz")) + .test() + .assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + + @Test + public void test_noErrorOnNonExistingValueWhenIsRequireFalse() { + Validation sv = new Str<>(); + Validation iv = new Int<>(); + + sv.validate(object, "first_name") + .flatMap(ignore -> sv.validate(object, "last_name")) + .flatMap(ignore -> iv.validate(object, "details.xyz")) + .test() + .assertValue(value -> true); + } + + @Test + public void test_integerValidation() { + + Validation sv = new Str<>(); + Validation iv = new Int<>(); + + sv.validate(object, "first_nam") + .flatMap(ignore -> sv.validate(object, "last_name")) + .flatMap(ignore -> iv.validate(object, "details.age")) + .test() + .assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + + @Test + public void test_arrayValidationWithSupplier() { + @NoArgsConstructor + class FirstLayerObjectValidation implements ValidationSupplier { + + private Validation sv = new Str<>(); + private Validation av = new JArray<>(); + private Loop lvS = new Loop(new SiblingValidation<>(), "siblings"); + private Loop lvI = new Loop(new InterestValidation<>(), "details.basic.interests"); + + @Override + public Single> get(T s, String parentField) { + return sv.validate(s, parentField, "first_name") + .flatMap(ignore -> sv.validate(s, parentField, "last_name")) + .flatMap(ignore -> av.registerDefaultValue(Arrays.asList("Binod", "Roshan", "Bhushan")) + .validate(s, parentField, "siblings")) + .flatMap(siblings -> lvS.validate(siblings.getData(), parentField, "siblings")) + .flatMap(ignore -> av.validate(s, parentField, "details.basic.interests")) + .flatMap(interests -> lvI.validate(interests.getData(), parentField, "")); + } + + class SiblingValidation implements ValidationSupplier { + + private Validation sv = new Str<>(); + + @Override + public Single> get(U s, String parentField) { + return sv.registerParentField(parentField).validate(s).map(x -> x); + } + + } + + + class InterestValidation implements ValidationSupplier { + + private Validation jov = new JObject<>(); + + @Override + public Single> get(U s, String parentField) { + return jov.validate(s, parentField, "").flatMap(vrInterest -> { + Validation lvI = new KeyLoop(new InterestObjectValidation<>(), parentField); + JsonObject interest = ((JsonObject) vrInterest.getData()); + return lvI.registerParentField(parentField).validate(interest); + }); + } + + class InterestObjectValidation implements ValidationSupplier { + + private Validation sv = new Str<>(); + + @Override + public Single> get(V s, String parentField) { + return sv.validate(s, parentField, "").map(x -> x); + } + + } + + } + + } + + URL resource = ValidationTest.class.getClassLoader().getResource("example.json"); + Object object = new JsonArray(FileUtils.readFileToString(resource.toString())); + + Validation av = new JArray<>(); + Validation lv = new Loop(new FirstLayerObjectValidation<>(), ""); + + av.validate(object) + .flatMap(vrArray -> { + JsonArray array = (JsonArray) vrArray.getData(); + return lv.validate(array); + }).test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + +} + diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java new file mode 100644 index 000000000..915b7e544 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java @@ -0,0 +1,40 @@ +package core.nubeiot.core.validator.validations; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Alternative; +import com.nubeiot.core.validator.validations.Dbl; +import com.nubeiot.core.validator.validations.Str; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class AlternativeTest { + + private static final Logger logger = LoggerFactory.getLogger(AlternativeTest.class); + + @Test + public void test_alternative() { + JsonObject jsonObject = new JsonObject().put("a", "10"); + JsonObject jsonObject1 = new JsonObject().put("a", 10d); + JsonObject jsonObject2 = new JsonObject().put("a", 10); + + List> validations = new ArrayList<>(); + validations.add(new Dbl<>()); + validations.add(new Str<>()); + + Validation validation = new Alternative<>(validations); + validation.validate(jsonObject, "a").test().assertValue(value -> value.getData().equals("10")); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData().equals(10d)); + validation.validate(jsonObject2, "a").test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java new file mode 100644 index 000000000..0e88088d3 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java @@ -0,0 +1,15 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.validations.Any; + +public class AnyTest { + + @Test + public void test_anyValidation() { + new Any().validate(null).test().assertValue(v -> true); + new Any().validate("XYZ").test().assertValue(v -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java new file mode 100644 index 000000000..2094cc2f9 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java @@ -0,0 +1,39 @@ +package core.nubeiot.core.validator.validations; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Composition; +import com.nubeiot.core.validator.validations.Dbl; +import com.nubeiot.core.validator.validations.Max; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class CompositionTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(CompositionTest.class); + + @Test + public void test_composition() { + JsonObject jsonObject = new JsonObject().put("a", 10.00d); + JsonObject jsonObject1 = new JsonObject().put("a", 10); + + List> validations = new ArrayList<>(); + validations.add(new Dbl<>()); + validations.add(new Max<>(10d)); + + Validation> validation = new Composition<>(validations); + validation.validate(jsonObject, "a").test().assertValue(output -> true); + validation.validate(jsonObject1, "a").test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java new file mode 100644 index 000000000..e6848f631 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java @@ -0,0 +1,23 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Dbl; + +import io.vertx.core.json.JsonObject; + +public class DblTest { + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1.000); + JsonObject jsonObject1 = new JsonObject().put("a", 1); + JsonObject jsonObject2 = new JsonObject().put("a", 1d); + Validation validation = new Dbl<>(); + validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 1d); + validation.validate(jsonObject1, "a").test().assertError(error -> true); + validation.validate(jsonObject2, "a").test().assertValue(value -> value.getData() == 1d); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java new file mode 100644 index 000000000..ad95b1c05 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java @@ -0,0 +1,28 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Exist; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class ExistTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); + + @Test + public void test_existValidation() { + JsonObject jsonObject = new JsonObject().put("a", 1); + Validation validation = new Exist(); + validation.validate(jsonObject, "a").test().assertValue(v -> true); + validation.validate(jsonObject, "b").test().assertError(e -> { + logger.error(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java new file mode 100644 index 000000000..821a371b0 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java @@ -0,0 +1,15 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.validations.Forbidden; + +public class ForbiddenTest { + + @Test + public void test_anyValidation() { + new Forbidden<>().validate(null).test().assertError(v -> v.getMessage().equals(Forbidden.FORBIDDEN_MESSAGE)); + new Forbidden<>().validate("XYZ").test().assertError(v -> v.getMessage().equals(Forbidden.FORBIDDEN_MESSAGE)); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java new file mode 100644 index 000000000..d6c4aef74 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java @@ -0,0 +1,23 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Int; + +import io.vertx.core.json.JsonObject; + +public class IntTest { + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1.1); + JsonObject jsonObject1 = new JsonObject().put("a", 1); + JsonObject jsonObject2 = new JsonObject().put("a", "1"); + Validation validation = new Int<>(); + validation.validate(jsonObject, "a").test().assertError(error -> true); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 1); + validation.validate(jsonObject2, "a").test().assertError(error -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java new file mode 100644 index 000000000..6eb653650 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java @@ -0,0 +1,41 @@ +package core.nubeiot.core.validator.validations; + +import java.util.Arrays; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Items; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class ItemsTest { + + private static final Logger logger = LoggerFactory.getLogger(ItemsTest.class); + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", Arrays.asList(1, 6)); + JsonObject jsonObject1 = new JsonObject().put("a", new JsonArray().add(1).add(2)); + JsonObject jsonObject2 = new JsonObject().put("a", 1); + Validation validation = new Items<>(Arrays.asList(1, 2, 3, 4, 5)); + validation.validate(jsonObject, "a").test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + + validation.validate(jsonObject1, "a").test().assertValue(value -> { + logger.info(value.getData()); + return true; + }); + + validation.validate(jsonObject2, "a").test().assertValue(value -> { + logger.info(value.getData()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java new file mode 100644 index 000000000..4298c89c2 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java @@ -0,0 +1,35 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.JArray; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class JArrayTest { + + private static final Logger logger = LoggerFactory.getLogger(JArrayTest.class); + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1); + JsonObject jsonObject2 = new JsonObject().put("a", new JsonArray().add(1).add(2).add(3)); + JsonArray jsonArray = new JsonArray().add(1).add(2).add(3); + Validation validation = new JArray<>(); + + validation.validate(jsonObject, "a").test().assertError(error -> true); + validation.validate(jsonObject2, "a").test().assertValue(value -> { + logger.info(value.getData()); + return true; + }); + validation.validate(jsonArray).test().assertValue(value -> { + logger.info(value.getData()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java new file mode 100644 index 000000000..f353de8ac --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java @@ -0,0 +1,31 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.JObject; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class JObjectTest { + + private static final Logger logger = LoggerFactory.getLogger(JObjectTest.class); + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", new JsonObject().put("result", "success")); + JsonObject jsonObject1 = new JsonObject().put("a", new JsonArray().add(1).add(2).add(3)); + + Validation validation = new JObject<>(); + + validation.validate(jsonObject, "a").test().assertValue(value -> { + logger.info(value.getData()); + return true; + }); + validation.validate(jsonObject1, "a").test().assertError(error -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java new file mode 100644 index 000000000..3321695af --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java @@ -0,0 +1,23 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Max; + +import io.vertx.core.json.JsonObject; + +public class MaxTest { + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 10.000); + JsonObject jsonObject1 = new JsonObject().put("a", 10); + JsonObject jsonObject2 = new JsonObject().put("a", 40d); + Validation validation = new Max<>(15d); + validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject2, "a").test().assertError(error -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java new file mode 100644 index 000000000..4526b9e74 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java @@ -0,0 +1,23 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Min; + +import io.vertx.core.json.JsonObject; + +public class MinValidationTest { + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 10.000); + JsonObject jsonObject1 = new JsonObject().put("a", 10); + JsonObject jsonObject2 = new JsonObject().put("a", 4d); + Validation validation = new Min<>(5d); + validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject2, "a").test().assertError(error -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java new file mode 100644 index 000000000..196f25163 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java @@ -0,0 +1,34 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.NumericOrString; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class NumericOrStringTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1); + JsonObject jsonObject2 = new JsonObject().put("a", 1.0); + JsonObject jsonObject3 = new JsonObject().put("a", "1"); + JsonObject jsonObject4 = new JsonObject().put("a", new JsonObject()); + Validation validation = new NumericOrString<>(); + + validation.validate(jsonObject, "a").test().assertValue(v -> true); + validation.validate(jsonObject2, "a").test().assertValue(v -> true); + validation.validate(jsonObject3, "a").test().assertValue(v -> true); + validation.validate(jsonObject4, "a").test().assertError(e -> { + logger.error(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java new file mode 100644 index 000000000..3b1544979 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java @@ -0,0 +1,32 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Numeric; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class NumericTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(NumericTest.class); + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1); + JsonObject jsonObject2 = new JsonObject().put("a", 1.0); + JsonObject jsonObject3 = new JsonObject().put("a", "1"); + Validation validation = new Numeric<>(); + + validation.validate(jsonObject, "a").test().assertValue(v -> true); + validation.validate(jsonObject2, "a").test().assertValue(v -> true); + validation.validate(jsonObject3, "a").test().assertError(e -> { + logger.error(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java new file mode 100644 index 000000000..06b3886be --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java @@ -0,0 +1,21 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Ptrn; + +import io.vertx.core.json.JsonObject; + +public class PtrnTest { + + @Test + public void test_validate() { + JsonObject object = new JsonObject().put("a", "0123456"); + JsonObject object1 = new JsonObject().put("a", "012ABC"); + Validation validation = new Ptrn("[0-9]+"); + validation.validate(object, "a").test().assertValue(ignore -> true); + validation.validate(object1, "a").test().assertError(ignore -> true); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java new file mode 100644 index 000000000..a4d0ae463 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java @@ -0,0 +1,36 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Range; + +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class RangeTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); + + @Test + public void test_rangeValidate() { + JsonObject jsonObject = new JsonObject().put("a", 10.000); + JsonObject jsonObject1 = new JsonObject().put("a", 10); + JsonObject jsonObject2 = new JsonObject().put("a", 4.0); + JsonObject jsonObject3 = new JsonObject().put("a", "4d"); + Validation validation = new Range<>(5d, 15d); + validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); + validation.validate(jsonObject2, "a").test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + validation.validate(jsonObject3, "a").test().assertError(error -> { + logger.error(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java new file mode 100644 index 000000000..8974646e7 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java @@ -0,0 +1,30 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.TestBase; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Int; +import com.nubeiot.core.validator.validations.Required; + +import core.nubeiot.core.validator.ValidationTest; +import io.vertx.core.json.JsonObject; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; + +public class RequiredTest extends TestBase { + + private static final Logger logger = LoggerFactory.getLogger(ValidationTest.class); + + @Test + public void test_validateRequired() { + JsonObject jsonObject = new JsonObject().put("a", 1); + Validation validation = new Required<>(new Int<>()); + validation.validate(jsonObject, "a").test().assertValue(v -> true); + validation.validate(jsonObject, "b").test().assertError(e -> { + logger.error(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java new file mode 100644 index 000000000..6bf6c7fb4 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java @@ -0,0 +1,21 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Str; + +import io.vertx.core.json.JsonObject; + +public class StrTest { + + @Test + public void test_validate() { + JsonObject jsonObject = new JsonObject().put("a", 1); + JsonObject jsonObject1 = new JsonObject().put("a", "1"); + Validation validation = new Str<>(); + validation.validate(jsonObject, "a").test().assertError(error -> true); + validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData().equals("1")); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java new file mode 100644 index 000000000..1effb8762 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java @@ -0,0 +1,58 @@ +package core.nubeiot.core.validator.validations; + +import java.util.Arrays; + +import org.junit.Test; + +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.validations.Any; +import com.nubeiot.core.validator.validations.Items; +import com.nubeiot.core.validator.validations.When; + +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; + +public class WhenTest { + + @Test + public void test_whenValidation() { + + /* Scenario 1: + 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, pass any value as valid*/ + JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); + new When<>().registerIs(new Items<>(Arrays.asList(1, 2, 3)).validate(jsonObject, "id")) + .registerThen(new Items<>(Arrays.asList("ON", "OFF")).validate(jsonObject, "value")) + .registerOtherwise(new Any().validate(null)) + .validate(null) + .test() + .assertValue(value -> true); + + /* Scenario 2: + 1. When id is in [1] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, when id is in [2] then it's value should be valid on ["ON"] + 3. Otherwise, pass any value as valid*/ + JsonObject jsonObject2 = new JsonObject().put("id", 2).put("value", "ON"); + + Single> whenId2 = new When<>().registerIs( + new Items<>(Arrays.asList(2)).validate(jsonObject2, "id")) + .registerThen(new Items<>(Arrays.asList("OFF")) + .validate(jsonObject2, "value")) + .registerOtherwise(new Any().validate()) + .validate(); + + Single> whenId1 = new When<>().registerIs( + new Items<>(Arrays.asList(1)).validate(jsonObject2, "id")) + .registerThen(new Items<>( + Arrays.asList("ON", "OFF")).validate( + jsonObject2, "value")) + .registerOtherwise(whenId2) + .validate(); + + whenId1.test() + .assertError(error -> error.getMessage() + .equals("ValidationError: \"value\" field value " + + "does not fall on the items [OFF]")); + } + +} diff --git a/core/validator/src/test/resources/example.json b/core/validator/src/test/resources/example.json new file mode 100644 index 000000000..d7ea82dcf --- /dev/null +++ b/core/validator/src/test/resources/example.json @@ -0,0 +1,28 @@ +[ + { + "first_name": "Binod", + "last_name": "Rai", + "siblings": [ + "Guna", + "Rina" + ] + }, + { + "first_name": "Binod", + "last_name": "Rai", + "details": { + "basic": { + "interests": [ + { + "sports": "Cricket", + "music": "Piano" + }, + { + "sports": "Football", + "music": 123 + } + ] + } + } + } +] diff --git a/settings.gradle b/settings.gradle index 2ea2ad61f..428f50ba4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -11,6 +11,7 @@ include ':core:httpserver' include ':core:auth' include ':core:kafka' include ':core:common' +include ':core:validator' include ':dashboard:server' include ':dashboard:connector:edge' From f9bc681d612f970dce23a745854ca15459911198 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Sat, 26 Jan 2019 01:20:04 +0545 Subject: [PATCH 2/6] - Improvements on Validation Base --- .../core/exceptions/ValidationError.java | 15 ++ .../core/validator/DataTypeValidation.java | 24 +++ .../nubeiot/core/validator/JsonConverter.java | 108 ++++++++++ .../nubeiot/core/validator/Validation.java | 119 ++++------ .../core/validator/ValidationResult.java | 42 ++-- .../core/validator/enums/ValidationState.java | 5 - .../validator/validations/Alternative.java | 7 +- .../core/validator/validations/Any.java | 8 +- .../validator/validations/Composition.java | 11 +- .../core/validator/validations/Contains.java | 51 +++++ .../core/validator/validations/Dbl.java | 26 --- .../core/validator/validations/Exist.java | 12 +- .../core/validator/validations/Forbidden.java | 17 +- .../core/validator/validations/Int.java | 26 --- .../validations/IntegerValidation.java | 15 ++ .../core/validator/validations/Items.java | 42 ---- .../core/validator/validations/JArray.java | 27 --- .../core/validator/validations/JObject.java | 27 --- .../validations/JsonArrayValidation.java | 15 ++ .../validations/JsonObjectValidation.java | 16 ++ .../core/validator/validations/KeyLoop.java | 21 +- .../core/validator/validations/Loop.java | 31 +-- .../core/validator/validations/Max.java | 17 +- .../core/validator/validations/Min.java | 5 +- ...ing.java => NumberOrStringValidation.java} | 8 +- .../validations/NumberValidation.java | 12 ++ .../core/validator/validations/Numeric.java | 24 --- .../core/validator/validations/Range.java | 17 +- .../{Ptrn.java => RegexValidation.java} | 12 +- .../core/validator/validations/Required.java | 7 +- .../core/validator/validations/Str.java | 26 --- .../validations/StringValidation.java | 15 ++ .../core/validator/validations/When.java | 16 +- .../core/validator/JsonConverterTest.java | 77 +++++++ .../validator/RegisterDefaultValueTest.java | 50 +++++ .../core/validator/ValidationResultTest.java | 17 +- .../core/validator/ValidationTest.java | 203 +++++++++++------- .../validations/AlternativeTest.java | 37 ++-- .../core/validator/validations/AnyTest.java | 7 +- .../validations/CompositionTest.java | 38 ++-- .../validator/validations/ContainsTest.java | 59 +++++ .../core/validator/validations/DblTest.java | 23 -- .../core/validator/validations/ExistTest.java | 26 +-- .../validator/validations/ForbiddenTest.java | 18 +- .../core/validator/validations/IntTest.java | 23 -- .../validations/IntegerValidationTest.java | 29 +++ .../core/validator/validations/ItemsTest.java | 41 ---- .../validator/validations/JArrayTest.java | 35 --- .../validator/validations/JObjectTest.java | 31 --- .../validations/JsonArrayValidationTest.java | 32 +++ .../validations/JsonObjectValidationTest.java | 33 +++ .../validator/validations/KeyLoopTest.java | 83 +++++++ .../core/validator/validations/LoopTest.java | 82 +++++++ .../core/validator/validations/MaxTest.java | 23 +- .../core/validator/validations/MinTest.java | 26 +++ .../validations/MinValidationTest.java | 23 -- .../NumberOrStringValidationTest.java | 31 +++ .../validations/NumberValidationTest.java | 28 +++ .../validations/NumericOrStringTest.java | 34 --- .../validator/validations/NumericTest.java | 32 --- .../core/validator/validations/PtrnTest.java | 21 -- .../core/validator/validations/RangeTest.java | 32 ++- .../validations/RegexValidationTest.java | 28 +++ .../validator/validations/RequiredTest.java | 33 +-- .../core/validator/validations/StrTest.java | 21 -- .../validations/StringValidationTest.java | 26 +++ .../core/validator/validations/WhenTest.java | 85 ++++++-- .../resources/loop_and_key_loop_example.json | 21 ++ 68 files changed, 1344 insertions(+), 888 deletions(-) create mode 100644 core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java rename core/validator/src/main/java/com/nubeiot/core/validator/validations/{NumericOrString.java => NumberOrStringValidation.java} (51%) create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java rename core/validator/src/main/java/com/nubeiot/core/validator/validations/{Ptrn.java => RegexValidation.java} (57%) delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java create mode 100644 core/validator/src/test/resources/loop_and_key_loop_example.json diff --git a/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java b/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java new file mode 100644 index 000000000..e9510f2b0 --- /dev/null +++ b/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java @@ -0,0 +1,15 @@ +package com.nubeiot.core.exceptions; + +import lombok.NonNull; + +public class ValidationError extends NubeException { + + public ValidationError(@NonNull ErrorCode code, @NonNull String message) { + super(code, message); + } + + public ValidationError(@NonNull String message) { + super(ErrorCode.INVALID_ARGUMENT, message); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java new file mode 100644 index 000000000..9a9fc2612 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java @@ -0,0 +1,24 @@ +package com.nubeiot.core.validator; + +import com.nubeiot.core.utils.Strings; + +import io.reactivex.Single; + +public abstract class DataTypeValidation extends Validation { + + public abstract Class classType(); + + @Override + public Single> validity(T s) { + if (classType().isInstance(s)) { + return ValidationResult.valid(s); + } + return ValidationResult.invalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return Strings.format("{0}: \"{1}\" is not the type of {2}", getErrorType(), getInput(), classType().getName()); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java new file mode 100644 index 000000000..505c2808b --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java @@ -0,0 +1,108 @@ +package com.nubeiot.core.validator; + +import com.nubeiot.core.utils.Strings; + +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@RequiredArgsConstructor +public class JsonConverter extends Validation { + + private final Validation validator; + @Setter + private String parentField; + @Setter + private String field; + private Object defaultValue = null; + + public static Single> validate(Validation validator, E s, String field) { + return new JsonConverter<>(validator).validate(s, "", field); + } + + public static Single> validate(Validation validator, E s, String parentField, + String field) { + return new JsonConverter<>(validator).validate(s, parentField, field); + } + + public static Single> validate(Validation validator, E s, String parentField, + String field, Object defaultValue) { + return new JsonConverter<>(validator).registerDefaultValue(defaultValue).validate(s, parentField, field); + } + + /** + * @param defaultValue if value is null on the Json, then the default value will be inserted + * @return own class object + */ + public JsonConverter registerDefaultValue(Object defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + @Override + public Single> validity(T s) { + + if (s instanceof JsonObject) { + T value = null; + // field is generally blank for Loop and KeyLoop + if (Strings.isBlank(field)) { + return validator.registerInput(buildInputField()).validate((I) s); + } + String[] fields = field.split("\\."); + JsonObject jsonObject = (JsonObject) s; + + try { + for (int i = 0; i < fields.length - 1; i++) { + if (jsonObject.getJsonObject(fields[i]) == null && this.defaultValue != null) { + jsonObject.put(fields[i], new JsonObject()); + } + jsonObject = jsonObject.getJsonObject(fields[i]); + } + value = (T) jsonObject.getValue(fields[fields.length - 1]); + } catch (NullPointerException ignored) { + } + + if (value == null) { + if (this.defaultValue != null) { + jsonObject.put(fields[fields.length - 1], defaultValue); + value = (T) defaultValue; + } + } + + return validator.registerInput(buildInputField()).validate((I) value); + } + + if (this.validator.isNullable() && s == null) { + return ValidationResult.valid(); + } + + // Case: JsonArray + return validator.registerInput(buildInputField()).validate((I) s); + } + + @Override + protected String getErrorMessage() { + return null; + } + + @Override + public Validation registerInput(String input) { + return this; + } + + public Single> validate(T s, String parentField, String field) { + this.parentField = parentField; + this.field = field; + return this.validate(s); + } + + String buildInputField() { + if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) { + return this.parentField + "." + this.field; + } else { + return this.parentField + this.field; + } + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java index 2d14f5257..0614faf5d 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java @@ -1,103 +1,64 @@ package com.nubeiot.core.validator; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.NubeException; import io.reactivex.Single; -import io.vertx.core.json.JsonObject; +import lombok.Getter; +import lombok.Setter; public abstract class Validation { - protected String parentField = ""; - protected String field = ""; - protected Object defaultValue = null; - protected String errorType = "ValidationError"; + @Getter + protected String input = ""; - public abstract Single> validate(T s); - - protected abstract String getErrorMessage(); - - public Validation registerField(String field) { - this.field = field; - return this; - } - - public Validation registerParentField(String parentField) { - this.parentField = parentField; - return this; - } - - public Validation registerDefaultValue(Object defaultValue) { - this.defaultValue = defaultValue; - return this; - } + @Getter + @Setter + private String errorType = "ValidationError"; + @Getter + @Setter + private NubeException.ErrorCode errorCode = NubeException.ErrorCode.INVALID_ARGUMENT; + private boolean overrideInput = true; /** - * @param jsonObject : JSON object to be passed to extract value - * @param field : JSON field on String format like "thing.features.points.UI1.value" - * @return : Resulted value on ValidationResult form - *

- * Basically this will works as a mediator for parsing JSON value and sending it to actual business logic of - * validation + * @param s input value + * @return validation result */ - public final Single> validate(JsonObject jsonObject, String field) { - this.field = field; - if (Strings.isBlank(field)) { - return validate((T) jsonObject); + public final Single> validate(T s) { + // May be default value also be failed on the validation + if (isNullable() && s == null) { + return ValidationResult.valid(); } - T value; - String[] fields = field.split("\\."); - - JsonObject object = jsonObject; - try { - for (int i = 0; i < fields.length - 1; i++) { - if (object.getJsonObject(fields[i]) == null && this.defaultValue != null) { - object.put(fields[i], new JsonObject()); - } - object = object.getJsonObject(fields[i]); - } - } catch (NullPointerException ignored) { - } - value = (T) object.getValue(fields[fields.length - 1]); - - if (value == null) { - if (this.defaultValue != null) { - object.put(fields[fields.length - 1], defaultValue); - } - - if (this.passNullCase()) { - return new ValidationResult().asyncSuccess(); - } + // Set input only if no DI occurred from parent on Method: registerInput(String input) + if (overrideInput) { + this.input = s != null ? s.toString() : ""; } - return validate(value); + return this.validity(s); } - protected boolean passNullCase() { - return true; - } - - public final Single> validate(Object s, String parentField, String field) { - this.field = field; - this.parentField = parentField; - - if (s instanceof JsonObject) { - return validate((JsonObject) s, field); - } + /** + * This method contains the actual business logic for the individual validation + * + * @param s input value + * @return validation result + */ + public abstract Single> validity(T s); - if (this.passNullCase() && s == null) { - return new ValidationResult().asyncSuccess(); - } + protected abstract String getErrorMessage(); - return validate((T) s); + /** + * @param input input value for displaying error value if exist + * @return own class object + */ + public Validation registerInput(String input) { + overrideInput = false; + this.input = input; + return this; } - protected final String getAbsoluteField() { - if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) { - return parentField + "." + this.field; - } else { - return this.parentField + this.field; - } + protected boolean isNullable() { + return true; } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java index 62b228f50..821d61b69 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java @@ -1,49 +1,35 @@ package com.nubeiot.core.validator; import com.nubeiot.core.exceptions.NubeException; -import com.nubeiot.core.validator.enums.ValidationState; +import com.nubeiot.core.exceptions.ValidationError; import io.reactivex.Single; import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; @Getter -@NoArgsConstructor +@RequiredArgsConstructor public class ValidationResult { - private ValidationState validity; - private String reason; private T data; - public ValidationResult success(T data) { - this.validity = ValidationState.VALID; - this.reason = null; - this.data = data; - return this; + public static Single> valid() { + ValidationResult validationResult = new ValidationResult<>(); + return Single.just(validationResult); } - public ValidationResult success() { - return success(null); + public static Single> valid(E data) { + ValidationResult validationResult = new ValidationResult<>(); + validationResult.data = data; + return Single.just(validationResult); } - public NubeException invalid(String reason) { - return new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason); + public static Single> invalid(NubeException.ErrorCode errorCode, String message) { + return Single.error(new ValidationError(errorCode, message)); } - public Single> asyncSuccess(T data) { - return Single.just(success(data)); - } - - public Single> asyncSuccess() { - return Single.just(success()); - } - - public Single> asyncInvalid(String reason) { - return Single.error(new NubeException(NubeException.ErrorCode.INVALID_ARGUMENT, reason)); - } - - public Single> asyncInvalid(NubeException.ErrorCode errorCode, String reason) { - return Single.error(new NubeException(errorCode, reason)); + public static Single> invalid(String message) { + return Single.error(new ValidationError(message)); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java b/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java deleted file mode 100644 index a3dab4a45..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/enums/ValidationState.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.nubeiot.core.validator.enums; - -public enum ValidationState { - VALID, INVALID -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java index 1b80e679a..02edf029a 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java @@ -1,6 +1,7 @@ package com.nubeiot.core.validator.validations; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import com.nubeiot.core.exceptions.NubeException; @@ -16,12 +17,12 @@ public class Alternative extends Validation { private final List> validations; @Override - public Single> validate(T s) { + public Single> validity(T s) { final List exception = new ArrayList<>(); return Single.create(source -> { - for (Validation validation : validations) { + for (Validation validation : new HashSet<>(validations)) { - validation.registerField(field).registerParentField(parentField).validate(s) + validation.registerInput(this.input).validate(s) .subscribe(validationResult -> source.onSuccess((ValidationResult) validationResult), error -> exception.add((NubeException) error)); } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java index af6d1dd14..abacc4257 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java @@ -5,15 +5,15 @@ import io.reactivex.Single; -public class Any extends Validation { +public class Any extends Validation { - public Single> validate() { + public Single> validate() { return this.validate(null); } @Override - public Single> validate(Object s) { - return new ValidationResult<>().asyncSuccess(); + public Single> validity(T s) { + return ValidationResult.valid(s); } @Override diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java index e1f6fa7b8..73572125c 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java @@ -16,23 +16,22 @@ public class Composition extends Validation> { private final List> validations; @Override - public Single>> validate(T s) { + public Single>> validity(T s) { return Observable.fromIterable(validations) - .flatMapSingle( - validation -> validation.registerField(field).registerParentField(parentField).validate(s)) + .flatMapSingle(validation -> validation.registerInput(this.input).validate(s)) .toList() - .map(outputs -> { + .flatMap(outputs -> { List list = new ArrayList<>(); for (ValidationResult output : outputs) { list.add(output.getData()); } - return new ValidationResult>().success(list); + return ValidationResult.valid(list); }); } @Override - protected boolean passNullCase() { + protected boolean isNullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java new file mode 100644 index 000000000..2269ab8f1 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java @@ -0,0 +1,51 @@ +package com.nubeiot.core.validator.validations; + +import java.util.Set; + +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; + +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@AllArgsConstructor +public class Contains extends Validation { + + private final Set items; + private boolean strict = true; + + @Override + public Single> validity(T s) { + boolean contains = false; + if (s instanceof JsonArray) { + for (Object o : (JsonArray) s) { + if (items.contains(o)) { + contains = true; + if (!strict) { + break; + } + } else { + contains = false; + if (strict) { + break; + } + } + } + } else { + contains = items.contains(s); + } + return contains ? ValidationResult.valid(s) : ValidationResult.invalid(getErrorMessage()); + } + + @Override + protected String getErrorMessage() { + return strict + ? Strings.format("{0}: \"{1}\" strictly should fall in the {2}", getErrorType(), getInput(), items) + : Strings.format("{0}: \"{1}\" should fall in the {2}", getErrorType(), getInput(), items); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java deleted file mode 100644 index 037e717e1..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Dbl.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class Dbl extends Validation { - - @Override - public Single> validate(T s) { - if (s instanceof Double) { - return new ValidationResult().asyncSuccess((Double) s); - } - return new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not the type of Double", errorType, getAbsoluteField()); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java index 3e0c96f6d..ff784c0df 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java @@ -6,23 +6,23 @@ import io.reactivex.Single; -public class Exist extends Validation { +public class Exist extends Validation { @Override - public Single> validate(T s) { + public Single> validity(T s) { if (s != null) { - return new ValidationResult<>().asyncSuccess(); + return ValidationResult.valid(s); } - return new ValidationResult<>().asyncInvalid(getErrorMessage()); + return ValidationResult.invalid(getErrorMessage()); } @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is required", errorType, getAbsoluteField()); + return Strings.format("{0}: required value is null", getErrorType(), getInput()); } @Override - protected boolean passNullCase() { + protected boolean isNullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java index f6b7770e4..bc9b35174 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java @@ -1,6 +1,7 @@ package com.nubeiot.core.validator.validations; import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.utils.Strings; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; @@ -8,21 +9,25 @@ public class Forbidden extends Validation { - public static String FORBIDDEN_MESSAGE = "Forbidden: you are not authorized to post this value"; - public Single> validate() { return this.validate(null); } @Override - public Single> validate(T s) { - return new ValidationResult<>().asyncInvalid(NubeException.ErrorCode.INSUFFICIENT_PERMISSION_ERROR, - getErrorMessage()); + public Single> validity(T s) { + this.setErrorType("Forbidden"); + this.setErrorCode(NubeException.ErrorCode.INSUFFICIENT_PERMISSION_ERROR); + return ValidationResult.invalid(this.getErrorCode(), this.getErrorMessage()); } @Override protected String getErrorMessage() { - return FORBIDDEN_MESSAGE; + return Strings.format("{0}: you are not authorized to post this value", getErrorType()); + } + + @Override + protected boolean isNullable() { + return false; } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java deleted file mode 100644 index e71ead87a..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Int.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class Int extends Validation { - - @Override - public Single> validate(T s) { - if (s instanceof Integer) { - return new ValidationResult().asyncSuccess((Integer) s); - } - return new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - public String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not the type of Integer", errorType, getAbsoluteField()); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java new file mode 100644 index 000000000..1d4dedc85 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java @@ -0,0 +1,15 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.DataTypeValidation; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class IntegerValidation extends DataTypeValidation { + + @Override + public Class classType() { + return Integer.class; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java deleted file mode 100644 index 51a7497f6..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Items.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import java.util.List; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import io.vertx.core.json.JsonArray; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class Items extends Validation { - - private final List items; - - @Override - public Single> validate(T s) { - boolean contains = true; - if (s instanceof JsonArray) { - for (Object o : (JsonArray) s) { - if (!items.contains(o)) { - contains = false; - break; - } - } - } else { - contains = items.contains(s); - } - return contains - ? new ValidationResult().asyncSuccess(s) - : new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value does not fall on the items {2}", errorType, getAbsoluteField(), - items); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java deleted file mode 100644 index 22248b6c3..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JArray.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import io.vertx.core.json.JsonArray; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class JArray extends Validation { - - @Override - public Single> validate(T s) { - if (s instanceof JsonArray) { - return new ValidationResult().asyncSuccess((JsonArray) s); - } - return new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not the type of JsonArray", errorType, getAbsoluteField()); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java deleted file mode 100644 index 82ceb9567..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JObject.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import io.vertx.core.json.JsonObject; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class JObject extends Validation { - - @Override - public Single> validate(T s) { - if (s instanceof JsonObject) { - return new ValidationResult().asyncSuccess((JsonObject) s); - } - return new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not the type of JsonObject", errorType, getAbsoluteField()); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java new file mode 100644 index 000000000..f1583271c --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java @@ -0,0 +1,15 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.DataTypeValidation; + +import io.vertx.core.json.JsonArray; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class JsonArrayValidation extends DataTypeValidation { + + @Override + public Class classType() { + return JsonArray.class; + } +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java new file mode 100644 index 000000000..c4861836a --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java @@ -0,0 +1,16 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.DataTypeValidation; + +import io.vertx.core.json.JsonObject; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class JsonObjectValidation extends DataTypeValidation { + + @Override + public Class classType() { + return JsonObject.class; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java index 32f44fde9..56ef88058 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java @@ -1,5 +1,6 @@ package com.nubeiot.core.validator.validations; +import com.nubeiot.core.utils.Strings; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; import com.nubeiot.core.validator.ValidationSupplier; @@ -10,18 +11,22 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class KeyLoop extends Validation { +public class KeyLoop extends Validation { private final ValidationSupplier supplier; - private final String parentField; @Override - public Single> validate(JsonObject s) { - - return Observable.fromIterable(s) - .flatMapSingle(o -> supplier.get(o.getValue(), parentField + "." + o.getKey())) - .toList() - .flatMap(r -> new ValidationResult().asyncSuccess(s)); + public Single> validity(T s) { + if (s instanceof JsonObject) { + JsonObject jsonObject = (JsonObject) s; + return Observable.fromIterable(jsonObject) + .flatMapSingle(o -> supplier.get(o.getValue(), this.input + "." + o.getKey())) + .toList() + .flatMap(r -> ValidationResult.valid(jsonObject)); + } else { + return ValidationResult.invalid( + Strings.format("{0}: \"{1}\" must be of type JsonObject", getErrorType(), this.input)); + } } @Override diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java index 9660c3bf9..be7d16351 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import com.nubeiot.core.utils.Strings; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; import com.nubeiot.core.validator.ValidationSupplier; @@ -13,23 +14,29 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Loop extends Validation { +public class Loop extends Validation { private final ValidationSupplier supplier; - private final String parentField; @Override - public Single> validate(JsonArray s) { - final List objects = new ArrayList<>(); - // When isRequired is false then parsed JsonArray value will be of size 0 - if (s.size() == 0) { - return new ValidationResult().asyncSuccess(s); + public Single> validity(T s) { + if (s instanceof JsonArray) { + final List objects = new ArrayList<>(); + // When isRequired is false then parsed JsonArray value will be of size 0 + JsonArray jsonArray = (JsonArray) s; + if (jsonArray.size() == 0) { + return ValidationResult.valid(jsonArray); + } + return Observable.fromIterable(jsonArray).flatMapSingle(o -> { + + Single> output = supplier.get(o, this.input + "[" + objects.size() + "]"); + objects.add(o); + return output; + }).toList().flatMap(r -> ValidationResult.valid(jsonArray)); + } else { + return ValidationResult.invalid( + Strings.format("{0}: \"{1}\" must be of type JsonArray", getErrorType(), this.input)); } - return Observable.fromIterable(s).flatMapSingle(o -> { - Single> output = supplier.get(o, this.parentField + "[" + objects.size() + "]"); - objects.add(o); - return output; - }).toList().flatMap(r -> new ValidationResult().asyncSuccess(s)); } @Override diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java index 4671a019e..eb320797e 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java @@ -10,27 +10,26 @@ @RequiredArgsConstructor public class Max extends Validation { - private final Double value; + protected final Double value; @Override - public Single> validate(T s) { - if (s instanceof Double || s instanceof Integer || s instanceof Long || s instanceof Float) { + public Single> validity(T s) { + if (s instanceof Number) { Double d = Double.parseDouble(s.toString()); if (condition(d)) { - return new ValidationResult().asyncSuccess(d); + return ValidationResult.valid(d); } else { - return new ValidationResult().asyncInvalid(getErrorMessage()); + return ValidationResult.invalid(getErrorMessage()); } } else { - return new ValidationResult().asyncInvalid( - Strings.format("ClassCastException: \"{0}\" field value is not parsable to Number", - getAbsoluteField())); + return ValidationResult.invalid( + Strings.format("ClassCastException: {0} is not parsable to Number", getInput())); } } @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not less than {2}", errorType, getAbsoluteField(), value); + return Strings.format("{0}: \"{1}\" is not less than or equal to {2}", getErrorType(), getInput(), value); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java index 115cf02a3..dd9ed08e3 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java @@ -4,16 +4,13 @@ public class Min extends Max { - private final Double value; - public Min(Double value) { super(value); - this.value = value; } @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not greater than {2}", errorType, getAbsoluteField(), value); + return Strings.format("{0}: \"{1}\" is not greater than or equal to {2}", getErrorType(), getInput(), value); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java similarity index 51% rename from core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java rename to core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java index 9250f6078..b122d0bcb 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumericOrString.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java @@ -7,12 +7,12 @@ import io.reactivex.Single; -public class NumericOrString extends Validation { +public class NumberOrStringValidation extends Validation { @Override - public Single> validate(T s) { - return new Alternative<>(Arrays.asList(new Int<>(), new Dbl<>(), new Str<>())).registerField( - field).registerParentField(parentField).validate(s); + public Single> validity(T s) { + return new Alternative<>(Arrays.asList(new NumberValidation<>(), new StringValidation<>())).registerInput( + this.input).validate(s); } @Override diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java new file mode 100644 index 000000000..eb968b1a0 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java @@ -0,0 +1,12 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.DataTypeValidation; + +public class NumberValidation extends DataTypeValidation { + + @Override + public Class classType() { + return Number.class; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java deleted file mode 100644 index 53329189d..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Numeric.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import java.util.Arrays; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; - -public class Numeric extends Validation { - - @Override - public Single> validate(T s) { - return new Alternative<>(Arrays.asList(new Int<>(), new Dbl<>())).registerField(field) - .registerParentField(parentField) - .validate(s); - } - - @Override - protected String getErrorMessage() { - return null; - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java index 86bce199d..9e2afd519 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java @@ -14,25 +14,24 @@ public class Range extends Validation { private final Double maxValue; @Override - public Single> validate(T s) { - if (s instanceof Double || s instanceof Integer || s instanceof Long || s instanceof Float) { + public Single> validity(T s) { + if (s instanceof Number) { Double d = Double.parseDouble(s.toString()); if (minValue <= d && d <= maxValue) { - return new ValidationResult().asyncSuccess(d); + return ValidationResult.valid(d); } else { - return new ValidationResult().asyncInvalid(getErrorMessage()); + return ValidationResult.invalid(getErrorMessage()); } } else { - return new ValidationResult().asyncInvalid( - Strings.format("ClassCastException: \"{0}\" field value is not parsable to Number", - getAbsoluteField())); + return ValidationResult.invalid( + Strings.format("ClassCastException: {0} is not parsable to Number", getInput())); } } @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value should be on range {2}-{3}", errorType, getAbsoluteField(), - minValue, maxValue); + return Strings.format("{0}: \"{1}\" should be on range {2}-{3}", getErrorType(), getInput(), minValue, + maxValue); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java similarity index 57% rename from core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java rename to core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java index f885dcadb..d00cca8c8 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Ptrn.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java @@ -11,25 +11,23 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Ptrn extends Validation { +public class RegexValidation extends Validation { private final String regex; @Override - public Single> validate(String s) { + public Single> validity(String s) { Pattern pattern = java.util.regex.Pattern.compile(regex); Matcher matcher = pattern.matcher(s); boolean isValid = matcher.matches(); - return isValid - ? new ValidationResult().asyncSuccess((s)) - : new ValidationResult().asyncInvalid(getErrorMessage()); + return isValid ? ValidationResult.valid(s) : ValidationResult.invalid(getErrorMessage()); } @Override public String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value does not match with the pattern \"{2}\"", errorType, - getAbsoluteField(), regex); + return Strings.format("{0}: \"{1}\" does not match with the pattern \"{2}\"", getErrorType(), getInput(), + regex); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java index ece87df62..3c1de45c4 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java @@ -15,9 +15,8 @@ public class Required extends Validation> { private final Validation validation; @Override - public Single>> validate(T s) { - return new Composition<>(Arrays.asList(validation, new Exist<>())).registerParentField( - parentField).registerField(field).validate(s); + public Single>> validity(T s) { + return new Composition<>(Arrays.asList(validation, new Exist<>())).registerInput(this.input).validate(s); } @Override @@ -25,7 +24,7 @@ protected String getErrorMessage() { return null; } - protected boolean passNullCase() { + protected boolean isNullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java deleted file mode 100644 index a2b34c03e..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Str.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class Str extends Validation { - - @Override - public Single> validate(T s) { - if (s instanceof String) { - return new ValidationResult().asyncSuccess((String) s); - } - return new ValidationResult().asyncInvalid(getErrorMessage()); - } - - @Override - public String getErrorMessage() { - return Strings.format("{0}: \"{1}\" field value is not the type of String", errorType, getAbsoluteField()); - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java new file mode 100644 index 000000000..5592b5817 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java @@ -0,0 +1,15 @@ +package com.nubeiot.core.validator.validations; + +import com.nubeiot.core.validator.DataTypeValidation; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class StringValidation extends DataTypeValidation { + + @Override + public Class classType() { + return String.class; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java index ccd5babdc..180f40ad6 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java @@ -7,18 +7,14 @@ import lombok.NoArgsConstructor; @NoArgsConstructor -public class When>> extends Validation { +public class When>> extends Validation { private Single> is; private Single> then; - private T otherwise; - - public Single> validate() { - return this.validate(null); - } + private T2 otherwise; @Override - public Single> validate(T s) { + public Single> validity(T1 s) { return Single.create( source -> this.is.subscribe(ignored -> this.then.subscribe(source::onSuccess, source::onError), error -> otherwise.subscribe(source::onSuccess, source::onError))); @@ -29,17 +25,17 @@ protected String getErrorMessage() { return null; } - public When registerIs(Single> is) { + public When registerIs(Single> is) { this.is = is; return this; } - public When registerThen(Single> then) { + public When registerThen(Single> then) { this.then = then; return this; } - public When registerOtherwise(T otherwise) { + public When registerOtherwise(T2 otherwise) { this.otherwise = otherwise; return this; } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java new file mode 100644 index 000000000..8785956d8 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java @@ -0,0 +1,77 @@ +package core.nubeiot.core.validator; + +import org.junit.Test; + +import com.nubeiot.core.validator.JsonConverter; +import com.nubeiot.core.validator.validations.JsonArrayValidation; +import com.nubeiot.core.validator.validations.Min; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class JsonConverterTest { + + @Test + public void test_json_object_converter_success() { + JsonObject jsonObject = new JsonObject().put("a", 10); + JsonConverter.validate(new Min<>(1d), jsonObject, "a").test().assertValue(value -> { + System.out.println(jsonObject); + return true; + }); + } + + @Test + public void test_json_object_converter_with_parent_field_failure() { + JsonObject jsonObject = new JsonObject().put("a", 10); + JsonConverter.validate(new Min<>(100d), jsonObject, "xyz", "a").test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + + @Test + public void test_json_object_converter_with_default_value_success() { + JsonObject jsonObject = new JsonObject(); + JsonConverter.validate(new Min<>(5d), jsonObject, "xyz", "a", 10).test().assertValue(value -> { + System.out.println(jsonObject); + return jsonObject.getValue("a").equals(10); + }); + } + + @Test + public void test_json_object_converter_with_default_value_failure() { + JsonObject jsonObject = new JsonObject(); + JsonConverter.validate(new Min<>(100d), jsonObject, "xyz", "a", 10).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + + @Test + public void test_json_array_converter_success() { + JsonArray jsonArray = new JsonArray().add(1).add(2); + JsonObject jsonObject = new JsonObject().put("a", new JsonArray().add(1).add(2)); + JsonConverter.validate(new JsonArrayValidation<>(), jsonArray, "").test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + + JsonConverter.validate(new JsonArrayValidation<>(), jsonObject, "a").test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_json_array_converter_with_parent_field_failure() { + JsonConverter.validate(new JsonArrayValidation<>(), new JsonObject().put("a", new JsonObject()), "abc[0]", "a") + .test() + .assertError(error -> { + System.out.println(error.getMessage()); + return error.getMessage() + .equals("ValidationError: \"abc[0].a\" is not the type of io.vertx.core.json" + + ".JsonArray"); + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java new file mode 100644 index 000000000..bb2790b19 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java @@ -0,0 +1,50 @@ +package core.nubeiot.core.validator; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.nubeiot.core.validator.JsonConverter; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Composition; +import com.nubeiot.core.validator.validations.Max; +import com.nubeiot.core.validator.validations.Min; + +import io.vertx.core.json.JsonObject; + +public class RegisterDefaultValueTest { + + @Test + public void test_default_value_insertion_success() { + JsonObject jsonObject = new JsonObject().put("a", 10); + + List> validations = new ArrayList<>(); + validations.add(new Min<>(1d)); + validations.add(new Max<>(16d)); + + Validation> validation = new Composition<>(validations); + + JsonConverter.validate(validation, jsonObject, "", "b", 16).test().assertValue(output -> { + System.out.println(jsonObject); + return true; + }); + } + + @Test + public void test_without_default_value_success() { + JsonObject jsonObject = new JsonObject().put("a", 10); + + List> validations = new ArrayList<>(); + validations.add(new Min<>(1d)); + validations.add(new Max<>(16d)); + + Validation> validation = new Composition<>(validations); + + JsonConverter.validate(validation, jsonObject, "", "b").test().assertValue(output -> { + System.out.println(jsonObject); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java index fce3b03b6..aa3e558d0 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java @@ -1,28 +1,25 @@ package core.nubeiot.core.validator; -import org.junit.Assert; import org.junit.Test; -import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.enums.ValidationState; + +import io.reactivex.Single; public class ValidationResultTest { @Test - public void test_success() { + public void test_valid() { String output = "succeeded"; - ValidationResult validationResult = new ValidationResult().success(output); - Assert.assertEquals(validationResult.getData(), output); - Assert.assertEquals(validationResult.getValidity(), ValidationState.VALID); - Assert.assertNull(validationResult.getReason()); + Single> validationResult = ValidationResult.valid(output); + validationResult.test().assertValue(value -> value.getData().equals(output)); } @Test public void test_invalid() { String reason = "invalid"; - NubeException nubeException = new ValidationResult().invalid(reason); - Assert.assertEquals(nubeException.getMessage(), reason); + Single> validationResult = ValidationResult.invalid(reason); + validationResult.test().assertError(value -> value.getMessage().equals("invalid")); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java index aa6c603d3..472d41bfe 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java @@ -5,107 +5,161 @@ import org.junit.Test; -import com.nubeiot.core.TestBase; import com.nubeiot.core.utils.FileUtils; +import com.nubeiot.core.validator.JsonConverter; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; import com.nubeiot.core.validator.ValidationSupplier; import com.nubeiot.core.validator.validations.Composition; import com.nubeiot.core.validator.validations.Exist; -import com.nubeiot.core.validator.validations.Int; -import com.nubeiot.core.validator.validations.JArray; -import com.nubeiot.core.validator.validations.JObject; +import com.nubeiot.core.validator.validations.IntegerValidation; +import com.nubeiot.core.validator.validations.JsonArrayValidation; +import com.nubeiot.core.validator.validations.JsonObjectValidation; import com.nubeiot.core.validator.validations.KeyLoop; import com.nubeiot.core.validator.validations.Loop; -import com.nubeiot.core.validator.validations.Str; +import com.nubeiot.core.validator.validations.StringValidation; import io.reactivex.Single; import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; import lombok.NoArgsConstructor; -public class ValidationTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(ValidationTest.class); +public class ValidationTest { private JsonObject object = new JsonObject().put("first_name", "Binod") .put("last_name", "Rai") .put("details", new JsonObject().put("age", 26.2)); @Test - public void test_fieldDoesNotExistWhenIsRequiredTrue() { - Validation sv = new Str<>(); - Validation iv = new Int<>(); + public void test_field_does_not_exist_when_is_required_true() { + Validation sv = new StringValidation<>(); + Validation iv = new IntegerValidation<>(); Validation ev = new Exist<>(); - sv.validate(object, "first_name") - .flatMap(ignore -> sv.validate(object, "last_name")) - .flatMap(ignore -> new Composition<>(Arrays.asList(iv, ev)).validate(object, "details.xyz")) - .test() - .assertError(error -> { - logger.error(error.getMessage()); - return true; - }); + JsonConverter.validate(sv, object, "first_name") + .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) + .flatMap(ignore -> JsonConverter.validate(new Composition<>(Arrays.asList(iv, ev)), object, + "details.xyz")) + .test() + .assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + + @Test + public void test_no_error_on_non_existing_value_when_is_require_false() { + Validation sv = new StringValidation<>(); + Validation iv = new IntegerValidation<>(); + + JsonConverter.validate(sv, object, "first_name") + .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) + .flatMap(ignore -> JsonConverter.validate(iv, object, "details.xyz")) + .test() + .assertValue(value -> true); } @Test - public void test_noErrorOnNonExistingValueWhenIsRequireFalse() { - Validation sv = new Str<>(); - Validation iv = new Int<>(); - - sv.validate(object, "first_name") - .flatMap(ignore -> sv.validate(object, "last_name")) - .flatMap(ignore -> iv.validate(object, "details.xyz")) - .test() - .assertValue(value -> true); + public void test_integer_validation() { + + Validation sv = new StringValidation<>(); + Validation iv = new IntegerValidation<>(); + + JsonConverter.validate(sv, object, "first_nam") + .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) + .flatMap(ignore -> JsonConverter.validate(iv, object, "details.age")) + .test() + .assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); } @Test - public void test_integerValidation() { - - Validation sv = new Str<>(); - Validation iv = new Int<>(); - - sv.validate(object, "first_nam") - .flatMap(ignore -> sv.validate(object, "last_name")) - .flatMap(ignore -> iv.validate(object, "details.age")) - .test() - .assertError(error -> { - logger.error(error.getMessage()); - return true; - }); + public void test_loop_and_key_loop_failure() { + + URL resource = ValidationTest.class.getClassLoader().getResource("loop_and_key_loop_example.json"); + JsonObject jsonObject = new JsonObject(FileUtils.readFileToString(resource.toString())); + + class DetailsJsonArrayValidation implements ValidationSupplier { + + private Validation detailsJsonObjectValidation = new KeyLoop<>(new DetailsJsonObjectValidation<>()); + + @Override + public Single> get(V s, String parentField) { + // 2. jsonObject.details[i] value must be of JsonObject, and we loop that JsonObject on its each key + return JsonConverter.validate(detailsJsonObjectValidation, s, parentField, "").map(x -> x); + } + + class DetailsJsonObjectValidation implements ValidationSupplier { + + Validation innerLoop = new Loop<>(new InnerArrayLoopValidation<>()); + + @Override + public Single> get(W s, String parentField) { + // 3. jsonObject.details[i].key_value must be of JsonArray + return JsonConverter.validate(innerLoop, s, parentField, "").map(x -> x); + } + + class InnerArrayLoopValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(X s, String parentField) { + // 4. jsonObject.details[i].key_value[j] must be of String + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + } + + } + + // 1. jsonObject.details should be of array type, so we loop here + Validation loop = new Loop<>(new DetailsJsonArrayValidation<>()); + JsonConverter.validate(loop, jsonObject, "details").test().assertError(e -> { + System.out.println(e.getMessage()); + return e.getMessage() + .equals("ValidationError: \"details[1].movies[2]\" is not the type of java.lang.String"); + }); } @Test - public void test_arrayValidationWithSupplier() { + public void test_loop_and_key_loop_failure_2() { @NoArgsConstructor class FirstLayerObjectValidation implements ValidationSupplier { - private Validation sv = new Str<>(); - private Validation av = new JArray<>(); - private Loop lvS = new Loop(new SiblingValidation<>(), "siblings"); - private Loop lvI = new Loop(new InterestValidation<>(), "details.basic.interests"); + private Validation sv = new StringValidation<>(); + private Validation av = new JsonArrayValidation<>(); + private Validation lvS = new Loop<>(new SiblingValidation<>()); + private Validation lvI = new Loop<>(new InterestValidation<>()); @Override public Single> get(T s, String parentField) { - return sv.validate(s, parentField, "first_name") - .flatMap(ignore -> sv.validate(s, parentField, "last_name")) - .flatMap(ignore -> av.registerDefaultValue(Arrays.asList("Binod", "Roshan", "Bhushan")) - .validate(s, parentField, "siblings")) - .flatMap(siblings -> lvS.validate(siblings.getData(), parentField, "siblings")) - .flatMap(ignore -> av.validate(s, parentField, "details.basic.interests")) - .flatMap(interests -> lvI.validate(interests.getData(), parentField, "")); + // 2 + return JsonConverter.validate(sv, s, parentField, "first_name") + .flatMap(ignore -> JsonConverter.validate(sv, s, parentField, "last_name")) + .flatMap(ignore -> JsonConverter.validate(av, s, parentField, "siblings", + new JsonArray().add("Roshan") + .add("Bhushan"))) + .flatMap(siblings -> JsonConverter.validate(lvS, siblings.getData(), parentField, + "siblings")) + .flatMap( + ignore -> JsonConverter.validate(av, s, parentField, "details.basic.interests")) + .flatMap(interests -> JsonConverter.validate(lvI, interests.getData(), parentField, + "details.basic.interests")); } class SiblingValidation implements ValidationSupplier { - private Validation sv = new Str<>(); + private Validation sv = new StringValidation<>(); @Override public Single> get(U s, String parentField) { - return sv.registerParentField(parentField).validate(s).map(x -> x); + // 3 + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); } } @@ -113,24 +167,26 @@ public Single> get(U s, String parentField) { class InterestValidation implements ValidationSupplier { - private Validation jov = new JObject<>(); + private Validation jov = new JsonObjectValidation<>(); @Override public Single> get(U s, String parentField) { - return jov.validate(s, parentField, "").flatMap(vrInterest -> { - Validation lvI = new KeyLoop(new InterestObjectValidation<>(), parentField); + // 4 + return JsonConverter.validate(jov, s, parentField, "").flatMap(vrInterest -> { + Validation keyLoopInterestValidation = new KeyLoop<>(new InterestObjectValidation<>()); JsonObject interest = ((JsonObject) vrInterest.getData()); - return lvI.registerParentField(parentField).validate(interest); + return JsonConverter.validate(keyLoopInterestValidation, interest, parentField, ""); }); } class InterestObjectValidation implements ValidationSupplier { - private Validation sv = new Str<>(); + private Validation sv = new StringValidation<>(); @Override public Single> get(V s, String parentField) { - return sv.validate(s, parentField, "").map(x -> x); + // 5 + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); } } @@ -140,18 +196,15 @@ public Single> get(V s, String parentField) { } URL resource = ValidationTest.class.getClassLoader().getResource("example.json"); - Object object = new JsonArray(FileUtils.readFileToString(resource.toString())); - - Validation av = new JArray<>(); - Validation lv = new Loop(new FirstLayerObjectValidation<>(), ""); - - av.validate(object) - .flatMap(vrArray -> { - JsonArray array = (JsonArray) vrArray.getData(); - return lv.validate(array); - }).test().assertError(error -> { - logger.error(error.getMessage()); - return true; + JsonArray jsonArray = new JsonArray(FileUtils.readFileToString(resource.toString())); + + // 1 + Validation lv = new Loop<>(new FirstLayerObjectValidation<>()); + JsonConverter.validate(lv, jsonArray, "").test().assertError(e -> { + System.out.println(e.getMessage()); + return e.getMessage() + .equals("ValidationError: \"[1].details.basic.interests[1].music\" is not the type " + + "of java.lang.String"); }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java index 915b7e544..aead2facd 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java @@ -7,32 +7,33 @@ import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.validations.Alternative; -import com.nubeiot.core.validator.validations.Dbl; -import com.nubeiot.core.validator.validations.Str; +import com.nubeiot.core.validator.validations.NumberValidation; +import com.nubeiot.core.validator.validations.StringValidation; import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; public class AlternativeTest { - private static final Logger logger = LoggerFactory.getLogger(AlternativeTest.class); - @Test - public void test_alternative() { - JsonObject jsonObject = new JsonObject().put("a", "10"); - JsonObject jsonObject1 = new JsonObject().put("a", 10d); - JsonObject jsonObject2 = new JsonObject().put("a", 10); + public void test_string_or_number_success() { + List> validations = new ArrayList<>(); + validations.add(new NumberValidation<>()); + validations.add(new StringValidation<>()); + + Validation validation = new Alternative<>(validations); + validation.validate("10").test().assertValue(value -> value.getData().equals("10")); + validation.validate(10d).test().assertValue(value -> value.getData().equals(10d)); + } + @Test + public void test_string_or_number_failure() { List> validations = new ArrayList<>(); - validations.add(new Dbl<>()); - validations.add(new Str<>()); - - Validation validation = new Alternative<>(validations); - validation.validate(jsonObject, "a").test().assertValue(value -> value.getData().equals("10")); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData().equals(10d)); - validation.validate(jsonObject2, "a").test().assertError(error -> { - logger.error(error.getMessage()); + validations.add(new NumberValidation<>()); + validations.add(new StringValidation<>()); + + Validation validation = new Alternative<>(validations); + validation.validate(new JsonObject()).test().assertError(error -> { + System.out.println(error.getMessage()); return true; }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java index 0e88088d3..002a54262 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java @@ -7,9 +7,10 @@ public class AnyTest { @Test - public void test_anyValidation() { - new Any().validate(null).test().assertValue(v -> true); - new Any().validate("XYZ").test().assertValue(v -> true); + public void test_any_success() { + new Any<>().validate().test().assertValue(v -> true); + new Any<>().validate(null).test().assertValue(v -> true); + new Any<>().validate("XYZ").test().assertValue(v -> true); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java index 2094cc2f9..e970a63a6 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java @@ -5,33 +5,37 @@ import org.junit.Test; -import com.nubeiot.core.TestBase; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.validations.Composition; -import com.nubeiot.core.validator.validations.Dbl; import com.nubeiot.core.validator.validations.Max; +import com.nubeiot.core.validator.validations.Min; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; +public class CompositionTest { -public class CompositionTest extends TestBase { + @Test + public void test_number_with_min_max_success() { + List> validations = new ArrayList<>(); + validations.add(new Min<>(1d)); + validations.add(new Max<>(16d)); - private static final Logger logger = LoggerFactory.getLogger(CompositionTest.class); + Validation validation = new Composition<>(validations); - @Test - public void test_composition() { - JsonObject jsonObject = new JsonObject().put("a", 10.00d); - JsonObject jsonObject1 = new JsonObject().put("a", 10); + validation.validate(10).test().assertValue(output -> { + System.out.println(output.getData()); + return true; + }); + } + @Test + public void test_number_with_min_max_failure() { List> validations = new ArrayList<>(); - validations.add(new Dbl<>()); - validations.add(new Max<>(10d)); + validations.add(new Min<>(1d)); + validations.add(new Max<>(16d)); + + Validation validation = new Composition<>(validations); - Validation> validation = new Composition<>(validations); - validation.validate(jsonObject, "a").test().assertValue(output -> true); - validation.validate(jsonObject1, "a").test().assertError(error -> { - logger.error(error.getMessage()); + validation.validate("10").test().assertError(output -> { + System.out.println(output.toString()); return true; }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java new file mode 100644 index 000000000..8ebb1c15a --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java @@ -0,0 +1,59 @@ +package core.nubeiot.core.validator.validations; + +import java.util.Arrays; +import java.util.HashSet; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Contains; + +import io.vertx.core.json.JsonArray; + +public class ContainsTest { + + @Test + public void test_contains_success() { + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + + validation.validate(new JsonArray().add(1).add(2)).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + + validation.validate(1).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_contains_failure() { + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5))); + validation.validate(Arrays.asList(1, 6)).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + + @Test + public void test_contains_when_strict_false_success() { + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + + validation.validate(new JsonArray().add(1).add(7)).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_contains_when_strict_false_failure() { + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + + validation.validate(new JsonArray().add(7).add(8)).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java deleted file mode 100644 index e6848f631..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/DblTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Dbl; - -import io.vertx.core.json.JsonObject; - -public class DblTest { - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1.000); - JsonObject jsonObject1 = new JsonObject().put("a", 1); - JsonObject jsonObject2 = new JsonObject().put("a", 1d); - Validation validation = new Dbl<>(); - validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 1d); - validation.validate(jsonObject1, "a").test().assertError(error -> true); - validation.validate(jsonObject2, "a").test().assertValue(value -> value.getData() == 1d); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java index ad95b1c05..d1eeb7e89 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java @@ -2,25 +2,25 @@ import org.junit.Test; -import com.nubeiot.core.TestBase; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.validations.Exist; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; +public class ExistTest { -public class ExistTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); + @Test + public void test_exist_success() { + Validation validation = new Exist<>(); + validation.validate(1).test().assertValue(v -> { + System.out.println(v.getData()); + return true; + }); + } @Test - public void test_existValidation() { - JsonObject jsonObject = new JsonObject().put("a", 1); - Validation validation = new Exist(); - validation.validate(jsonObject, "a").test().assertValue(v -> true); - validation.validate(jsonObject, "b").test().assertError(e -> { - logger.error(e.getMessage()); + public void test_exist_failure() { + Validation validation = new Exist<>(); + validation.validate(null).test().assertError(e -> { + System.out.println(e.getMessage()); return true; }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java index 821a371b0..82ef71934 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java @@ -7,9 +7,21 @@ public class ForbiddenTest { @Test - public void test_anyValidation() { - new Forbidden<>().validate(null).test().assertError(v -> v.getMessage().equals(Forbidden.FORBIDDEN_MESSAGE)); - new Forbidden<>().validate("XYZ").test().assertError(v -> v.getMessage().equals(Forbidden.FORBIDDEN_MESSAGE)); + public void test_forbidden_success() { + new Forbidden<>().validate().test().assertError(v -> { + System.out.println(v.getMessage()); + return v.getMessage().equals("Forbidden: you are not authorized to post this value"); + }); + + new Forbidden<>().validate(null).test().assertError(v -> { + System.out.println(v.getMessage()); + return v.getMessage().equals("Forbidden: you are not authorized to post this value"); + }); + + new Forbidden<>().validate("XYZ").test().assertError(v -> { + System.out.println(v.getMessage()); + return v.getMessage().equals("Forbidden: you are not authorized to post this value"); + }); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java deleted file mode 100644 index d6c4aef74..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Int; - -import io.vertx.core.json.JsonObject; - -public class IntTest { - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1.1); - JsonObject jsonObject1 = new JsonObject().put("a", 1); - JsonObject jsonObject2 = new JsonObject().put("a", "1"); - Validation validation = new Int<>(); - validation.validate(jsonObject, "a").test().assertError(error -> true); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 1); - validation.validate(jsonObject2, "a").test().assertError(error -> true); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java new file mode 100644 index 000000000..bf6e020d0 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java @@ -0,0 +1,29 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.IntegerValidation; + +public class IntegerValidationTest { + + @Test + public void test_integer_success() { + Validation validation = new IntegerValidation<>(); + validation.validate(1).test().assertValue(value -> value.getData() == 1); + } + + @Test + public void test_integer_failure() { + Validation validation = new IntegerValidation<>(); + validation.validate(1.1).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + validation.validate("1").test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java deleted file mode 100644 index 6eb653650..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ItemsTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import java.util.Arrays; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Items; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - -public class ItemsTest { - - private static final Logger logger = LoggerFactory.getLogger(ItemsTest.class); - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", Arrays.asList(1, 6)); - JsonObject jsonObject1 = new JsonObject().put("a", new JsonArray().add(1).add(2)); - JsonObject jsonObject2 = new JsonObject().put("a", 1); - Validation validation = new Items<>(Arrays.asList(1, 2, 3, 4, 5)); - validation.validate(jsonObject, "a").test().assertError(error -> { - logger.error(error.getMessage()); - return true; - }); - - validation.validate(jsonObject1, "a").test().assertValue(value -> { - logger.info(value.getData()); - return true; - }); - - validation.validate(jsonObject2, "a").test().assertValue(value -> { - logger.info(value.getData()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java deleted file mode 100644 index 4298c89c2..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JArrayTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.JArray; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - -public class JArrayTest { - - private static final Logger logger = LoggerFactory.getLogger(JArrayTest.class); - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1); - JsonObject jsonObject2 = new JsonObject().put("a", new JsonArray().add(1).add(2).add(3)); - JsonArray jsonArray = new JsonArray().add(1).add(2).add(3); - Validation validation = new JArray<>(); - - validation.validate(jsonObject, "a").test().assertError(error -> true); - validation.validate(jsonObject2, "a").test().assertValue(value -> { - logger.info(value.getData()); - return true; - }); - validation.validate(jsonArray).test().assertValue(value -> { - logger.info(value.getData()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java deleted file mode 100644 index f353de8ac..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JObjectTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.JObject; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - -public class JObjectTest { - - private static final Logger logger = LoggerFactory.getLogger(JObjectTest.class); - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", new JsonObject().put("result", "success")); - JsonObject jsonObject1 = new JsonObject().put("a", new JsonArray().add(1).add(2).add(3)); - - Validation validation = new JObject<>(); - - validation.validate(jsonObject, "a").test().assertValue(value -> { - logger.info(value.getData()); - return true; - }); - validation.validate(jsonObject1, "a").test().assertError(error -> true); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java new file mode 100644 index 000000000..3209fe696 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java @@ -0,0 +1,32 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.JsonArrayValidation; + +import io.vertx.core.json.JsonArray; + +public class JsonArrayValidationTest { + + @Test + public void test_json_array_success() { + Validation validation = new JsonArrayValidation<>(); + + validation.validate(new JsonArray().add(1).add(2).add(3)).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_json_array_failure() { + Validation validation = new JsonArrayValidation<>(); + + validation.validate(1).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java new file mode 100644 index 000000000..03f559518 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java @@ -0,0 +1,33 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.JsonObjectValidation; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class JsonObjectValidationTest { + + @Test + public void test_json_object_success() { + Validation validation = new JsonObjectValidation<>(); + + validation.validate(new JsonObject().put("result", "success")).test().assertValue(value -> { + System.out.println(value.getData()); + return value.getData().getValue("result").equals("success"); + }); + } + + @Test + public void test_json_object_failure() { + Validation validation = new JsonObjectValidation<>(); + + validation.validate(new JsonArray().add(1).add(2)).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java new file mode 100644 index 000000000..80bbac1a0 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java @@ -0,0 +1,83 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.JsonConverter; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.ValidationSupplier; +import com.nubeiot.core.validator.validations.KeyLoop; +import com.nubeiot.core.validator.validations.StringValidation; + +import io.reactivex.Single; +import io.vertx.core.json.JsonObject; + +public class KeyLoopTest { + + @Test + public void test_json_object_values_as_strings_success() { + class ObjectValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonObject jsonObject = new JsonObject().put("first_name", "Shane").put("last_name", "Watson"); + Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); + keyLoop.validate(jsonObject).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_json_object_values_as_strings_failure() { + class ObjectValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonObject jsonObject = new JsonObject().put("first_name", "Shane").put("last_name", "Watson").put("age", 33); + Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); + keyLoop.validate(jsonObject).test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + + @Test + public void test_json_object_values_as_strings_failure_with_json_converter() { + class ObjectValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonObject jsonObject = new JsonObject().put("details", new JsonObject().put("first_name", "Shane") + .put("last_name", "Watson") + .put("age", 33)); + Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); + + JsonConverter.validate(keyLoop, jsonObject, "details").test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java new file mode 100644 index 000000000..99c29f54d --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java @@ -0,0 +1,82 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.JsonConverter; +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.ValidationSupplier; +import com.nubeiot.core.validator.validations.Loop; +import com.nubeiot.core.validator.validations.StringValidation; + +import io.reactivex.Single; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class LoopTest { + + @Test + public void test_json_object_values_as_strings_success() { + class JsonArrayValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonArray jsonArray = new JsonArray().add("Hello").add("World"); + Validation loop = new Loop<>(new JsonArrayValidation<>()); + loop.validate(jsonArray).test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_json_object_values_as_strings_failure() { + class JsonArrayValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonArray jsonArray = new JsonArray().add("Hello").add(123); + Validation loop = new Loop<>(new JsonArrayValidation<>()); + loop.validate(jsonArray).test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + + @Test + public void test_json_object_values_as_strings_failure_with_json_converter() { + class JsonArrayValidation implements ValidationSupplier { + + private Validation sv = new StringValidation<>(); + + @Override + public Single> get(V s, String parentField) { + return JsonConverter.validate(sv, s, parentField, "").map(x -> x); + } + + } + + JsonObject jsonObject = new JsonObject().put("details", new JsonArray().add("Hello").add(123)); + Validation loop = new Loop<>(new JsonArrayValidation<>()); + + JsonConverter.validate(loop, jsonObject, "details").test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java index 3321695af..c0d84caee 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java @@ -5,19 +5,22 @@ import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.validations.Max; -import io.vertx.core.json.JsonObject; - public class MaxTest { @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 10.000); - JsonObject jsonObject1 = new JsonObject().put("a", 10); - JsonObject jsonObject2 = new JsonObject().put("a", 40d); - Validation validation = new Max<>(15d); - validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject2, "a").test().assertError(error -> true); + public void test_max_success() { + Validation validation = new Max<>(15d); + validation.validate(10.00).test().assertValue(value -> value.getData() == 10d); + validation.validate(10).test().assertValue(value -> value.getData() == 10d); + } + + @Test + public void test_max_failure() { + Validation validation = new Max<>(15d); + validation.validate(40d).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java new file mode 100644 index 000000000..f5662ca6d --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java @@ -0,0 +1,26 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.Min; + +public class MinTest { + + @Test + public void test_min_success() { + Validation validation = new Min<>(5d); + validation.validate(10.00).test().assertValue(value -> value.getData() == 10d); + validation.validate(10).test().assertValue(value -> value.getData() == 10d); + } + + @Test + public void test_min_failure() { + Validation validation = new Min<>(5d); + validation.validate(4d).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java deleted file mode 100644 index 4526b9e74..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinValidationTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Min; - -import io.vertx.core.json.JsonObject; - -public class MinValidationTest { - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 10.000); - JsonObject jsonObject1 = new JsonObject().put("a", 10); - JsonObject jsonObject2 = new JsonObject().put("a", 4d); - Validation validation = new Min<>(5d); - validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject2, "a").test().assertError(error -> true); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java new file mode 100644 index 000000000..94c3f267a --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java @@ -0,0 +1,31 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.NumberOrStringValidation; + +import io.vertx.core.json.JsonObject; + +public class NumberOrStringValidationTest { + + @Test + public void test_numeric_or_string_success() { + Validation validation = new NumberOrStringValidation<>(); + + validation.validate(1).test().assertValue(v -> true); + validation.validate(1.0).test().assertValue(v -> true); + validation.validate("1").test().assertValue(v -> true); + } + + @Test + public void test_numeric_or_string_failure() { + Validation validation = new NumberOrStringValidation<>(); + + validation.validate(new JsonObject().put("a", 1)).test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java new file mode 100644 index 000000000..4be84663f --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java @@ -0,0 +1,28 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.NumberValidation; + +public class NumberValidationTest { + + @Test + public void test_numeric_success() { + Validation validation = new NumberValidation<>(); + + validation.validate(1).test().assertValue(v -> true); + validation.validate(1.0).test().assertValue(v -> true); + } + + @Test + public void test_numeric_failure() { + Validation validation = new NumberValidation<>(); + + validation.validate("1").test().assertError(e -> { + System.out.println(e.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java deleted file mode 100644 index 196f25163..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericOrStringTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.TestBase; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.NumericOrString; - -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - -public class NumericOrStringTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1); - JsonObject jsonObject2 = new JsonObject().put("a", 1.0); - JsonObject jsonObject3 = new JsonObject().put("a", "1"); - JsonObject jsonObject4 = new JsonObject().put("a", new JsonObject()); - Validation validation = new NumericOrString<>(); - - validation.validate(jsonObject, "a").test().assertValue(v -> true); - validation.validate(jsonObject2, "a").test().assertValue(v -> true); - validation.validate(jsonObject3, "a").test().assertValue(v -> true); - validation.validate(jsonObject4, "a").test().assertError(e -> { - logger.error(e.getMessage()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java deleted file mode 100644 index 3b1544979..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumericTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.TestBase; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Numeric; - -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; - -public class NumericTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(NumericTest.class); - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1); - JsonObject jsonObject2 = new JsonObject().put("a", 1.0); - JsonObject jsonObject3 = new JsonObject().put("a", "1"); - Validation validation = new Numeric<>(); - - validation.validate(jsonObject, "a").test().assertValue(v -> true); - validation.validate(jsonObject2, "a").test().assertValue(v -> true); - validation.validate(jsonObject3, "a").test().assertError(e -> { - logger.error(e.getMessage()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java deleted file mode 100644 index 06b3886be..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/PtrnTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Ptrn; - -import io.vertx.core.json.JsonObject; - -public class PtrnTest { - - @Test - public void test_validate() { - JsonObject object = new JsonObject().put("a", "0123456"); - JsonObject object1 = new JsonObject().put("a", "012ABC"); - Validation validation = new Ptrn("[0-9]+"); - validation.validate(object, "a").test().assertValue(ignore -> true); - validation.validate(object1, "a").test().assertError(ignore -> true); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java index a4d0ae463..d20ba3d76 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java @@ -2,33 +2,27 @@ import org.junit.Test; -import com.nubeiot.core.TestBase; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.validations.Range; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; +public class RangeTest { -public class RangeTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(NumericOrStringTest.class); + @Test + public void test_range_success() { + Validation validation = new Range<>(5d, 15d); + validation.validate(10.0).test().assertValue(value -> value.getData() == 10d); + validation.validate(10).test().assertValue(value -> value.getData() == 10d); + } @Test - public void test_rangeValidate() { - JsonObject jsonObject = new JsonObject().put("a", 10.000); - JsonObject jsonObject1 = new JsonObject().put("a", 10); - JsonObject jsonObject2 = new JsonObject().put("a", 4.0); - JsonObject jsonObject3 = new JsonObject().put("a", "4d"); - Validation validation = new Range<>(5d, 15d); - validation.validate(jsonObject, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData() == 10d); - validation.validate(jsonObject2, "a").test().assertError(error -> { - logger.error(error.getMessage()); + public void test_range_failure() { + Validation validation = new Range<>(5d, 15d); + validation.validate(4.0).test().assertError(error -> { + System.out.println(error.getMessage()); return true; }); - validation.validate(jsonObject3, "a").test().assertError(error -> { - logger.error(error.getMessage()); + validation.validate("4d").test().assertError(error -> { + System.out.println(error.getMessage()); return true; }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java new file mode 100644 index 000000000..9bcdda055 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java @@ -0,0 +1,28 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.RegexValidation; + +public class RegexValidationTest { + + @Test + public void test_regex_success() { + Validation validation = new RegexValidation("[0-9]+"); + validation.validate("0123456").test().assertValue(value -> { + System.out.println(value.getData()); + return true; + }); + } + + @Test + public void test_regex_failure() { + Validation validation = new RegexValidation("[0-9]+"); + validation.validate("012ABC").test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java index 8974646e7..2e738bce1 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java @@ -2,27 +2,30 @@ import org.junit.Test; -import com.nubeiot.core.TestBase; import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Int; +import com.nubeiot.core.validator.validations.IntegerValidation; import com.nubeiot.core.validator.validations.Required; -import core.nubeiot.core.validator.ValidationTest; -import io.vertx.core.json.JsonObject; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; +public class RequiredTest { -public class RequiredTest extends TestBase { - - private static final Logger logger = LoggerFactory.getLogger(ValidationTest.class); + @Test + public void test_required_integer_success() { + Validation validation = new Required<>(new IntegerValidation<>()); + validation.validate(1).test().assertValue(v -> { + System.out.println(v.getData()); + return true; + }); + } @Test - public void test_validateRequired() { - JsonObject jsonObject = new JsonObject().put("a", 1); - Validation validation = new Required<>(new Int<>()); - validation.validate(jsonObject, "a").test().assertValue(v -> true); - validation.validate(jsonObject, "b").test().assertError(e -> { - logger.error(e.getMessage()); + public void test_required_integer_failure() { + Validation validation = new Required<>(new IntegerValidation<>()); + validation.validate("1").test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + validation.validate(null).test().assertError(error -> { + System.out.println(error.getMessage()); return true; }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java deleted file mode 100644 index 6bf6c7fb4..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StrTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Str; - -import io.vertx.core.json.JsonObject; - -public class StrTest { - - @Test - public void test_validate() { - JsonObject jsonObject = new JsonObject().put("a", 1); - JsonObject jsonObject1 = new JsonObject().put("a", "1"); - Validation validation = new Str<>(); - validation.validate(jsonObject, "a").test().assertError(error -> true); - validation.validate(jsonObject1, "a").test().assertValue(value -> value.getData().equals("1")); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java new file mode 100644 index 000000000..5b8e9462c --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java @@ -0,0 +1,26 @@ +package core.nubeiot.core.validator.validations; + +import org.junit.Test; + +import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.validations.StringValidation; + +public class StringValidationTest { + + @Test + public void test_string_success() { + String message = "Hello World!"; + Validation validation = new StringValidation<>(); + validation.validate(message).test().assertValue(value -> value.getData().equals(message)); + } + + @Test + public void test_string_failure() { + Validation validation = new StringValidation<>(); + validation.validate(1).test().assertError(error -> { + System.out.println(error.getMessage()); + return true; + }); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java index 1effb8762..847bd6038 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java @@ -1,12 +1,16 @@ package core.nubeiot.core.validator.validations; import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import org.junit.Test; +import com.nubeiot.core.validator.JsonConverter; import com.nubeiot.core.validator.ValidationResult; import com.nubeiot.core.validator.validations.Any; -import com.nubeiot.core.validator.validations.Items; +import com.nubeiot.core.validator.validations.Contains; +import com.nubeiot.core.validator.validations.Forbidden; import com.nubeiot.core.validator.validations.When; import io.reactivex.Single; @@ -15,44 +19,87 @@ public class WhenTest { @Test - public void test_whenValidation() { + public void test_when_success() { /* Scenario 1: 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] 2. Otherwise, pass any value as valid*/ JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); - new When<>().registerIs(new Items<>(Arrays.asList(1, 2, 3)).validate(jsonObject, "id")) - .registerThen(new Items<>(Arrays.asList("ON", "OFF")).validate(jsonObject, "value")) - .registerOtherwise(new Any().validate(null)) - .validate(null) + new When<>().registerIs( + JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) + .registerThen( + JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, + "value")) + .registerOtherwise(new Forbidden<>().validate()) + .validate(jsonObject.getValue("id")) .test() .assertValue(value -> true); + } + @Test + public void test_when_failure() { /* Scenario 2: 1. When id is in [1] then it's values should be valid on ["ON" or "OFF"] 2. Otherwise, when id is in [2] then it's value should be valid on ["ON"] 3. Otherwise, pass any value as valid*/ - JsonObject jsonObject2 = new JsonObject().put("id", 2).put("value", "ON"); + JsonObject jsonObject = new JsonObject().put("id", 2).put("value", "ON"); Single> whenId2 = new When<>().registerIs( - new Items<>(Arrays.asList(2)).validate(jsonObject2, "id")) - .registerThen(new Items<>(Arrays.asList("OFF")) - .validate(jsonObject2, "value")) - .registerOtherwise(new Any().validate()) - .validate(); + JsonConverter.validate(new Contains<>(new HashSet<>(Collections.singletonList(2))), jsonObject, "id")) + .registerThen(JsonConverter.validate(new Contains<>( + new HashSet<>(Collections.singletonList("OFF"))), + jsonObject, + "value")) + .registerOtherwise(new Any<>().validate()) + .validate(jsonObject.getValue("id")); Single> whenId1 = new When<>().registerIs( - new Items<>(Arrays.asList(1)).validate(jsonObject2, "id")) - .registerThen(new Items<>( - Arrays.asList("ON", "OFF")).validate( - jsonObject2, "value")) + JsonConverter.validate(new Contains<>(new HashSet<>(Collections.singletonList(1))), jsonObject, "id")) + .registerThen(JsonConverter.validate(new Contains<>( + new HashSet<>(Arrays.asList("ON", "OFF"))), + jsonObject, + "value")) .registerOtherwise(whenId2) - .validate(); + .validate(jsonObject.getValue("id")); whenId1.test() .assertError(error -> error.getMessage() - .equals("ValidationError: \"value\" field value " + - "does not fall on the items [OFF]")); + .equals("ValidationError: \"value\" strictly should fall in the" + " [OFF]")); + } + + @Test + public void test_skip_when_validation_when_value_null_success() { + + /* Scenario 1: + 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, pass any value as valid*/ + JsonObject jsonObject = new JsonObject().put("id", 10).put("value", "ON"); + new When<>().registerIs( + JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) + .registerThen( + JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, + "value")) + .registerOtherwise(new Forbidden<>().validate()) + .validate(null) // value is null + .test() + .assertValue(value -> true); + } + + @Test + public void test_skip_when_validation_when_value_null_with_json_success() { + + /* Scenario 1: + 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, pass any value as valid*/ + JsonObject jsonObject = new JsonObject().put("value", "ON"); + JsonConverter.validate(new When<>().registerIs( + JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) + .registerThen(JsonConverter.validate( + new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, + "value")) + .registerOtherwise(new Forbidden<>().validate()), jsonObject, + "id") // JsonObject id value is null + .test().assertValue(value -> true); } } diff --git a/core/validator/src/test/resources/loop_and_key_loop_example.json b/core/validator/src/test/resources/loop_and_key_loop_example.json new file mode 100644 index 000000000..502daf337 --- /dev/null +++ b/core/validator/src/test/resources/loop_and_key_loop_example.json @@ -0,0 +1,21 @@ +{ + "details": [ + { + "visited_place": [ + "London", + "Melbourne" + ], + "on_list": [ + "Sydney", + "New York" + ] + }, + { + "movies": [ + "Forrest Gump", + "Bad Man", + 1 + ] + } + ] +} From e3780f2055707b4c5c53f76ff56b0864c5c71f8c Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Thu, 31 Jan 2019 16:27:43 +0545 Subject: [PATCH 3/6] - Improvements on error message display. --- .../com/nubeiot/core/validator/DataTypeValidation.java | 2 +- .../core/validator/validations/Alternative.java | 10 +++++++++- .../nubeiot/core/validator/validations/Contains.java | 4 ++-- .../nubeiot/core/validator/validations/KeyLoop.java | 2 +- .../com/nubeiot/core/validator/validations/Loop.java | 2 +- .../com/nubeiot/core/validator/validations/Max.java | 2 +- .../com/nubeiot/core/validator/validations/Min.java | 2 +- .../com/nubeiot/core/validator/validations/Range.java | 2 +- .../core/validator/validations/RegexValidation.java | 2 +- .../core/nubeiot/core/validator/JsonConverterTest.java | 4 ++-- .../core/nubeiot/core/validator/ValidationTest.java | 5 ++--- .../nubeiot/core/validator/validations/WhenTest.java | 2 +- 12 files changed, 23 insertions(+), 16 deletions(-) diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java index 9a9fc2612..eee954b95 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java @@ -18,7 +18,7 @@ public Single> validity(T s) { @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" is not the type of {2}", getErrorType(), getInput(), classType().getName()); + return Strings.format("{0}: {1} is not the type of {2}", getErrorType(), getInput(), classType().getName()); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java index 02edf029a..8ba75315b 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java @@ -5,6 +5,7 @@ import java.util.List; import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; @@ -28,7 +29,14 @@ public Single> validity(T s) { } if (exception.size() == validations.size()) { - source.onError(exception.get(0)); + String message = ""; + for (int i = 0; i < exception.size(); i++) { + message += exception.get(i).getMessage(); + if (i != exception.size() - 1) { + message += " || "; + } + } + source.onError(new ValidationError(message)); } }); } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java index 2269ab8f1..2eeed3824 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java @@ -44,8 +44,8 @@ public Single> validity(T s) { @Override protected String getErrorMessage() { return strict - ? Strings.format("{0}: \"{1}\" strictly should fall in the {2}", getErrorType(), getInput(), items) - : Strings.format("{0}: \"{1}\" should fall in the {2}", getErrorType(), getInput(), items); + ? Strings.format("{0}: {1} strictly should fall in the {2}", getErrorType(), getInput(), items) + : Strings.format("{0}: {1} should fall in the {2}", getErrorType(), getInput(), items); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java index 56ef88058..2aedb1350 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java @@ -25,7 +25,7 @@ public Single> validity(T s) { .flatMap(r -> ValidationResult.valid(jsonObject)); } else { return ValidationResult.invalid( - Strings.format("{0}: \"{1}\" must be of type JsonObject", getErrorType(), this.input)); + Strings.format("{0}: {1} must be of type JsonObject", getErrorType(), this.input)); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java index be7d16351..8a4e1f015 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java @@ -35,7 +35,7 @@ public Single> validity(T s) { }).toList().flatMap(r -> ValidationResult.valid(jsonArray)); } else { return ValidationResult.invalid( - Strings.format("{0}: \"{1}\" must be of type JsonArray", getErrorType(), this.input)); + Strings.format("{0}: {1} must be of type JsonArray", getErrorType(), this.input)); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java index eb320797e..b114e1a05 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java @@ -29,7 +29,7 @@ public Single> validity(T s) { @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" is not less than or equal to {2}", getErrorType(), getInput(), value); + return Strings.format("{0}: {1} is not less than or equal to {2}", getErrorType(), getInput(), value); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java index dd9ed08e3..ff2f63716 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java @@ -10,7 +10,7 @@ public Min(Double value) { @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" is not greater than or equal to {2}", getErrorType(), getInput(), value); + return Strings.format("{0}: {1} is not greater than or equal to {2}", getErrorType(), getInput(), value); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java index 9e2afd519..a5d05f2f9 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java @@ -30,7 +30,7 @@ public Single> validity(T s) { @Override protected String getErrorMessage() { - return Strings.format("{0}: \"{1}\" should be on range {2}-{3}", getErrorType(), getInput(), minValue, + return Strings.format("{0}: {1} should be on range [{2}-{3}]", getErrorType(), getInput(), minValue, maxValue); } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java index d00cca8c8..ac0c27229 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java @@ -26,7 +26,7 @@ public Single> validity(String s) { @Override public String getErrorMessage() { - return Strings.format("{0}: \"{1}\" does not match with the pattern \"{2}\"", getErrorType(), getInput(), + return Strings.format("{0}: {1} does not match with the pattern {2}", getErrorType(), getInput(), regex); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java index 8785956d8..f0baf743e 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java @@ -69,8 +69,8 @@ public void test_json_array_converter_with_parent_field_failure() { .assertError(error -> { System.out.println(error.getMessage()); return error.getMessage() - .equals("ValidationError: \"abc[0].a\" is not the type of io.vertx.core.json" + - ".JsonArray"); + .equals( + "ValidationError: abc[0].a is not the type of io.vertx.core.json.JsonArray"); }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java index 472d41bfe..63d0b546b 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java @@ -121,8 +121,7 @@ public Single> get(X s, String parentField) { Validation loop = new Loop<>(new DetailsJsonArrayValidation<>()); JsonConverter.validate(loop, jsonObject, "details").test().assertError(e -> { System.out.println(e.getMessage()); - return e.getMessage() - .equals("ValidationError: \"details[1].movies[2]\" is not the type of java.lang.String"); + return e.getMessage().equals("ValidationError: details[1].movies[2] is not the type of java.lang.String"); }); } @@ -203,7 +202,7 @@ public Single> get(V s, String parentField) { JsonConverter.validate(lv, jsonArray, "").test().assertError(e -> { System.out.println(e.getMessage()); return e.getMessage() - .equals("ValidationError: \"[1].details.basic.interests[1].music\" is not the type " + + .equals("ValidationError: [1].details.basic.interests[1].music is not the type " + "of java.lang.String"); }); } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java index 847bd6038..f0e6a3644 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java @@ -64,7 +64,7 @@ public void test_when_failure() { whenId1.test() .assertError(error -> error.getMessage() - .equals("ValidationError: \"value\" strictly should fall in the" + " [OFF]")); + .equals("ValidationError: value strictly should fall in the" + " [OFF]")); } @Test From e51c818665eb3ad9b602265ce71f9888eeb21dac Mon Sep 17 00:00:00 2001 From: zero-88 Date: Fri, 1 Feb 2019 00:04:34 +0700 Subject: [PATCH 4/6] - Proposal validation solution --- .../proposal/DependencyValidation.java | 39 ++++++++++++ .../core/validator/proposal/Validation.java | 10 ++++ .../validator/proposal/ValidationHolder.java | 38 ++++++++++++ .../validator/proposal/ValidationResult.java | 15 +++++ .../core/validator/proposal/Validator.java | 60 +++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/proposal/DependencyValidation.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validation.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationHolder.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationResult.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/DependencyValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/DependencyValidation.java new file mode 100644 index 000000000..719d66d80 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/DependencyValidation.java @@ -0,0 +1,39 @@ +package com.nubeiot.core.validator.proposal; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import lombok.NonNull; + +public interface DependencyValidation extends ValidationHolder { + + /** + * Dependency validations + *

+ * It means after validating specified key then do validate for another + */ + //TODO: maybe need to detected Circular dependency + Map>> dependencies(); + + DependencyValidation add(@NonNull String field, @NonNull Validation validation, + @NonNull Map> depends); + + DependencyValidation add(@NonNull String field, @NonNull Validation validation, @NonNull String dependField, + Validation... dependValidations); + + @Override + default ValidationResult validate(T data) { + //Collect data + validations().forEach((key, validations) -> { + Object v = get(data, key); + validations.forEach(validation -> validation.validate(v)); + dependencies().getOrDefault(key, new HashMap<>()).forEach((k2, validations2) -> { + Object v2 = get(data, k2); + validations2.forEach(validation -> validation.validate(v2)); + }); + }); + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validation.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validation.java new file mode 100644 index 000000000..a022e9491 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validation.java @@ -0,0 +1,10 @@ +package com.nubeiot.core.validator.proposal; + +/** + * @param + */ +public interface Validation { + + ValidationResult validate(T data); + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationHolder.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationHolder.java new file mode 100644 index 000000000..d4fc5602f --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationHolder.java @@ -0,0 +1,38 @@ +package com.nubeiot.core.validator.proposal; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import lombok.NonNull; + +/** + * For map, json object, or POJO + * + * @param + */ +public interface ValidationHolder extends Validation { + + Map> validations(); + + ValidationHolder add(String field, @NonNull Validation validation); + + Object get(T data, String key); + + default ValidationHolder add(String field, Validation... validations) { + Arrays.stream(validations).filter(Objects::nonNull).forEach(validation -> add(field, validation)); + return this; + } + + @Override + default ValidationResult validate(T data) { + //Collect data + validations().forEach((s, validations) -> { + Object v = get(data, s); + validations.forEach(validation -> validation.validate(v)); + }); + return null; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationResult.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationResult.java new file mode 100644 index 000000000..bffbfa5fb --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/ValidationResult.java @@ -0,0 +1,15 @@ +package com.nubeiot.core.validator.proposal; + +import java.util.List; + +public interface ValidationResult { + + T data(); + + default boolean isValid() { + return errors().isEmpty(); + } + + List errors(); + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java new file mode 100644 index 000000000..0710f108b --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java @@ -0,0 +1,60 @@ +package com.nubeiot.core.validator.proposal; + +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; + +import com.nubeiot.core.exceptions.ValidationError; + +import lombok.Builder; +import lombok.Builder.Default; +import lombok.NonNull; +import lombok.Singular; + +@Builder(builderClassName = "Builder") +public class Validator { + + private T defaultValue; + //TODO introduce some static BiFunction such as merge json + @Default + private BiFunction mergeFunc = (t, t2) -> Objects.isNull(t2) ? t : t2; + @Default + private boolean nullable = true; + @NonNull + @Singular + private List> validations; + + /** + * Validate data to the end then bundle all errors in {@link ValidationResult} + * + * @param data + * @return + */ + public ValidationResult execute(T data) { + T merged = before(data); + // TODO: Collect and merge all errors if any at here + validations.forEach(validation -> validation.validate(merged)); + return null; + } + + /** + * Validate data and raise error immediately if encounter any error + * + * @param data + * @return + */ + public ValidationResult eagerExecute(T data) { + T merged = before(data); + return null; + } + + private T before(T data) { + T d = mergeFunc.apply(defaultValue, data); + if (Objects.isNull(d) && !nullable) { + // or return ValidationResult + throw new ValidationError("non null"); + } + return d; + } + +} From 5455b975a4442fac8ceea7df842ed6a440d410ae Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Sat, 9 Feb 2019 00:37:32 +0545 Subject: [PATCH 5/6] - Finalizing the ValidationBase. --- build.gradle | 2 +- .../core/exceptions/ValidationError.java | 26 ++- .../com/nubeiot/core/utils/JsonUtils.java | 121 ++++++++++ .../com/nubeiot/core/utils/JsonUtilsTest.java | 113 ++++++++++ .../core/validator/DataTypeValidation.java | 20 +- .../nubeiot/core/validator/JsonConverter.java | 108 --------- .../com/nubeiot/core/validator/JsonLoop.java | 85 +++++++ .../core/validator/JsonValidationHolder.java | 47 ++++ .../nubeiot/core/validator/Validation.java | 58 +---- .../core/validator/ValidationHolder.java | 63 ++++++ .../core/validator/ValidationResult.java | 39 ++-- .../core/validator/ValidationSupplier.java | 9 - .../com/nubeiot/core/validator/Validator.java | 69 ++++++ .../java/com/nubeiot/core/validator/When.java | 88 ++++++++ .../core/validator/proposal/Validator.java | 4 +- .../core/validator/utils/ValidationUtils.java | 48 ++++ .../validator/validations/Alternative.java | 63 +++--- .../core/validator/validations/Any.java | 15 +- .../validator/validations/Composition.java | 64 ++++-- .../core/validator/validations/Contains.java | 16 +- .../core/validator/validations/Exist.java | 19 +- .../core/validator/validations/Forbidden.java | 24 +- .../validations/IntegerValidation.java | 2 +- .../validations/JsonArrayValidation.java | 3 +- .../validations/JsonObjectValidation.java | 2 +- .../core/validator/validations/KeyLoop.java | 37 --- .../core/validator/validations/Loop.java | 47 ---- .../core/validator/validations/Max.java | 24 +- .../core/validator/validations/Min.java | 9 +- .../validations/NumberOrStringValidation.java | 14 +- .../validations/NumberValidation.java | 2 +- .../core/validator/validations/Range.java | 28 +-- .../validations/RegexValidation.java | 20 +- .../core/validator/validations/Required.java | 17 +- .../validations/StringValidation.java | 2 +- .../core/validator/validations/When.java | 43 ---- .../core/validator/JsonConverterTest.java | 77 ------- .../core/validator/JsonLoopingTest.java | 79 +++++++ .../validator/JsonValidationHolderTest.java | 78 +++++++ .../validator/RegisterDefaultValueTest.java | 51 ++--- .../core/validator/ValidationResultTest.java | 25 --- .../core/validator/ValidationTest.java | 211 ------------------ .../core/nubeiot/core/validator/WhenTest.java | 77 +++++++ .../validator/utils/ValidationUtilsTest.java | 5 + .../validations/AlternativeTest.java | 27 +-- .../core/validator/validations/AnyTest.java | 8 +- .../validations/CompositionTest.java | 22 +- .../validator/validations/ContainsTest.java | 41 ++-- .../core/validator/validations/ExistTest.java | 19 +- .../validator/validations/ForbiddenTest.java | 24 +- .../validations/IntegerValidationTest.java | 77 ++++++- .../validations/JsonArrayValidationTest.java | 20 +- .../validations/JsonObjectValidationTest.java | 21 +- .../validator/validations/KeyLoopTest.java | 83 ------- .../core/validator/validations/LoopTest.java | 82 ------- .../core/validator/validations/MaxTest.java | 18 +- .../core/validator/validations/MinTest.java | 17 +- .../NumberOrStringValidationTest.java | 20 +- .../validations/NumberValidationTest.java | 19 +- .../core/validator/validations/RangeTest.java | 24 +- .../validations/RegexValidationTest.java | 20 +- .../validator/validations/RequiredTest.java | 26 +-- .../validations/StringValidationTest.java | 15 +- .../core/validator/validations/WhenTest.java | 105 --------- .../validator/src/test/resources/example.json | 20 +- .../resources/loop_and_key_loop_example.json | 31 +-- 66 files changed, 1360 insertions(+), 1333 deletions(-) create mode 100644 core/base/src/main/java/com/nubeiot/core/utils/JsonUtils.java create mode 100644 core/base/src/test/java/com/nubeiot/core/utils/JsonUtilsTest.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/ValidationHolder.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/Validator.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/When.java create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/utils/ValidationUtils.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationHolderTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/utils/ValidationUtilsTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java diff --git a/build.gradle b/build.gradle index d74ac25c2..91e0967e6 100644 --- a/build.gradle +++ b/build.gradle @@ -73,13 +73,13 @@ subprojects { compile project.deps.jackson.databind compile project.deps.logs.slf4j compile project.deps.logs.logback + compile project.deps.tests.jsonAssert compileOnly project.deps.vertx.codegen compileOnly project.deps.lombok annotationProcessor project.deps.lombok testCompile project.deps.tests.junit - testCompile project.deps.tests.jsonAssert testCompile project.deps.vertx.junit testCompileOnly project.deps.lombok testAnnotationProcessor project.deps.lombok diff --git a/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java b/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java index e9510f2b0..a5e4abebe 100644 --- a/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java +++ b/core/base/src/main/java/com/nubeiot/core/exceptions/ValidationError.java @@ -1,15 +1,27 @@ package com.nubeiot.core.exceptions; -import lombok.NonNull; +import com.nubeiot.core.utils.Strings; -public class ValidationError extends NubeException { +import lombok.Builder; - public ValidationError(@NonNull ErrorCode code, @NonNull String message) { - super(code, message); - } +@Builder(builderClassName = "Builder") +public class ValidationError { + + static final NubeException.ErrorCode DEFAULT_ERROR_CODE = NubeException.ErrorCode.INVALID_ARGUMENT; + static final String DEFAULT_ERROR_TYPE = "ValidationError"; + + @lombok.Builder.Default + private NubeException.ErrorCode errorCode = DEFAULT_ERROR_CODE; + @lombok.Builder.Default + private String errorType = DEFAULT_ERROR_TYPE; + @lombok.Builder.Default + private String value = ""; + private String message; - public ValidationError(@NonNull String message) { - super(ErrorCode.INVALID_ARGUMENT, message); + public NubeException execute() { + String errorMessage = (((Strings.isNotBlank(errorType) ? errorType + ": " : "") + value).trim() + " " + message) + .trim(); + return new NubeException(errorCode, errorMessage); } } diff --git a/core/base/src/main/java/com/nubeiot/core/utils/JsonUtils.java b/core/base/src/main/java/com/nubeiot/core/utils/JsonUtils.java new file mode 100644 index 000000000..d45ff5c43 --- /dev/null +++ b/core/base/src/main/java/com/nubeiot/core/utils/JsonUtils.java @@ -0,0 +1,121 @@ +package com.nubeiot.core.utils; + +import java.util.Map; +import java.util.function.BiFunction; + +import org.skyscreamer.jsonassert.JSONCompare; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.skyscreamer.jsonassert.JSONCompareResult; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class JsonUtils { + + /** + * JsonObject @source gets merge with the JsonObject @defaultValue. + */ + public static BiFunction mergeJsonObjectFunc = (source, defaultValue) -> { + ((JsonObject) defaultValue).forEach( + (defaultValueMap) -> iterateMergeFunction((JsonObject) source, defaultValueMap)); + return source; + }; + + public static Object getObject(JsonObject s, String field, Object defaultValue) { + Object output = getObject(s, field); + if (output == null) { + output = defaultValue; + } + return output; + } + + public static Object getObject(JsonObject s, String field) { + String[] fields; + if (Strings.isNotBlank(field)) { + fields = field.split("\\."); + } else { + return s; + } + + Object output = null; + + try { + for (int i = 0; i < fields.length - 1; i++) { + s = s.getJsonObject(fields[i]); + } + output = s.getValue(fields[fields.length - 1]); + } catch (NullPointerException | ClassCastException ignored) { + } + return output; + } + + public static boolean compareJsonObject(JsonObject expected, JsonObject actual) { + if (expected == null && actual == null) { + return true; + } else if (expected == null || actual == null) { + return false; + } + + JSONCompareResult result = null; + try { + result = JSONCompare.compareJSON(expected.encode(), actual.encode(), JSONCompareMode.STRICT); + } catch (org.json.JSONException e) { + e.printStackTrace(); + } + return result != null && result.passed(); + } + + private static void iterateMergeFunction(JsonObject source, Map.Entry defaultValueMap) { + Object defaultValue = defaultValueMap.getValue(); + String defaultKey = defaultValueMap.getKey(); + JsonObject sourceObject = source; + Object sourceValue = sourceObject.getValue(defaultKey); + if (defaultValue instanceof JsonObject && (sourceValue instanceof JsonObject || sourceValue == null)) { + if (sourceValue == null) { + sourceObject.put(defaultKey, new JsonObject()); + } + sourceObject = sourceObject.getJsonObject(defaultKey); + for (Map.Entry defaultValueMapChild : (JsonObject) defaultValue) { + iterateMergeFunction(sourceObject, defaultValueMapChild); + } + } else if (defaultValue instanceof JsonArray && (sourceValue instanceof JsonArray || sourceValue == null)) { + if (sourceValue == null) { + sourceObject.put(defaultKey, new JsonArray()); + } + JsonArray sourceArray = sourceObject.getJsonArray(defaultKey); + iterateJsonArrayMergeFunction(sourceArray, (JsonArray) defaultValue); + } else if (!(defaultValue instanceof Iterable) && !(sourceValue instanceof Iterable)) { + if (sourceValue == null) { + sourceObject.put(defaultKey, defaultValue); + } + } + } + + private static void iterateJsonArrayMergeFunction(JsonArray sourceArray, JsonArray defaultValueArray) { + Object defaultValue = defaultValueArray.getValue(0); + if (defaultValue instanceof JsonObject) { + if (sourceArray.size() == 0) { + sourceArray.add(new JsonObject()); + } + for (Object o : sourceArray) { + ((JsonObject) defaultValue).forEach( + defaultValueMapChild -> iterateMergeFunction((JsonObject) o, defaultValueMapChild)); + } + } else if (defaultValue instanceof JsonArray) { + if (sourceArray.size() == 0) { + sourceArray.add(new JsonArray()); + } + for (Object o : sourceArray) { + if (o instanceof JsonArray) { + iterateJsonArrayMergeFunction((JsonArray) o, (JsonArray) defaultValue); + } + } + } else { + if (sourceArray.size() == 0) { + sourceArray.add(defaultValue); + } + } + } + +} + diff --git a/core/base/src/test/java/com/nubeiot/core/utils/JsonUtilsTest.java b/core/base/src/test/java/com/nubeiot/core/utils/JsonUtilsTest.java new file mode 100644 index 000000000..876690388 --- /dev/null +++ b/core/base/src/test/java/com/nubeiot/core/utils/JsonUtilsTest.java @@ -0,0 +1,113 @@ +package com.nubeiot.core.utils; + +import org.json.JSONException; +import org.junit.Assert; +import org.junit.Test; +import org.skyscreamer.jsonassert.JSONAssert; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class JsonUtilsTest { + + @Test + public void test_get_json_value() { + JsonObject jsonObject = new JsonObject().put("details", new JsonObject().put("first_name", "Shane") + .put("last_name", "Watson") + .put("club", new JsonArray().add( + "Sydney Sixers").add("RR"))); + Assert.assertEquals(JsonUtils.getObject(jsonObject, "details").toString(), + "{\"first_name\":\"Shane\"," + "\"last_name\":\"Watson\",\"club\":[\"Sydney " + + "Sixers\",\"RR\"]}"); + Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.first_name"), "Shane"); + Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.last_name"), "Watson"); + Assert.assertEquals(JsonUtils.getObject(jsonObject, "details.club").toString(), "[\"Sydney Sixers\",\"RR\"]"); + + Assert.assertNull(JsonUtils.getObject(jsonObject, "details.last_name.club")); + } + + @Test + public void test_compareJsonObject_success() { + JsonObject actual = new JsonObject().put("details", new JsonObject().put("first_name", "Shane")); + JsonObject expected = new JsonObject().put("details", new JsonObject().put("first_name", "Shane")); + + Assert.assertTrue(JsonUtils.compareJsonObject(expected, actual)); + Assert.assertTrue(JsonUtils.compareJsonObject(null, null)); + } + + @Test + public void test_compareJsonObject_failure() { + JsonObject actual = new JsonObject().put("details", new JsonObject().put("first_name", "Shane")); + JsonObject expected = new JsonObject().put("details", new JsonObject()); + + Assert.assertFalse(JsonUtils.compareJsonObject(expected, actual)); + Assert.assertFalse(JsonUtils.compareJsonObject(expected, null)); + Assert.assertFalse(JsonUtils.compareJsonObject(null, actual)); + } + + @Test + public void test_mergeJsonObjectFunc1() throws JSONException { + JsonObject sourceJsonObject = new JsonObject().put("a", "10").put("d", new JsonArray()); + JsonObject defaultJsonObject = new JsonObject().put("b", 20) + .put("c", new JsonObject().put("x", "2")) + .put("d", new JsonArray().add(new JsonObject().put("y", 3))); + + JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject); + System.out.println(sourceJsonObject); + JSONAssert.assertEquals(sourceJsonObject.encode(), + "{\"a\":\"10\",\"d\":[{\"y\":3}],\"b\":20," + "\"c\":{\"x\":\"2\"}}", true); + } + + @Test + public void test_mergeJsonObjectFunc2() throws JSONException { + JsonObject sourceJsonObject = new JsonObject().put("a", "10") + .put("d", new JsonArray().add(new JsonObject().put("z", 3))); + JsonObject defaultJsonObject = new JsonObject().put("b", 20) + .put("c", new JsonObject().put("x", "2")) + .put("d", new JsonArray().add(new JsonObject().put("y", 3))); + + JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject); + System.out.println(sourceJsonObject); + JSONAssert.assertEquals(sourceJsonObject.encode(), + "{\"a\":\"10\",\"d\":[{\"z\":3,\"y\":3}],\"b\":20,\"c\":{\"x\":\"2\"}}", true); + } + + @Test + public void test_mergeJsonObjectFunc3() throws JSONException { + JsonObject sourceJsonObject = new JsonObject().put("a", "10").put("d", new JsonArray()); + JsonObject defaultJsonObject = new JsonObject().put("b", 20) + .put("c", new JsonObject().put("x", "2")) + .put("d", new JsonArray().add(new JsonArray().add("Hello"))); + + JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject); + System.out.println(sourceJsonObject); + JSONAssert.assertEquals(sourceJsonObject.encode(), + "{\"a\":\"10\",\"d\":[[\"Hello\"]],\"b\":20,\"c\":{\"x\":\"2\"}}", true); + } + + @Test + public void test_mergeJsonObjectFunc4() throws JSONException { + JsonObject sourceJsonObject = new JsonObject().put("a", "10"); + JsonObject defaultJsonObject = new JsonObject().put("b", 20) + .put("c", new JsonObject().put("x", "2")) + .put("d", new JsonArray().add("y")); + + JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject); + System.out.println(sourceJsonObject); + JSONAssert.assertEquals(sourceJsonObject.encode(), "{\"a\":\"10\",\"b\":20,\"c\":{\"x\":\"2\"},\"d\":[\"y\"]}", + true); + } + + @Test + public void test_mergeJsonObjectFunc5() throws JSONException { + JsonObject sourceJsonObject = new JsonObject().put("d", + new JsonArray().add(new JsonObject()).add(new JsonObject())); + JsonObject defaultJsonObject = new JsonObject().put("d", new JsonArray().add( + new JsonObject().put("x", new JsonArray().add("2")))); + + JsonUtils.mergeJsonObjectFunc.apply(sourceJsonObject, defaultJsonObject); + System.out.println(sourceJsonObject); + JSONAssert.assertEquals(sourceJsonObject.encode(), "{\"d\":[{\"x\":[\"2\"]},{\"x\":[\"2\"]}]}", true); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java index eee954b95..0e7a0fdd9 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/DataTypeValidation.java @@ -1,24 +1,20 @@ package com.nubeiot.core.validator; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; -import io.reactivex.Single; +public abstract class DataTypeValidation implements Validation { -public abstract class DataTypeValidation extends Validation { - - public abstract Class classType(); + protected abstract Class classType(); @Override - public Single> validity(T s) { + public ValidationResult validity(T s) { if (classType().isInstance(s)) { - return ValidationResult.valid(s); + return ValidationResult.valid(); } - return ValidationResult.invalid(getErrorMessage()); - } - @Override - protected String getErrorMessage() { - return Strings.format("{0}: {1} is not the type of {2}", getErrorType(), getInput(), classType().getName()); + return ValidationResult.invalid(ValidationError.builder() + .value(s == null ? null : s.toString()) + .message("is not the type of " + classType().getName())); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java deleted file mode 100644 index 505c2808b..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/JsonConverter.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.nubeiot.core.validator; - -import com.nubeiot.core.utils.Strings; - -import io.reactivex.Single; -import io.vertx.core.json.JsonObject; -import lombok.RequiredArgsConstructor; -import lombok.Setter; - -@RequiredArgsConstructor -public class JsonConverter extends Validation { - - private final Validation validator; - @Setter - private String parentField; - @Setter - private String field; - private Object defaultValue = null; - - public static Single> validate(Validation validator, E s, String field) { - return new JsonConverter<>(validator).validate(s, "", field); - } - - public static Single> validate(Validation validator, E s, String parentField, - String field) { - return new JsonConverter<>(validator).validate(s, parentField, field); - } - - public static Single> validate(Validation validator, E s, String parentField, - String field, Object defaultValue) { - return new JsonConverter<>(validator).registerDefaultValue(defaultValue).validate(s, parentField, field); - } - - /** - * @param defaultValue if value is null on the Json, then the default value will be inserted - * @return own class object - */ - public JsonConverter registerDefaultValue(Object defaultValue) { - this.defaultValue = defaultValue; - return this; - } - - @Override - public Single> validity(T s) { - - if (s instanceof JsonObject) { - T value = null; - // field is generally blank for Loop and KeyLoop - if (Strings.isBlank(field)) { - return validator.registerInput(buildInputField()).validate((I) s); - } - String[] fields = field.split("\\."); - JsonObject jsonObject = (JsonObject) s; - - try { - for (int i = 0; i < fields.length - 1; i++) { - if (jsonObject.getJsonObject(fields[i]) == null && this.defaultValue != null) { - jsonObject.put(fields[i], new JsonObject()); - } - jsonObject = jsonObject.getJsonObject(fields[i]); - } - value = (T) jsonObject.getValue(fields[fields.length - 1]); - } catch (NullPointerException ignored) { - } - - if (value == null) { - if (this.defaultValue != null) { - jsonObject.put(fields[fields.length - 1], defaultValue); - value = (T) defaultValue; - } - } - - return validator.registerInput(buildInputField()).validate((I) value); - } - - if (this.validator.isNullable() && s == null) { - return ValidationResult.valid(); - } - - // Case: JsonArray - return validator.registerInput(buildInputField()).validate((I) s); - } - - @Override - protected String getErrorMessage() { - return null; - } - - @Override - public Validation registerInput(String input) { - return this; - } - - public Single> validate(T s, String parentField, String field) { - this.parentField = parentField; - this.field = field; - return this.validate(s); - } - - String buildInputField() { - if (Strings.isNotBlank(parentField) && Strings.isNotBlank(this.field)) { - return this.parentField + "." + this.field; - } else { - return this.parentField + this.field; - } - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java new file mode 100644 index 000000000..57e405d8d --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java @@ -0,0 +1,85 @@ +package com.nubeiot.core.validator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.nubeiot.core.exceptions.ValidationError; +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.utils.ValidationUtils; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class JsonLoop extends JsonValidationHolder { + + protected final String parentField; + private List> jsonLoops = new ArrayList<>(); + private String previousParentField; + + public void add(@NonNull JsonLoop validation) { + jsonLoops.add(validation); + } + + @Override + public ValidationResult validate(T data) { + return validate(this, data); + } + + protected ValidationResult validate(JsonLoop looper, T data) { + if (nullable() && data == null) { + return ValidationResult.valid(); + } + + List validationResults = new ArrayList<>(); + + Object value = this.get(data, looper.parentField); + if (!(value instanceof JsonArray || value instanceof JsonObject)) { + return ValidationResult.invalid(ValidationError.builder() + .value(looper.parentField) + .message("is not the type of JsonArray || JsonObject")); + } + + Iterable v = (Iterable) value; + int i = 0; + for (final Object o : v) { + Object loopedValue; + String actualParentField = + (Strings.isNotBlank(looper.previousParentField) ? looper.previousParentField + "." : "") + + (Strings.isNotBlank(looper.parentField) ? looper.parentField + "." : ""); + + if (o instanceof Map.Entry) { + Map.Entry keyValuePair = (Map.Entry) o; + actualParentField += keyValuePair.getKey(); + loopedValue = keyValuePair.getValue(); + } else { + actualParentField += "[" + i + "]"; + i++; + loopedValue = o; + } + + for (Map.Entry>> entry : looper.validations.entrySet()) { + String key = entry.getKey(); + List> innerValidations = entry.getValue(); + Object validateValue = get(loopedValue, key); + for (Validation validation : innerValidations) { + String actualField = Strings.isNotBlank(key) ? actualParentField + "." + key : actualParentField; + validationResults.add( + ValidationUtils.transferValidationInputToFieldFunc.apply(validation.validate(validateValue), + actualField)); + } + } + + for (JsonLoop validation : looper.jsonLoops) { + validation.previousParentField = actualParentField; + validationResults.add(validation.validate(validation, this.get(loopedValue, validation.parentField))); + } + } + + return ValidationUtils.mergeValidationResultsFunc.apply(validationResults); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java new file mode 100644 index 000000000..e82c367c0 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java @@ -0,0 +1,47 @@ +package com.nubeiot.core.validator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.nubeiot.core.utils.JsonUtils; +import com.nubeiot.core.utils.Strings; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; +import lombok.NonNull; + +public class JsonValidationHolder implements ValidationHolder { + + protected Map>> validations = new HashMap<>(); + + @Override + public Map>> validations() { + return this.validations; + } + + @Override + public ValidationHolder add(String field, @NonNull Validation validation) { + List> validationList = this.validations.get(field); + if (validationList == null) { + validationList = new ArrayList<>(); + } + validationList.add(validation); + this.validations.put(field, validationList); + return this; + } + + @Override + public Object get(Object data, String key) { + if (Strings.isBlank(key) || data instanceof JsonArray) { + return data; + } + if (!(data instanceof JsonObject)) { + return null; + } + return JsonUtils.getObject((JsonObject) data, key); + } + +} + diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java index 0614faf5d..8e091c8a1 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/Validation.java @@ -1,63 +1,17 @@ package com.nubeiot.core.validator; -import com.nubeiot.core.exceptions.NubeException; +public interface Validation { -import io.reactivex.Single; -import lombok.Getter; -import lombok.Setter; - -public abstract class Validation { - - @Getter - protected String input = ""; - - @Getter - @Setter - private String errorType = "ValidationError"; - @Getter - @Setter - private NubeException.ErrorCode errorCode = NubeException.ErrorCode.INVALID_ARGUMENT; - private boolean overrideInput = true; - - /** - * @param s input value - * @return validation result - */ - public final Single> validate(T s) { - // May be default value also be failed on the validation - if (isNullable() && s == null) { + default ValidationResult validate(T data) { + if (nullable() && data == null) { return ValidationResult.valid(); } - - // Set input only if no DI occurred from parent on Method: registerInput(String input) - if (overrideInput) { - this.input = s != null ? s.toString() : ""; - } - - return this.validity(s); + return validity(data); } - /** - * This method contains the actual business logic for the individual validation - * - * @param s input value - * @return validation result - */ - public abstract Single> validity(T s); - - protected abstract String getErrorMessage(); - - /** - * @param input input value for displaying error value if exist - * @return own class object - */ - public Validation registerInput(String input) { - overrideInput = false; - this.input = input; - return this; - } + ValidationResult validity(T data); - protected boolean isNullable() { + default boolean nullable() { return true; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationHolder.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationHolder.java new file mode 100644 index 000000000..02bd8e14d --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationHolder.java @@ -0,0 +1,63 @@ +package com.nubeiot.core.validator; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import com.nubeiot.core.validator.utils.ValidationUtils; + +import lombok.NonNull; + +/** + * For map, json object, or POJO + * + * @param + */ +public interface ValidationHolder extends Validation { + + Map>> validations(); + + ValidationHolder add(String field, @NonNull Validation validation); + + Object get(Object data, String field); + + default ValidationHolder add(String field, Validation... validations) { + Arrays.stream(validations).filter(Objects::nonNull).forEach(validation -> add(field, validation)); + return this; + } + + @Override + default ValidationResult validate(T data) { + final List validationResults = new ArrayList<>(); + validations().forEach((field, validations) -> { + Object v = get(data, field); + validations.forEach(validation -> validationResults.add( + ValidationUtils.transferValidationInputToFieldFunc.apply(validation.validate(v), field))); + }); + return ValidationUtils.mergeValidationResultsFunc.apply(validationResults); + } + + @Override + default ValidationResult validity(T data) { + return null; + } + + // todo: we will work on this + default ValidationResult eagerValidate(T data) { + for (Map.Entry>> entry : validations().entrySet()) { + String field = entry.getKey(); + List> validations = entry.getValue(); + Object v = get(data, field); + for (Validation validation : validations) { + ValidationResult validationResult = validation.validate(v); + if (!validationResult.errors().isEmpty()) { + return ValidationUtils.transferValidationInputToFieldFunc.apply(validationResult, field); + } + } + } + return ValidationResult.valid(); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java index 821d61b69..863204ef8 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationResult.java @@ -1,35 +1,40 @@ package com.nubeiot.core.validator; -import com.nubeiot.core.exceptions.NubeException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import com.nubeiot.core.exceptions.ValidationError; -import io.reactivex.Single; +import lombok.AllArgsConstructor; import lombok.Getter; -import lombok.RequiredArgsConstructor; +import lombok.NoArgsConstructor; @Getter -@RequiredArgsConstructor -public class ValidationResult { +@NoArgsConstructor +@AllArgsConstructor +public class ValidationResult { + + List errors = new ArrayList<>(); - private T data; + public static ValidationResult valid() { + return new ValidationResult(); + } - public static Single> valid() { - ValidationResult validationResult = new ValidationResult<>(); - return Single.just(validationResult); + public static ValidationResult invalid(List validationErrorBuilders) { + return new ValidationResult(validationErrorBuilders); } - public static Single> valid(E data) { - ValidationResult validationResult = new ValidationResult<>(); - validationResult.data = data; - return Single.just(validationResult); + public static ValidationResult invalid(ValidationError.Builder validationErrorBuilder) { + return invalid(Collections.singletonList(validationErrorBuilder)); } - public static Single> invalid(NubeException.ErrorCode errorCode, String message) { - return Single.error(new ValidationError(errorCode, message)); + public boolean isValid() { + return errors().isEmpty(); } - public static Single> invalid(String message) { - return Single.error(new ValidationError(message)); + public List errors() { + return errors; } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java b/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java deleted file mode 100644 index d092d5d8a..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/ValidationSupplier.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.nubeiot.core.validator; - -import io.reactivex.Single; - -public interface ValidationSupplier { - - Single> get(T s, String parentField); - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/Validator.java b/core/validator/src/main/java/com/nubeiot/core/validator/Validator.java new file mode 100644 index 000000000..d3a34a8cf --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/Validator.java @@ -0,0 +1,69 @@ +package com.nubeiot.core.validator; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.BiFunction; + +import com.nubeiot.core.exceptions.ValidationError; + +import lombok.Builder; +import lombok.Builder.Default; +import lombok.NonNull; +import lombok.Singular; + +@Builder(builderClassName = "Builder") +public class Validator { + + private T defaultValue; + @Default + private BiFunction mergeFunc = (o1, o2) -> Objects.isNull(o1) ? o2 : o1; + @Default + private boolean nullable = true; + @NonNull + @Singular + private List> validations; + + /** + * Validate data to the end then bundle all errors in {@link ValidationResult} + * + * @param data + * @return + */ + public ValidationResult execute(T data) { + T merged = before(data); + List errors = new ArrayList<>(); + for (Validation validation : validations) { + ValidationResult validationResult = validation.validate(merged); + if (!validationResult.errors().isEmpty()) { + errors.addAll(validationResult.errors()); + } + } + return new ValidationResult(errors); + } + + /** + * Validate data and raise error immediately if encounter any error + * + * @param data + * @return + */ + public ValidationResult eagerExecute(T data) { + T merged = before(data); + for (Validation validation : validations) { + ValidationResult validationResult; + + validationResult = validation.validate(merged); + + if (!validationResult.errors().isEmpty()) { + return ValidationResult.invalid(validationResult.errors()); + } + } + return ValidationResult.valid(); + } + + private T before(T data) { + return mergeFunc.apply(data, defaultValue); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/When.java b/core/validator/src/main/java/com/nubeiot/core/validator/When.java new file mode 100644 index 000000000..32f6baf87 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/When.java @@ -0,0 +1,88 @@ +package com.nubeiot.core.validator; + +import java.util.HashSet; +import java.util.Set; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.exceptions.ValidationError; +import com.nubeiot.core.utils.JsonUtils; +import com.nubeiot.core.validator.utils.ValidationUtils; + +import io.vertx.core.json.JsonObject; +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class When implements Validation { + + private String isField; + private String thenField; + private String otherwiseField; + + private Validation is; + private Validation then; + private Validation otherwise; + + private Set inputs = new HashSet<>(); + + public Object get(T data, String key) { + if (!(data instanceof JsonObject)) { + return null; + } + return JsonUtils.getObject((JsonObject) data, key); + } + + @Override + public ValidationResult validity(T s) { + if (inputs.size() == 3) { // when all case are specified + Object v = get(s, isField); + if (is.validate(v).isValid()) { + v = get(s, thenField); + return ValidationUtils.transferValidationInputToFieldFunc.apply(then.validate(v), thenField); + } else { + v = get(s, otherwiseField); + if (otherwise instanceof When) { + return otherwise.validate(v); + } + return ValidationUtils.transferValidationInputToFieldFunc.apply(otherwise.validate(v), otherwiseField); + } + } else { + return ValidationResult.invalid(ValidationError.builder() + .errorCode(NubeException.ErrorCode.INITIALIZER_ERROR) + .message("When validation Initialization Error")); + } + } + + public void setIs(String field, Validation is) { + inputs.add(1); + this.isField = field; + this.is = is; + } + + public void setThen(String field, Validation then) { + inputs.add(2); + this.thenField = field; + this.then = then; + } + + public void setOtherwise(String field, Validation otherwise) { + inputs.add(3); + this.otherwiseField = field; + this.otherwise = otherwise; + } + + public void setIs(Validation is) { + inputs.add(1); + this.is = is; + } + + public void setThen(Validation then) { + inputs.add(2); + this.then = then; + } + + public void setOtherwise(Validation otherwise) { + inputs.add(3); + this.otherwise = otherwise; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java index 0710f108b..03ba68e7e 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/proposal/Validator.java @@ -4,8 +4,6 @@ import java.util.Objects; import java.util.function.BiFunction; -import com.nubeiot.core.exceptions.ValidationError; - import lombok.Builder; import lombok.Builder.Default; import lombok.NonNull; @@ -52,7 +50,7 @@ private T before(T data) { T d = mergeFunc.apply(defaultValue, data); if (Objects.isNull(d) && !nullable) { // or return ValidationResult - throw new ValidationError("non null"); + // throw new ValidationError("non null"); } return d; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/utils/ValidationUtils.java b/core/validator/src/main/java/com/nubeiot/core/validator/utils/ValidationUtils.java new file mode 100644 index 000000000..b1baaf5cc --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/utils/ValidationUtils.java @@ -0,0 +1,48 @@ +package com.nubeiot.core.validator.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.exceptions.ValidationError; +import com.nubeiot.core.validator.ValidationResult; + +public class ValidationUtils { + + public static Function, NubeException> convertValidationErrorsToException + = (List errorBuilders) -> { + StringBuilder message = new StringBuilder(); + NubeException.ErrorCode code = NubeException.ErrorCode.INVALID_ARGUMENT; + for (int i = 0; i < errorBuilders.size(); i++) { + NubeException nubeException = errorBuilders.get(i).build().execute(); + message.append(nubeException.getMessage()); + if (code != nubeException.getErrorCode()) { + code = nubeException.getErrorCode(); + } + if (i < errorBuilders.size() - 1) { + message.append(" && "); + } + } + return new NubeException(code, message.toString()); + }; + + public static BiFunction transferValidationInputToFieldFunc + = (validationResult, field) -> { + validationResult.errors().forEach(error -> error.value(field)); + return validationResult; + }; + + public static Function, ValidationResult> mergeValidationResultsFunc + = (validationResults) -> { + List validationErrors = new ArrayList<>(); + for (ValidationResult validationResult : validationResults) { + if (!validationResult.errors().isEmpty()) { + validationErrors.addAll(validationResult.errors()); + } + } + return new ValidationResult(validationErrors); + }; + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java index 8ba75315b..3c3fa23b6 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Alternative.java @@ -3,47 +3,54 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.function.BiFunction; +import java.util.stream.Collectors; import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.utils.ValidationUtils; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Alternative extends Validation { - - private final List> validations; - - @Override - public Single> validity(T s) { - final List exception = new ArrayList<>(); - return Single.create(source -> { - for (Validation validation : new HashSet<>(validations)) { - - validation.registerInput(this.input).validate(s) - .subscribe(validationResult -> source.onSuccess((ValidationResult) validationResult), - error -> exception.add((NubeException) error)); +public class Alternative implements Validation { + + private final List> validations; + private BiFunction alternativeValidationBuilderFunc + = (validationResult, value) -> { + StringBuilder message = new StringBuilder(); + NubeException.ErrorCode errorCode = NubeException.ErrorCode.INVALID_ARGUMENT; + for (int i = 0; i < validationResult.getErrors().size(); i++) { + ValidationError.Builder error = validationResult.getErrors().get(i); + // clearing errorType and value + NubeException nubeException = error.errorType("").value("").build().execute(); + message.append(nubeException.getMessage()); + if (i != validationResult.getErrors().size() - 1) { + message.append(" || "); } - - if (exception.size() == validations.size()) { - String message = ""; - for (int i = 0; i < exception.size(); i++) { - message += exception.get(i).getMessage(); - if (i != exception.size() - 1) { - message += " || "; - } - } - source.onError(new ValidationError(message)); + if (errorCode != nubeException.getErrorCode()) { + errorCode = nubeException.getErrorCode(); } - }); - } + } + return ValidationError.builder().value(value).message(message.toString()).errorCode(errorCode); + }; @Override - protected String getErrorMessage() { - return null; + public ValidationResult validity(T s) { + List validationResults = new ArrayList<>(); + for (Validation validation : new HashSet<>(validations)) { + validationResults.add(validation.validate(s)); + } + + if (validationResults.stream().filter(x -> !x.isValid()).collect(Collectors.toList()).size() == + validations.size()) { + + return ValidationResult.invalid(alternativeValidationBuilderFunc.apply( + ValidationUtils.mergeValidationResultsFunc.apply(validationResults), s.toString())); + } + return ValidationResult.valid(); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java index abacc4257..3ccb94016 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Any.java @@ -3,22 +3,15 @@ import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; +public class Any implements Validation { -public class Any extends Validation { - - public Single> validate() { + public ValidationResult validate() { return this.validate(null); } @Override - public Single> validity(T s) { - return ValidationResult.valid(s); - } - - @Override - protected String getErrorMessage() { - return null; + public ValidationResult validity(T s) { + return ValidationResult.valid(); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java index 73572125c..7f97a417a 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Composition.java @@ -2,42 +2,60 @@ import java.util.ArrayList; import java.util.List; +import java.util.function.BiFunction; +import java.util.stream.Collectors; +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.utils.ValidationUtils; -import io.reactivex.Observable; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Composition extends Validation> { - - private final List> validations; +public class Composition implements Validation { + + private final List> validations; + private BiFunction compositionValidationBuilderFunc + = (validationResult, value) -> { + StringBuilder message = new StringBuilder(); + NubeException.ErrorCode errorCode = NubeException.ErrorCode.INVALID_ARGUMENT; + for (int i = 0; i < validationResult.getErrors().size(); i++) { + ValidationError.Builder error = validationResult.getErrors().get(i); + // clearing errorType and value + NubeException nubeException = error.errorType("").value("").build().execute(); + message.append(nubeException.getMessage()); + if (i != validationResult.getErrors().size() - 1) { + message.append(" && "); + } + if (errorCode != nubeException.getErrorCode()) { + errorCode = nubeException.getErrorCode(); + } + } + return ValidationError.builder().value(value).message(message.toString()).errorCode(errorCode); + }; @Override - public Single>> validity(T s) { - - return Observable.fromIterable(validations) - .flatMapSingle(validation -> validation.registerInput(this.input).validate(s)) - .toList() - .flatMap(outputs -> { - List list = new ArrayList<>(); - for (ValidationResult output : outputs) { - list.add(output.getData()); - } - return ValidationResult.valid(list); - }); + public ValidationResult validity(T s) { + List validationResults = new ArrayList<>(); + for (Validation validation : validations) { + validationResults.add(validation.validate(s)); + } + + if (validationResults.stream().filter(ValidationResult::isValid).collect(Collectors.toList()).size() == + validations.size()) { + + return ValidationResult.valid(); + } + return ValidationResult.invalid( + compositionValidationBuilderFunc.apply(ValidationUtils.mergeValidationResultsFunc.apply(validationResults), + s == null ? null : s.toString())); } @Override - protected boolean isNullable() { + public boolean nullable() { return false; } - @Override - protected String getErrorMessage() { - return null; - } - } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java index 2eeed3824..bad8bd819 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Contains.java @@ -2,24 +2,23 @@ import java.util.Set; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; import io.vertx.core.json.JsonArray; import lombok.AllArgsConstructor; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @AllArgsConstructor -public class Contains extends Validation { +public class Contains implements Validation { private final Set items; private boolean strict = true; @Override - public Single> validity(T s) { + public ValidationResult validity(T s) { boolean contains = false; if (s instanceof JsonArray) { for (Object o : (JsonArray) s) { @@ -38,14 +37,13 @@ public Single> validity(T s) { } else { contains = items.contains(s); } - return contains ? ValidationResult.valid(s) : ValidationResult.invalid(getErrorMessage()); + return contains ? ValidationResult.valid() : ValidationResult.invalid(buildErrorMessage(s)); } - @Override - protected String getErrorMessage() { + private ValidationError.Builder buildErrorMessage(T s) { return strict - ? Strings.format("{0}: {1} strictly should fall in the {2}", getErrorType(), getInput(), items) - : Strings.format("{0}: {1} should fall in the {2}", getErrorType(), getInput(), items); + ? ValidationError.builder().value(s.toString()).message("strictly should fall in the " + items) + : ValidationError.builder().value(s.toString()).message("should fall in the " + items); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java index ff784c0df..0fc2e437a 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Exist.java @@ -1,28 +1,21 @@ package com.nubeiot.core.validator.validations; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; - -public class Exist extends Validation { +public class Exist implements Validation { @Override - public Single> validity(T s) { + public ValidationResult validity(T s) { if (s != null) { - return ValidationResult.valid(s); + return ValidationResult.valid(); } - return ValidationResult.invalid(getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: required value is null", getErrorType(), getInput()); + return ValidationResult.invalid(ValidationError.builder().message("required value is null")); } @Override - protected boolean isNullable() { + public boolean nullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java index bc9b35174..48c742f01 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Forbidden.java @@ -1,32 +1,26 @@ package com.nubeiot.core.validator.validations; import com.nubeiot.core.exceptions.NubeException; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; +public class Forbidden implements Validation { -public class Forbidden extends Validation { - - public Single> validate() { + public ValidationResult validate() { return this.validate(null); } @Override - public Single> validity(T s) { - this.setErrorType("Forbidden"); - this.setErrorCode(NubeException.ErrorCode.INSUFFICIENT_PERMISSION_ERROR); - return ValidationResult.invalid(this.getErrorCode(), this.getErrorMessage()); - } - - @Override - protected String getErrorMessage() { - return Strings.format("{0}: you are not authorized to post this value", getErrorType()); + public ValidationResult validity(T s) { + return ValidationResult.invalid(ValidationError.builder() + .errorType("Forbidden") + .errorCode(NubeException.ErrorCode.INSUFFICIENT_PERMISSION_ERROR) + .message("you are not authorized to post this value")); } @Override - protected boolean isNullable() { + public boolean nullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java index 1d4dedc85..b786a356f 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/IntegerValidation.java @@ -8,7 +8,7 @@ public class IntegerValidation extends DataTypeValidation { @Override - public Class classType() { + protected Class classType() { return Integer.class; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java index f1583271c..9ad718f62 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonArrayValidation.java @@ -9,7 +9,8 @@ public class JsonArrayValidation extends DataTypeValidation { @Override - public Class classType() { + protected Class classType() { return JsonArray.class; } + } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java index c4861836a..e4e438e4a 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/JsonObjectValidation.java @@ -9,7 +9,7 @@ public class JsonObjectValidation extends DataTypeValidation { @Override - public Class classType() { + protected Class classType() { return JsonObject.class; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java deleted file mode 100644 index 2aedb1350..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/KeyLoop.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.ValidationSupplier; - -import io.reactivex.Observable; -import io.reactivex.Single; -import io.vertx.core.json.JsonObject; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class KeyLoop extends Validation { - - private final ValidationSupplier supplier; - - @Override - public Single> validity(T s) { - if (s instanceof JsonObject) { - JsonObject jsonObject = (JsonObject) s; - return Observable.fromIterable(jsonObject) - .flatMapSingle(o -> supplier.get(o.getValue(), this.input + "." + o.getKey())) - .toList() - .flatMap(r -> ValidationResult.valid(jsonObject)); - } else { - return ValidationResult.invalid( - Strings.format("{0}: {1} must be of type JsonObject", getErrorType(), this.input)); - } - } - - @Override - protected String getErrorMessage() { - return null; - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java deleted file mode 100644 index 8a4e1f015..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Loop.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import java.util.ArrayList; -import java.util.List; - -import com.nubeiot.core.utils.Strings; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.ValidationSupplier; - -import io.reactivex.Observable; -import io.reactivex.Single; -import io.vertx.core.json.JsonArray; -import lombok.RequiredArgsConstructor; - -@RequiredArgsConstructor -public class Loop extends Validation { - - private final ValidationSupplier supplier; - - @Override - public Single> validity(T s) { - if (s instanceof JsonArray) { - final List objects = new ArrayList<>(); - // When isRequired is false then parsed JsonArray value will be of size 0 - JsonArray jsonArray = (JsonArray) s; - if (jsonArray.size() == 0) { - return ValidationResult.valid(jsonArray); - } - return Observable.fromIterable(jsonArray).flatMapSingle(o -> { - - Single> output = supplier.get(o, this.input + "[" + objects.size() + "]"); - objects.add(o); - return output; - }).toList().flatMap(r -> ValidationResult.valid(jsonArray)); - } else { - return ValidationResult.invalid( - Strings.format("{0}: {1} must be of type JsonArray", getErrorType(), this.input)); - } - } - - @Override - protected String getErrorMessage() { - return null; - } - -} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java index b114e1a05..a72c75ba3 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Max.java @@ -1,35 +1,37 @@ package com.nubeiot.core.validator.validations; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Max extends Validation { +public class Max implements Validation { protected final Double value; @Override - public Single> validity(T s) { + public ValidationResult validity(T s) { if (s instanceof Number) { Double d = Double.parseDouble(s.toString()); if (condition(d)) { - return ValidationResult.valid(d); + return ValidationResult.valid(); } else { - return ValidationResult.invalid(getErrorMessage()); + return ValidationResult.invalid(getErrorMessage(s)); } } else { - return ValidationResult.invalid( - Strings.format("ClassCastException: {0} is not parsable to Number", getInput())); + return ValidationResult.invalid(ValidationError.builder() + .errorType("ClassCastException") + .value(s.toString()) + .message("is not parsable to Number")); } } - @Override - protected String getErrorMessage() { - return Strings.format("{0}: {1} is not less than or equal to {2}", getErrorType(), getInput(), value); + protected ValidationError.Builder getErrorMessage(T s) { + return ValidationError.builder() + .value(s.toString()) + .message("is not less than or equal to " + value.toString()); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java index ff2f63716..a6a4c9914 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Min.java @@ -1,6 +1,6 @@ package com.nubeiot.core.validator.validations; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; public class Min extends Max { @@ -8,9 +8,10 @@ public Min(Double value) { super(value); } - @Override - protected String getErrorMessage() { - return Strings.format("{0}: {1} is not greater than or equal to {2}", getErrorType(), getInput(), value); + protected ValidationError.Builder getErrorMessage(T s) { + return ValidationError.builder() + .value(s.toString()) + .message("is not greater than or equal to " + value.toString()); } protected boolean condition(Double d) { diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java index b122d0bcb..a698f6f85 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberOrStringValidation.java @@ -5,19 +5,11 @@ import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; - -public class NumberOrStringValidation extends Validation { - - @Override - public Single> validity(T s) { - return new Alternative<>(Arrays.asList(new NumberValidation<>(), new StringValidation<>())).registerInput( - this.input).validate(s); - } +public class NumberOrStringValidation implements Validation { @Override - protected String getErrorMessage() { - return null; + public ValidationResult validity(T s) { + return new Alternative<>(Arrays.asList(new NumberValidation<>(), new StringValidation<>())).validate(s); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java index eb968b1a0..e8a6d2ac3 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/NumberValidation.java @@ -5,7 +5,7 @@ public class NumberValidation extends DataTypeValidation { @Override - public Class classType() { + protected Class classType() { return Number.class; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java index a5d05f2f9..506483316 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Range.java @@ -1,37 +1,37 @@ package com.nubeiot.core.validator.validations; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.utils.Strings; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Range extends Validation { +public class Range implements Validation { private final Double minValue; private final Double maxValue; @Override - public Single> validity(T s) { + public ValidationResult validity(T s) { if (s instanceof Number) { Double d = Double.parseDouble(s.toString()); - if (minValue <= d && d <= maxValue) { - return ValidationResult.valid(d); + if (minValue <= d && d < maxValue) { + return ValidationResult.valid(); } else { - return ValidationResult.invalid(getErrorMessage()); + return ValidationResult.invalid(ValidationError.builder() + .value(s.toString()) + .message( + Strings.format("should be on range [{0}<= x < {1}]", + minValue, maxValue))); } } else { - return ValidationResult.invalid( - Strings.format("ClassCastException: {0} is not parsable to Number", getInput())); + return ValidationResult.invalid(ValidationError.builder() + .errorType("ClassCastException") + .value(s.toString()) + .message("is not parsable to Number")); } } - @Override - protected String getErrorMessage() { - return Strings.format("{0}: {1} should be on range [{2}-{3}]", getErrorType(), getInput(), minValue, - maxValue); - } - } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java index ac0c27229..078988cda 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/RegexValidation.java @@ -3,31 +3,27 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.exceptions.ValidationError; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class RegexValidation extends Validation { +public class RegexValidation implements Validation { private final String regex; @Override - public Single> validity(String s) { + public ValidationResult validity(T s) { Pattern pattern = java.util.regex.Pattern.compile(regex); - Matcher matcher = pattern.matcher(s); + Matcher matcher = pattern.matcher(s.toString()); boolean isValid = matcher.matches(); - return isValid ? ValidationResult.valid(s) : ValidationResult.invalid(getErrorMessage()); - } - - @Override - public String getErrorMessage() { - return Strings.format("{0}: {1} does not match with the pattern {2}", getErrorType(), getInput(), - regex); + return isValid + ? ValidationResult.valid() + : ValidationResult.invalid( + ValidationError.builder().value(s.toString()).message("does not match with the pattern " + regex)); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java index 3c1de45c4..17c6d87a0 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/Required.java @@ -1,30 +1,23 @@ package com.nubeiot.core.validator.validations; import java.util.Arrays; -import java.util.List; import com.nubeiot.core.validator.Validation; import com.nubeiot.core.validator.ValidationResult; -import io.reactivex.Single; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class Required extends Validation> { +public class Required implements Validation { - private final Validation validation; + private final Validation validation; @Override - public Single>> validity(T s) { - return new Composition<>(Arrays.asList(validation, new Exist<>())).registerInput(this.input).validate(s); + public ValidationResult validity(T s) { + return new Composition<>(Arrays.asList(validation, new Exist<>())).validate(s); } - @Override - protected String getErrorMessage() { - return null; - } - - protected boolean isNullable() { + public boolean nullable() { return false; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java index 5592b5817..655f23c6b 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/validations/StringValidation.java @@ -8,7 +8,7 @@ public class StringValidation extends DataTypeValidation { @Override - public Class classType() { + protected Class classType() { return String.class; } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java b/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java deleted file mode 100644 index 180f40ad6..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/validations/When.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.nubeiot.core.validator.validations; - -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class When>> extends Validation { - - private Single> is; - private Single> then; - private T2 otherwise; - - @Override - public Single> validity(T1 s) { - return Single.create( - source -> this.is.subscribe(ignored -> this.then.subscribe(source::onSuccess, source::onError), - error -> otherwise.subscribe(source::onSuccess, source::onError))); - } - - @Override - protected String getErrorMessage() { - return null; - } - - public When registerIs(Single> is) { - this.is = is; - return this; - } - - public When registerThen(Single> then) { - this.then = then; - return this; - } - - public When registerOtherwise(T2 otherwise) { - this.otherwise = otherwise; - return this; - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java deleted file mode 100644 index f0baf743e..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/JsonConverterTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package core.nubeiot.core.validator; - -import org.junit.Test; - -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.validations.JsonArrayValidation; -import com.nubeiot.core.validator.validations.Min; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; - -public class JsonConverterTest { - - @Test - public void test_json_object_converter_success() { - JsonObject jsonObject = new JsonObject().put("a", 10); - JsonConverter.validate(new Min<>(1d), jsonObject, "a").test().assertValue(value -> { - System.out.println(jsonObject); - return true; - }); - } - - @Test - public void test_json_object_converter_with_parent_field_failure() { - JsonObject jsonObject = new JsonObject().put("a", 10); - JsonConverter.validate(new Min<>(100d), jsonObject, "xyz", "a").test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - } - - @Test - public void test_json_object_converter_with_default_value_success() { - JsonObject jsonObject = new JsonObject(); - JsonConverter.validate(new Min<>(5d), jsonObject, "xyz", "a", 10).test().assertValue(value -> { - System.out.println(jsonObject); - return jsonObject.getValue("a").equals(10); - }); - } - - @Test - public void test_json_object_converter_with_default_value_failure() { - JsonObject jsonObject = new JsonObject(); - JsonConverter.validate(new Min<>(100d), jsonObject, "xyz", "a", 10).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - } - - @Test - public void test_json_array_converter_success() { - JsonArray jsonArray = new JsonArray().add(1).add(2); - JsonObject jsonObject = new JsonObject().put("a", new JsonArray().add(1).add(2)); - JsonConverter.validate(new JsonArrayValidation<>(), jsonArray, "").test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); - - JsonConverter.validate(new JsonArrayValidation<>(), jsonObject, "a").test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); - } - - @Test - public void test_json_array_converter_with_parent_field_failure() { - JsonConverter.validate(new JsonArrayValidation<>(), new JsonObject().put("a", new JsonObject()), "abc[0]", "a") - .test() - .assertError(error -> { - System.out.println(error.getMessage()); - return error.getMessage() - .equals( - "ValidationError: abc[0].a is not the type of io.vertx.core.json.JsonArray"); - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java new file mode 100644 index 000000000..214741a68 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java @@ -0,0 +1,79 @@ +package core.nubeiot.core.validator; + +import java.net.URL; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.utils.FileUtils; +import com.nubeiot.core.validator.JsonLoop; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.utils.ValidationUtils; +import com.nubeiot.core.validator.validations.IntegerValidation; +import com.nubeiot.core.validator.validations.JsonArrayValidation; +import com.nubeiot.core.validator.validations.StringValidation; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public class JsonLoopingTest { + + @Test + public void test_jsonArrayLoop() { + URL resource = JsonLoopingTest.class.getClassLoader().getResource("example.json"); + JsonArray jsonArray = new JsonArray(FileUtils.readFileToString(resource.toString())); + + JsonLoop outerLoop = new JsonLoop<>(""); + outerLoop.add("first_name", new StringValidation<>()); + outerLoop.add("last_name", new StringValidation<>()); + outerLoop.add("siblings", new JsonArrayValidation<>()); + + JsonLoop interestsLoop = new JsonLoop<>("details.basic.interests"); + interestsLoop.add("sports", new JsonArrayValidation<>()); + + JsonLoop musicsLoop = new JsonLoop<>("music"); + musicsLoop.add("classical", new JsonArrayValidation<>()); + musicsLoop.add("rock", new JsonArrayValidation<>()); + + interestsLoop.add(musicsLoop); // adding JsonLoop inside JsonLoop + + outerLoop.add(interestsLoop); // adding JsonLoop inside JsonLoop + + ValidationResult validationResult = outerLoop.validate(jsonArray); + System.out.println(validationResult.getErrors()); + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + validationResult.getErrors()); + String expected = + "ValidationError: [1].details.basic.interests.[0].music.[1].rock is not the type of io.vertx.core.json" + + ".JsonArray && ValidationError: [1].details.basic.interests.[1].sports is not the type of io.vertx.core" + + ".json.JsonArray"; + Assert.assertEquals(expected, nubeException.getMessage()); + } + + @Test + public void test_jsonArrayAndJsonObject() { + URL resource = JsonLoopingTest.class.getClassLoader().getResource("loop_and_key_loop_example.json"); + JsonObject jsonObject = new JsonObject(FileUtils.readFileToString(resource.toString())); + + JsonLoop outerLoop = new JsonLoop<>(""); + outerLoop.add("type", new StringValidation<>()); + outerLoop.add("value", new IntegerValidation<>()); + outerLoop.add("attributes", new JsonArrayValidation<>()); + + JsonLoop attributesLoop = new JsonLoop<>("attributes"); + attributesLoop.add("", new StringValidation<>()); + + outerLoop.add(attributesLoop); + + ValidationResult validationResult = outerLoop.validate(jsonObject); + System.out.println(validationResult.getErrors()); + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + validationResult.getErrors()); + String expected = + "ValidationError: UI2.value is not the type of java.lang.Integer && ValidationError: UI2.attributes.[0]" + + " is not the type of java.lang.String"; + Assert.assertEquals(expected, nubeException.getMessage()); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationHolderTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationHolderTest.java new file mode 100644 index 000000000..08d74b850 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationHolderTest.java @@ -0,0 +1,78 @@ +package core.nubeiot.core.validator; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.core.validator.JsonValidationHolder; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.Validator; +import com.nubeiot.core.validator.utils.ValidationUtils; +import com.nubeiot.core.validator.validations.Composition; +import com.nubeiot.core.validator.validations.IntegerValidation; +import com.nubeiot.core.validator.validations.RegexValidation; +import com.nubeiot.core.validator.validations.StringValidation; + +import io.vertx.core.json.JsonObject; + +public class JsonValidationHolderTest { + + @Test + public void test_jsonValidationHolderExecute() { + JsonObject jsonObject = new JsonObject().put("first_name", "Shane") + .put("last_name", 11) + .put("email", "shane@gmail.com") + .put("details", new JsonObject().put("age", 26.2)); + + String emailRegex = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b"; + + JsonValidationHolder jsonValidationHolder = new JsonValidationHolder<>(); + jsonValidationHolder.add("first_name", new StringValidation<>()); + jsonValidationHolder.add("last_name", new StringValidation<>()); + jsonValidationHolder.add("email", new Composition<>( + Arrays.asList(new StringValidation<>(), new RegexValidation<>(emailRegex)))); + jsonValidationHolder.add("details.age", new IntegerValidation<>()); + + ValidationResult validationResult = Validator.builder() + .validations(Collections.singletonList(jsonValidationHolder)) + .build() + .execute(jsonObject); + String expected = + "ValidationError: last_name is not the type of java.lang.String && ValidationError: details.age is not " + + "the type of java.lang.Integer"; + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validationResult.getErrors()).getMessage(), + expected); + } + + @Test + public void test_jsonValidationHolderEagerExecute() { + JsonObject jsonObject = new JsonObject().put("first_name", "Shane") + .put("last_name", 11) + .put("email", "shane@gmail.com") + .put("details", new JsonObject().put("age", 26.2)); + + String emailRegex = "\\b[\\w.%-]+@[-.\\w]+\\.[A-Za-z]{2,4}\\b"; + + JsonValidationHolder jsonValidationHolder = new JsonValidationHolder<>(); + jsonValidationHolder.add("first_name", new StringValidation<>()); + jsonValidationHolder.add("last_name", new StringValidation<>()); + jsonValidationHolder.add("email", new Composition<>( + Arrays.asList(new StringValidation<>(), new RegexValidation<>(emailRegex)))); + jsonValidationHolder.add("details.age", new IntegerValidation<>()); + + ValidationResult validationResult = Validator.builder() + .validations(Collections.singletonList(jsonValidationHolder)) + .build() + .eagerExecute(jsonObject); + String expected = + "ValidationError: last_name is not the type of java.lang.String && ValidationError: details.age is not " + + "the type of java.lang.Integer"; + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validationResult.getErrors()).getMessage(), + expected); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java index bb2790b19..15020673b 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/RegisterDefaultValueTest.java @@ -1,15 +1,13 @@ package core.nubeiot.core.validator; -import java.util.ArrayList; -import java.util.List; +import java.util.Collections; import org.junit.Test; -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.validations.Composition; -import com.nubeiot.core.validator.validations.Max; -import com.nubeiot.core.validator.validations.Min; +import com.nubeiot.core.utils.JsonUtils; +import com.nubeiot.core.validator.JsonValidationHolder; +import com.nubeiot.core.validator.Validator; +import com.nubeiot.core.validator.validations.Range; import io.vertx.core.json.JsonObject; @@ -17,34 +15,17 @@ public class RegisterDefaultValueTest { @Test public void test_default_value_insertion_success() { - JsonObject jsonObject = new JsonObject().put("a", 10); - - List> validations = new ArrayList<>(); - validations.add(new Min<>(1d)); - validations.add(new Max<>(16d)); - - Validation> validation = new Composition<>(validations); - - JsonConverter.validate(validation, jsonObject, "", "b", 16).test().assertValue(output -> { - System.out.println(jsonObject); - return true; - }); - } - - @Test - public void test_without_default_value_success() { - JsonObject jsonObject = new JsonObject().put("a", 10); - - List> validations = new ArrayList<>(); - validations.add(new Min<>(1d)); - validations.add(new Max<>(16d)); - - Validation> validation = new Composition<>(validations); - - JsonConverter.validate(validation, jsonObject, "", "b").test().assertValue(output -> { - System.out.println(jsonObject); - return true; - }); + JsonObject jsonObject = new JsonObject(); + JsonObject defaultJsonObject = new JsonObject().put("a", 18); + + JsonValidationHolder jsonValidationHolder = new JsonValidationHolder<>(); + jsonValidationHolder.add("a", new Range<>(1d, 17d)); + Validator validation = Validator.builder() + .validations(Collections.singletonList(jsonValidationHolder)) + .mergeFunc(JsonUtils.mergeJsonObjectFunc) + .defaultValue(defaultJsonObject) + .build(); + System.out.println(validation.execute(jsonObject).getErrors()); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java deleted file mode 100644 index aa3e558d0..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationResultTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package core.nubeiot.core.validator; - -import org.junit.Test; - -import com.nubeiot.core.validator.ValidationResult; - -import io.reactivex.Single; - -public class ValidationResultTest { - - @Test - public void test_valid() { - String output = "succeeded"; - Single> validationResult = ValidationResult.valid(output); - validationResult.test().assertValue(value -> value.getData().equals(output)); - } - - @Test - public void test_invalid() { - String reason = "invalid"; - Single> validationResult = ValidationResult.invalid(reason); - validationResult.test().assertError(value -> value.getMessage().equals("invalid")); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java deleted file mode 100644 index 63d0b546b..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/ValidationTest.java +++ /dev/null @@ -1,211 +0,0 @@ -package core.nubeiot.core.validator; - -import java.net.URL; -import java.util.Arrays; - -import org.junit.Test; - -import com.nubeiot.core.utils.FileUtils; -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.ValidationSupplier; -import com.nubeiot.core.validator.validations.Composition; -import com.nubeiot.core.validator.validations.Exist; -import com.nubeiot.core.validator.validations.IntegerValidation; -import com.nubeiot.core.validator.validations.JsonArrayValidation; -import com.nubeiot.core.validator.validations.JsonObjectValidation; -import com.nubeiot.core.validator.validations.KeyLoop; -import com.nubeiot.core.validator.validations.Loop; -import com.nubeiot.core.validator.validations.StringValidation; - -import io.reactivex.Single; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; -import lombok.NoArgsConstructor; - -public class ValidationTest { - - private JsonObject object = new JsonObject().put("first_name", "Binod") - .put("last_name", "Rai") - .put("details", new JsonObject().put("age", 26.2)); - - @Test - public void test_field_does_not_exist_when_is_required_true() { - Validation sv = new StringValidation<>(); - Validation iv = new IntegerValidation<>(); - Validation ev = new Exist<>(); - - JsonConverter.validate(sv, object, "first_name") - .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) - .flatMap(ignore -> JsonConverter.validate(new Composition<>(Arrays.asList(iv, ev)), object, - "details.xyz")) - .test() - .assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - } - - @Test - public void test_no_error_on_non_existing_value_when_is_require_false() { - Validation sv = new StringValidation<>(); - Validation iv = new IntegerValidation<>(); - - JsonConverter.validate(sv, object, "first_name") - .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) - .flatMap(ignore -> JsonConverter.validate(iv, object, "details.xyz")) - .test() - .assertValue(value -> true); - } - - @Test - public void test_integer_validation() { - - Validation sv = new StringValidation<>(); - Validation iv = new IntegerValidation<>(); - - JsonConverter.validate(sv, object, "first_nam") - .flatMap(ignore -> JsonConverter.validate(sv, object, "last_name")) - .flatMap(ignore -> JsonConverter.validate(iv, object, "details.age")) - .test() - .assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - } - - @Test - public void test_loop_and_key_loop_failure() { - - URL resource = ValidationTest.class.getClassLoader().getResource("loop_and_key_loop_example.json"); - JsonObject jsonObject = new JsonObject(FileUtils.readFileToString(resource.toString())); - - class DetailsJsonArrayValidation implements ValidationSupplier { - - private Validation detailsJsonObjectValidation = new KeyLoop<>(new DetailsJsonObjectValidation<>()); - - @Override - public Single> get(V s, String parentField) { - // 2. jsonObject.details[i] value must be of JsonObject, and we loop that JsonObject on its each key - return JsonConverter.validate(detailsJsonObjectValidation, s, parentField, "").map(x -> x); - } - - class DetailsJsonObjectValidation implements ValidationSupplier { - - Validation innerLoop = new Loop<>(new InnerArrayLoopValidation<>()); - - @Override - public Single> get(W s, String parentField) { - // 3. jsonObject.details[i].key_value must be of JsonArray - return JsonConverter.validate(innerLoop, s, parentField, "").map(x -> x); - } - - class InnerArrayLoopValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(X s, String parentField) { - // 4. jsonObject.details[i].key_value[j] must be of String - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - } - - } - - // 1. jsonObject.details should be of array type, so we loop here - Validation loop = new Loop<>(new DetailsJsonArrayValidation<>()); - JsonConverter.validate(loop, jsonObject, "details").test().assertError(e -> { - System.out.println(e.getMessage()); - return e.getMessage().equals("ValidationError: details[1].movies[2] is not the type of java.lang.String"); - }); - } - - @Test - public void test_loop_and_key_loop_failure_2() { - @NoArgsConstructor - class FirstLayerObjectValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - private Validation av = new JsonArrayValidation<>(); - private Validation lvS = new Loop<>(new SiblingValidation<>()); - private Validation lvI = new Loop<>(new InterestValidation<>()); - - @Override - public Single> get(T s, String parentField) { - // 2 - return JsonConverter.validate(sv, s, parentField, "first_name") - .flatMap(ignore -> JsonConverter.validate(sv, s, parentField, "last_name")) - .flatMap(ignore -> JsonConverter.validate(av, s, parentField, "siblings", - new JsonArray().add("Roshan") - .add("Bhushan"))) - .flatMap(siblings -> JsonConverter.validate(lvS, siblings.getData(), parentField, - "siblings")) - .flatMap( - ignore -> JsonConverter.validate(av, s, parentField, "details.basic.interests")) - .flatMap(interests -> JsonConverter.validate(lvI, interests.getData(), parentField, - "details.basic.interests")); - } - - class SiblingValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(U s, String parentField) { - // 3 - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - - class InterestValidation implements ValidationSupplier { - - private Validation jov = new JsonObjectValidation<>(); - - @Override - public Single> get(U s, String parentField) { - // 4 - return JsonConverter.validate(jov, s, parentField, "").flatMap(vrInterest -> { - Validation keyLoopInterestValidation = new KeyLoop<>(new InterestObjectValidation<>()); - JsonObject interest = ((JsonObject) vrInterest.getData()); - return JsonConverter.validate(keyLoopInterestValidation, interest, parentField, ""); - }); - } - - class InterestObjectValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - // 5 - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - } - - } - - URL resource = ValidationTest.class.getClassLoader().getResource("example.json"); - JsonArray jsonArray = new JsonArray(FileUtils.readFileToString(resource.toString())); - - // 1 - Validation lv = new Loop<>(new FirstLayerObjectValidation<>()); - JsonConverter.validate(lv, jsonArray, "").test().assertError(e -> { - System.out.println(e.getMessage()); - return e.getMessage() - .equals("ValidationError: [1].details.basic.interests[1].music is not the type " + - "of java.lang.String"); - }); - } - -} - diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java new file mode 100644 index 000000000..ebe9de8a0 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java @@ -0,0 +1,77 @@ +package core.nubeiot.core.validator; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.When; +import com.nubeiot.core.validator.utils.ValidationUtils; +import com.nubeiot.core.validator.validations.Any; +import com.nubeiot.core.validator.validations.Contains; +import com.nubeiot.core.validator.validations.Forbidden; + +import io.vertx.core.json.JsonObject; + +public class WhenTest { + + @Test + public void test_when_initialization_failure() { + JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); + + When validation = new When<>(); + validation.setIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))); + validation.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); + NubeException exception = ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(jsonObject).getErrors()); + + Assert.assertEquals(exception.getMessage(), "ValidationError: When validation Initialization Error"); + Assert.assertEquals(exception.getErrorCode(), NubeException.ErrorCode.INITIALIZER_ERROR); + } + + @Test + public void test_when_success() { + /* Scenario 1: + 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, Forbidden*/ + JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); + + When validation = new When<>(); + validation.setIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))); + validation.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); + validation.setOtherwise(new Forbidden<>()); + + System.out.println( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(jsonObject).getErrors()) + .getMessage()); + Assert.assertTrue(validation.validate(jsonObject).isValid()); + } + + @Test + public void test_when_failure() { + /* Scenario 2: + 1. When id is in [1] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, when id is in [2] then it's value should be valid on ["OFF"] + 3. Otherwise, pass any value as valid*/ + JsonObject jsonObject = new JsonObject().put("id", 2).put("value", "ON"); + + When whenId1 = new When<>(); + whenId1.setIs("id", new Contains<>(new HashSet<>(Collections.singletonList(1)))); + whenId1.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); + + When whenId2 = new When<>(); + whenId2.setIs("id", new Contains<>(new HashSet<>(Collections.singletonList(2)))); + whenId2.setThen("value", new Contains<>(new HashSet<>(Collections.singletonList("OFF")))); + whenId2.setOtherwise(new Any<>()); + + whenId1.setOtherwise(whenId2); + + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + whenId1.validate(jsonObject).getErrors()); + Assert.assertEquals(nubeException.getMessage(), "ValidationError: value strictly should fall in the [OFF]"); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/utils/ValidationUtilsTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/utils/ValidationUtilsTest.java new file mode 100644 index 000000000..032960d4a --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/utils/ValidationUtilsTest.java @@ -0,0 +1,5 @@ +package core.nubeiot.core.validator.utils; + +public class ValidationUtilsTest { + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java index aead2facd..a2726de35 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AlternativeTest.java @@ -3,39 +3,40 @@ import java.util.ArrayList; import java.util.List; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Alternative; +import com.nubeiot.core.validator.validations.IntegerValidation; import com.nubeiot.core.validator.validations.NumberValidation; import com.nubeiot.core.validator.validations.StringValidation; -import io.vertx.core.json.JsonObject; - public class AlternativeTest { @Test public void test_string_or_number_success() { - List> validations = new ArrayList<>(); + List> validations = new ArrayList<>(); validations.add(new NumberValidation<>()); validations.add(new StringValidation<>()); - Validation validation = new Alternative<>(validations); - validation.validate("10").test().assertValue(value -> value.getData().equals("10")); - validation.validate(10d).test().assertValue(value -> value.getData().equals(10d)); + Validation validation = new Alternative<>(validations); + Assert.assertTrue(validation.validate("10").isValid()); + Assert.assertTrue(validation.validate(10d).isValid()); } @Test public void test_string_or_number_failure() { - List> validations = new ArrayList<>(); + List> validations = new ArrayList<>(); validations.add(new NumberValidation<>()); - validations.add(new StringValidation<>()); + validations.add(new IntegerValidation<>()); - Validation validation = new Alternative<>(validations); - validation.validate(new JsonObject()).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new Alternative<>(validations); + System.out.println( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate("1").getErrors()) + .getMessage()); + Assert.assertFalse(validation.validate("1").isValid()); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java index 002a54262..00f108d35 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/AnyTest.java @@ -1,5 +1,6 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.validations.Any; @@ -8,9 +9,10 @@ public class AnyTest { @Test public void test_any_success() { - new Any<>().validate().test().assertValue(v -> true); - new Any<>().validate(null).test().assertValue(v -> true); - new Any<>().validate("XYZ").test().assertValue(v -> true); + + Assert.assertTrue(new Any<>().validate().isValid()); + Assert.assertTrue(new Any<>().validate(null).isValid()); + Assert.assertTrue(new Any<>().validate("XYZ").isValid()); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java index e970a63a6..73a9577bf 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/CompositionTest.java @@ -3,9 +3,11 @@ import java.util.ArrayList; import java.util.List; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Composition; import com.nubeiot.core.validator.validations.Max; import com.nubeiot.core.validator.validations.Min; @@ -14,30 +16,26 @@ public class CompositionTest { @Test public void test_number_with_min_max_success() { - List> validations = new ArrayList<>(); + List> validations = new ArrayList<>(); validations.add(new Min<>(1d)); validations.add(new Max<>(16d)); - Validation validation = new Composition<>(validations); + Validation validation = new Composition<>(validations); - validation.validate(10).test().assertValue(output -> { - System.out.println(output.getData()); - return true; - }); + Assert.assertTrue(validation.validate(10).isValid()); } @Test public void test_number_with_min_max_failure() { - List> validations = new ArrayList<>(); + List> validations = new ArrayList<>(); validations.add(new Min<>(1d)); validations.add(new Max<>(16d)); - Validation validation = new Composition<>(validations); + Validation validation = new Composition<>(validations); - validation.validate("10").test().assertError(output -> { - System.out.println(output.toString()); - return true; - }); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(17).getErrors()).getMessage(), + "ValidationError: 17 is not less than or equal to 16.0"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java index 8ebb1c15a..18e3acdda 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ContainsTest.java @@ -3,9 +3,11 @@ import java.util.Arrays; import java.util.HashSet; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Contains; import io.vertx.core.json.JsonArray; @@ -14,46 +16,33 @@ public class ContainsTest { @Test public void test_contains_success() { - Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); - validation.validate(new JsonArray().add(1).add(2)).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); - - validation.validate(1).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); + Assert.assertTrue(validation.validate(new JsonArray().add(1).add(2)).isValid()); + Assert.assertTrue(validation.validate(1).isValid()); } @Test public void test_contains_failure() { - Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5))); - validation.validate(Arrays.asList(1, 6)).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5))); + Assert.assertEquals(ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(new JsonArray().add(1).add(8)).getErrors()).getMessage(), + "ValidationError: [1,8] strictly should fall in the [1, 2, 3, 4, 5]"); } @Test public void test_contains_when_strict_false_success() { - Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); - - validation.validate(new JsonArray().add(1).add(7)).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + Assert.assertTrue(validation.validate(new JsonArray().add(1).add(8)).isValid()); } @Test public void test_contains_when_strict_false_failure() { - Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); + Validation validation = new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3, 4, 5)), false); - validation.validate(new JsonArray().add(7).add(8)).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Assert.assertEquals(ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(new JsonArray().add(7).add(8)).getErrors()).getMessage(), + "ValidationError: [7,8] should fall in the [1, 2, 3, 4, 5]"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java index d1eeb7e89..a63ea1eac 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ExistTest.java @@ -1,28 +1,27 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Exist; public class ExistTest { @Test public void test_exist_success() { - Validation validation = new Exist<>(); - validation.validate(1).test().assertValue(v -> { - System.out.println(v.getData()); - return true; - }); + Validation validation = new Exist<>(); + Assert.assertTrue(validation.validate(1).isValid()); } @Test public void test_exist_failure() { - Validation validation = new Exist<>(); - validation.validate(null).test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); + Validation validation = new Exist<>(); + Assert.assertFalse(validation.validate(null).isValid()); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(null).errors()).getMessage(), + "ValidationError: required value is null"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java index 82ef71934..8947843df 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/ForbiddenTest.java @@ -1,27 +1,23 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Forbidden; public class ForbiddenTest { @Test public void test_forbidden_success() { - new Forbidden<>().validate().test().assertError(v -> { - System.out.println(v.getMessage()); - return v.getMessage().equals("Forbidden: you are not authorized to post this value"); - }); - - new Forbidden<>().validate(null).test().assertError(v -> { - System.out.println(v.getMessage()); - return v.getMessage().equals("Forbidden: you are not authorized to post this value"); - }); - - new Forbidden<>().validate("XYZ").test().assertError(v -> { - System.out.println(v.getMessage()); - return v.getMessage().equals("Forbidden: you are not authorized to post this value"); - }); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(new Forbidden<>().validate().errors()) + .getMessage(), + "Forbidden: you are not authorized to post this value"); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(new Forbidden<>().validate("XYZ").errors()) + .getMessage(), + "Forbidden: you are not authorized to post this value"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java index bf6e020d0..dae0371ed 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/IntegerValidationTest.java @@ -1,29 +1,84 @@ package core.nubeiot.core.validator.validations; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Assert; import org.junit.Test; +import com.nubeiot.core.validator.JsonValidationHolder; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.ValidationResult; +import com.nubeiot.core.validator.Validator; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.IntegerValidation; +import io.vertx.core.json.JsonObject; + public class IntegerValidationTest { @Test public void test_integer_success() { - Validation validation = new IntegerValidation<>(); - validation.validate(1).test().assertValue(value -> value.getData() == 1); + Validation validation = new IntegerValidation<>(); + Assert.assertTrue(validation.validate(1).errors().isEmpty()); + + Validator validator = Validator.builder().validations(Collections.singletonList(validation)).build(); + Assert.assertTrue(validator.execute(1).isValid()); } @Test public void test_integer_failure() { - Validation validation = new IntegerValidation<>(); - validation.validate(1.1).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - validation.validate("1").test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + JsonObject jsonObject = new JsonObject(); + JsonObject source = jsonObject; + if (source.getJsonObject("a") == null) { + source.put("a", new JsonObject()); + } + source = source.getJsonObject("a"); + + source.put("b", 5); + System.out.println(jsonObject); + + Validation validation = new IntegerValidation<>(); + Assert.assertEquals(validation.validate(1.1).errors().size(), 1); + Assert.assertEquals(validation.validate(1.1).errors().get(0).build().execute().getMessage(), + "ValidationError: 1.1 is not the type of java.lang.Integer"); + } + + @Test + public void test_integer_json_holder_validation() { + Validation validation = new IntegerValidation<>(); + JsonObject jsonObject = new JsonObject().put("a", 1.1).put("b", 1.2); + JsonValidationHolder jsonValidationHolder1 = new JsonValidationHolder<>(); + JsonValidationHolder jsonValidationHolder2 = new JsonValidationHolder<>(); + jsonValidationHolder1.add("a", validation); + jsonValidationHolder2.add("b", validation); + ValidationResult validationResult = Validator.builder() + .validations( + Arrays.asList(jsonValidationHolder1, jsonValidationHolder2)) + .build() + .execute(jsonObject); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validationResult.errors()).getMessage(), + "ValidationError: a is not the type of java.lang.Integer && ValidationError: b is not the" + + " type of java.lang.Integer"); + } + + @Test + public void test_integer_json_holder_eager_validation() { + Validation validation = new IntegerValidation<>(); + JsonObject jsonObject = new JsonObject().put("a", new JsonObject().put("x", "1.1")).put("b", 1.2); + JsonValidationHolder jsonValidationHolder1 = new JsonValidationHolder<>(); + JsonValidationHolder jsonValidationHolder2 = new JsonValidationHolder<>(); + jsonValidationHolder1.add("a.x", validation); + jsonValidationHolder2.add("b", validation); + ValidationResult eagerValidationResult = Validator.builder() + .validations(Arrays.asList(jsonValidationHolder1, + jsonValidationHolder2)) + .build() + .eagerExecute(jsonObject); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(eagerValidationResult.errors()).getMessage(), + "ValidationError: a.x is not the type of java.lang.Integer"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java index 3209fe696..afef60a21 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonArrayValidationTest.java @@ -1,8 +1,11 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; +import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.JsonArrayValidation; import io.vertx.core.json.JsonArray; @@ -11,22 +14,19 @@ public class JsonArrayValidationTest { @Test public void test_json_array_success() { - Validation validation = new JsonArrayValidation<>(); + Validation validation = new JsonArrayValidation<>(); - validation.validate(new JsonArray().add(1).add(2).add(3)).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); + Assert.assertTrue(validation.validate(new JsonArray().add(1).add(2).add(3)).isValid()); } @Test public void test_json_array_failure() { - Validation validation = new JsonArrayValidation<>(); + Validation validation = new JsonArrayValidation<>(); - validation.validate(1).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(1).getErrors()); + Assert.assertEquals(nubeException.getMessage(), + "ValidationError: 1 is not the type of io.vertx.core.json.JsonArray"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java index 03f559518..d92e239c3 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/JsonObjectValidationTest.java @@ -1,8 +1,11 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; +import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.JsonObjectValidation; import io.vertx.core.json.JsonArray; @@ -12,22 +15,20 @@ public class JsonObjectValidationTest { @Test public void test_json_object_success() { - Validation validation = new JsonObjectValidation<>(); + Validation validation = new JsonObjectValidation<>(); - validation.validate(new JsonObject().put("result", "success")).test().assertValue(value -> { - System.out.println(value.getData()); - return value.getData().getValue("result").equals("success"); - }); + Assert.assertTrue(validation.validate(new JsonObject().put("result", "success")).isValid()); } @Test public void test_json_object_failure() { - Validation validation = new JsonObjectValidation<>(); + Validation validation = new JsonObjectValidation<>(); - validation.validate(new JsonArray().add(1).add(2)).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(new JsonArray().add(1).add(2)).getErrors()); + + Assert.assertEquals(nubeException.getMessage(), + "ValidationError: [1,2] is not the type of io.vertx.core.json.JsonObject"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java deleted file mode 100644 index 80bbac1a0..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/KeyLoopTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.ValidationSupplier; -import com.nubeiot.core.validator.validations.KeyLoop; -import com.nubeiot.core.validator.validations.StringValidation; - -import io.reactivex.Single; -import io.vertx.core.json.JsonObject; - -public class KeyLoopTest { - - @Test - public void test_json_object_values_as_strings_success() { - class ObjectValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonObject jsonObject = new JsonObject().put("first_name", "Shane").put("last_name", "Watson"); - Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); - keyLoop.validate(jsonObject).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); - } - - @Test - public void test_json_object_values_as_strings_failure() { - class ObjectValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonObject jsonObject = new JsonObject().put("first_name", "Shane").put("last_name", "Watson").put("age", 33); - Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); - keyLoop.validate(jsonObject).test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); - } - - @Test - public void test_json_object_values_as_strings_failure_with_json_converter() { - class ObjectValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonObject jsonObject = new JsonObject().put("details", new JsonObject().put("first_name", "Shane") - .put("last_name", "Watson") - .put("age", 33)); - Validation keyLoop = new KeyLoop<>(new ObjectValidation<>()); - - JsonConverter.validate(keyLoop, jsonObject, "details").test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java deleted file mode 100644 index 99c29f54d..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/LoopTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import org.junit.Test; - -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.Validation; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.ValidationSupplier; -import com.nubeiot.core.validator.validations.Loop; -import com.nubeiot.core.validator.validations.StringValidation; - -import io.reactivex.Single; -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; - -public class LoopTest { - - @Test - public void test_json_object_values_as_strings_success() { - class JsonArrayValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonArray jsonArray = new JsonArray().add("Hello").add("World"); - Validation loop = new Loop<>(new JsonArrayValidation<>()); - loop.validate(jsonArray).test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); - } - - @Test - public void test_json_object_values_as_strings_failure() { - class JsonArrayValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonArray jsonArray = new JsonArray().add("Hello").add(123); - Validation loop = new Loop<>(new JsonArrayValidation<>()); - loop.validate(jsonArray).test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); - } - - @Test - public void test_json_object_values_as_strings_failure_with_json_converter() { - class JsonArrayValidation implements ValidationSupplier { - - private Validation sv = new StringValidation<>(); - - @Override - public Single> get(V s, String parentField) { - return JsonConverter.validate(sv, s, parentField, "").map(x -> x); - } - - } - - JsonObject jsonObject = new JsonObject().put("details", new JsonArray().add("Hello").add(123)); - Validation loop = new Loop<>(new JsonArrayValidation<>()); - - JsonConverter.validate(loop, jsonObject, "details").test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java index c0d84caee..70fc08662 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MaxTest.java @@ -1,26 +1,28 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Max; public class MaxTest { @Test public void test_max_success() { - Validation validation = new Max<>(15d); - validation.validate(10.00).test().assertValue(value -> value.getData() == 10d); - validation.validate(10).test().assertValue(value -> value.getData() == 10d); + Validation validation = new Max<>(15d); + Assert.assertTrue(validation.validate(10.00).isValid()); + Assert.assertTrue(validation.validate(10).isValid()); } @Test public void test_max_failure() { - Validation validation = new Max<>(15d); - validation.validate(40d).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + + Validation validation = new Max<>(15d); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(40d).errors()).getMessage(), + "ValidationError: 40.0 is not less than or equal to 15.0"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java index f5662ca6d..030b7a085 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/MinTest.java @@ -1,26 +1,27 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Min; public class MinTest { @Test public void test_min_success() { - Validation validation = new Min<>(5d); - validation.validate(10.00).test().assertValue(value -> value.getData() == 10d); - validation.validate(10).test().assertValue(value -> value.getData() == 10d); + Validation validation = new Min<>(5d); + Assert.assertTrue(validation.validate(10.0).isValid()); + Assert.assertTrue(validation.validate(10).isValid()); } @Test public void test_min_failure() { - Validation validation = new Min<>(5d); - validation.validate(4d).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new Min<>(5d); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(4.0).errors()).getMessage(), + "ValidationError: 4.0 is not greater than or equal to 5.0"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java index 94c3f267a..d9393fc7e 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberOrStringValidationTest.java @@ -1,8 +1,10 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.NumberOrStringValidation; import io.vertx.core.json.JsonObject; @@ -11,21 +13,19 @@ public class NumberOrStringValidationTest { @Test public void test_numeric_or_string_success() { - Validation validation = new NumberOrStringValidation<>(); - - validation.validate(1).test().assertValue(v -> true); - validation.validate(1.0).test().assertValue(v -> true); - validation.validate("1").test().assertValue(v -> true); + Validation validation = new NumberOrStringValidation<>(); + Assert.assertTrue(validation.validate(1).isValid()); + Assert.assertTrue(validation.validate(1.0).isValid()); + Assert.assertTrue(validation.validate("ABC").isValid()); } @Test public void test_numeric_or_string_failure() { - Validation validation = new NumberOrStringValidation<>(); + Validation validation = new NumberOrStringValidation<>(); - validation.validate(new JsonObject().put("a", 1)).test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); + System.out.println(ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(new JsonObject().put("a", 1)).getErrors()).getMessage()); + Assert.assertFalse(validation.validate(new JsonObject().put("a", 1)).isValid()); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java index 4be84663f..b522285a6 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/NumberValidationTest.java @@ -1,28 +1,27 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.NumberValidation; public class NumberValidationTest { @Test public void test_numeric_success() { - Validation validation = new NumberValidation<>(); - - validation.validate(1).test().assertValue(v -> true); - validation.validate(1.0).test().assertValue(v -> true); + Validation validation = new NumberValidation<>(); + Assert.assertTrue(validation.validate(1).isValid()); + Assert.assertTrue(validation.validate(1.0).isValid()); } @Test public void test_numeric_failure() { - Validation validation = new NumberValidation<>(); - - validation.validate("1").test().assertError(e -> { - System.out.println(e.getMessage()); - return true; - }); + Validation validation = new NumberValidation<>(); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate("1").errors()).getMessage(), + "ValidationError: 1 is not the type of java.lang.Number"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java index d20ba3d76..d483aa99c 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RangeTest.java @@ -1,30 +1,30 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.Range; public class RangeTest { @Test public void test_range_success() { - Validation validation = new Range<>(5d, 15d); - validation.validate(10.0).test().assertValue(value -> value.getData() == 10d); - validation.validate(10).test().assertValue(value -> value.getData() == 10d); + Validation validation = new Range<>(5d, 15d); + Assert.assertTrue(validation.validate(10.0).isValid()); + Assert.assertTrue(validation.validate(10).isValid()); } @Test public void test_range_failure() { - Validation validation = new Range<>(5d, 15d); - validation.validate(4.0).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - validation.validate("4d").test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new Range<>(5d, 15d); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(4.0).errors()).getMessage(), + "ValidationError: 4.0 should be on range [5.0<= x < 15.0]"); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate("4d").errors()).getMessage(), + "ClassCastException: 4d is not parsable to Number"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java index 9bcdda055..574b4b556 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RegexValidationTest.java @@ -1,28 +1,28 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.RegexValidation; public class RegexValidationTest { @Test public void test_regex_success() { - Validation validation = new RegexValidation("[0-9]+"); - validation.validate("0123456").test().assertValue(value -> { - System.out.println(value.getData()); - return true; - }); + + Validation validation = new RegexValidation("[0-9]+"); + Assert.assertTrue(validation.validate("0123456").isValid()); } @Test public void test_regex_failure() { - Validation validation = new RegexValidation("[0-9]+"); - validation.validate("012ABC").test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new RegexValidation("[0-9]+"); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate("012ABC").errors()) + .getMessage(), + "ValidationError: 012ABC does not match with the pattern [0-9]+"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java index 2e738bce1..a949af618 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/RequiredTest.java @@ -1,8 +1,10 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.IntegerValidation; import com.nubeiot.core.validator.validations.Required; @@ -10,24 +12,20 @@ public class RequiredTest { @Test public void test_required_integer_success() { - Validation validation = new Required<>(new IntegerValidation<>()); - validation.validate(1).test().assertValue(v -> { - System.out.println(v.getData()); - return true; - }); + Validation validation = new Required<>(new IntegerValidation<>()); + Assert.assertTrue(validation.validate(1).isValid()); } @Test public void test_required_integer_failure() { - Validation validation = new Required<>(new IntegerValidation<>()); - validation.validate("1").test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); - validation.validate(null).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new Required<>(new IntegerValidation<>()); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate("1").getErrors()).getMessage(), + "ValidationError: 1 is not the type of java.lang.Integer"); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(null).getErrors()) + .getMessage(), + "ValidationError: null required value is null"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java index 5b8e9462c..77c97458a 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/validations/StringValidationTest.java @@ -1,8 +1,10 @@ package core.nubeiot.core.validator.validations; +import org.junit.Assert; import org.junit.Test; import com.nubeiot.core.validator.Validation; +import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.StringValidation; public class StringValidationTest { @@ -10,17 +12,16 @@ public class StringValidationTest { @Test public void test_string_success() { String message = "Hello World!"; - Validation validation = new StringValidation<>(); - validation.validate(message).test().assertValue(value -> value.getData().equals(message)); + Validation validation = new StringValidation<>(); + Assert.assertTrue(validation.validate(message).isValid()); } @Test public void test_string_failure() { - Validation validation = new StringValidation<>(); - validation.validate(1).test().assertError(error -> { - System.out.println(error.getMessage()); - return true; - }); + Validation validation = new StringValidation<>(); + Assert.assertEquals( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(1).errors()).getMessage(), + "ValidationError: 1 is not the type of java.lang.String"); } } diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java deleted file mode 100644 index f0e6a3644..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/validations/WhenTest.java +++ /dev/null @@ -1,105 +0,0 @@ -package core.nubeiot.core.validator.validations; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; - -import org.junit.Test; - -import com.nubeiot.core.validator.JsonConverter; -import com.nubeiot.core.validator.ValidationResult; -import com.nubeiot.core.validator.validations.Any; -import com.nubeiot.core.validator.validations.Contains; -import com.nubeiot.core.validator.validations.Forbidden; -import com.nubeiot.core.validator.validations.When; - -import io.reactivex.Single; -import io.vertx.core.json.JsonObject; - -public class WhenTest { - - @Test - public void test_when_success() { - - /* Scenario 1: - 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, pass any value as valid*/ - JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); - new When<>().registerIs( - JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) - .registerThen( - JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, - "value")) - .registerOtherwise(new Forbidden<>().validate()) - .validate(jsonObject.getValue("id")) - .test() - .assertValue(value -> true); - } - - @Test - public void test_when_failure() { - /* Scenario 2: - 1. When id is in [1] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, when id is in [2] then it's value should be valid on ["ON"] - 3. Otherwise, pass any value as valid*/ - JsonObject jsonObject = new JsonObject().put("id", 2).put("value", "ON"); - - Single> whenId2 = new When<>().registerIs( - JsonConverter.validate(new Contains<>(new HashSet<>(Collections.singletonList(2))), jsonObject, "id")) - .registerThen(JsonConverter.validate(new Contains<>( - new HashSet<>(Collections.singletonList("OFF"))), - jsonObject, - "value")) - .registerOtherwise(new Any<>().validate()) - .validate(jsonObject.getValue("id")); - - Single> whenId1 = new When<>().registerIs( - JsonConverter.validate(new Contains<>(new HashSet<>(Collections.singletonList(1))), jsonObject, "id")) - .registerThen(JsonConverter.validate(new Contains<>( - new HashSet<>(Arrays.asList("ON", "OFF"))), - jsonObject, - "value")) - .registerOtherwise(whenId2) - .validate(jsonObject.getValue("id")); - - whenId1.test() - .assertError(error -> error.getMessage() - .equals("ValidationError: value strictly should fall in the" + " [OFF]")); - } - - @Test - public void test_skip_when_validation_when_value_null_success() { - - /* Scenario 1: - 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, pass any value as valid*/ - JsonObject jsonObject = new JsonObject().put("id", 10).put("value", "ON"); - new When<>().registerIs( - JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) - .registerThen( - JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, - "value")) - .registerOtherwise(new Forbidden<>().validate()) - .validate(null) // value is null - .test() - .assertValue(value -> true); - } - - @Test - public void test_skip_when_validation_when_value_null_with_json_success() { - - /* Scenario 1: - 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, pass any value as valid*/ - JsonObject jsonObject = new JsonObject().put("value", "ON"); - JsonConverter.validate(new When<>().registerIs( - JsonConverter.validate(new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3))), jsonObject, "id")) - .registerThen(JsonConverter.validate( - new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF"))), jsonObject, - "value")) - .registerOtherwise(new Forbidden<>().validate()), jsonObject, - "id") // JsonObject id value is null - .test().assertValue(value -> true); - } - -} diff --git a/core/validator/src/test/resources/example.json b/core/validator/src/test/resources/example.json index d7ea82dcf..b155cd8db 100644 --- a/core/validator/src/test/resources/example.json +++ b/core/validator/src/test/resources/example.json @@ -14,12 +14,24 @@ "basic": { "interests": [ { - "sports": "Cricket", - "music": "Piano" + "sports": [ + "Cricket", + "Tennis" + ], + "music": [ + { + "classical": [ + "Baroque", + "Choral" + ] + }, + { + "rock": "Arena Rock" + } + ] }, { - "sports": "Football", - "music": 123 + "sports": "Football" } ] } diff --git a/core/validator/src/test/resources/loop_and_key_loop_example.json b/core/validator/src/test/resources/loop_and_key_loop_example.json index 502daf337..c66cc9977 100644 --- a/core/validator/src/test/resources/loop_and_key_loop_example.json +++ b/core/validator/src/test/resources/loop_and_key_loop_example.json @@ -1,21 +1,14 @@ { - "details": [ - { - "visited_place": [ - "London", - "Melbourne" - ], - "on_list": [ - "Sydney", - "New York" - ] - }, - { - "movies": [ - "Forrest Gump", - "Bad Man", - 1 - ] - } - ] + "UI1": { + "type": "abc", + "value": 12 + }, + "UI2": { + "type": "xyz", + "value": "True", + "attributes": [ + 123, + "ABC" + ] + } } From 126e74d25e6f4dcee60680d027a964abb3012333 Mon Sep 17 00:00:00 2001 From: RaiBnod Date: Mon, 11 Feb 2019 02:28:13 +0545 Subject: [PATCH 6/6] - Improvement on WhenValidation. --- .../core/validator/JsonValidation.java | 21 +++++ .../core/validator/JsonValidationHolder.java | 15 +--- ...{JsonLoop.java => JsonValidationLoop.java} | 12 +-- .../core/validator/JsonValidationWhen.java | 83 +++++++++++++++++ .../java/com/nubeiot/core/validator/When.java | 88 ------------------- ...st.java => JsonValidationLoopingTest.java} | 22 ++--- .../validator/JsonValidationWhenTest.java | 77 ++++++++++++++++ .../core/nubeiot/core/validator/WhenTest.java | 77 ---------------- 8 files changed, 200 insertions(+), 195 deletions(-) create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonValidation.java rename core/validator/src/main/java/com/nubeiot/core/validator/{JsonLoop.java => JsonValidationLoop.java} (87%) create mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationWhen.java delete mode 100644 core/validator/src/main/java/com/nubeiot/core/validator/When.java rename core/validator/src/test/java/core/nubeiot/core/validator/{JsonLoopingTest.java => JsonValidationLoopingTest.java} (74%) create mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationWhenTest.java delete mode 100644 core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidation.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidation.java new file mode 100644 index 000000000..e5335e34a --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidation.java @@ -0,0 +1,21 @@ +package com.nubeiot.core.validator; + +import com.nubeiot.core.utils.JsonUtils; +import com.nubeiot.core.utils.Strings; + +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; + +public interface JsonValidation { + + default Object get(Object data, String key) { + if (Strings.isBlank(key) || data instanceof JsonArray) { + return data; + } + if (!(data instanceof JsonObject)) { + return null; + } + return JsonUtils.getObject((JsonObject) data, key); + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java index e82c367c0..1b92ead62 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationHolder.java @@ -5,14 +5,9 @@ import java.util.List; import java.util.Map; -import com.nubeiot.core.utils.JsonUtils; -import com.nubeiot.core.utils.Strings; - -import io.vertx.core.json.JsonArray; -import io.vertx.core.json.JsonObject; import lombok.NonNull; -public class JsonValidationHolder implements ValidationHolder { +public class JsonValidationHolder implements JsonValidation, ValidationHolder { protected Map>> validations = new HashMap<>(); @@ -34,13 +29,7 @@ public ValidationHolder add(String field, @NonNull Validation validation @Override public Object get(Object data, String key) { - if (Strings.isBlank(key) || data instanceof JsonArray) { - return data; - } - if (!(data instanceof JsonObject)) { - return null; - } - return JsonUtils.getObject((JsonObject) data, key); + return JsonValidation.super.get(data, key); } } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationLoop.java similarity index 87% rename from core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java rename to core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationLoop.java index 57e405d8d..d67706b9d 100644 --- a/core/validator/src/main/java/com/nubeiot/core/validator/JsonLoop.java +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationLoop.java @@ -14,14 +14,14 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class JsonLoop extends JsonValidationHolder { +public class JsonValidationLoop extends JsonValidationHolder { protected final String parentField; - private List> jsonLoops = new ArrayList<>(); + private List> jsonValidationLoops = new ArrayList<>(); private String previousParentField; - public void add(@NonNull JsonLoop validation) { - jsonLoops.add(validation); + public void add(@NonNull JsonValidationLoop validation) { + jsonValidationLoops.add(validation); } @Override @@ -29,7 +29,7 @@ public ValidationResult validate(T data) { return validate(this, data); } - protected ValidationResult validate(JsonLoop looper, T data) { + protected ValidationResult validate(JsonValidationLoop looper, T data) { if (nullable() && data == null) { return ValidationResult.valid(); } @@ -73,7 +73,7 @@ protected ValidationResult validate(JsonLoop looper, T data) { } } - for (JsonLoop validation : looper.jsonLoops) { + for (JsonValidationLoop validation : looper.jsonValidationLoops) { validation.previousParentField = actualParentField; validationResults.add(validation.validate(validation, this.get(loopedValue, validation.parentField))); } diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationWhen.java b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationWhen.java new file mode 100644 index 000000000..27fec3196 --- /dev/null +++ b/core/validator/src/main/java/com/nubeiot/core/validator/JsonValidationWhen.java @@ -0,0 +1,83 @@ +package com.nubeiot.core.validator; + +import java.util.HashSet; +import java.util.Set; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.exceptions.ValidationError; +import com.nubeiot.core.utils.Strings; +import com.nubeiot.core.validator.utils.ValidationUtils; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor +public class JsonValidationWhen implements JsonValidation, Validation { + + private String isField; + + private Validation is; + private Validation then; + private Validation otherwise; + + private Set inputs = new HashSet<>(); + + private String field; + + @Override + public ValidationResult validity(T s) { + return this.validate(this, s); + } + + protected ValidationResult validate(JsonValidationWhen jsonValidationWhen, T s) { + if (jsonValidationWhen.inputs.size() == 3 && + Strings.isNotBlank(field)) { // jsonValidationWhen all case are specified + + if (jsonValidationWhen.then instanceof JsonValidationWhen) { + return validate((JsonValidationWhen) jsonValidationWhen.then, s); + } else if (jsonValidationWhen.otherwise instanceof JsonValidationWhen) { + return validate((JsonValidationWhen) jsonValidationWhen.otherwise, s); + } + + Object v = get(s, jsonValidationWhen.isField); + if (jsonValidationWhen.is.validate(v).isValid()) { + v = get(s, field); + return ValidationUtils.transferValidationInputToFieldFunc.apply(jsonValidationWhen.then.validate(v), + field); + } else { + v = get(s, field); + return ValidationUtils.transferValidationInputToFieldFunc.apply( + jsonValidationWhen.otherwise.validate(v), field); + } + } else { + return ValidationResult.invalid(ValidationError.builder() + .errorCode(NubeException.ErrorCode.INITIALIZER_ERROR) + .message( + "JsonValidationWhen validation Initialization Error")); + } + } + + public JsonValidationWhen registerField(String field) { + this.field = field; + return this; + } + + public JsonValidationWhen registerIs(String field, Validation is) { + inputs.add(1); + this.isField = field; + this.is = is; + return this; + } + + public JsonValidationWhen registerThen(Validation then) { + inputs.add(2); + this.then = then; + return this; + } + + public JsonValidationWhen registerOtherwise(Validation otherwise) { + inputs.add(3); + this.otherwise = otherwise; + return this; + } + +} diff --git a/core/validator/src/main/java/com/nubeiot/core/validator/When.java b/core/validator/src/main/java/com/nubeiot/core/validator/When.java deleted file mode 100644 index 32f6baf87..000000000 --- a/core/validator/src/main/java/com/nubeiot/core/validator/When.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.nubeiot.core.validator; - -import java.util.HashSet; -import java.util.Set; - -import com.nubeiot.core.exceptions.NubeException; -import com.nubeiot.core.exceptions.ValidationError; -import com.nubeiot.core.utils.JsonUtils; -import com.nubeiot.core.validator.utils.ValidationUtils; - -import io.vertx.core.json.JsonObject; -import lombok.NoArgsConstructor; - -@NoArgsConstructor -public class When implements Validation { - - private String isField; - private String thenField; - private String otherwiseField; - - private Validation is; - private Validation then; - private Validation otherwise; - - private Set inputs = new HashSet<>(); - - public Object get(T data, String key) { - if (!(data instanceof JsonObject)) { - return null; - } - return JsonUtils.getObject((JsonObject) data, key); - } - - @Override - public ValidationResult validity(T s) { - if (inputs.size() == 3) { // when all case are specified - Object v = get(s, isField); - if (is.validate(v).isValid()) { - v = get(s, thenField); - return ValidationUtils.transferValidationInputToFieldFunc.apply(then.validate(v), thenField); - } else { - v = get(s, otherwiseField); - if (otherwise instanceof When) { - return otherwise.validate(v); - } - return ValidationUtils.transferValidationInputToFieldFunc.apply(otherwise.validate(v), otherwiseField); - } - } else { - return ValidationResult.invalid(ValidationError.builder() - .errorCode(NubeException.ErrorCode.INITIALIZER_ERROR) - .message("When validation Initialization Error")); - } - } - - public void setIs(String field, Validation is) { - inputs.add(1); - this.isField = field; - this.is = is; - } - - public void setThen(String field, Validation then) { - inputs.add(2); - this.thenField = field; - this.then = then; - } - - public void setOtherwise(String field, Validation otherwise) { - inputs.add(3); - this.otherwiseField = field; - this.otherwise = otherwise; - } - - public void setIs(Validation is) { - inputs.add(1); - this.is = is; - } - - public void setThen(Validation then) { - inputs.add(2); - this.then = then; - } - - public void setOtherwise(Validation otherwise) { - inputs.add(3); - this.otherwise = otherwise; - } - -} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationLoopingTest.java similarity index 74% rename from core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java rename to core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationLoopingTest.java index 214741a68..131ce4dd8 100644 --- a/core/validator/src/test/java/core/nubeiot/core/validator/JsonLoopingTest.java +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationLoopingTest.java @@ -7,7 +7,7 @@ import com.nubeiot.core.exceptions.NubeException; import com.nubeiot.core.utils.FileUtils; -import com.nubeiot.core.validator.JsonLoop; +import com.nubeiot.core.validator.JsonValidationLoop; import com.nubeiot.core.validator.ValidationResult; import com.nubeiot.core.validator.utils.ValidationUtils; import com.nubeiot.core.validator.validations.IntegerValidation; @@ -17,28 +17,28 @@ import io.vertx.core.json.JsonArray; import io.vertx.core.json.JsonObject; -public class JsonLoopingTest { +public class JsonValidationLoopingTest { @Test public void test_jsonArrayLoop() { - URL resource = JsonLoopingTest.class.getClassLoader().getResource("example.json"); + URL resource = JsonValidationLoopingTest.class.getClassLoader().getResource("example.json"); JsonArray jsonArray = new JsonArray(FileUtils.readFileToString(resource.toString())); - JsonLoop outerLoop = new JsonLoop<>(""); + JsonValidationLoop outerLoop = new JsonValidationLoop<>(""); outerLoop.add("first_name", new StringValidation<>()); outerLoop.add("last_name", new StringValidation<>()); outerLoop.add("siblings", new JsonArrayValidation<>()); - JsonLoop interestsLoop = new JsonLoop<>("details.basic.interests"); + JsonValidationLoop interestsLoop = new JsonValidationLoop<>("details.basic.interests"); interestsLoop.add("sports", new JsonArrayValidation<>()); - JsonLoop musicsLoop = new JsonLoop<>("music"); + JsonValidationLoop musicsLoop = new JsonValidationLoop<>("music"); musicsLoop.add("classical", new JsonArrayValidation<>()); musicsLoop.add("rock", new JsonArrayValidation<>()); - interestsLoop.add(musicsLoop); // adding JsonLoop inside JsonLoop + interestsLoop.add(musicsLoop); // adding JsonValidationLoop inside JsonValidationLoop - outerLoop.add(interestsLoop); // adding JsonLoop inside JsonLoop + outerLoop.add(interestsLoop); // adding JsonValidationLoop inside JsonValidationLoop ValidationResult validationResult = outerLoop.validate(jsonArray); System.out.println(validationResult.getErrors()); @@ -53,15 +53,15 @@ public void test_jsonArrayLoop() { @Test public void test_jsonArrayAndJsonObject() { - URL resource = JsonLoopingTest.class.getClassLoader().getResource("loop_and_key_loop_example.json"); + URL resource = JsonValidationLoopingTest.class.getClassLoader().getResource("loop_and_key_loop_example.json"); JsonObject jsonObject = new JsonObject(FileUtils.readFileToString(resource.toString())); - JsonLoop outerLoop = new JsonLoop<>(""); + JsonValidationLoop outerLoop = new JsonValidationLoop<>(""); outerLoop.add("type", new StringValidation<>()); outerLoop.add("value", new IntegerValidation<>()); outerLoop.add("attributes", new JsonArrayValidation<>()); - JsonLoop attributesLoop = new JsonLoop<>("attributes"); + JsonValidationLoop attributesLoop = new JsonValidationLoop<>("attributes"); attributesLoop.add("", new StringValidation<>()); outerLoop.add(attributesLoop); diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationWhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationWhenTest.java new file mode 100644 index 000000000..15f0e6ff5 --- /dev/null +++ b/core/validator/src/test/java/core/nubeiot/core/validator/JsonValidationWhenTest.java @@ -0,0 +1,77 @@ +package core.nubeiot.core.validator; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +import org.junit.Assert; +import org.junit.Test; + +import com.nubeiot.core.exceptions.NubeException; +import com.nubeiot.core.validator.JsonValidationWhen; +import com.nubeiot.core.validator.utils.ValidationUtils; +import com.nubeiot.core.validator.validations.Any; +import com.nubeiot.core.validator.validations.Contains; +import com.nubeiot.core.validator.validations.Forbidden; + +import io.vertx.core.json.JsonObject; + +public class JsonValidationWhenTest { + + @Test + public void test_when_initialization_failure() { + JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); + + JsonValidationWhen validation = new JsonValidationWhen<>().registerField("value"); + validation.registerIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))) + .registerThen(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); + + NubeException exception = ValidationUtils.convertValidationErrorsToException.apply( + validation.validate(jsonObject).getErrors()); + + Assert.assertEquals(exception.getMessage(), + "ValidationError: JsonValidationWhen validation Initialization Error"); + Assert.assertEquals(exception.getErrorCode(), NubeException.ErrorCode.INITIALIZER_ERROR); + } + + @Test + public void test_when_success() { + /* Scenario 1: + 1. JsonValidationWhen id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, Forbidden*/ + JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); + + JsonValidationWhen validation = new JsonValidationWhen<>().registerField("value"); + validation.registerIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))) + .registerThen(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))) + .registerOtherwise(new Forbidden<>()); + + System.out.println( + ValidationUtils.convertValidationErrorsToException.apply(validation.validate(jsonObject).getErrors()) + .getMessage()); + Assert.assertTrue(validation.validate(jsonObject).isValid()); + } + + @Test + public void test_when_failure() { + /* Scenario 2: + 1. JsonValidationWhen id is in [1] then it's values should be valid on ["ON" or "OFF"] + 2. Otherwise, jsonValidationWhen id is in [2] then it's value should be valid on ["OFF"] + 3. Otherwise, pass any value as valid*/ + JsonObject jsonObject = new JsonObject().put("id", 2).put("value", "ON"); + + JsonValidationWhen when = new JsonValidationWhen<>().registerField("value"); + + when.registerIs("id", new Contains<>(new HashSet<>(Collections.singletonList(1)))) + .registerThen(new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))) + .registerOtherwise( + new JsonValidationWhen<>().registerIs("id", new Contains<>(new HashSet<>(Collections.singletonList(2)))) + .registerThen(new Contains<>(new HashSet<>(Collections.singletonList("OFF")))) + .registerOtherwise(new Any<>())); + + NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( + when.validate(jsonObject).getErrors()); + Assert.assertEquals(nubeException.getMessage(), "ValidationError: value strictly should fall in the [OFF]"); + } + +} diff --git a/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java b/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java deleted file mode 100644 index ebe9de8a0..000000000 --- a/core/validator/src/test/java/core/nubeiot/core/validator/WhenTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package core.nubeiot.core.validator; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; - -import org.junit.Assert; -import org.junit.Test; - -import com.nubeiot.core.exceptions.NubeException; -import com.nubeiot.core.validator.When; -import com.nubeiot.core.validator.utils.ValidationUtils; -import com.nubeiot.core.validator.validations.Any; -import com.nubeiot.core.validator.validations.Contains; -import com.nubeiot.core.validator.validations.Forbidden; - -import io.vertx.core.json.JsonObject; - -public class WhenTest { - - @Test - public void test_when_initialization_failure() { - JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); - - When validation = new When<>(); - validation.setIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))); - validation.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); - NubeException exception = ValidationUtils.convertValidationErrorsToException.apply( - validation.validate(jsonObject).getErrors()); - - Assert.assertEquals(exception.getMessage(), "ValidationError: When validation Initialization Error"); - Assert.assertEquals(exception.getErrorCode(), NubeException.ErrorCode.INITIALIZER_ERROR); - } - - @Test - public void test_when_success() { - /* Scenario 1: - 1. When id is in [1, 2, 3] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, Forbidden*/ - JsonObject jsonObject = new JsonObject().put("id", 1).put("value", "ON"); - - When validation = new When<>(); - validation.setIs("id", new Contains<>(new HashSet<>(Arrays.asList(1, 2, 3)))); - validation.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); - validation.setOtherwise(new Forbidden<>()); - - System.out.println( - ValidationUtils.convertValidationErrorsToException.apply(validation.validate(jsonObject).getErrors()) - .getMessage()); - Assert.assertTrue(validation.validate(jsonObject).isValid()); - } - - @Test - public void test_when_failure() { - /* Scenario 2: - 1. When id is in [1] then it's values should be valid on ["ON" or "OFF"] - 2. Otherwise, when id is in [2] then it's value should be valid on ["OFF"] - 3. Otherwise, pass any value as valid*/ - JsonObject jsonObject = new JsonObject().put("id", 2).put("value", "ON"); - - When whenId1 = new When<>(); - whenId1.setIs("id", new Contains<>(new HashSet<>(Collections.singletonList(1)))); - whenId1.setThen("value", new Contains<>(new HashSet<>(Arrays.asList("ON", "OFF")))); - - When whenId2 = new When<>(); - whenId2.setIs("id", new Contains<>(new HashSet<>(Collections.singletonList(2)))); - whenId2.setThen("value", new Contains<>(new HashSet<>(Collections.singletonList("OFF")))); - whenId2.setOtherwise(new Any<>()); - - whenId1.setOtherwise(whenId2); - - NubeException nubeException = ValidationUtils.convertValidationErrorsToException.apply( - whenId1.validate(jsonObject).getErrors()); - Assert.assertEquals(nubeException.getMessage(), "ValidationError: value strictly should fall in the [OFF]"); - } - -}