I’ve created a custom validator and set it at class level, message is empty instead of the defined one.
The DTO subject to validation
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AuthorizationTerms
@Schema(description = "Task.")
public class TaskDTO extends IdentifiableDTO {
// ..... omitted fields
private String authorizationTerm;
@NullOrNotEmpty
private List<String> authorizationTerms;
}
The annotation
@Constraint(validatedBy = TaskDTOValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorizationTerms {
String message() default "Either authorizationTerm or authorizationTerms must be provided";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
The validator
public class TaskDTOValidator implements ConstraintValidator<AuthorizationTerms, TaskDTO> {
@Override
public boolean isValid(TaskDTO task, ConstraintValidatorContext context) {
if (task == null) {
return true;
}
return StringUtils.isNotBlank(task.getAuthorizationTerm()) ||
task.getAuthorizationTerms() != null;
}
}
The endpoint with validation
@PostMapping
public K create(@Valid @RequestBody K daoDto) {
return entityMapperService.createAndMap(daoDto);
}
The test
TaskDTO taskDTO = TaskDTO.builder()
.identifier(TASK_IDENTIFIER)
.startDate(INSTANT)
.updateDate(INSTANT)
.dueDate(INSTANT)
.assigneeIdentifier(TASK_ASSIGNEE_IDENTIFIER)
.assigneeName(TASK_ASSIGNEE_NAME)
.stageIndex(0)
.accounts(accountDTOs)
.actions(actionDTOs)
.clients(clientDTOs)
.status(statusDTO)
.translations(List.of(translatedFirstTaskDTO))
.activityIdentifier(activityDTO.getIdentifier())
.authorizationTerm(null)
.authorizationTerms(null)
.build();
// Act
final ResponseEntity<String> responseEntity = testRestTemplate.postForEntity("/tasks", getHttpEntityWithJwtTokenHeader(taskDTO, SYSTEM_AUTHORIZATION_HEADER_VALUE), String.class);
// Assert
Assertions.assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
Assertions.assertThat(responseEntity.getBody())
.isEqualTo("Either authorizationTerm or authorizationTerms must be provided");
The test error
Expected :"Either authorizationTerm or authorizationTerms must be provided"
Actual :"{}"
Feels like I’m missing something or there is a bug.
Note: A similar annotation at class level but not at root level works (a field of TaskDTO has it), may it be something related to that?
Went through the official documentation already, everything seems to be fine.