From 78736d6c506f284ee256453fd2031fb0c785d61e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Mon, 12 Jan 2015 16:25:13 +0000 Subject: [PATCH] Improve the abstraction that's used for link extraction Previously, the link extraction abstraction was inadequate as it made assumptions about the format of the links that did not apply to all media types. For example, it was suited to the links returned in a application/hal+json response, but was not suited to the Atom-style links often found in application/json responses. This commit improves the abstraction so that the extracted links are decoupled from the format of the response. In addition to the existing support for extracting HAL links a new extractor for Atom-style links has been introduced. Both extractors are now available via static methods on the new LinkExtractors class. The sample applications have been updated accordingly. Closes #6 --- .../notes/RestNotesSpringDataRest.java | 2 +- .../com/example/notes/ApiDocumentation.java | 4 +- .../com/example/notes/ApiDocumentation.java | 4 +- .../springframework/restdocs/core/Link.java | 94 ++++++++++ .../restdocs/core/LinkExtractor.java | 24 ++- .../restdocs/core/LinkExtractors.java | 162 ++++++++++++++++++ .../restdocs/core/RestDocumentation.java | 14 +- .../core/RestDocumentationResultHandlers.java | 12 +- .../restdocs/core/LinkExtractorsTests.java | 124 ++++++++++++++ .../atom/multiple-links-different-rels.json | 9 + .../atom/multiple-links-same-rels.json | 9 + .../link-payloads/atom/no-links.json | 1 + .../link-payloads/atom/single-link.json | 6 + .../link-payloads/atom/wrong-format.json | 5 + .../hal/multiple-links-different-rels.json | 6 + .../hal/multiple-links-same-rels.json | 5 + .../resources/link-payloads/hal/no-links.json | 1 + .../link-payloads/hal/single-link.json | 5 + .../link-payloads/hal/wrong-format.json | 9 + 19 files changed, 467 insertions(+), 29 deletions(-) create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/core/Link.java create mode 100644 spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractors.java create mode 100644 spring-restdocs-core/src/test/java/org/springframework/restdocs/core/LinkExtractorsTests.java create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/atom/no-links.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/hal/no-links.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json create mode 100644 spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json diff --git a/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java b/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java index 0c995e30..74b98dd0 100644 --- a/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java +++ b/rest-notes-spring-data-rest/src/main/java/com/example/notes/RestNotesSpringDataRest.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java b/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java index e3d26418..f3f95d8e 100644 --- a/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java +++ b/rest-notes-spring-data-rest/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,7 @@ package com.example.notes; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.springframework.restdocs.core.RestDocumentation.document; -import static org.springframework.restdocs.core.RestDocumentation.halLinks; +import static org.springframework.restdocs.core.LinkExtractors.halLinks; import static org.springframework.restdocs.core.RestDocumentation.linkWithRel; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; diff --git a/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java b/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java index 745c4bfe..da8ca724 100644 --- a/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java +++ b/rest-notes-spring-hateoas/src/test/java/com/example/notes/ApiDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,8 +18,8 @@ package com.example.notes; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; +import static org.springframework.restdocs.core.LinkExtractors.halLinks; import static org.springframework.restdocs.core.RestDocumentation.document; -import static org.springframework.restdocs.core.RestDocumentation.halLinks; import static org.springframework.restdocs.core.RestDocumentation.linkWithRel; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/Link.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/Link.java new file mode 100644 index 00000000..135a51e4 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/Link.java @@ -0,0 +1,94 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.core; + +import org.springframework.core.style.ToStringCreator; + +/** + * Representation of a link used in a Hypermedia-based API + * + * @author Andy Wilkinson + */ +public class Link { + + private final String rel; + + private final String href; + + /** + * Creates a new {@code Link} with the given {@code rel} and {@code href} + * + * @param rel The link's rel + * @param href The link's href + */ + public Link(String rel, String href) { + this.rel = rel; + this.href = href; + } + + /** + * Returns the link's {@code rel} + * @return the link's {@code rel} + */ + public String getRel() { + return rel; + } + + /** + * Returns the link's {@code href} + * @return the link's {@code href} + */ + public String getHref() { + return href; + } + + @Override + public int hashCode() { + int prime = 31; + int result = 1; + result = prime * result + href.hashCode(); + result = prime * result + rel.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Link other = (Link) obj; + if (!href.equals(other.href)) { + return false; + } + if (!rel.equals(other.rel)) { + return false; + } + return true; + } + + public String toString() { + return new ToStringCreator(this).append("rel", this.rel) + .append("href", this.href).toString(); + } + +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractor.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractor.java index 3df9e7b8..bb65fd8e 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractor.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,30 @@ package org.springframework.restdocs.core; +import java.io.IOException; +import java.util.List; import java.util.Map; +import org.springframework.mock.web.MockHttpServletResponse; + +/** + * A {@code LinkExtractor} is used to extract {@link Link links} from a JSON response. The + * expected format of the links in the response is determined by the implementation. + * + * @author Andy Wilkinson + * + */ public interface LinkExtractor { - Map extractLinks(Map responseJson); + /** + * Extract the links from the given response, returning a {@code Map} of links where + * the keys are the link rels. + * + * @param response The response from which the links are to be extracted + * @return The extracted links, keyed by rel + * @throws IOException if link extraction fails + */ + Map> extractLinks(MockHttpServletResponse response) + throws IOException; } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractors.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractors.java new file mode 100644 index 00000000..e6c28d53 --- /dev/null +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/LinkExtractors.java @@ -0,0 +1,162 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.core; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.springframework.mock.web.MockHttpServletResponse; + +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Static factory methods provided a selection of {@link LinkExtractor link extractors} + * for use when documentating a hypermedia-based API. + * + * @author Andy Wilkinson + * + */ +public class LinkExtractors { + + /** + * Returns a {@code LinkExtractor} capable of extracting links in Hypermedia + * Application Language (HAL) format where the links are found in a map named + * {@code _links}. + * + * @return The extract for HAL-style links + */ + public static LinkExtractor halLinks() { + return new HalLinkExtractor(); + } + + /** + * Returns a {@code LinkExtractor} capable of extracting links in Atom format where + * the links are found in an array named {@code links}. + * + * @return The extractor for Atom-style links + */ + public static LinkExtractor atomLinks() { + return new AtomLinkExtractor(); + } + + private static abstract class JsonContentLinkExtractor implements LinkExtractor { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @SuppressWarnings("unchecked") + public Map> extractLinks(MockHttpServletResponse response) + throws IOException { + Map jsonContent = this.objectMapper.readValue( + response.getContentAsString(), Map.class); + return extractLinks(jsonContent); + } + + protected abstract Map> extractLinks(Map json); + } + + private static class HalLinkExtractor extends JsonContentLinkExtractor { + + @SuppressWarnings("unchecked") + @Override + public Map> extractLinks(Map json) { + Map> extractedLinks = new HashMap<>(); + Object possibleLinks = json.get("_links"); + if (possibleLinks instanceof Map) { + Map links = (Map) possibleLinks; + for (Entry entry : links.entrySet()) { + String rel = (String) entry.getKey(); + extractedLinks.put(rel, convertToLinks(entry.getValue(), rel)); + } + } + return extractedLinks; + } + + @SuppressWarnings("unchecked") + private static List convertToLinks(Object object, String rel) { + List links = new ArrayList<>(); + if (object instanceof Collection) { + Collection hrefObjects = (Collection) object; + for (Object hrefObject : hrefObjects) { + maybeAddLink(maybeCreateLink(rel, hrefObject), links); + } + } + else { + maybeAddLink(maybeCreateLink(rel, object), links); + } + return links; + } + + private static Link maybeCreateLink(String rel, Object possibleHref) { + if (possibleHref instanceof String) { + return new Link(rel, (String) possibleHref); + } + return null; + } + + private static void maybeAddLink(Link possibleLink, List links) { + if (possibleLink != null) { + links.add(possibleLink); + } + } + } + + private static class AtomLinkExtractor extends JsonContentLinkExtractor { + + @SuppressWarnings("unchecked") + @Override + public Map> extractLinks(Map json) { + Map> extractedLinks = new HashMap<>(); + Object possibleLinks = json.get("links"); + if (possibleLinks instanceof Collection) { + Collection linksCollection = (Collection) possibleLinks; + for (Object linkObject : linksCollection) { + if (linkObject instanceof Map) { + Link link = maybeCreateLink((Map) linkObject); + maybeStoreLink(link, extractedLinks); + } + } + } + return extractedLinks; + } + + private static Link maybeCreateLink(Map linkMap) { + Object hrefObject = linkMap.get("href"); + Object relObject = linkMap.get("rel"); + if (relObject instanceof String && hrefObject instanceof String) { + return new Link((String) relObject, (String) hrefObject); + } + return null; + } + + private static void maybeStoreLink(Link link, + Map> extractedLinks) { + if (link != null) { + List linksForRel = extractedLinks.get(link.getRel()); + if (linksForRel == null) { + linksForRel = new ArrayList(); + extractedLinks.put(link.getRel(), linksForRel); + } + linksForRel.add(link); + } + } + } +} diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentation.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentation.java index 160119ca..974e1dbb 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentation.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentation.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,6 @@ package org.springframework.restdocs.core; -import java.util.Map; - public class RestDocumentation { public static RestDocumentationResultHandler document(String outputDir) @@ -29,14 +27,4 @@ public class RestDocumentation { return new LinkDescriptor(rel); } - public static LinkExtractor halLinks() { - return new LinkExtractor() { - - @SuppressWarnings("unchecked") - @Override - public Map extractLinks(Map responseJson) { - return (Map) responseJson.get("_links"); - } - }; - } } diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentationResultHandlers.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentationResultHandlers.java index 04afb317..256279d0 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentationResultHandlers.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/core/RestDocumentationResultHandlers.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,8 +41,6 @@ import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.RequestMethod; -import com.fasterxml.jackson.databind.ObjectMapper; - public abstract class RestDocumentationResultHandlers { public static CurlResultHandler documentCurlRequest(String outputDir) { @@ -245,8 +243,6 @@ public abstract class RestDocumentationResultHandlers { static class LinkDocumentingResultHandler extends RestDocumentationResultHandler { - private final ObjectMapper objectMapper = new ObjectMapper(); - private final Map descriptorsByRel = new HashMap(); private final LinkExtractor extractor; @@ -262,12 +258,10 @@ public abstract class RestDocumentationResultHandlers { } } - @SuppressWarnings("unchecked") @Override void handle(MvcResult result, DocumentationWriter writer) throws Exception { - Map json = this.objectMapper.readValue(result.getResponse() - .getContentAsString(), Map.class); - Map links = this.extractor.extractLinks(json); + Map> links = this.extractor.extractLinks(result + .getResponse()); Set actualRels = links.keySet(); Set expectedRels = this.descriptorsByRel.keySet(); diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/core/LinkExtractorsTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/core/LinkExtractorsTests.java new file mode 100644 index 00000000..2e94fead --- /dev/null +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/core/LinkExtractorsTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2014-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.restdocs.core; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.util.FileCopyUtils; + +/** + * Tests for {@link LinkExtractors}. + * + * @author Andy Wilkinson + */ +@RunWith(Parameterized.class) +public class LinkExtractorsTests { + + private final LinkExtractor linkExtractor; + + private final String linkType; + + @Parameters + public static Collection data() { + return Arrays.asList(new Object[] { LinkExtractors.halLinks(), "hal" }, + new Object[] { LinkExtractors.atomLinks(), "atom" }); + } + + public LinkExtractorsTests(LinkExtractor linkExtractor, String linkType) { + this.linkExtractor = linkExtractor; + this.linkType = linkType; + } + + @Test + public void singleLink() throws IOException { + Map> links = this.linkExtractor + .extractLinks(createResponse("single-link")); + assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com")), links); + } + + @Test + public void multipleLinksWithDifferentRels() throws IOException { + Map> links = this.linkExtractor + .extractLinks(createResponse("multiple-links-different-rels")); + assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com"), + new Link("bravo", "http://bravo.example.com")), links); + } + + @Test + public void multipleLinksWithSameRels() throws IOException { + Map> links = this.linkExtractor + .extractLinks(createResponse("multiple-links-same-rels")); + assertLinks(Arrays.asList(new Link("alpha", "http://alpha.example.com/one"), + new Link("alpha", "http://alpha.example.com/two")), links); + } + + @Test + public void noLinks() throws IOException { + Map> links = this.linkExtractor + .extractLinks(createResponse("no-links")); + assertLinks(Collections. emptyList(), links); + } + + @Test + public void linksInTheWrongFormat() throws IOException { + Map> links = this.linkExtractor + .extractLinks(createResponse("wrong-format")); + assertLinks(Collections. emptyList(), links); + } + + private void assertLinks(List expectedLinks, Map> actualLinks) { + Map> expectedLinksByRel = new HashMap<>(); + for (Link expectedLink : expectedLinks) { + List expectedlinksWithRel = expectedLinksByRel.get(expectedLink + .getRel()); + if (expectedlinksWithRel == null) { + expectedlinksWithRel = new ArrayList<>(); + expectedLinksByRel.put(expectedLink.getRel(), expectedlinksWithRel); + } + expectedlinksWithRel.add(expectedLink); + } + assertEquals(expectedLinksByRel, actualLinks); + } + + private MockHttpServletResponse createResponse(String contentName) throws IOException { + MockHttpServletResponse response = new MockHttpServletResponse(); + FileCopyUtils.copy(new FileReader(getPayloadFile(contentName)), + response.getWriter()); + return response; + } + + private File getPayloadFile(String name) { + return new File("src/test/resources/link-payloads/" + linkType + "/" + name + + ".json"); + } +} diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json new file mode 100644 index 00000000..35e63537 --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-different-rels.json @@ -0,0 +1,9 @@ +{ + "links": [ { + "rel": "alpha", + "href": "http://alpha.example.com" + }, { + "rel": "bravo", + "href": "http://bravo.example.com" + } ] +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json new file mode 100644 index 00000000..ff0d3f4a --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/multiple-links-same-rels.json @@ -0,0 +1,9 @@ +{ + "links": [ { + "rel": "alpha", + "href": "http://alpha.example.com/one" + }, { + "rel": "alpha", + "href": "http://alpha.example.com/two" + } ] +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/no-links.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/no-links.json new file mode 100644 index 00000000..6f31cf5a --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/no-links.json @@ -0,0 +1 @@ +{ } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json new file mode 100644 index 00000000..57532675 --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/single-link.json @@ -0,0 +1,6 @@ +{ + "links": [ { + "rel": "alpha", + "href": "http://alpha.example.com" + } ] +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json b/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json new file mode 100644 index 00000000..04a6d84b --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/atom/wrong-format.json @@ -0,0 +1,5 @@ +{ + "_links": { + "alpha": ["http://alpha.example.com/one", "http://alpha.example.com/two"] + } +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json new file mode 100644 index 00000000..80d36d72 --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-different-rels.json @@ -0,0 +1,6 @@ +{ + "_links": { + "alpha": "http://alpha.example.com", + "bravo": "http://bravo.example.com" + } +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json new file mode 100644 index 00000000..04a6d84b --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/multiple-links-same-rels.json @@ -0,0 +1,5 @@ +{ + "_links": { + "alpha": ["http://alpha.example.com/one", "http://alpha.example.com/two"] + } +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/no-links.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/no-links.json new file mode 100644 index 00000000..6f31cf5a --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/no-links.json @@ -0,0 +1 @@ +{ } \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json new file mode 100644 index 00000000..be90b377 --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/single-link.json @@ -0,0 +1,5 @@ +{ + "_links": { + "alpha": "http://alpha.example.com" + } +} \ No newline at end of file diff --git a/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json b/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json new file mode 100644 index 00000000..7c99aa4e --- /dev/null +++ b/spring-restdocs-core/src/test/resources/link-payloads/hal/wrong-format.json @@ -0,0 +1,9 @@ +{ + "_links": [ { + "rel": "alpha", + "href": "http://alpha.example.com/one" + }, { + "rel": "alpha", + "href": "http://alpha.example.com/two" + } ] +} \ No newline at end of file