package com.temenos.interaction.media.hal;
/*
* #%L
* interaction-media-hal
* %%
* Copyright (C) 2012 - 2013 Temenos Holdings N.V.
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* #L%
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.beanutils.PropertyUtils;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLAssert;
import org.junit.Test;
import org.odata4j.core.OEntities;
import org.odata4j.core.OEntity;
import org.odata4j.core.OEntityKey;
import org.odata4j.core.OLink;
import org.odata4j.core.OProperties;
import org.odata4j.core.OProperty;
import org.odata4j.edm.EdmEntitySet;
import org.odata4j.edm.EdmEntityType;
import org.odata4j.edm.EdmProperty;
import org.odata4j.edm.EdmSimpleType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.temenos.interaction.core.MultivaluedMapImpl;
import com.temenos.interaction.core.command.CommandHelper;
import com.temenos.interaction.core.entity.Entity;
import com.temenos.interaction.core.entity.EntityMetadata;
import com.temenos.interaction.core.entity.Metadata;
import com.temenos.interaction.core.entity.vocabulary.Vocabulary;
import com.temenos.interaction.core.entity.vocabulary.terms.TermComplexType;
import com.temenos.interaction.core.entity.vocabulary.terms.TermValueType;
import com.temenos.interaction.core.hypermedia.Action;
import com.temenos.interaction.core.hypermedia.DefaultResourceStateProvider;
import com.temenos.interaction.core.hypermedia.Link;
import com.temenos.interaction.core.hypermedia.ResourceState;
import com.temenos.interaction.core.hypermedia.ResourceStateMachine;
import com.temenos.interaction.core.hypermedia.ResourceStateProvider;
import com.temenos.interaction.core.hypermedia.Transition;
import com.temenos.interaction.core.resource.CollectionResource;
import com.temenos.interaction.core.resource.EntityResource;
import com.temenos.interaction.core.resource.MetaDataResource;
import com.temenos.interaction.core.resource.RESTResource;
public class TestHALProvider {
/*
* Test the getSize operation of GET with this provider
*/
@Test
public void testSize() {
HALProvider hp = new HALProvider(mock(Metadata.class), mock(ResourceStateProvider.class));
assertEquals(-1, hp.getSize(null, null, null, null, null));
}
/** utility method to parse a json string for use in comparisons
*/
public Map parseJson(String json) throws IOException {
//converting json to Map
byte[] mapData = json.getBytes();
Map<String,Object> myMap = new HashMap<String, Object>();
ObjectMapper objectMapper = new ObjectMapper();
myMap = objectMapper.readValue(mapData, HashMap.class);
return myMap;
}
/*
* Test the getSize operation of GET with this provider
*/
@SuppressWarnings("unchecked")
@Test
public void testDeserialise() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource href=\"/children\"><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
assertNotNull(entity.getProperties());
// string type
assertEquals("noah", entity.getProperties().getProperty("name").getValue());
// long type
// TODO handle non string entity properties
assertEquals(new Long(2), entity.getProperties().getProperty("age").getValue());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityName() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource href=\"/children\"><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameJSON() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "{ \"_links\": { \"self\": { \"href\": \"http://www.temenos.com/rest.svc/children\" } }, \"name\": \"noah\", \"age\": 2 }";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_JSON_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialisePlainJSON() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm),
new com.theoryinpractise.halbuilder.standard.StandardRepresentationFactory().withReader(javax.ws.rs.core.MediaType.APPLICATION_JSON, com.theoryinpractise.halbuilder.json.JsonRepresentationReader.class)
);
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "{ \"_links\": { \"self\": { \"href\": \"http://www.temenos.com/rest.svc/children\" } }, \"name\": \"noah\", \"age\": 2 }";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testNestedDeserialiseResolveEntityNameJSON() throws IOException, URISyntaxException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("students", "initial", new ArrayList<Action>(), "/students"));
HALProvider hp = new HALProvider(createNestedMockStudentsVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/students");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "{'_links':{'self':{'href':'http://www.temenos.com/rest.svc/students'}},'name':'noah','age':'2','tuitions':[{'Duration':'2.5','TutionName':'Maths'},{'TutionName':'English','Duration':'2'}]}".replace('\'','\"');
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_JSON_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("students", entity.getName());
assertEquals(2L, PropertyUtils.getProperty(entity, "properties.properties.age.value"));
assertEquals("noah", PropertyUtils.getProperty(entity, "properties.properties.name.value"));
assertEquals("2.5", PropertyUtils.getProperty(entity, "properties.properties.tuitions.value[0].properties.Duration.value"));
}
@SuppressWarnings("unchecked")
@Test
public void testMoreComplexNestedDeserialiseResolveEntityNameJSON() throws IOException, URISyntaxException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("students", "initial", new ArrayList<Action>(), "/students"));
HALProvider hp = new HALProvider(createMoreComplexNestedMockStudentVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/students");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "{'_links':{'self':{'href':'http://www.temenos.com/rest.svc/students'}},'name':'noah','age':'2','address': {'houseNumber':'123', 'roadName': 'Fenchurch Street'},'tuitions':[{'Duration':'2.5','TutionName':'Maths'},{'TutionName':'English','Duration':'2', 'Teachers': [{'Name': 'John'}, {'Name': 'Martin'}]}]}".replace('\'','\"');
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_JSON_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("students", entity.getName());
assertEquals(2L, PropertyUtils.getProperty(entity, "properties.properties(age).value"));
assertEquals("noah", PropertyUtils.getProperty(entity, "properties.properties(name).value"));
assertEquals("123", PropertyUtils.getProperty(entity, "properties.properties(address).value.properties(houseNumber).value"));
assertEquals("Fenchurch Street", PropertyUtils.getProperty(entity, "properties.properties(address).value.properties(roadName).value"));
assertEquals("2.5", PropertyUtils.getProperty(entity, "properties.properties(tuitions).value[0].properties(Duration).value"));
}
@Test
public void testIsWritable(){
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider provider = new HALProvider(createNestedMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
GenericEntity<EntityResource<Entity>> entity = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, MediaType.APPLICATION_HAL_JSON_TYPE));
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE));
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE));
}
@Test
public void testIsWritableReturnsTrueForCollectionResourceObjects(){
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider provider = new HALProvider(createNestedMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
GenericEntity<CollectionResource<Entity>> entity = new GenericEntity<CollectionResource<Entity>>(new CollectionResource<Entity>()) {};
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, MediaType.APPLICATION_HAL_JSON_TYPE));
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE));
assertTrue(provider.isWriteable(RESTResource.class, entity.getType(), null, javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE));
}
@Test
public void testIsWritableReturnsFalseForUnwritableTypes(){
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider provider = new HALProvider(createNestedMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
GenericEntity<EntityResource<Entity>> entity = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
assertFalse(provider.isWriteable(RESTResource.class, entity.getType(), null, javax.ws.rs.core.MediaType.APPLICATION_SVG_XML_TYPE));
}
@Test
public void testIsWritableReturnsFalseForNonEntityOrCollectionTypes(){
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider provider = new HALProvider(createNestedMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
GenericEntity<EntityResource<Entity>> entity = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
assertFalse(provider.isWriteable(RESTResource.class, entity.getType(), null, javax.ws.rs.core.MediaType.APPLICATION_SVG_XML_TYPE));
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameWithId() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children/{id}", "id", null));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children/123");
MultivaluedMap<String, String> mockPathParameters = new MultivaluedMapImpl<String>();
when(mockUriInfo.getPathParameters()).thenReturn(mockPathParameters);
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource href=\"/children/123\"><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameWithIdODataPath() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children({id})/updated", "id", null));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn("/children(123)/updated");
MultivaluedMap<String, String> mockPathParameters = new MultivaluedMapImpl<String>();
mockPathParameters.add("id", "123");
when(mockUriInfo.getPathParameters()).thenReturn(mockPathParameters);
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource href=\"/children(123)/updated\"><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameUriInfo() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
when(mockUriInfo.getPath()).thenReturn("/children");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameUriInfoRelative() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/Orders()"));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
when(mockUriInfo.getPath()).thenReturn("Orders()");
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameUriInfoWithId() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children/{id}", "id", null));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
when(mockUriInfo.getPath()).thenReturn("/children/123");
MultivaluedMap<String, String> mockPathParameters = new MultivaluedMapImpl<String>();
mockPathParameters.add("id", "123");
when(mockUriInfo.getPathParameters()).thenReturn(mockPathParameters);
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
@Test
public void testDeserialiseResolveEntityNameUriInfoWithIdODataPath() throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), "/children({id})/updated", "id", null));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
when(mockUriInfo.getPath()).thenReturn("/children(123)/updated");
MultivaluedMap<String, String> mockPathParameters = new MultivaluedMapImpl<String>();
mockPathParameters.add("id", "123");
when(mockUriInfo.getPathParameters()).thenReturn(mockPathParameters);
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "<resource><name>noah</name><age>2</age></resource>";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, MediaType.APPLICATION_HAL_XML_TYPE, null, entityStream);
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
private Metadata createMockChildVocabMetadata() {
EntityMetadata vocs = new EntityMetadata("Children");
Vocabulary vocId = new Vocabulary();
vocId.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("name", vocId);
Vocabulary vocBody = new Vocabulary();
vocBody.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER));
vocs.setPropertyVocabulary("age", vocBody);
Metadata metadata = new Metadata("Family");
metadata.setEntityMetadata(vocs);
return metadata;
}
private Metadata createNestedMockChildVocabMetadata() {
EntityMetadata vocs = new EntityMetadata("Children");
Vocabulary vocId = new Vocabulary();
vocId.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("name", vocId);
Vocabulary vocBody = new Vocabulary();
vocBody.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER));
vocs.setPropertyVocabulary("age", vocBody);
Vocabulary vocRides = new Vocabulary();
vocRides.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("tuitions", vocRides);
Vocabulary vocTutionName = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("TutionName", vocTutionName, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTutionDuration = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("Duration", vocTutionDuration, Collections.enumeration(Collections.singletonList("tuitions")));
Metadata metadata = new Metadata("Family");
metadata.setEntityMetadata(vocs);
return metadata;
}
private Metadata createNestedMockStudentsVocabMetadata() {
EntityMetadata vocs = new EntityMetadata("students");
Vocabulary vocId = new Vocabulary();
vocId.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("name", vocId);
Vocabulary vocBody = new Vocabulary();
vocBody.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER));
vocs.setPropertyVocabulary("age", vocBody);
Vocabulary vocRides = new Vocabulary();
vocRides.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("tuitions", vocRides);
Vocabulary vocTutionName = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("TutionName", vocTutionName, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTutionDuration = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("Duration", vocTutionDuration, Collections.enumeration(Collections.singletonList("tuitions")));
Metadata metadata = new Metadata("Faculty");
metadata.setEntityMetadata(vocs);
return metadata;
}
private Metadata createMoreComplexNestedMockStudentVocabMetadata() {
EntityMetadata vocs = new EntityMetadata("students");
Vocabulary vocId = new Vocabulary();
vocId.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("name", vocId);
Vocabulary vocBody = new Vocabulary();
vocBody.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER));
vocs.setPropertyVocabulary("age", vocBody);
Vocabulary vocRides = new Vocabulary();
vocRides.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("tuitions", vocRides);
Vocabulary vocTeachers = new Vocabulary();
vocTeachers.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("Teachers", vocTeachers, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTutionName = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("TutionName", vocTutionName, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTutionDuration = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("Duration", vocTutionDuration, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTeacherName = new Vocabulary();
vocTeacherName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("Name", vocTeacherName, Collections.enumeration(Arrays.asList(new String[]{"tuitions","Teachers"})));
Vocabulary vocAddress = new Vocabulary();
vocAddress.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("address", vocAddress);
Vocabulary vocAddressHouseNumber = new Vocabulary();
vocAddressHouseNumber.setTerm(new TermValueType(TermValueType.NUMBER));
vocs.setPropertyVocabulary("houseNumber", vocAddressHouseNumber, Collections.enumeration(Arrays.asList(new String[]{"address"})));
Vocabulary vocAddressRoadName = new Vocabulary();
vocAddressRoadName.setTerm(new TermValueType(TermValueType.NUMBER));
vocs.setPropertyVocabulary("roadName", vocAddressRoadName, Collections.enumeration(Arrays.asList(new String[]{"address"})));
Metadata metadata = new Metadata("Faculty");
metadata.setEntityMetadata(vocs);
return metadata;
}
private Metadata createObjectNestedVocabMetadataStub(){
EntityMetadata vocs = new EntityMetadata("Children");
Vocabulary vocId = new Vocabulary();
vocId.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("name", vocId);
Vocabulary vocBody = new Vocabulary();
vocBody.setTerm(new TermValueType(TermValueType.INTEGER_NUMBER));
vocs.setPropertyVocabulary("age", vocBody);
Vocabulary vocRides = new Vocabulary();
vocRides.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("tuitions", vocRides);
Vocabulary vocTutionName = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("TutionName", vocTutionName, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocTutionDuration = new Vocabulary();
vocTutionName.setTerm(new TermValueType(TermValueType.TEXT));
vocs.setPropertyVocabulary("Duration", vocTutionDuration, Collections.enumeration(Collections.singletonList("tuitions")));
Vocabulary vocAddress = new Vocabulary();
vocAddress.setTerm(new TermComplexType(true));
vocs.setPropertyVocabulary("address", vocAddress);
Vocabulary vocAddressHouseNumber = new Vocabulary();
vocAddressHouseNumber.setTerm(new TermValueType(TermValueType.NUMBER));
vocs.setPropertyVocabulary("houseNumber", vocAddressHouseNumber, Collections.enumeration(Arrays.asList(new String[]{"address"})));
Vocabulary vocAddressRoadName = new Vocabulary();
vocAddressRoadName.setTerm(new TermValueType(TermValueType.NUMBER));
vocs.setPropertyVocabulary("roadName", vocAddressRoadName, Collections.enumeration(Arrays.asList(new String[]{"address"})));
Metadata metadata = new Metadata("Family");
metadata.setEntityMetadata(vocs);
return metadata;
}
@Test(expected = WebApplicationException.class)
public void testAttemptToSerialiseNonEntityResource() throws Exception {
EntityResource<?> mdr = mock(EntityResource.class);
HALProvider hp = new HALProvider(mock(Metadata.class));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
hp.writeTo(mdr, MetaDataResource.class, null, null, MediaType.APPLICATION_HAL_XML_TYPE, null, new ByteArrayOutputStream());
}
@Test
public void testSerialiseSimpleResource() throws Exception {
// the test key
OEntityKey entityKey = OEntityKey.create("123");
// the test properties
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
OEntity entity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
EntityResource<OEntity> er = CommandHelper.createEntityResource(entity, OEntity.class);
er.setEntityName("Children");
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"><name>noah</name><age>2</age></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testSerialiseCollectionResource() throws Exception {
// the test key
OEntityKey entityKey = OEntityKey.create("123");
// the test properties
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
Collection<EntityResource<OEntity>> entities = new ArrayList<EntityResource<OEntity>>();
entities.add(createEntityResourceWithSelfLink(entityKey, properties, "http://www.temenos.com/rest.svc/children/1"));
entities.add(createEntityResourceWithSelfLink(entityKey, properties, "http://www.temenos.com/rest.svc/children/2"));
entities.add(createEntityResourceWithSelfLink(entityKey, properties, "http://www.temenos.com/rest.svc/children/3"));
CollectionResource<OEntity> er = new CollectionResource<OEntity>("Children", entities);
// mock setting entity name
er.setEntityName("Children");
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, CollectionResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"><resource href=\"http://www.temenos.com/rest.svc/children/1\" rel=\"item\"><age>2</age><name>noah</name></resource><resource href=\"http://www.temenos.com/rest.svc/children/2\" rel=\"item\"><age>2</age><name>noah</name></resource><resource href=\"http://www.temenos.com/rest.svc/children/3\" rel=\"item\"><age>2</age><name>noah</name></resource></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testSerialiseEmbeddedResources() throws Exception {
OEntityKey parentEntityKey = OEntityKey.create("333");
List<OProperty<?>> parentProperties = new ArrayList<OProperty<?>>();
parentProperties.add(OProperties.string("name", "aaron"));
parentProperties.add(OProperties.string("age", "30"));
OEntityKey childEntityKey = OEntityKey.create("123");
List<OProperty<?>> childProperties = new ArrayList<OProperty<?>>();
childProperties.add(OProperties.string("name", "noah"));
childProperties.add(OProperties.string("age", "2"));
OEntity childEntity = OEntities.create(createMockChildrenEntitySet(), childEntityKey, childProperties, new ArrayList<OLink>());
EntityResource<OEntity> childEntityResource = CommandHelper.createEntityResource(childEntity, OEntity.class);
childEntityResource.setEntityName("Children");
OEntity parentEntity = OEntities.create(createMockChildrenEntitySet(), parentEntityKey, parentProperties, new ArrayList<OLink>());
EntityResource<OEntity> parentEntityResource = CommandHelper.createEntityResource(parentEntity, OEntity.class);
parentEntityResource.setEntityName("Children");
// build the embedded map
Map<Transition, RESTResource> embedded = new HashMap<Transition, RESTResource>();
Transition childToParent = new Transition.Builder()
.source(new ResourceState("PERSON", "child", new ArrayList<Action>(), "/child/{id}"))
.target(new ResourceState("PERSON", "parent", new ArrayList<Action>(), "/parent/{id}"))
.build();
embedded.put(childToParent, parentEntityResource);
// child has a parent
childEntityResource.setEmbedded(embedded);
// mock the test links
List<Link> links = new ArrayList<Link>();
links.add(mockLink("child", "self", "/child/123", null));
links.add(mockLink("parent", "person", "/parent/333", childToParent));
childEntityResource.setLinks(links);
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(childEntityResource, EntityResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_JSON_TYPE, null, bos);
String expectedXML = "{\"_links\":{\"self\":{\"href\":\"/child/123\"},\"person\":[{\"href\":\"/parent/333\",\"name\":\"parent\",\"title\":\"parent\"}]},\"age\":\"2\",\"name\":\"noah\",\"_embedded\":{\"person\":[{\"_links\":{\"self\":{\"href\":\"/parent/333\"}},\"age\":\"30\",\"name\":\"aaron\"}]}}";
String responseString = new String(bos.toByteArray(), "UTF-8");
responseString = responseString.replaceAll(System.getProperty("line.separator"), "");
Map<String,Object> expectedData = parseJson(expectedXML);
Map<String,Object> actualData = parseJson(responseString);
assertEquals(expectedData, actualData);
}
private EntityResource<OEntity> createEntityResourceWithSelfLink(OEntityKey entityKey, List<OProperty<?>> properties, String selfLink) {
OEntity oentity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
EntityResource<OEntity> entityResource = new EntityResource<OEntity>(oentity);
Collection<Link> links = new ArrayList<Link>();
links.add(new Link("id", "self", selfLink, null, null));
entityResource.setLinks(links);
return entityResource;
}
@Test
public void testSerialiseBeanResource() throws Exception {
// the test bean, with elements that should not be serialised
Children person = new Children("noah", 2, "42");
EntityResource<Children> er = new EntityResource<Children>(person);
er.setEntityName("Children");
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, Children.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"><name>noah</name><age>2</age></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testSerialiseNullBeanResource() throws Exception {
// null object
EntityResource<Object> er = new EntityResource<Object>(null);
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
hp.writeTo(er, EntityResource.class, Object.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, new ByteArrayOutputStream());
}
private String createFlatXML(ByteArrayOutputStream bos) throws Exception {
String responseString = new String(bos.toByteArray(), "UTF-8");
responseString = responseString.replaceAll(System.getProperty("line.separator"), "");
responseString = responseString.replaceAll(">\\s+<", "><");
return responseString;
}
private Link mockLink(String id, String rel, String href, Transition transition) {
Link link = mock(Link.class);
when(link.getId()).thenReturn(id);
when(link.getTitle()).thenReturn(id);
when(link.getRel()).thenReturn(rel);
when(link.getHref()).thenReturn(href);
when(link.getTransition()).thenReturn(transition);
return link;
}
@Test
public void testSerialiseResourceNoEntity() throws Exception {
EntityResource<?> er = mock(EntityResource.class);
when(er.getEntity()).thenReturn(null);
HALProvider hp = new HALProvider(mock(Metadata.class));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, null, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com\"></resource>";
String responseString = createFlatXML(bos);
XMLAssert.assertXMLEqual(expectedXML, responseString);
}
@Test
public void testBaseUri() throws Exception {
EntityResource<?> er = mock(EntityResource.class);
when(er.getEntity()).thenReturn(null);
HALProvider hp = new HALProvider(mock(Metadata.class));
UriInfo mockUriInfo = mock(UriInfo.class);
// java 1.6 bug getBaseUri returns absolute path
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, null, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"></resource>";
String responseString = createFlatXML(bos);
XMLAssert.assertXMLEqual(expectedXML, responseString);
}
@Test
public void testJSONMediaTypeWithCharset() throws Exception {
EntityResource<?> er = mock(EntityResource.class);
when(er.getEntity()).thenReturn(null);
HALProvider hp = new HALProvider(mock(Metadata.class));
UriInfo mockUriInfo = mock(UriInfo.class);
// java 1.6 bug getBaseUri returns absolute path
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, null, null, javax.ws.rs.core.MediaType.valueOf("application/hal+json; charset=utf-8"), null, bos);
String expectedXML = "{\"_links\":{\"self\":{\"href\":\"http://www.temenos.com/rest.svc/\"}}}";
String responseString = new String(bos.toByteArray(), "UTF-8");
responseString = responseString.replaceAll(System.getProperty("line.separator"), "");
assertEquals(expectedXML, responseString);
}
@Test
public void testXMLMediaTypeWithCharset() throws Exception {
EntityResource<?> er = mock(EntityResource.class);
when(er.getEntity()).thenReturn(null);
HALProvider hp = new HALProvider(mock(Metadata.class));
UriInfo mockUriInfo = mock(UriInfo.class);
// java 1.6 bug getBaseUri returns absolute path
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, null, null, javax.ws.rs.core.MediaType.valueOf("application/hal+xml; charset=utf-8"), null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"></resource>";
String responseString = createFlatXML(bos);
XMLAssert.assertXMLEqual(expectedXML, responseString);
}
@Test
public void testSerialiseResourceWithLinks() throws Exception {
// the test key
OEntityKey entityKey = OEntityKey.create("123");
// the test properties
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
// the test links
List<Link> links = new ArrayList<Link>();
links.add(mockLink("father", "_person", "humans/31", null));
links.add(mockLink("mother", "_person", "/rest.svc/humans/32", null));
OEntity entity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
EntityResource<OEntity> er = CommandHelper.createEntityResource(entity, OEntity.class);
er.setEntityName("Children");
er.setLinks(links);
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"><link href=\"humans/31\" rel=\"_person\" name=\"father\" title=\"father\"/><link href=\"/rest.svc/humans/32\" rel=\"_person\" name=\"mother\" title=\"mother\"/><name>noah</name><age>2</age></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testSerialiseResourceWithRelatedLinks() throws Exception {
// the test key
OEntityKey entityKey = OEntityKey.create("123");
// the test properties
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
// the test links
/*
* Not sure, but I think relatedEntity and link are the same thing in an OEntity.
* However, a relatedEntity also has the relatedEntityInline capability.
* TODO add tests for 'inline' links
*/
List<Link> links = new ArrayList<Link>();
links.add(mockLink("father", "_person", "humans/31", null));
links.add(mockLink("mother", "_person", "humans/32", null));
links.add(mockLink("siblings", "_family", "humans/phetheans", null));
OEntity entity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
EntityResource<OEntity> er = new EntityResource<OEntity>(entity);
er.setEntityName("Children");
er.setLinks(links);
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\"><link href=\"humans/phetheans\" rel=\"_family\" name=\"siblings\" title=\"siblings\"/><link href=\"humans/31\" rel=\"_person\" name=\"father\" title=\"father\"/><link href=\"humans/32\" rel=\"_person\" name=\"mother\" title=\"mother\"/><name>noah</name><age>2</age></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testSerialiseResourceWithDoubleBarrelledRelatedLinks() throws Exception {
// the test key
OEntityKey entityKey = OEntityKey.create("123");
// the test properties
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
// the test links
/*
* Not sure, but I think relatedEntity and link are the same thing in an OEntity.
* However, a relatedEntity also has the relatedEntityInline capability.
* TODO add tests for 'inline' links
*/
List<Link> links = new ArrayList<Link>();
links.add(mockLink("father", "_person edit", "humans/31", null));
links.add(mockLink("mother", "_person edit", "humans/32", null));
links.add(mockLink("siblings", "_family", "humans/phetheans", null));
OEntity entity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
EntityResource<OEntity> er = new EntityResource<OEntity>(entity);
er.setEntityName("Children");
er.setLinks(links);
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc/"));
hp.setUriInfo(mockUriInfo);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
hp.writeTo(er, EntityResource.class, OEntity.class, null, MediaType.APPLICATION_HAL_XML_TYPE, null, bos);
String expectedXML = "<resource href=\"http://www.temenos.com/rest.svc/\">"
+ "<link href=\"humans/phetheans\" rel=\"_family\" name=\"siblings\" title=\"siblings\"/><link href=\"humans/31\" rel=\"_person\" name=\"father\" title=\"father\"/><link href=\"humans/32\" rel=\"_person\" name=\"mother\" title=\"mother\"/>"
+ "<link rel=\"edit\" href=\"humans/31\" name=\"father\" title=\"father\" /><link rel=\"edit\" href=\"humans/32\" name=\"mother\" title=\"mother\" />"
+ "<name>noah</name><age>2</age></resource>";
String responseString = createFlatXML(bos);
Diff diff = new Diff(expectedXML, responseString);
// don't worry about the order of the elements in the xml
assertTrue(diff.similar());
}
@Test
public void testBuildMapFromOEntity() {
HALProvider hp = new HALProvider(createMockChildVocabMetadata());
/*
* create an OEntity with more properties than the
* supplied metadata. The point is that we should only
* fill the map with the defined entities properties.
*/
OEntityKey entityKey = OEntityKey.create("123");
List<OProperty<?>> properties = new ArrayList<OProperty<?>>();
properties.add(OProperties.string("name", "noah"));
properties.add(OProperties.string("age", "2"));
properties.add(OProperties.string("shoeSize", "5"));
OEntity entity = OEntities.create(createMockChildrenEntitySet(), entityKey, properties, new ArrayList<OLink>());
// map of property name to value object
Map<String, Object> map = new HashMap<String, Object>();
hp.buildFromOEntity(map, entity, "Children");
assertEquals(2, map.keySet().size());
assertTrue(map.keySet().contains("name"));
assertTrue(map.keySet().contains("age"));
assertEquals("noah", map.get("name"));
assertEquals("2", map.get("age"));
}
@Test
public void testSerialiseResourceWithForm() {
// don't know how to deal with forms yet, possibly embed an xform
}
@Test
public void testSerialiseStreamingResource() {
// cannot decorate a streaming resource so should fail
}
@Test
public void testDeserialiseResourceWithSelfLinkDifferentFromRequestedResourceLinkForApplicationJson() throws IOException, URISyntaxException {
EntityResource<Entity> er = runDeserialiseResourceWithLinks(javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE, "http://www.temenos.com/rest.svc/name", "/children");
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@Test
public void testDeserialiseResourceWithSelfLinkDifferentFromRequestedResourceLinkForApplicationHalJson() throws IOException, URISyntaxException {
EntityResource<Entity> er = runDeserialiseResourceWithLinks(MediaType.APPLICATION_HAL_JSON_TYPE, "http://www.temenos.com/rest.svc/name", "/children");
assertNotNull(er.getEntity());
Entity entity = er.getEntity();
assertEquals("Children", entity.getName());
}
@SuppressWarnings("unchecked")
private EntityResource<Entity> runDeserialiseResourceWithLinks(javax.ws.rs.core.MediaType mediaType, String selfLink, String targetResource) throws IOException, URISyntaxException {
ResourceStateMachine sm = new ResourceStateMachine(new ResourceState("Children", "initial", new ArrayList<Action>(), targetResource));
HALProvider hp = new HALProvider(createMockChildVocabMetadata(), new DefaultResourceStateProvider(sm));
UriInfo mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getBaseUri()).thenReturn(new URI("http://www.temenos.com/rest.svc"));
when(mockUriInfo.getPath()).thenReturn(targetResource);
hp.setUriInfo(mockUriInfo);
Request requestContext = mock(Request.class);
when(requestContext.getMethod()).thenReturn("GET");
hp.setRequestContext(requestContext);
String strEntityStream = "{ \"_links\": { \"self\": { \"href\": \"" + selfLink + "\" } }, \"name\": \"noah\", \"age\": 2 }";
InputStream entityStream = new ByteArrayInputStream(strEntityStream.getBytes());
GenericEntity<EntityResource<Entity>> ge = new GenericEntity<EntityResource<Entity>>(new EntityResource<Entity>()) {};
EntityResource<Entity> er = (EntityResource<Entity>) hp.readFrom(RESTResource.class, ge.getType(), null, mediaType, null, entityStream);
return er;
}
private EdmEntitySet createMockChildrenEntitySet() {
// mock a simple entity (Children entity set)
List<EdmProperty.Builder> eprops = new ArrayList<EdmProperty.Builder>();
eprops.add(EdmProperty.newBuilder("ID").setType(EdmSimpleType.STRING));
eprops.add(EdmProperty.newBuilder("name").setType(EdmSimpleType.STRING));
eprops.add(EdmProperty.newBuilder("age").setType(EdmSimpleType.STRING));
EdmEntityType.Builder eet = EdmEntityType.newBuilder().setNamespace("InteractionTest").setName("Children").addKeys(Arrays.asList("ID")).addProperties(eprops);
EdmEntitySet.Builder ees = EdmEntitySet.newBuilder().setName("Children").setEntityType(eet);
return ees.build();
}
}