diff --git a/src/main/java/org/springframework/hateoas/MediaTypes.java b/src/main/java/org/springframework/hateoas/MediaTypes.java index 5d1531cc..5f5e02b3 100644 --- a/src/main/java/org/springframework/hateoas/MediaTypes.java +++ b/src/main/java/org/springframework/hateoas/MediaTypes.java @@ -76,4 +76,15 @@ public class MediaTypes { * Public constant media type for {@code application/vnd.amundsen-uber+json}. */ public static final MediaType UBER_JSON = MediaType.parseMediaType(UBER_JSON_VALUE); + + + /** + * A String equivalent of {@link MediaTypes#VND_ERROR_JSON}. + */ + public static final String VND_ERROR_JSON_VALUE = "application/vnd.error+json"; + + /** + * Public constant media type for {@code application/vnd.error+json}. + */ + public static final MediaType VND_ERROR_JSON = MediaType.valueOf(VND_ERROR_JSON_VALUE); } diff --git a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java index e3c03c40..11852354 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java +++ b/src/main/java/org/springframework/hateoas/mediatype/vnderrors/VndErrors.java @@ -15,42 +15,80 @@ */ package org.springframework.hateoas.mediatype.vnderrors; +import lombok.EqualsAndHashCode; +import lombok.Getter; + import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.Link; +import org.springframework.hateoas.Links; import org.springframework.hateoas.RepresentationModel; -import org.springframework.lang.Nullable; +import org.springframework.hateoas.server.core.Relation; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; /** - * A representation model class to be rendered as specified for the media type {@code application/vnd.error}. + * A representation model class to be rendered as specified for the media type {@code application/vnd.error+json}. * * @see https://github.com/blongden/vnd.error * @author Oliver Gierke * @author Greg Turnquist */ -public class VndErrors implements Iterable { +@JsonPropertyOrder({ "message", "logref", "total", "_links", "_embedded" }) +@JsonIgnoreProperties(ignoreUnknown = true) +@EqualsAndHashCode +public class VndErrors extends CollectionModel { - private final List vndErrors; + /** + * @deprecated Use {@link org.springframework.hateoas.IanaLinkRelations#HELP} + */ + @Deprecated public static final String REL_HELP = "help"; + + /** + * @deprecated Use {@link org.springframework.hateoas.IanaLinkRelations#DESCRIBES} + */ + @Deprecated public static final String REL_DESCRIBES = "describes"; + + /** + * @deprecated Use {@link org.springframework.hateoas.IanaLinkRelations#ABOUT} + */ + @Deprecated public static final String REL_ABOUT = "about"; + + private final List errors; + + @Getter // + @JsonInclude(value = JsonInclude.Include.NON_EMPTY) // + private final String message; + + @Getter // + @JsonInclude(value = JsonInclude.Include.NON_EMPTY) // + private final Integer logref; + + public VndErrors() { + + this.errors = new ArrayList<>(); + this.message = null; + this.logref = null; + } /** * Creates a new {@link VndErrors} instance containing a single {@link VndError} with the given logref, message and * optional {@link Link}s. - * - * @param logref must not be {@literal null} or empty. - * @param message must not be {@literal null} or empty. - * @param links */ public VndErrors(String logref, String message, Link... links) { - this(new VndError(logref, message, links)); + this(new VndError(message, null, Integer.parseInt(logref), links)); } /** @@ -62,9 +100,11 @@ public class VndErrors implements Iterable { Assert.notNull(error, "Error must not be null"); - this.vndErrors = new ArrayList<>(errors.length + 1); - this.vndErrors.add(error); - this.vndErrors.addAll(Arrays.asList(errors)); + this.errors = new ArrayList<>(); + this.errors.add(error); + Collections.addAll(this.errors, errors); + this.message = null; + this.logref = null; } /** @@ -73,38 +113,84 @@ public class VndErrors implements Iterable { * @param errors must not be {@literal null} or empty. */ @JsonCreator - public VndErrors(List errors) { + public VndErrors(@JsonProperty("_embedded") List errors, @JsonProperty("message") String message, + @JsonProperty("logref") Integer logref, @JsonProperty("_links") Links links) { - Assert.notNull(errors, "Errors must not be null!"); - Assert.isTrue(!errors.isEmpty(), "Errors must not be empty!"); - this.vndErrors = errors; + Assert.notNull(errors, "Errors must not be null!"); // Retain for compatibility + Assert.notEmpty(errors, "Errors must not be empty!"); + + this.errors = errors; + this.message = message; + this.logref = logref; + + if (links != null && !links.isEmpty()) { + add(links); + } + } + + public VndErrors withMessage(String message) { + return new VndErrors(this.errors, message, this.logref, this.getLinks()); + } + + public VndErrors withLogref(Integer logref) { + return new VndErrors(this.errors, this.message, logref, this.getLinks()); + } + + public VndErrors withErrors(List errors) { + + Assert.notNull(errors, "errors must not be null!"); + Assert.notEmpty(errors, "errors must not empty!"); + + return new VndErrors(errors, this.message, this.logref, this.getLinks()); + } + + public VndErrors withError(VndError error) { + + this.errors.add(error); + return new VndErrors(this.errors, this.message, this.logref, this.getLinks()); + } + + public VndErrors withLink(Link link) { + + add(link); + return new VndErrors(this.errors, this.message, this.logref, this.getLinks()); + } + + public VndErrors withLinks(Link... links) { + + add(links); + return new VndErrors(this.errors, this.message, this.logref, this.getLinks()); } /** - * Protected default constructor to allow JAXB marshalling. + * Returns the underlying elements. + * + * @return the content will never be {@literal null}. */ - protected VndErrors() { - this.vndErrors = new ArrayList<>(); + @Override + public Collection getContent() { + return this.errors; + } + + /** + * Virtual attribute to generate JSON field of {@literal total}. Only generated when there are multiple errors. + */ + @JsonInclude(JsonInclude.Include.NON_NULL) + public Integer getTotal() { + return this.errors.size() > 1 // + ? this.errors.size() // + : null; // } /** * Adds an additional {@link VndError} to the wrapper. * * @param error + * @deprecated Use {{@link #withError(VndError)}} */ + @Deprecated public VndErrors add(VndError error) { - this.vndErrors.add(error); - return this; - } - - /** - * Dummy method to allow {@link JsonValue} to be configured. - * - * @return the vndErrors - */ - @JsonValue - private List getErrors() { - return vndErrors; + return withError(error); } /* @@ -113,142 +199,70 @@ public class VndErrors implements Iterable { */ @Override public Iterator iterator() { - return this.vndErrors.iterator(); + return this.errors.iterator(); } - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ @Override public String toString() { - return String.format("VndErrors[%s]", StringUtils.collectionToCommaDelimitedString(vndErrors)); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#hashCode() - */ - @Override - public int hashCode() { - return vndErrors.hashCode(); - } - - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ - @Override - public boolean equals(@Nullable Object obj) { - - if (this == obj) { - return true; - } - - if (!(obj instanceof VndErrors)) { - return false; - } - - VndErrors that = (VndErrors) obj; - return this.vndErrors.equals(that.vndErrors); + return String.format("VndErrors[%s]", StringUtils.collectionToCommaDelimitedString(this.errors)); } /** * A single {@link VndError}. * * @author Oliver Gierke + * @author Greg Turnquist */ + @JsonPropertyOrder({ "message", "path", "logref" }) + @Relation(collectionRelation = "errors") + @EqualsAndHashCode public static class VndError extends RepresentationModel { - @JsonProperty private final String logref; - @JsonProperty private final String message; + @Getter // + private final String message; + + @Getter(onMethod = @__(@JsonInclude(JsonInclude.Include.NON_EMPTY))) // + private final String path; + + @Getter(onMethod = @__(@JsonInclude(JsonInclude.Include.NON_EMPTY))) // + private final Integer logref; /** - * Creates a new {@link VndError} with the given logref, a message as well as some {@link Link}s. + * Creates a new {@link VndError} with a message and optional a path and a logref. * - * @param logref must not be {@literal null} or empty. * @param message must not be {@literal null} or empty. + * @param path + * @param logref must not be {@literal null} or empty. * @param links */ - public VndError(String logref, String message, Link... links) { + @JsonCreator + public VndError(@JsonProperty("message") String message, @JsonProperty("path") String path, + @JsonProperty("logref") Integer logref, @JsonProperty("_links") List links) { - Assert.hasText(logref, "Logref must not be null or empty!"); Assert.hasText(message, "Message must not be null or empty!"); - this.logref = logref; this.message = message; - this.add(Arrays.asList(links)); + this.path = path; + this.logref = logref; + this.add(links); + } + + public VndError(String message, String path, Integer logref, Link... link) { + this(message, path, logref, Arrays.asList(link)); } /** - * Protected default constructor to allow JAXB marshalling. + * @deprecated Use {@link #VndError(String, String, Integer, Link...)} (with proper ordering of arguments) */ - protected VndError() { - - this.logref = null; - this.message = null; + @Deprecated + public VndError(String logref, String message, Link... links) { + this(message, null, Integer.parseInt(logref), Arrays.asList(links)); } - /** - * Returns the logref of the error. - * - * @return the logref - */ - public String getLogref() { - return logref; - } - - /** - * Returns the message of the error. - * - * @return the message - */ - public String getMessage() { - return message; - } - - /* - * (non-Javadoc) - * @see org.springframework.hateoas.ResourceSupport#toString() - */ @Override public String toString() { - return String.format("VndError[logref: %s, message: %s, links: [%s]]", logref, message, getLinks().toString()); - } - - /* - * (non-Javadoc) - * @see org.springframework.hateoas.ResourceSupport#hashCode() - */ - @Override - public int hashCode() { - - int result = 17; - - result += 31 * logref.hashCode(); - result += 31 * message.hashCode(); - - return result; - } - - /* - * (non-Javadoc) - * @see org.springframework.hateoas.ResourceSupport#equals(java.lang.Object) - */ - @Override - public boolean equals(@Nullable Object obj) { - - if (obj == this) { - return true; - } - - if (!(obj instanceof VndError)) { - return false; - } - - VndError that = (VndError) obj; - - return this.logref.equals(that.logref) && this.message.equals(that.message); + return String.format("VndError[logref: %s, message: %s, links: [%s]]", this.logref, this.message, + getLinks().toString()); } } } diff --git a/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsMarshallingTest.java b/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsMarshallingTest.java index da758bba..1451b365 100755 --- a/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsMarshallingTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsMarshallingTest.java @@ -16,24 +16,23 @@ package org.springframework.hateoas.mediatype.vnderror; import static org.assertj.core.api.Assertions.*; +import static org.springframework.hateoas.support.MappingUtils.*; -import java.io.FileInputStream; import java.io.IOException; -import java.nio.MappedByteBuffer; -import java.nio.channels.FileChannel; -import java.nio.charset.Charset; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; +import org.springframework.hateoas.IanaLinkRelations; import org.springframework.hateoas.Link; import org.springframework.hateoas.mediatype.MessageResolver; import org.springframework.hateoas.mediatype.hal.CurieProvider; import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; +import org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalHandlerInstantiator; import org.springframework.hateoas.mediatype.vnderrors.VndErrors; import org.springframework.hateoas.mediatype.vnderrors.VndErrors.VndError; import org.springframework.hateoas.server.LinkRelationProvider; -import org.springframework.hateoas.server.core.EvoInflectorLinkRelationProvider; +import org.springframework.hateoas.server.core.AnnotationLinkRelationProvider; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; @@ -46,58 +45,92 @@ import com.fasterxml.jackson.databind.SerializationFeature; */ class VndErrorsMarshallingTest { - ObjectMapper jackson2Mapper; - - LinkRelationProvider relProvider = new EvoInflectorLinkRelationProvider(); - - VndErrors errors; - String jsonReference; - String json2Reference; - - public VndErrorsMarshallingTest() throws IOException { - - jsonReference = readFile(new ClassPathResource("vnderror.json")); - json2Reference = readFile(new ClassPathResource("vnderror2.json")); - } + ObjectMapper mapper; @BeforeEach void setUp() { - jackson2Mapper = new com.fasterxml.jackson.databind.ObjectMapper(); - jackson2Mapper.registerModule(new Jackson2HalModule()); - jackson2Mapper.setHandlerInstantiator( - new Jackson2HalModule.HalHandlerInstantiator(relProvider, CurieProvider.NONE, MessageResolver.DEFAULTS_ONLY)); - jackson2Mapper.configure(SerializationFeature.INDENT_OUTPUT, true); + LinkRelationProvider relProvider = new AnnotationLinkRelationProvider(); - VndError error = new VndError("42", "Validation failed!", // - new Link("http://...", "describes"), new Link("http://...", "help")); - errors = new VndErrors(error, error, error); + this.mapper = new ObjectMapper(); + this.mapper.registerModule(new Jackson2HalModule()); + this.mapper.setHandlerInstantiator( + new HalHandlerInstantiator(relProvider, CurieProvider.NONE, MessageResolver.DEFAULTS_ONLY)); + this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true); } - /** - * @see #62 - */ - @Test - void jackson2Marshalling() throws Exception { + @Test // #93, #94, #775 + void singleItemVndErrorShouldDeserialize() throws IOException { - assertThat(jackson2Mapper.writeValueAsString(errors)) // - .isEqualToIgnoringWhitespace(json2Reference); + String expected = read(new ClassPathResource("vnderror-single-item.json", getClass())); + + VndError actual = new VndError("Validation failed", "/username", 42, + new Link("http://path.to/user/resource/1", IanaLinkRelations.ABOUT), + new Link("http://path.to/describes", IanaLinkRelations.DESCRIBES), + new Link("http://path.to/help", IanaLinkRelations.HELP)); + + assertThat(this.mapper.readValue(expected, VndError.class)).isEqualTo(actual); } - /** - * @see #93, #94 - */ - @Test - void jackson2UnMarshalling() throws Exception { - assertThat(jackson2Mapper.readValue(jsonReference, VndErrors.class)).isEqualTo(errors); + @Test // #62, #775 + public void singleItemVndErrorShouldSerialize() throws IOException { + + VndError error = new VndError("Validation failed", "/username", 42, // + new Link("http://path.to/user/resource/1", IanaLinkRelations.ABOUT), + new Link("http://path.to/describes", IanaLinkRelations.DESCRIBES), + new Link("http://path.to/help", IanaLinkRelations.HELP)); + + String json = read(new ClassPathResource("vnderror-single-item.json", getClass())); + + assertThat(mapper.writeValueAsString(error)).isEqualToIgnoringWhitespace(json); } - private static String readFile(org.springframework.core.io.Resource resource) throws IOException { + @Test // #62, #775 + public void multipleItemVndErrorsShouldDeserialize() throws IOException { - try (FileInputStream stream = new FileInputStream(resource.getFile())) { - FileChannel fc = stream.getChannel(); - MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); - return Charset.defaultCharset().decode(bb).toString(); - } + String json = read(new ClassPathResource("vnderror-multiple-items.json", getClass())); + + VndError error1 = new VndError("\"username\" field validation failed", null, 50, // + new Link("http://.../", IanaLinkRelations.HELP)); + + VndError error2 = new VndError("\"postcode\" field validation failed", null, 55, // + new Link("http://.../", IanaLinkRelations.HELP)); + + VndErrors vndErrors = new VndErrors().withError(error1).withError(error2); + + assertThat(this.mapper.readValue(json, VndErrors.class)).isEqualTo(vndErrors); + } + + @Test // #775 + public void multipleItemVndErrorsShouldSerialize() throws IOException { + + VndError error1 = new VndError("\"username\" field validation failed", null, 50, // + new Link("http://.../", IanaLinkRelations.HELP)); + + VndError error2 = new VndError("\"postcode\" field validation failed", null, 55, // + new Link("http://.../", IanaLinkRelations.HELP)); + + VndErrors vndErrors = new VndErrors().withError(error1).withError(error2); + + String json = read(new ClassPathResource("vnderror-multiple-items.json", getClass())); + + assertThat(this.mapper.writeValueAsString(vndErrors)).isEqualToIgnoringWhitespace(json); + } + + @Test // #775 + public void nestedVndErrorsShouldSerialize() throws IOException { + + VndError error = new VndError("Username must contain at least three characters", "/username", (Integer) null, // + new Link("http://path.to/user/resource/1", IanaLinkRelations.ABOUT)); + + VndErrors vndErrors = new VndErrors().withError(error) + .withLink(new Link("http://path.to/describes").withRel(IanaLinkRelations.DESCRIBES)) + .withLink(new Link("http://path.to/help").withRel(IanaLinkRelations.HELP)) + .withLink(new Link("http://path.to/user/resource/1").withRel(IanaLinkRelations.ABOUT)) + .withMessage("Validation failed").withLogref(42); + + String json = read(new ClassPathResource("vnderror-nested.json", getClass())); + + assertThat(mapper.writeValueAsString(vndErrors)).isEqualToIgnoringWhitespace(json); } } diff --git a/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsUnitTest.java b/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsUnitTest.java index 5e698a7f..dd4e6abf 100755 --- a/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsUnitTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/vnderror/VndErrorsUnitTest.java @@ -17,6 +17,8 @@ package org.springframework.hateoas.mediatype.vnderror; import static org.assertj.core.api.Assertions.*; +import java.util.ArrayList; + import org.junit.jupiter.api.Test; import org.springframework.hateoas.Link; import org.springframework.hateoas.mediatype.vnderrors.VndErrors; @@ -26,17 +28,66 @@ import org.springframework.hateoas.mediatype.vnderrors.VndErrors.VndError; * Unit tests for {@link VndErrors}. * * @author Oliver Gierke + * @author Greg Turnquist */ class VndErrorsUnitTest { + /** + * @see #775 + */ @Test - void rendersToStringCorrectly() { + void vndErrorsDoesntTakeNull() { + assertThatIllegalArgumentException().isThrownBy(() -> new VndErrors().withErrors(null)); + } - VndError error = new VndErrors.VndError("logref", "message", new Link("foo", "bar")); - assertThat(error.toString()).isEqualTo("VndError[logref: logref, message: message, links: [;rel=\"bar\"]]"); + /** + * @see #775 + */ + @Test + public void vndErrorsDoesntTakeEmptyCollection() { + assertThatIllegalArgumentException().isThrownBy(() -> new VndErrors().withErrors(new ArrayList<>())); + } - VndErrors errors = new VndErrors(error); - assertThat(errors.toString()) // - .isEqualTo("VndErrors[VndError[logref: logref, message: message, links: [;rel=\"bar\"]]]"); + /** + * @see #775 + */ + @Test + public void vndErrorsUsingSingleErrorArguments() { + + VndErrors errors = new VndErrors().withError(new VndError("message", "/path", 50, new Link("/link").withSelfRel())); + + assertThat(errors.getTotal()).isNull(); + assertThat(errors.getContent()).hasSize(1); + assertThat(errors.getContent()) + .containsExactly(new VndError("message", "/path", 50, new Link("/link").withSelfRel())); + } + + /** + * @see #775 + */ + @Test + public void appendingVndErrorsShouldWork() { + + VndErrors errors = new VndErrors().withError(new VndError("message", "/path", 50, new Link("/link").withSelfRel())); + assertThat(errors.getContent()).hasSize(1); + + errors.getContent().add(new VndError("message2", "/path2", 51, new Link("/link2", "link2"))); + assertThat(errors.getContent()).hasSize(2); + } + + @Test + void vndErrorRendersToStringCorrectly() { + + VndError error = new VndError("message", "path", 42, new Link("foo", "bar")); + assertThat(error.toString()).isEqualTo("VndError[logref: 42, message: message, links: [;rel=\"bar\"]]"); + + } + + @Test + void vndErrorsRendersToStringCorrectly() { + + VndErrors errors = new VndErrors(new VndError("message", "path", 42, new Link("foo", "bar"))); + assertThat(errors.toString()) + .isEqualTo("VndErrors[VndError[logref: 42, message: message, links: [;rel=\"bar\"]]]"); } } diff --git a/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-multiple-items.json b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-multiple-items.json new file mode 100644 index 00000000..eb877af2 --- /dev/null +++ b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-multiple-items.json @@ -0,0 +1,25 @@ +{ + "total": 2, + "_embedded": { + "errors": [ + { + "message": "\"username\" field validation failed", + "logref": 50, + "_links": { + "help": { + "href": "http://.../" + } + } + }, + { + "message": "\"postcode\" field validation failed", + "logref": 55, + "_links": { + "help": { + "href": "http://.../" + } + } + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-nested.json b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-nested.json new file mode 100644 index 00000000..0ba5b9de --- /dev/null +++ b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-nested.json @@ -0,0 +1,28 @@ +{ + "message": "Validation failed", + "logref": 42, + "_links": { + "describes": { + "href": "http://path.to/describes" + }, + "help": { + "href": "http://path.to/help" + }, + "about": { + "href": "http://path.to/user/resource/1" + } + }, + "_embedded": { + "errors": [ + { + "message": "Username must contain at least three characters", + "path": "/username", + "_links": { + "about": { + "href": "http://path.to/user/resource/1" + } + } + } + ] + } +} \ No newline at end of file diff --git a/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-single-item.json b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-single-item.json new file mode 100644 index 00000000..afbbe88e --- /dev/null +++ b/src/test/resources/org/springframework/hateoas/mediatype/vnderror/vnderror-single-item.json @@ -0,0 +1,16 @@ +{ + "message": "Validation failed", + "path": "/username", + "logref": 42, + "_links": { + "about": { + "href": "http://path.to/user/resource/1" + }, + "describes": { + "href": "http://path.to/describes" + }, + "help": { + "href": "http://path.to/help" + } + } +} \ No newline at end of file diff --git a/src/test/resources/vnderror.json b/src/test/resources/vnderror.json deleted file mode 100644 index aeaa93a8..00000000 --- a/src/test/resources/vnderror.json +++ /dev/null @@ -1,34 +0,0 @@ -[ { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -}, { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -}, { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -} ] \ No newline at end of file diff --git a/src/test/resources/vnderror2.json b/src/test/resources/vnderror2.json deleted file mode 100644 index f3faf2d7..00000000 --- a/src/test/resources/vnderror2.json +++ /dev/null @@ -1,34 +0,0 @@ -[ { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -}, { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -}, { - "logref" : "42", - "message" : "Validation failed!", - "_links" : { - "describes" : { - "href" : "http://..." - }, - "help" : { - "href" : "http://..." - } - } -} ]