Skip to content

Commit e15ea5f

Browse files
committed
Support for official HAL and HAL-FORMS media type in link extraction.
We now register the HalLinkExtractor for both the official HAL media type (application/vnd.hal+json) and the HAL-FORMS one (application/prs.hal-forms+json).
1 parent 1d34bcb commit e15ea5f

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@
3030
* content type.
3131
*
3232
* @author Andy Wilkinson
33+
* @author Oliver Drotbohm
3334
*/
3435
class ContentTypeLinkExtractor implements LinkExtractor {
3536

3637
private Map<MediaType, LinkExtractor> linkExtractors = new HashMap<>();
3738

3839
ContentTypeLinkExtractor() {
3940
this.linkExtractors.put(MediaType.APPLICATION_JSON, new AtomLinkExtractor());
40-
this.linkExtractors.put(HalLinkExtractor.HAL_MEDIA_TYPE, new HalLinkExtractor());
41+
42+
LinkExtractor halLinkExtractor = new HalLinkExtractor();
43+
this.linkExtractors.put(HalLinkExtractor.HAL_MEDIA_TYPE, halLinkExtractor);
44+
this.linkExtractors.put(HalLinkExtractor.VND_HAL_MEDIA_TYPE, halLinkExtractor);
45+
this.linkExtractors.put(HalLinkExtractor.HAL_FORMS_MEDIA_TYPE, halLinkExtractor);
4146
}
4247

4348
ContentTypeLinkExtractor(Map<MediaType, LinkExtractor> linkExtractors) {

spring-restdocs-core/src/main/java/org/springframework/restdocs/hypermedia/HalLinkExtractor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
class HalLinkExtractor extends AbstractJsonLinkExtractor {
3535

3636
static final MediaType HAL_MEDIA_TYPE = new MediaType("application", "hal+json");
37+
static final MediaType VND_HAL_MEDIA_TYPE = new MediaType("application", "vnd.hal+json");
38+
static final MediaType HAL_FORMS_MEDIA_TYPE = new MediaType("application", "prs.hal-forms+json");
3739

3840
@Override
3941
public Map<String, List<Link>> extractLinks(Map<String, Object> json) {

spring-restdocs-core/src/test/java/org/springframework/restdocs/hypermedia/ContentTypeLinkExtractorTests.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.io.IOException;
2020
import java.util.HashMap;
21+
import java.util.List;
2122
import java.util.Map;
2223

2324
import org.junit.Test;
@@ -29,6 +30,7 @@
2930
import org.springframework.restdocs.operation.OperationResponseFactory;
3031

3132
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
33+
import static org.assertj.core.api.Assertions.assertThat;
3234
import static org.mockito.Mockito.mock;
3335
import static org.mockito.Mockito.verify;
3436

@@ -40,6 +42,7 @@
4042
public class ContentTypeLinkExtractorTests {
4143

4244
private final OperationResponseFactory responseFactory = new OperationResponseFactory();
45+
private final String halBody = "{ \"_links\" : { \"someRel\" : { \"href\" : \"someHref\" }} }";
4346

4447
@Test
4548
public void extractionFailsWithNullContentType() {
@@ -71,4 +74,22 @@ public void extractorCalledWithCompatibleContextType() throws IOException {
7174
verify(extractor).extractLinks(response);
7275
}
7376

77+
@Test
78+
public void extractsLinksFromVndHalMediaType() throws IOException {
79+
HttpHeaders httpHeaders = new HttpHeaders();
80+
httpHeaders.setContentType(MediaType.parseMediaType("application/vnd.hal+json"));
81+
OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, halBody.getBytes());
82+
Map<String, List<Link>> links = new ContentTypeLinkExtractor().extractLinks(response);
83+
assertThat(links).containsKey("someRel");
84+
}
85+
86+
@Test
87+
public void extractsLinksFromHalFormsMediaType() throws IOException {
88+
HttpHeaders httpHeaders = new HttpHeaders();
89+
httpHeaders.setContentType(MediaType.parseMediaType("application/prs.hal-forms+json"));
90+
OperationResponse response = this.responseFactory.create(HttpStatus.OK, httpHeaders, halBody.getBytes());
91+
Map<String, List<Link>> links = new ContentTypeLinkExtractor().extractLinks(response);
92+
assertThat(links).containsKey("someRel");
93+
}
94+
7495
}

0 commit comments

Comments
 (0)