DATAREST-630 - Polishing.

Simplified implementation change. Integrated new test case into the existing one. Cleaned up existing test case to always use TestMvcClient.

Original pull request: #189.
This commit is contained in:
Oliver Gierke
2015-07-31 14:43:30 +02:00
parent b359aba77a
commit ec0590ff51
4 changed files with 67 additions and 176 deletions

View File

@@ -50,10 +50,7 @@ import org.springframework.data.rest.core.mapping.SimpleResourceDescription;
import org.springframework.data.rest.core.mapping.SupportedHttpMethods;
import org.springframework.data.rest.webmvc.RootResourceInformation;
import org.springframework.data.rest.webmvc.json.JacksonMetadata;
import org.springframework.data.rest.webmvc.json.JsonSchema;
import org.springframework.data.rest.webmvc.mapping.AssociationLinks;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
import org.springframework.hateoas.EntityLinks;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.TemplateVariable;
@@ -324,12 +321,8 @@ public class RootResourceInformationToAlpsDescriptorConverter {
ResourceMapping propertyMapping = metadata.getMappingFor(property);
if (propertyDefinition != null) {
PersistentProperty<?> persistentProperty = entity.getPersistentProperty(propertyDefinition.getInternalName());
TypeInformation<?> propertyType = persistentProperty == null ? ClassTypeInformation.from(propertyDefinition
.getPrimaryMember().getRawType()) : persistentProperty.getTypeInformation();
Class<?> rawEntityType = entity.getTypeInformation().getType();
if (persistentProperty.isIdProperty() && !configuration.isIdExposedFor(type)) {
if (property.isIdProperty() && !configuration.isIdExposedFor(property.getOwner().getType())) {
return;
}

View File

@@ -251,11 +251,26 @@ public class TestMvcClient {
* @throws Exception
*/
public Link discoverUnique(Link root, String rel) throws Exception {
return discoverUnique(root, rel, DEFAULT_MEDIA_TYPE);
}
MockHttpServletResponse response = mvc.perform(get(root.expand().getHref()).accept(DEFAULT_MEDIA_TYPE)).//
andExpect(status().isOk()).//
andExpect(hasLinkWithRel(rel)).//
andReturn().getResponse();
/**
* Given a URI (root), discover the unique URI for a given rel. NOTE: Assumes there is only one URI
*
* @param root the link to the resource to access.
* @param rel the link relation to discover in the response.
* @param mediaType the {@link MediaType} to request.
* @return {@link org.springframework.hateoas.Link Link} tied to a given rel
* @throws Exception
*/
public Link discoverUnique(Link root, String rel, MediaType mediaType) throws Exception {
MockHttpServletResponse response = mvc
.perform(get(root.expand().getHref())//
.accept(mediaType))
.andExpect(status().isOk())//
.andExpect(hasLinkWithRel(rel))//
.andReturn().getResponse();
return assertHasLinkWithRel(rel, response);
}

View File

@@ -17,7 +17,6 @@ package org.springframework.data.rest.webmvc.alps;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.junit.Before;
@@ -29,7 +28,6 @@ import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.AbstractControllerIntegrationTests;
import org.springframework.data.rest.webmvc.TestMvcClient;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.data.rest.webmvc.jpa.Item;
import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig;
import org.springframework.hateoas.Link;
@@ -37,8 +35,6 @@ import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.LinkDiscoverers;
import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
@@ -59,20 +55,27 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Autowired LinkDiscoverers discoverers;
@Configuration
static class Config {
static class Config extends RepositoryRestConfigurerAdapter {
@Bean
public LinkDiscoverer alpsLinkDiscoverer() {
return new JsonPathLinkDiscoverer("$.descriptors[?(@.name == '%s')].href",
MediaType.valueOf("application/alps+json"));
}
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Item.class);
}
}
protected MockMvc mvc;
TestMvcClient client;
@Before
public void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(context).build();
MockMvc mvc = MockMvcBuilders.webAppContextSetup(context).build();
this.client = new TestMvcClient(mvc, this.discoverers);
}
/**
@@ -81,9 +84,9 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void exposesProfileLink() throws Exception {
mvc.perform(get("/")).//
andExpect(status().is2xxSuccessful()).//
andExpect(jsonPath("$._links.profile.href", endsWith(AlpsController.ALPS_ROOT_MAPPING)));
client.follow("/")//
.andExpect(status().is2xxSuccessful())//
.andExpect(jsonPath("$._links.profile.href", endsWith(AlpsController.ALPS_ROOT_MAPPING)));
}
/**
@@ -92,11 +95,11 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void alpsResourceExposesResourcePerCollectionResource() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link profileLink = client.discoverUnique("profile");
assertThat(discoverUnique(profileLink.getHref(), "orders"), is(notNullValue()));
assertThat(discoverUnique(profileLink.getHref(), "people"), is(notNullValue()));
assertThat(discoverUnique(profileLink.getHref(), "items"), is(notNullValue()));
assertThat(client.discoverUnique(profileLink, "orders", MediaType.ALL), is(notNullValue()));
assertThat(client.discoverUnique(profileLink, "people", MediaType.ALL), is(notNullValue()));
assertThat(client.discoverUnique(profileLink, "items", MediaType.ALL), is(notNullValue()));
}
/**
@@ -105,12 +108,12 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void exposesAlpsCollectionResources() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link peopleLink = discoverUnique(profileLink.getHref(), "people");
Link profileLink = client.discoverUnique("profile");
Link peopleLink = client.discoverUnique(profileLink, "people", MediaType.ALL);
mvc.perform(get(peopleLink.getHref())).//
andExpect(jsonPath("$.version").value("1.0")).//
andExpect(jsonPath("$.descriptors[*].name", hasItems("people", "person")));
client.follow(peopleLink)//
.andExpect(jsonPath("$.version").value("1.0"))//
.andExpect(jsonPath("$.descriptors[*].name", hasItems("people", "person")));
}
/**
@@ -119,18 +122,16 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void verifyThatAttributesIgnoredDontAppearInAlps() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link usersLink = discoverUnique(profileLink.getHref(), "users");
Link itemsLink = discoverUnique(profileLink.getHref(), "items");
Link profileLink = client.discoverUnique("profile");
Link itemsLink = client.discoverUnique(profileLink, "items", MediaType.ALL);
assertThat(usersLink, is(nullValue()));
mvc.perform(get(itemsLink.getHref()))
client.follow(itemsLink)//
// Exposes standard property
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", hasItems("name")))
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", not(hasItems("id"))))
.andExpect(
jsonPath("$.descriptors[*].descriptors[*].name", everyItem(not(isIn(new String[]{"owner", "manager",
"curator"})))));
// Does not expose explicitly @JsonIgnored property
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", not(hasItems("owner"))))
// Does not expose properties pointing to non exposed types
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", not(hasItems("manager", "curator"))));
}
/**
@@ -139,13 +140,13 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void linksToJsonSchemaFromRepresentationDescriptor() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link usersLink = discoverUnique(profileLink.getHref(), "items");
Link profileLink = client.discoverUnique("profile");
Link itemsLink = client.discoverUnique(profileLink, "items", MediaType.ALL);
assertThat(usersLink, is(notNullValue()));
assertThat(itemsLink, is(notNullValue()));
mvc.perform(get(usersLink.getHref())).//
andExpect(jsonPath("$.descriptors[?(@.id == 'item-representation')].href", is(notNullValue())));
client.follow(itemsLink)//
.andExpect(jsonPath("$.descriptors[?(@.id == 'item-representation')].href", is(notNullValue())));
}
/**
@@ -154,28 +155,29 @@ public class AlpsControllerIntegrationTests extends AbstractControllerIntegratio
@Test
public void referenceToAssociatedEntityDesciptorPointsToRepresentationDescriptor() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link usersLink = discoverUnique(profileLink.getHref(), "people");
Link profileLink = client.discoverUnique("profile");
Link usersLink = client.discoverUnique(profileLink, "people", MediaType.ALL);
String jsonPath = "$."; // Root
jsonPath += "descriptors[?(@.id == 'person-representation')]."; // Representation descriptor
jsonPath += "descriptors[?(@.name == 'father')][0]."; // First father descriptor
jsonPath += "rt"; // Return type
mvc.perform(get(usersLink.getHref())).andExpect(
jsonPath(jsonPath, allOf(containsString("alps"), endsWith("-representation"))));
client.follow(usersLink)//
.andExpect(jsonPath(jsonPath, allOf(containsString("alps"), endsWith("-representation"))));
}
/**
* TODO: Switch to {@link TestMvcClient#discoverUnique(String)}
* @see DATAREST-630
*/
private Link discoverUnique(String href, String rel) throws Exception {
@Test
public void onlyExposesIdAttributesWhenExposedInTheConfiguration() throws Exception {
MockHttpServletResponse response = mvc.perform(get(href)).//
andExpect(status().is2xxSuccessful()).//
andReturn().getResponse();
Link profileLink = client.discoverUnique("profile");
Link itemsLink = client.discoverUnique(profileLink, "items", MediaType.ALL);
LinkDiscoverer discoverer = discoverers.getLinkDiscovererFor(MediaType.valueOf(response.getContentType()));
return discoverer.findLinkWithRel(rel, response.getContentAsString());
client.follow(itemsLink)//
// Exposes identifier if configured to
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", hasItems("id", "name")));
}
}

View File

@@ -1,119 +0,0 @@
/*
* Copyright 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.data.rest.webmvc.alps;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.AbstractControllerIntegrationTests;
import org.springframework.data.rest.webmvc.TestMvcClient;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.data.rest.webmvc.jpa.Item;
import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.LinkDiscoverers;
import org.springframework.hateoas.core.JsonPathLinkDiscoverer;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
/**
* Additional integration tests for {@link AlpsController} with a different {@link RepositoryRestConfiguration} via the
* {@link RepositoryRestConfigurerAdapter}.
*
* @author Greg Turnquist
*/
@WebAppConfiguration
@ContextConfiguration(classes = { JpaRepositoryConfig.class, AlpsControllerWithExposedIdIntegrationTests.Config.class })
public class AlpsControllerWithExposedIdIntegrationTests extends AbstractControllerIntegrationTests {
@Autowired WebApplicationContext context;
@Autowired LinkDiscoverers discoverers;
@Configuration
static class Config extends RepositoryRestConfigurerAdapter {
@Bean
public LinkDiscoverer alpsLinkDiscoverer() {
return new JsonPathLinkDiscoverer("$.descriptors[?(@.name == '%s')].href",
MediaType.valueOf("application/alps+json"));
}
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Item.class);
}
}
protected MockMvc mvc;
private TestMvcClient testMvcClient;
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(context).build();
this.testMvcClient = new TestMvcClient(this.mvc, this.discoverers);
}
/**
* @see DATAREST-630
*/
@Test
public void verifyThatIdAttributesAreOnlyShownWhenExposedInTheConfiguration() throws Exception {
Link profileLink = discoverUnique("/", "profile");
Link usersLink = discoverUnique(profileLink.getHref(), "users");
Link itemsLink = discoverUnique(profileLink.getHref(), "items");
assertThat(usersLink, is(nullValue()));
mvc.perform(get(itemsLink.getHref()))
.andExpect(jsonPath("$.descriptors[*].descriptors[*].name", hasItems("id", "name")))
.andExpect(
jsonPath("$.descriptors[*].descriptors[*].name", everyItem(not(isIn(new String[] { "owner", "manager",
"curator" })))));
}
/**
* TODO: Switch to {@link TestMvcClient#discoverUnique(String)}
*/
private Link discoverUnique(String href, String rel) throws Exception {
MockHttpServletResponse response = mvc.perform(get(href)).//
andExpect(status().is2xxSuccessful()).//
andReturn().getResponse();
LinkDiscoverer discoverer = discoverers.getLinkDiscovererFor(MediaType.valueOf(response.getContentType()));
return discoverer.findLinkWithRel(rel, response.getContentAsString());
}
}