ErrorHalRepresentationFactory { public ErrorHalRepresentation halRepresentationForValidationErrors(Errors validationResult) { ErrorHalRepresentation.Builder builder = ErrorHalRepresentation.builder() .withProfile(errorProfile) .withErrorMessage(String.format("Validation failed. %d error(s)", validationResult.getErrorCount())); validationResult.getAllErrors() .stream() .filter(o -> o instanceof FieldError) .map(FieldError.class::cast) .sorted(comparing(FieldError::getField)) .forEach(e -> { builder.withError(e.getField(), messageSource.getMessage(e.getCode() + ".key", null, "unknown", Locale.getDefault()), e.getDefaultMessage(), serializeRejectedValue(e)); }); return builder.build(); } @Autowired  ErrorHalRepresentationFactory(
            ResourceBundleMessageSource edisonValidationMessageSource,
            ObjectMapper objectMapper,
            @Value("${edison.validation.error-profile:http://spec.otto.de/profiles/error}") String errorProfile); ErrorHalRepresentation halRepresentationForErrorMessage(String errorMessage); ErrorHalRepresentation halRepresentationForValidationErrors(Errors validationResult);  }
@Test public void shouldBuildRepresentationForValidationResults() { final ErrorHalRepresentationFactory factory = new ErrorHalRepresentationFactory(messageSource, new ObjectMapper(), "someErrorProfile"); final Errors mockErrors = mock(Errors.class); final FieldError fieldError = new FieldError("someObject", "xyzField", "rejected", true, new String[]{"NotEmpty"}, new Object[]{}, "Some default message"); when(mockErrors.getAllErrors()).thenReturn(Collections.singletonList(fieldError)); when(mockErrors.getErrorCount()).thenReturn(1); final ErrorHalRepresentation errorHalRepresentation = factory.halRepresentationForValidationErrors(mockErrors); assertThat(errorHalRepresentation.getErrorMessage(), is("Validation failed. 1 error(s)")); assertThat(errorHalRepresentation.getLinks().getLinkBy("profile").isPresent(), is(true)); assertThat(errorHalRepresentation.getLinks().getLinkBy("profile").get().getHref(), is("someErrorProfile")); final List<Map<String, String>> listOfViolations = errorHalRepresentation.getErrors().get("xyzField"); assertThat(listOfViolations, hasSize(1)); assertThat(listOfViolations.get(0), hasEntry("key", "text.not_empty")); assertThat(listOfViolations.get(0), hasEntry("message", "Some default message")); assertThat(listOfViolations.get(0), hasEntry("rejected", "rejected")); }
@Test public void shouldNotCrashOnNullValues() { final ErrorHalRepresentationFactory factory = new ErrorHalRepresentationFactory(messageSource, new ObjectMapper(), "someErrorProfile"); final Errors mockErrors = mock(Errors.class); final FieldError fieldError = new FieldError("someObject", "xyzField", null, true, new String[]{"NotEmpty"}, new Object[]{}, "Some default message"); when(mockErrors.getAllErrors()).thenReturn(Collections.singletonList(fieldError)); when(mockErrors.getErrorCount()).thenReturn(1); final ErrorHalRepresentation errorHalRepresentation = factory.halRepresentationForValidationErrors(mockErrors); assertThat(errorHalRepresentation.getErrorMessage(), is("Validation failed. 1 error(s)")); assertThat(errorHalRepresentation.getLinks().getLinkBy("profile").isPresent(), is(true)); assertThat(errorHalRepresentation.getLinks().getLinkBy("profile").get().getHref(), is("someErrorProfile")); final List<Map<String, String>> listOfViolations = errorHalRepresentation.getErrors().get("xyzField"); assertThat(listOfViolations, hasSize(1)); assertThat(listOfViolations.get(0), hasEntry("key", "text.not_empty")); assertThat(listOfViolations.get(0), hasEntry("message", "Some default message")); assertThat(listOfViolations.get(0), hasEntry("rejected", "null")); }