Skip to content

Commit

Permalink
Fix error message when introspection is missing and method has generi…
Browse files Browse the repository at this point in the history
…c signature (#443)

Fixed #417
  • Loading branch information
altro3 authored Jan 17, 2025
1 parent 080fe0e commit d3977c5
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import jakarta.inject.Singleton;
import jakarta.validation.Valid;
import org.junit.jupiter.api.Test;
import spock.lang.Specification;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

@Property(name = "spec.name", value = "PojoOptionalGetterSpec")
@MicronautTest
class PojoOptionalGetterTest extends Specification {
class PojoOptionalGetterSpec {

@Test
void pojoCanHaveGetterWhichReturnsAnOptional(MockService service) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.micronaut.docs.validation;

import io.micronaut.context.annotation.Property;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import io.micronaut.validation.Validated;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Valid;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

@Property(name = "spec.name", value = "WrongValidationTest")
@MicronautTest
class WrongValidationTest {

@Inject
ValidatedService validatedService;

@Test
void validateEvent() {
assertDoesNotThrow(() -> validatedService.send(new IntrospectedEvent()));

var ex = assertThrows(ConstraintViolationException.class, () -> validatedService.send(new NonIntrospectedEvent()));

assertTrue(ex.getMessage().contains("NonIntrospectedEvent"));
}

@Requires(property = "spec.name", value = "WrongValidationTest")
@Singleton
@Validated
static class ValidatedService {

<E> void send(@Valid E event) {

}
}

@Introspected
static class IntrospectedEvent {}

static class NonIntrospectedEvent {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,7 @@ private <R, E> void propagateValidation(DefaultConstraintValidatorContext<R> con
final BeanIntrospection<E> beanIntrospection = getBeanIntrospection(elementValue, elementType.getType());
if (beanIntrospection == null) {
// Error if not introspected
ConstraintDescriptor<Annotation> constraintDescriptor = notIntrospectedConstraint(elementType);
ConstraintDescriptor<Annotation> constraintDescriptor = notIntrospectedConstraint(elementType, elementValue);
DefaultConstraintViolation<R> violation = createConstraintViolation(context, leftBean, elementValue, constraintDescriptor);
context.addViolation(violation);
return;
Expand Down Expand Up @@ -1572,7 +1572,7 @@ public static String requireNonEmpty(String name, String value) {
return value;
}

private static ConstraintDescriptor<Annotation> notIntrospectedConstraint(Argument<?> notIntrospectedArgument) {
private static <E> ConstraintDescriptor<Annotation> notIntrospectedConstraint(Argument<E> notIntrospectedArgument, E elementValue) {
return new ConstraintDescriptor<>() {

@Override
Expand Down Expand Up @@ -1607,7 +1607,11 @@ public ConstraintTarget getValidationAppliesTo() {

@Override
public Map<String, Object> getAttributes() {
return Collections.singletonMap("type", notIntrospectedArgument.getType().getName());
var argType = notIntrospectedArgument.getType().getName();
if (notIntrospectedArgument.isTypeVariable()) {
argType = elementValue.getClass().getName();
}
return Collections.singletonMap("type", argType);
}

@Override
Expand Down

0 comments on commit d3977c5

Please sign in to comment.