package org.springframework.data.rest.tck;
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 static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
import java.util.Collections;
import java.util.List;
import javax.servlet.ServletContext;
import com.jayway.jsonpath.JsonPath;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.LinkDiscoverer;
import org.springframework.hateoas.core.DefaultLinkDiscoverer;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
/**
* @author Jon Brisbin
*/
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("src/main/webapp")
@ContextConfiguration(classes = {TckConfig.class, TestApplicationConfig.class})
public abstract class AbstractTckTest {
protected static final MediaType COMPACT_JSON = MediaType.parseMediaType("application/x-spring-data-compact+json");
protected static final MediaType VERBOSE_JSON = MediaType.parseMediaType("application/x-spring-data-verbose+json");
protected final LinkDiscoverer links = new DefaultLinkDiscoverer();
@Autowired
protected WebApplicationContext webAppCtx;
@Autowired
protected ServletContext servletContext;
protected MockMvc mockMvc;
public static ResultMatcher linkWithRel(final String rel) {
return new ResultMatcher() {
@Override public void match(MvcResult result) throws Exception {
String s = result.getResponse().getContentAsString();
Object o = JsonPath.read(s, String.format("$links[?(@.rel == '%s')].href", rel));
assertThat(String.format("Link with rel '%s' exists", rel),
o,
notNullValue());
}
};
}
protected List<Link> follow(Link parent, String followRel, String childRel) throws Exception {
List<Link> links = discover(parent, followRel);
if(null == links || links.isEmpty()) {
return Collections.emptyList();
}
String json = mockMvc
.perform(get(links.get(0).getHref()).accept(COMPACT_JSON))
.andExpect(status().isOk())
.andReturn().getResponse().getContentAsString();
return this.links.findLinksWithRel(childRel, json);
}
protected List<Link> discover(String rel) throws Exception {
return discover(new Link("/"), rel);
}
protected List<Link> discover(Link root, String rel) throws Exception {
String s = mockMvc
.perform(get(root.getHref()).accept(COMPACT_JSON))
.andExpect(status().isOk())
.andExpect(linkWithRel(rel))
.andReturn().getResponse().getContentAsString();
return links.findLinksWithRel(rel, s);
}
protected Link discoverRootLink(String rel) throws Exception {
List<Link> l = discover(rel);
assertThat(String.format("Link rel='%s' is exposed", rel),
l,
Matchers.<Link>iterableWithSize(1));
return l.get(0);
}
protected MockHttpServletResponse request(String href, MediaType contentType) throws Exception {
return mockMvc
.perform(get(href).accept(contentType))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andReturn().getResponse();
}
protected MockHttpServletResponse request(String href) throws Exception {
return request(href, MediaType.APPLICATION_JSON);
}
protected MockHttpServletResponse requestCompact(String href) throws Exception {
return request(href, COMPACT_JSON);
}
@Before
public void setup() {
OpenEntityManagerInViewFilter oemivf = new OpenEntityManagerInViewFilter();
oemivf.setServletContext(servletContext);
mockMvc = webAppContextSetup(webAppCtx)
.addFilter(oemivf)
.build();
loadData();
}
@After
public void tearDown() {
deleteData();
}
protected abstract void loadData();
protected abstract void deleteData();
}