Adding tests.

This commit is contained in:
Jon Brisbin
2012-03-09 16:49:49 -06:00
parent cdd0eb5df8
commit b68c16eab2
12 changed files with 281 additions and 52 deletions

View File

@@ -127,18 +127,26 @@ public class JpaEntityMetadata {
}
public Object get(String name, Object target) {
try {
return fields.get(name).get(target);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
if (fields.containsKey(name)) {
try {
return fields.get(name).get(target);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
} else {
throw new NoSuchFieldError(name);
}
}
public void set(String name, Object arg, Object target) {
try {
fields.get(name).set(target, arg);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
if (fields.containsKey(name)) {
try {
fields.get(name).set(target, arg);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
} else {
throw new NoSuchFieldError(name);
}
}

View File

@@ -1,5 +1,6 @@
package org.springframework.data.rest.repository;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -39,7 +40,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
this.metamodel = entityManager.getMetamodel();
}
public CrudRepository repositoryFor(String name) {
@SuppressWarnings({"unchecked"})
public <T> CrudRepository<T, ? extends Serializable> repositoryFor(String name) {
if (null != name) {
for (Map.Entry<Class<?>, RepositoryCacheEntry> entry : repositories.entrySet()) {
if (name.equals(repositoryNameFor(entry.getValue().repository))) {
@@ -50,7 +52,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
return null;
}
public CrudRepository repositoryFor(Class<?> domainClass) {
@SuppressWarnings({"unchecked"})
public <T> CrudRepository<T, ? extends Serializable> repositoryFor(Class<T> domainClass) {
RepositoryCacheEntry entry = repositories.get(domainClass);
if (null != entry) {
return entry.repository;
@@ -58,7 +61,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
return null;
}
public EntityInformation entityInfoFor(Class<?> domainClass) {
@SuppressWarnings({"unchecked"})
public <T> EntityInformation<T, ? extends Serializable> entityInfoFor(Class<T> domainClass) {
RepositoryCacheEntry entry = repositories.get(domainClass);
if (null != entry) {
return entry.entityInfo;
@@ -70,7 +74,8 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
return metamodel.entity(domainClass);
}
public EntityInformation entityInfoFor(CrudRepository repository) {
@SuppressWarnings({"unchecked"})
public <T> EntityInformation<T, ? extends Serializable> entityInfoFor(CrudRepository<T, ? extends Serializable> repository) {
for (Map.Entry<Class<?>, RepositoryCacheEntry> entry : repositories.entrySet()) {
if (entry.getValue().repository == repository) {
return entry.getValue().entityInfo;
@@ -116,7 +121,7 @@ public class JpaRepositoryMetadata implements InitializingBean, ApplicationConte
return names;
}
public void setRepositories(Collection<CrudRepository> repositories) {
public void setRepositories(Collection<? extends CrudRepository> repositories) {
for (CrudRepository repository : repositories) {
Class<?> repoClass = AopUtils.getTargetClass(repository);
Field infoField = ReflectionUtils.findField(repoClass, "entityInformation");

View File

@@ -1,14 +1,15 @@
package org.springframework.data.rest.repository.spec
import javax.persistence.Entity
import javax.persistence.EntityManager
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.PersistenceContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.ApplicationContext
import org.springframework.data.repository.CrudRepository
import org.springframework.data.rest.repository.JpaRepositoryMetadata
import org.springframework.data.rest.repository.test.Family
import org.springframework.data.rest.repository.test.FamilyRepository
import org.springframework.data.rest.repository.test.Person
import org.springframework.data.rest.repository.test.PersonRepository
import org.springframework.test.context.ContextConfiguration
import spock.lang.Specification
@@ -24,41 +25,50 @@ class JpaMetadataSpec extends Specification {
EntityManager entityManager
@Autowired
Collection<CrudRepository> repositories
@Autowired
JpaRepositoryMetadata repoMeta
def setup() {
repoMeta = new JpaRepositoryMetadata(
repositories: repositories,
applicationContext: applicationContext,
entityManager: entityManager
)
repoMeta.afterPropertiesSet()
}
def "finds repositories in ApplicationContext"() {
when:
def repo = repoMeta.repositoryFor("simple")
when: "find repo by String identifier"
def repo = repoMeta.repositoryFor("person")
then:
null != repo
repo instanceof SimpleRepository
repo instanceof PersonRepository
when:
repo = repoMeta.repositoryFor(Simple)
when: "find repo by domain Class<?>"
repo = repoMeta.repositoryFor(Family)
then:
null != repo
repo instanceof SimpleRepository
repo instanceof FamilyRepository
}
def "provides entity metadata"() {
given:
def personRepo = repoMeta.repositoryFor(Person)
def familyRepo = repoMeta.repositoryFor(Family)
def johnDoe = personRepo.save(new Person("John Doe"))
def janeDoe = personRepo.save(new Person("Jane Doe"))
def doeFamily = familyRepo.save(new Family(
surname: "Doe",
members: [johnDoe, janeDoe]
))
when:
def personMeta = repoMeta.entityMetadataFor(Person)
def familyMeta = repoMeta.entityMetadataFor(Family)
then:
personMeta.get("name", johnDoe) == "John Doe"
familyMeta.get("surname", doeFamily) == "Doe"
familyMeta.get("members", doeFamily).size() == 2
personMeta.embeddedAttributes().size() == 1
familyMeta.linkedAttributes().size() == 1
}
}
@Entity
class Simple {
@Id @GeneratedValue Long id
String name
}
interface SimpleRepository extends CrudRepository<Simple, Long> {}

View File

@@ -0,0 +1,57 @@
package org.springframework.data.rest.repository.test;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
@Entity
public class Family {
@Id
@GeneratedValue
private Long id;
private String surname;
@OneToMany
private List<Person> members;
public Family() {
}
public Family(String surname) {
this.surname = surname;
}
public Long getId() {
return id;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public List<Person> getMembers() {
return members;
}
public void setMembers(List<Person> members) {
this.members = members;
}
@Override public String toString() {
return "Family{" +
"id=" + id +
", surname='" + surname + '\'' +
", members=" + members +
'}';
}
}

View File

@@ -0,0 +1,9 @@
package org.springframework.data.rest.repository.test;
import org.springframework.data.repository.CrudRepository;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
public interface FamilyRepository extends CrudRepository<Family, Long> {
}

View File

@@ -0,0 +1,44 @@
package org.springframework.data.rest.repository.test;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

View File

@@ -0,0 +1,9 @@
package org.springframework.data.rest.repository.test;
import org.springframework.data.repository.CrudRepository;
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
public interface PersonRepository extends CrudRepository<Person, Long> {
}

View File

@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="jpa.sample">
<class>org.springframework.data.rest.repository.spec.Simple</class>
<class>org.springframework.data.rest.repository.test.Person</class>
<class>org.springframework.data.rest.repository.test.Family</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:spring"/>

View File

@@ -7,6 +7,8 @@
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
@@ -18,9 +20,14 @@
<property name="persistenceUnitName" value="jpa.sample"/>
<property name="persistenceXmlLocation" value="/JpaMetadataSpec-persistence.xml"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<jdbc:embedded-database id="dataSource" type="HSQL"/>
<jpa:repositories base-package="org.springframework.data.rest.repository.test"/>
<jpa:repositories base-package="org.springframework.data.rest.repository.spec"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="jpaRepositoryMetadata" class="org.springframework.data.rest.repository.JpaRepositoryMetadata"/>
</beans>

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:META-INF/spring-data-rest/**/*-export.xml"/>
</beans>

View File

@@ -0,0 +1,88 @@
package org.springframework.data.rest.mvc.spec
import org.codehaus.jackson.map.ObjectMapper
import org.codehaus.jackson.map.ser.CustomSerializerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.rest.core.SimpleLink
import org.springframework.data.rest.core.util.FluentBeanSerializer
import org.springframework.data.rest.mvc.RepositoryRestConfiguration
import org.springframework.data.rest.mvc.RepositoryRestController
import org.springframework.data.rest.mvc.RepositoryRestMvcConfiguration
import org.springframework.http.HttpStatus
import org.springframework.http.server.ServletServerHttpRequest
import org.springframework.mock.web.MockHttpServletRequest
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.annotation.Transactional
import org.springframework.ui.ExtendedModelMap
import spock.lang.Shared
import spock.lang.Specification
/**
* @author Jon Brisbin <jon@jbrisbin.com>
*/
@ContextConfiguration(classes = [RepositoryRestConfiguration, RepositoryRestMvcConfiguration])
class RepositoryRestControllerSpec extends Specification {
@Shared
ObjectMapper mapper = new ObjectMapper()
@Autowired
URI baseUri
@Autowired
RepositoryRestController controller
ServletServerHttpRequest createRequest(String method, String path) {
return new ServletServerHttpRequest(new MockHttpServletRequest(
serverPort: 8080,
requestURI: "/data/$path",
method: method
))
}
Map GET(String path) {
def request = createRequest("GET", path)
def model = new ExtendedModelMap()
controller.get(request, model)
return model
}
def setupSpec() {
def customSerializerFactory = new CustomSerializerFactory()
customSerializerFactory.addSpecificMapping(SimpleLink, new FluentBeanSerializer(SimpleLink))
mapper.setSerializerFactory(customSerializerFactory)
}
@Transactional
def "responds to GET"() {
when:
def repos = GET("")
def reposLinks = repos.resource?._links
then:
repos.status == HttpStatus.OK
reposLinks?.size() == 3
when:
def persons = GET("person")
def personsLinks = persons.resource?._links
then:
persons.status == HttpStatus.OK
personsLinks[0].href().toString() == "http://localhost:8080/data/person/1"
when:
def person = GET("person/1")
then:
person?.resource.name == "John Doe"
when:
def profiles = GET("person/1/profiles")
def profilesLinks = profiles?.resource.profiles
then:
profilesLinks.size() == 2
}
}

View File

@@ -9,8 +9,7 @@
</appender>
<logger name="org.springframework.data.rest" level="DEBUG"/>
<logger name="org.springframework.data" level="DEBUG"/>
<logger name="org.springframework" level="INFO"/>
<logger name="org.springframework.data" level="INFO"/>
<root level="INFO">
<appender-ref ref="stdout"/>