Skip to content

Commit

Permalink
Add a few validator tests
Browse files Browse the repository at this point in the history
  • Loading branch information
andriy-dmytruk committed Nov 7, 2022
1 parent 79c3e9d commit a464f35
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1025,7 +1025,6 @@ private boolean doesHaveValidatedTypeParameters(
) {
if (!context.elementRequireCascadeValidation.containsKey(annotatedElement)) {
context.elementRequireCascadeValidation.put(annotatedElement, false);
AnnotationMetadata annotationMetadata = annotatedElement.getAnnotationMetadata();

Argument<Object> annotatedElementAsArgument = null;
if (annotatedElement instanceof Argument) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ public <A extends Annotation, T> Optional<ConstraintValidator<A, T>> findConstra
ArgumentUtils.requireNonNull("constraintType", constraintType);
ArgumentUtils.requireNonNull("targetType", targetType);
final ValidatorKey key = new ValidatorKey(constraintType, targetType);
targetType = ReflectionUtils.getWrapperType(targetType);
Class<?> targetWrapperType = ReflectionUtils.getWrapperType(targetType);
ConstraintValidator constraintValidator = localValidators.get(key);
if (constraintValidator != null) {
return Optional.of(constraintValidator);
Expand All @@ -444,9 +444,9 @@ public <A extends Annotation, T> Optional<ConstraintValidator<A, T>> findConstra
} else {
final Qualifier<ConstraintValidator> qualifier = Qualifiers.byTypeArguments(
constraintType,
ReflectionUtils.getWrapperType(targetType)
ReflectionUtils.getWrapperType(targetWrapperType)
);
Class<T> finalTargetType = targetType;
Class<?> finalTargetType = targetWrapperType;
final Class[] finalTypeArguments = {constraintType, finalTargetType};
final Optional<ConstraintValidator> local = localValidators.entrySet().stream().filter(entry -> {
final ValidatorKey k = entry.getKey();
Expand All @@ -469,7 +469,7 @@ public <A extends Annotation, T> Optional<ConstraintValidator<A, T>> findConstra
}
} else {
// last chance lookup
final ConstraintValidator cv = findLocalConstraintValidator(constraintType, targetType)
final ConstraintValidator cv = findLocalConstraintValidator(constraintType, targetWrapperType)
.orElse(ConstraintValidator.VALID);
validatorCache.put(key, cv);
if (cv != ConstraintValidator.VALID) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.micronaut.core.annotation.Introspected
import io.micronaut.validation.validator.resolver.CompositeTraversableResolver
import jakarta.inject.Singleton
import spock.lang.AutoCleanup
import spock.lang.Ignore
import spock.lang.Shared
import spock.lang.Specification

Expand Down Expand Up @@ -246,7 +247,7 @@ class ValidatorSpec extends Specification {
void "validate property argument - with iterable constraints"() {
given:
var e = new ValidatorSpecClasses.Email(["[email protected]", "", "[email protected]"])
var violations = validator.validate(e);
var violations = validator.validate(e)
violations = violations.sort{it->it.getPropertyPath().toString()}

expect:
Expand Down Expand Up @@ -777,6 +778,34 @@ class ValidatorSpec extends Specification {
constraintViolations[0].toString() == 'DefaultConstraintViolation{rootBean=class io.micronaut.validation.validator.$BookService$Definition$Intercepted, invalidValue=50, path=saveBook.pages}'
constraintViolations[1].toString() == 'DefaultConstraintViolation{rootBean=class io.micronaut.validation.validator.$BookService$Definition$Intercepted, invalidValue=, path=saveBook.title}'
}
void "test cascade to container"() {
given:
def salad = new ValidatorSpecClasses.Salad([
new ValidatorSpecClasses.Ingredient("carrot"),
new ValidatorSpecClasses.Ingredient("")
])
def violations = validator.validate(salad)
expect:
violations.size() == 1
violations[0].invalidValue == ""
}
@Ignore("https://github.com/micronaut-projects/micronaut-core/issues/8301")
void "test cascade to container with setter"() {
given:
def salad = new ValidatorSpecClasses.SaladWithSetter()
salad.ingredients = [
new ValidatorSpecClasses.Ingredient("carrot"),
new ValidatorSpecClasses.Ingredient("")
]
def violations = validator.validate(salad)

expect:
violations.size() == 1
violations[0].invalidValue == ""
}
}

@Introspected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ public Set<Book> getBooks() {
// test validate property argument cascade
@Introspected
public static class Email {
final private @Size(max=2) List<@NotBlank String> recoveryEmails;
private @Size(max=2) List<@NotBlank String> recoveryEmails;

public Email(@Size(max=2) List<String> recoveryEmails) {
public Email(List<String> recoveryEmails) {
this.recoveryEmails = recoveryEmails;
}

Expand Down Expand Up @@ -290,4 +290,36 @@ enum AuthorState {
PUBLISHED,
DRAFT
}

// test cascade to container
@Introspected
public static class Salad {
List<@Valid Ingredient> ingredients;

public Salad(List<Ingredient> ingredients) {
this.ingredients = ingredients;
}

public List<Ingredient> getIngredients() {
return ingredients;
}
}

@Introspected
public static class SaladWithSetter {
List<@Valid Ingredient> ingredients;

public List<Ingredient> getIngredients() {
return ingredients;
}

public void setIngredients(List<Ingredient> ingredients) {
this.ingredients = ingredients;
}
}

@Introspected
public record Ingredient(
@NotBlank String name
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import io.micronaut.context.ApplicationContext
import io.micronaut.core.annotation.Introspected
import io.micronaut.validation.validator.Validator
import spock.lang.AutoCleanup
import spock.lang.Ignore
import spock.lang.Shared
import spock.lang.Specification

import javax.validation.Valid

@Ignore("Validation module needs to be removed from core first")
class CustomConstraintsSpec extends Specification {

@Shared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ public class PojoConfigProps {

private List<@Valid Pojo> pojos;

public List<Pojo> getPojos() {
public List<@Valid Pojo> getPojos() {
return pojos;
}

public void setPojos(List<Pojo> pojos) {
public void setPojos(List<@Valid Pojo> pojos) {
this.pojos = pojos;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.micronaut.validation.validator.pojo

import io.micronaut.context.ApplicationContext
import io.micronaut.context.annotation.Executable
import io.micronaut.context.exceptions.BeanInstantiationException
import io.micronaut.validation.Pojo
import jakarta.inject.Singleton
import spock.lang.Specification

import javax.validation.ConstraintViolationException
import javax.validation.Valid


class PojoConfigurationPropertiesSpec extends Specification {
Expand All @@ -15,6 +19,20 @@ class PojoConfigurationPropertiesSpec extends Specification {
]
])

void "test @Valid on config props property manual"() {
when:
Pojo pojo = new Pojo()
pojo.name = ""
PojoConfigProps configProps = new PojoConfigProps()
configProps.pojos = [pojo]

context.getBean(PojoConfigPropsValidator).validateConfigProps(configProps)

then:
def ex = thrown(ConstraintViolationException)
ex.message.contains("must not be blank")
}

void "test @Valid on config props property"() {
when:
context.getBean(PojoConfigProps)
Expand All @@ -24,3 +42,9 @@ class PojoConfigurationPropertiesSpec extends Specification {
ex.message.contains("List of constraint violations:[\n\tpojos[0]<E Pojo>.name - must not be blank\n]")
}
}

@Singleton
class PojoConfigPropsValidator {
@Executable
void validateConfigProps(@Valid PojoConfigProps configProps) {}
}

0 comments on commit a464f35

Please sign in to comment.