package de.escalon.hypermedia.spring.siren; import com.fasterxml.jackson.annotation.JsonUnwrapped; import com.fasterxml.jackson.databind.ObjectMapper; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.springframework.hateoas.Link; import org.springframework.hateoas.PagedResources; import org.springframework.hateoas.PagedResources.PageMetadata; import org.springframework.hateoas.Resource; import org.springframework.hateoas.Resources; import org.springframework.hateoas.core.EmbeddedWrapper; import org.springframework.hateoas.core.Relation; import java.util.*; import static com.jayway.jsonassert.JsonAssert.with; import static org.hamcrest.Matchers.*; public class SirenUtilsTest { ObjectMapper objectMapper = new ObjectMapper(); SirenUtils sirenUtils = new SirenUtils(); @Before public void setUp() { } @Relation("city") class City { String postalCode = "74199"; String name = "Donnbronn"; public String getPostalCode() { return postalCode; } public String getName() { return name; } } @Relation("address") class Address { String street = "Grant Street"; City city = new City(); public String getStreet() { return street; } public City getCity() { return city; } } @Test public void testNestedBeansToSirenEntityProperties() throws Exception { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final Address address = new Address(); public String getCustomerId() { return customerId; } public String getName() { return name; } public Address getAddress() { return address; } } SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, new Customer()); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.customerId", equalTo("pj123")); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.properties.address", Matchers.instanceOf(Map.class)); with(json).assertThat("$.properties.address.street", equalTo("Grant Street")); } @Relation(value = "email", collectionRelation = "emails") public class Email { private final String email; private final String type; public Email(String email, String type) { this.email = email; this.type = type; } public String getEmail() { return email; } public String getType() { return type; } } @Relation(value = "profile") public class ProfileResource { private final String firstName; private final String lastName; @JsonUnwrapped private final Resources<EmbeddedWrapper> embeddeds; public ProfileResource(String firstName, String lastName, Resources<EmbeddedWrapper> embeddeds) { this.firstName = firstName; this.lastName = lastName; this.embeddeds = embeddeds; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public Resources<EmbeddedWrapper> getEmbeddeds() { return embeddeds; } } // @Test // public void testEmbeddedResource() { // Resource<Email> primary = new Resource<Email>(new Email("neo@matrix.net", "primary")); // Resource<Email> home = new Resource<Email>(new Email("t.anderson@matrix.net", "home")); // // EmbeddedWrappers wrappers = new EmbeddedWrappers(true); // // List<EmbeddedWrapper> embeddeds = Arrays.asList(wrappers.wrap(primary), wrappers.wrap(home)); // // Resources<EmbeddedWrapper> embeddedEmails = new Resources(embeddeds, new Link("self")); // // return ResponseEntity.ok(new Resource(new ProfileResource("Thomas", "Anderson", embeddedEmails), linkTo // (ProfileController.class).withSelfRel())); // } @Test public void testNestedResourceToEmbeddedRepresentation() throws Exception { class Customer { private final String name = "Peter Joseph"; private final Resource<Address> address = new Resource<Address>(new Address()); public String getName() { return name; } public Resource<Address> getAddress() { address.add(new Link("http://example.com/customer/123/address/geolocation", "geolocation")); return address; } } SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, new Customer()); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.entities[0].properties.street", equalTo("Grant Street")); with(json).assertThat("$.entities[0].rel", contains("address")); } @Test public void testEmbeddedLink() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final Address address = new Address(); public String getCustomerId() { return customerId; } public String getName() { return name; } } Resource<Customer> customerResource = new Resource<Customer>(new Customer()); customerResource.add(new Link("http://api.example.com/customers/123/address", "address")); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customerResource); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities[0].rel", contains("address")); with(json).assertThat("$.entities[0].href", equalTo("http://api.example.com/customers/123/address")); } @Test public void testListOfResource() { List<Resource<Address>> addresses = new ArrayList<Resource<Address>>(); for (int i = 0; i < 4; i++) { addresses.add(new Resource<Address>(new Address())); } SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, addresses); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); with(json).assertThat("$.entities[3].properties.city.name", equalTo("Donnbronn")); } @Test public void testResources() { List<Address> addresses = new ArrayList<Address>(); for (int i = 0; i < 4; i++) { addresses.add(new Address()); } Resources<Address> addressResources = new Resources<Address>(addresses); addressResources.add(new Link("http://example.com/addresses", "self")); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, addressResources); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); with(json).assertThat("$.entities[3].properties.city.name", equalTo("Donnbronn")); with(json).assertThat("$.links", hasSize(1)); } @Test public void testPagedResources() { List<Address> addresses = new ArrayList<Address>(); for (int i = 0; i < 4; i++) { addresses.add(new Address()); } PagedResources<Address> addressResources = new PagedResources<Address>(addresses, new PageMetadata(2, 0, addresses.size())); addressResources.add(new Link("http://example.com/addresses", "self")); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, addressResources); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); with(json).assertThat("$.entities[3].properties.city.name", equalTo("Donnbronn")); with(json).assertThat("$.links", hasSize(1)); } @Test public void testMap() { Map<String, Object> map = new LinkedHashMap<String, Object>(); map.put("name", "Joe"); map.put("address", new Address()); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, map); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.name", equalTo("Joe")); with(json).assertThat("$.properties.address.city.name", equalTo("Donnbronn")); } @Test public void testAttributeWithListOfBeans() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final List<Address> addresses = new ArrayList<Address>(); Customer() { for (int i = 0; i < 4; i++) { addresses.add(new Address()); } } public String getCustomerId() { return customerId; } public String getName() { return name; } public List<Address> getAddresses() { return addresses; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); } @Test public void testAttributeWithListOfSingleValueTypes() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final List<Integer> favoriteNumbers = Arrays.asList(1, 3, 5, 7); public String getCustomerId() { return customerId; } public String getName() { return name; } public List<Integer> getFavoriteNumbers() { return favoriteNumbers; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.favoriteNumbers", hasSize(4)); with(json).assertThat("$.properties.favoriteNumbers", contains(1, 3, 5, 7)); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); } enum Daytime { MORNING, NOON, AFTERNOON, EVENING, NIGHT } @Test public void testAttributeWithListOfEnums() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final List<Daytime> favoriteDaytime = Arrays.asList(Daytime.AFTERNOON, Daytime.NIGHT); public String getCustomerId() { return customerId; } public String getName() { return name; } public List<Daytime> getFavoriteNumbers() { return favoriteDaytime; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.favoriteNumbers", hasSize(2)); with(json).assertThat("$.properties.favoriteNumbers", contains(Daytime.AFTERNOON.name(), Daytime.NIGHT.name())); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); } @Test public void testListOfBean() { List<Address> addresses = new ArrayList<Address>(); for (int i = 0; i < 4; i++) { addresses.add(new Address()); } SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, addresses); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); with(json).assertThat("$.entities[3].properties.city.name", equalTo("Donnbronn")); } @Test public void testMapContainingResource() { Map<String, Object> map = new LinkedHashMap<String, Object>(); map.put("name", "Joe"); Resource<Address> addressResource = new Resource<Address>(new Address()); addressResource.add(new Link("http://example.com/addresses/1", "self")); map.put("address", addressResource); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, map); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.name", equalTo("Joe")); with(json).assertThat("$.entities[0].properties.street", equalTo("Grant Street")); with(json).assertThat("$.entities[0].links", hasSize(1)); } @Test public void testAttributeWithResources() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private Resources<Address> addresses; Customer() { List<Address> content = new ArrayList<Address>(); for (int i = 0; i < 4; i++) { content.add(new Address()); } addresses = new Resources<Address>(content); } public String getCustomerId() { return customerId; } public String getName() { return name; } public Resources<Address> getAddresses() { return addresses; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.entities", hasSize(4)); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.entities[0].properties.city.postalCode", equalTo("74199")); } @Test public void testAttributeWithMap() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final Map<String, Object> address = new HashMap<String, Object>(); Customer() { address.put("street", "Grant Street"); Map<String, String> city = new HashMap<String, String>(); address.put("city", city); city.put("name", "Donnbronn"); city.put("postalCode", "74199"); } public String getCustomerId() { return customerId; } public String getName() { return name; } public Map<String, Object> getAddress() { return address; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.properties.address.city.postalCode", equalTo("74199")); } @Test public void testAttributeWithMapContainingBean() { class Customer { private final String customerId = "pj123"; private final String name = "Peter Joseph"; private final Map<String, Object> address = new HashMap<String, Object>(); Customer() { address.put("street", "Grant Street"); Map<String, String> city = new HashMap<String, String>(); address.put("city", new City()); } public String getCustomerId() { return customerId; } public String getName() { return name; } public Map<String, Object> getAddress() { return address; } } Customer customer = new Customer(); SirenEntity entity = new SirenEntity(); sirenUtils.toSirenEntity(entity, customer); String json = objectMapper.valueToTree(entity) .toString(); with(json).assertThat("$.properties.name", equalTo("Peter Joseph")); with(json).assertThat("$.properties.address.city.postalCode", equalTo("74199")); } // TODO beans with setters, non-specific input parameter types }