http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java new file mode 100644 index 0000000..9615caa --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/ProducerConsumerIntegrationTest.java @@ -0,0 +1,811 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.olingo.odata2.api.batch.BatchException; +import org.apache.olingo.odata2.api.batch.BatchResponsePart; +import org.apache.olingo.odata2.api.client.batch.BatchChangeSet; +import org.apache.olingo.odata2.api.client.batch.BatchChangeSetPart; +import org.apache.olingo.odata2.api.client.batch.BatchPart; +import org.apache.olingo.odata2.api.client.batch.BatchSingleResponse; +import org.apache.olingo.odata2.api.commons.HttpStatusCodes; +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.edm.EdmFunctionImport; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.api.ep.feed.ODataDeltaFeed; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.api.exception.ODataException; +import org.apache.olingo.odata2.api.processor.ODataResponse; +import org.apache.olingo.odata2.client.api.ODataClient; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.Entity; +import org.apache.olingo.odata2.client.api.ep.EntityCollection; +import org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.core.batch.v2.BatchLineReader; +import org.apache.olingo.odata2.core.batch.v2.BatchParser; +import org.apache.olingo.odata2.core.batch.v2.Line; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +public class ProducerConsumerIntegrationTest { + protected static final URI BASE_URI; + private static final String PUT = "PUT"; + private static final String BOUNDARY = "batch_123"; + private static final Object CRLF = "\r\n"; + + static { + try { + BASE_URI = new URI("http://host:80/service/"); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + } + private static final DeserializerProperties DEFAULT_READ_PROPERTIES + = DeserializerProperties.init() + .build(); + private static final EntitySerializerProperties DEFAULT_WRITE_PROPERTIES + = EntitySerializerProperties + .serviceRoot( + BASE_URI).build(); + private static final String XML = "application/xml"; + private static final String JSON = "application/json"; + + @Test + public void produceRoomAndThenConsumeIt() throws Exception { + EdmEntitySet roomSet = MockFacade.getMockEdm() + .getDefaultEntityContainer().getEntitySet("Rooms"); + Entity localRoomData = new Entity(); + localRoomData.addProperty("Id", "1"); + localRoomData.addProperty("Name", "Neu \n Schwansteinè´è¶"); + + Map<String, Object> properties = execute(localRoomData, roomSet, XML); + assertEquals("1", properties.get("Id")); + assertEquals("Neu \n Schwansteinè´è¶", properties.get("Name")); + + Map<String, Object> properties2 = execute(localRoomData, roomSet, JSON); + assertEquals("1", properties2.get("Id")); + assertEquals("Neu \n Schwansteinè´è¶", properties2.get("Name")); + } + + @Test + public void produceRoomFeedAndThenConsumeIt() throws Exception { + EdmEntitySet roomSet = MockFacade.getMockEdm() + .getDefaultEntityContainer().getEntitySet("Rooms"); + EntityCollection roomsData = new EntityCollection(); + Entity localRoomData = new Entity(); + localRoomData.addProperty("Id", "1"); + localRoomData.addProperty("Name", "Neu \n Schwansteinè´è¶"); + roomsData.addEntity(localRoomData); + + localRoomData = new Entity(); + localRoomData.addProperty("Id", "2"); + localRoomData.addProperty("Name", "Johnè´è¶"); + roomsData.addEntity(localRoomData); + + List<Map<String, Object>> entries = execute1(roomsData, roomSet, XML); + validateResults(entries); + + entries = execute1(roomsData, roomSet, JSON); + validateResults(entries); + } + + @Test(expected=EntityProviderException.class) + public void negativeTests() throws Exception { + EdmEntitySet roomSet = MockFacade.getMockEdm() + .getDefaultEntityContainer().getEntitySet("Rooms"); + Entity localRoomData = new Entity(); + localRoomData.addProperty("Id", "1"); + localRoomData.addProperty("Name", "Neu \n Schwansteinè´è¶"); + + Map<String, Object> properties = execute(localRoomData, roomSet, "abc"); + assertEquals("1", properties.get("Id")); + assertEquals("Neu \n Schwansteinè´è¶", properties.get("Name")); + } + + @Test(expected=EntityProviderException.class) + public void negativeTestsDeserializer() throws Exception { + EdmEntitySet roomSet = MockFacade.getMockEdm() + .getDefaultEntityContainer().getEntitySet("Rooms"); + Entity localRoomData = new Entity(); + localRoomData.addProperty("Id", "1"); + localRoomData.addProperty("Name", "Neu \n Schwansteinè´è¶"); + + Map<String, Object> properties = executeFail(localRoomData, roomSet, "abc"); + assertEquals("1", properties.get("Id")); + assertEquals("Neu \n Schwansteinè´è¶", properties.get("Name")); + } + + /** + * @param entries + */ + private void validateResults(List<Map<String, Object>> entries) { + for (Map<String, Object> entryProperties : entries) { + for (Entry<String, Object> properties : entryProperties.entrySet()) { + if (properties.getKey().equals("Id")) { + assertTrue(properties.getValue().toString().contains("1") || + properties.getValue().toString().contains("2")); + } else { + assertTrue(properties.getValue().toString().contains("Neu \n Schwansteinè´è¶") || + properties.getValue().toString().contains("Johnè´è¶")); + } + } + } + } + + private Map<String, Object> execute(final Entity localRoomData, final EdmEntitySet roomSet, + final String contentType) + throws ODataException { + localRoomData.setWriteProperties(DEFAULT_WRITE_PROPERTIES); + ODataResponse response = ODataClient.newInstance().createSerializer(contentType) + .writeEntry(roomSet, localRoomData); + InputStream content = response.getEntityAsStream(); + EntityStream entityContent = new EntityStream(); + entityContent.setReadProperties(DEFAULT_READ_PROPERTIES); + entityContent.setContent(content); + ODataEntry entry = ODataClient.newInstance() + .createDeserializer(contentType).readEntry(roomSet, entityContent); + Map<String, Object> properties = entry.getProperties(); + return properties; + } + + private Map<String, Object> executeFail(final Entity localRoomData, final EdmEntitySet roomSet, + final String contentType) + throws ODataException { + localRoomData.setWriteProperties(DEFAULT_WRITE_PROPERTIES); + ODataResponse response = ODataClient.newInstance().createSerializer(XML) + .writeEntry(roomSet, localRoomData); + InputStream content = response.getEntityAsStream(); + EntityStream entityContent = new EntityStream(); + entityContent.setReadProperties(DEFAULT_READ_PROPERTIES); + entityContent.setContent(content); + ODataEntry entry = ODataClient.newInstance() + .createDeserializer(contentType).readEntry(roomSet, entityContent); + Map<String, Object> properties = entry.getProperties(); + return properties; + } + + private List<Map<String, Object>> execute1(final EntityCollection localRoomData, final EdmEntitySet roomSet, + final String contentType) + throws ODataException { + List<Map<String, Object>> propertiesList = new ArrayList<Map<String,Object>>(); + localRoomData.setCollectionProperties(EntityCollectionSerializerProperties.serviceRoot(BASE_URI).build()); + ODataResponse response = ODataClient.newInstance().createSerializer(contentType) + .writeFeed(roomSet, localRoomData); + InputStream content = response.getEntityAsStream(); + EntityStream entityContent = new EntityStream(); + entityContent.setReadProperties(DEFAULT_READ_PROPERTIES); + entityContent.setContent(content); + ODataFeed feed = ODataClient.newInstance() + .createDeserializer(contentType).readFeed(roomSet, entityContent); + List<ODataEntry> entries = feed.getEntries(); + for (ODataEntry entry : entries) { + propertiesList.add(entry.getProperties()); + } + return propertiesList; + } + + + @Test + public void executeWriteBatchRequestJSON() throws IOException, + EntityProviderException, BatchException, URISyntaxException { + List<BatchPart> batch = new ArrayList<BatchPart>(); + Map<String, String> headers = new HashMap<String, String>(); + headers.put("content-type", "application/json"); + BatchChangeSetPart request = BatchChangeSetPart.method(PUT) + .uri("Employees('2')") + .body("{\"Age\":40}") + .headers(headers) + .contentId("111") + .build(); + BatchChangeSet changeSet = BatchChangeSet.newBuilder().build(); + changeSet.add(request); + batch.add((BatchPart) changeSet); + + InputStream batchRequest = ODataClient.newInstance().createSerializer(JSON). + readBatchRequest(batch, BOUNDARY); + validateBatchRequest(batchRequest); + } + + private void validateBatchRequest(InputStream batchRequest) throws IOException { + BatchLineReader reader = + new BatchLineReader(batchRequest); + List<Line> lines = reader.toLineList(); + reader.close(); + int index = 0; + + assertTrue(lines.get(index++).toString().startsWith("--batch")); + assertTrue(lines.get(index++).toString().startsWith("Content-Type: multipart/mixed; boundary=changeset_")); + assertEquals(CRLF, lines.get(index++).toString()); + assertTrue(lines.get(index++).toString().startsWith("--changeset")); + assertEquals("Content-Type: application/http" + CRLF, lines.get(index++).toString()); + assertEquals("Content-Transfer-Encoding: binary" + CRLF, lines.get(index++).toString()); + assertEquals("Content-Id: 111" + CRLF, lines.get(index++).toString()); + assertEquals(CRLF, lines.get(index++).toString()); + assertEquals("PUT Employees('2') HTTP/1.1" + CRLF, lines.get(index++).toString()); + assertEquals("Content-Length: 10" + CRLF, lines.get(index++).toString()); + assertEquals("content-type: application/json" + CRLF, lines.get(index++).toString()); + assertEquals(CRLF, lines.get(index++).toString()); + assertEquals("{\"Age\":40}" + CRLF, lines.get(index++).toString()); + assertTrue(lines.get(index++).toString().startsWith("--changeset")); + assertTrue(lines.get(index++).toString().startsWith("--batch")); + } + + @Test + public void executeWriteBatchResponseJSON() throws BatchException, EntityProviderException { + List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>(); + ODataResponse response = ODataResponse.entity("Walter Winter") + .status(HttpStatusCodes.OK) + .contentHeader("application/json") + .build(); + List<ODataResponse> responses = new ArrayList<ODataResponse>(1); + responses.add(response); + parts.add(BatchResponsePart.responses(responses).changeSet(false).build()); + + ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build(); + responses = new ArrayList<ODataResponse>(1); + responses.add(changeSetResponse); + parts.add(BatchResponsePart.responses(responses).changeSet(true).build()); + + ODataResponse batchResponse = ODataClient.newInstance().createDeserializer(JSON).writeBatchResponse(parts); + assertEquals(202, batchResponse.getStatus().getStatusCode()); + assertNotNull(batchResponse.getEntity()); + String body = (String) batchResponse.getEntity(); + + assertTrue(body.contains("--batch")); + assertTrue(body.contains("--changeset")); + assertTrue(body.contains("HTTP/1.1 200 OK")); + assertTrue(body.contains("Content-Type: application/http")); + assertTrue(body.contains("Content-Transfer-Encoding: binary")); + assertTrue(body.contains("Walter Winter")); + assertTrue(body.contains("multipart/mixed; boundary=changeset")); + assertTrue(body.contains("HTTP/1.1 204 No Content")); + + String contentHeader = batchResponse.getContentHeader(); + BatchParser parser = new BatchParser(contentHeader, true); + List<BatchSingleResponse> result = parser.parseBatchResponse(new ByteArrayInputStream(body.getBytes())); + assertEquals(2, result.size()); + } + + @Test + public void readFunctionImportJOSNSimpleProperty1() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("MaximalAge"); + InputStream content = new ByteArrayInputStream("{\"d\":{\"MaximalAge\":42}}".getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + assertEquals((short) 42, result); + } + + @Test + public void readFunctionImportXMLSimpleProperty() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("MaximalAge"); + InputStream content = new ByteArrayInputStream(( + "<?xml version='1.0' encoding='utf-8'?>" + + "<MaximalAge xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" " + + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">" + + "42</MaximalAge>").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, XML); + assertEquals((short) 42, result); + } + + @Test + public void readFunctionImportJOSNSimpleProperty2() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("MaximalAge"); + InputStream content = new ByteArrayInputStream("{\"MaximalAge\":42}".getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + assertEquals((short) 42, result); + } + + @SuppressWarnings("unchecked") + @Test + public void readFunctionImportJSONCollectionOfComplexProperty1() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllLocations"); + InputStream content = new ByteArrayInputStream(( + "{\"results\": [{\"City\": {\"PostalCode\":\"56\",\"CityName\":\"Bangalore\"}," + + "\"Country\": \"India\"}]}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + List<Map<String, Object>> res = (List<Map<String, Object>>) result; + assertEquals(1, res.size()); + assertEquals("India", ((HashMap<String, Object>)res.get(0)).get("Country")); + assertEquals(2, ((Map<String, Object>)((Map<String, Object>)res.get(0)).get("City")).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void readFunctionImportJSONCollectionOfComplexProperty2() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllLocations"); + InputStream content = new ByteArrayInputStream(( + "{\"d\":{\"results\": [{\"City\": {\"PostalCode\":\"56\",\"CityName\":\"Bangalore\"}," + + "\"Country\": \"India\"}]}}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + List<Map<String, Object>> res = (List<Map<String, Object>>) result; + assertEquals(1, res.size()); + assertEquals("India", ((HashMap<String, Object>)res.get(0)).get("Country")); + assertEquals(2, ((Map<String, Object>)((Map<String, Object>)res.get(0)).get("City")).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void readFunctionImportXMLCollectionOfComplexProperty() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("AllLocations"); + InputStream content = new ByteArrayInputStream(( + "<?xml version='1.0' encoding='utf-8'?>" + + "<AllLocations xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" " + + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">" + + "<element m:type=\"RefScenario.c_Location\">" + + "<City m:type=\"RefScenario.c_City\">" + + "<PostalCode>69124</PostalCode>" + + "<CityName>Heidelberg</CityName>" + + "</City>" + + "<Country>Germany</Country>" + + "</element>" + + "<element m:type=\"RefScenario.c_Location\">" + + "<City m:type=\"RefScenario.c_City\">" + + "<PostalCode>69190</PostalCode>" + + "<CityName>Walldorf</CityName>" + + "</City>" + + "<Country>Germany</Country>" + + "</element>" + + "</AllLocations>").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, XML); + List<Map<String, Object>> res = (List<Map<String, Object>>) result; + assertEquals(2, res.size()); + assertEquals("Germany", ((HashMap<String, Object>)res.get(0)).get("Country")); + assertEquals(2, ((Map<String, Object>)((Map<String, Object>)res.get(0)).get("City")).size()); + } + + @Test + public void readFunctionImportJSONSingleEntity1() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("OldestEmployee"); + InputStream content = new ByteArrayInputStream( + ("{\"d\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.Employee\"," + + "\"content_type\": \"image/jpeg\"," + + "\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"," + + "\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"" + + "}," + + "\"EmployeeId\": \"3\"," + + "\"EmployeeName\": \"Jonathan Smith\"," + + "\"ManagerId\": \"1\"," + + "\"RoomId\": \"2\"," + + "\"TeamId\": \"1\"," + + "\"Location\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_Location\"" + + "}," + + "\"City\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_City\"" + + "}," + + "\"PostalCode\": \"69190\"," + + "\"CityName\": \"Walldorf\"" + + "}," + + "\"Country\": \"Germany\"" + + "}," + + "\"Age\": 56," + + "\"EntryDate\": null," + + "\"ImageUrl\": \"Employees('3')/$value\"," + + "\"ne_Manager\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\"" + + "}" + + "}," + + "\"ne_Team\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\"" + + "}" + + "}," + + "\"ne_Room\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\"" + + "}" + + "}" + + "}" + + "}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + ODataEntry entry = (ODataEntry) result; + assertEquals(9, entry.getProperties().size()); + assertEquals("3", entry.getProperties().get("EmployeeId")); + } + + @Test + public void readFunctionImportXMLSingleEntity() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("OldestEmployee"); + InputStream content = new ByteArrayInputStream( + ("<?xml version='1.0' encoding='utf-8'?>" + + "<entry xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" " + + "xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" " + + "xml:base=\"http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/\">" + + "<id>" + + "http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('3')" + + "</id>" + + "<title type=\"text\">Jonathan Smith</title>" + + "<updated>2017-10-26T09:06:41.15+05:30</updated>" + + "<category term=\"RefScenario.Employee\" " + + "scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>" + + "<link href=\"Employees('3')\" rel=\"edit\" title=\"Employee\"/>" + + "<link href=\"Employees('3')/$value\" rel=\"edit-media\" " + + "type=\"image/jpeg\"/><link href=\"Employees('3')/ne_Manager\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\" " + + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('3')/ne_Team\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\" " + + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('3')/ne_Room\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\" " + + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>" + + "<content type=\"image/jpeg\" src=\"Employees('3')/$value\"/>" + + "<m:properties><d:EmployeeId>3</d:EmployeeId>" + + "<d:EmployeeName>Jonathan Smith</d:EmployeeName>" + + "<d:ManagerId>1</d:ManagerId><d:RoomId>2</d:RoomId>" + + "<d:TeamId>1</d:TeamId><d:Location m:type=\"RefScenario.c_Location\">" + + "<d:City m:type=\"RefScenario.c_City\"><d:PostalCode>69190</d:PostalCode>" + + "<d:CityName>Walldorf</d:CityName></d:City><d:Country>Germany</d:Country>" + + "</d:Location><d:Age>56</d:Age><d:EntryDate m:null=\"true\"/>" + + "<d:ImageUrl>Employees('3')/$value</d:ImageUrl>" + + "</m:properties></entry>").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, XML); + ODataEntry entry = (ODataEntry) result; + assertEquals(9, entry.getProperties().size()); + assertEquals("3", entry.getProperties().get("EmployeeId")); + assertEquals("Employees('3')/ne_Manager", entry.getMetadata().getAssociationUris("ne_Manager").get(0)); + assertEquals("http://localhost:8083/olingo-odata2-ref-web/" + + "ReferenceScenarioNonJaxrs.svc/Employees('3')", entry.getMetadata().getId()); + } + + @Test + public void readFunctionImportJSONSingleEntity2() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("OldestEmployee"); + InputStream content = new ByteArrayInputStream( + ("{" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.Employee\"," + + "\"content_type\": \"image/jpeg\"," + + "\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"," + + "\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"" + + "}," + + "\"EmployeeId\": \"3\"," + + "\"EmployeeName\": \"Jonathan Smith\"," + + "\"ManagerId\": \"1\"," + + "\"RoomId\": \"2\"," + + "\"TeamId\": \"1\"," + + "\"Location\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_Location\"" + + "}," + + "\"City\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_City\"" + + "}," + + "\"PostalCode\": \"69190\"," + + "\"CityName\": \"Walldorf\"" + + "}," + + "\"Country\": \"Germany\"" + + "}," + + "\"Age\": 56," + + "\"EntryDate\": null," + + "\"ImageUrl\": \"Employees('3')/$value\"," + + "\"ne_Manager\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\"" + + "}" + + "}," + + "\"ne_Team\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\"" + + "}" + + "}," + + "\"ne_Room\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\"" + + "}" + + "}" + + "}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + ODataEntry entry = (ODataEntry) result; + assertEquals(9, entry.getProperties().size()); + assertEquals("3", entry.getProperties().get("EmployeeId")); + } + + @Test + public void readMultipleEntityJSONFunctionImport1() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("EmployeeSearch"); + InputStream content = new ByteArrayInputStream( + ("{\"d\": {" + + "\"results\": [{" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.Employee\"," + + "\"content_type\": \"image/jpeg\"," + + "\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"," + + "\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"" + + "}," + + "\"EmployeeId\": \"3\"," + + "\"EmployeeName\": \"Jonathan Smith\"," + + "\"ManagerId\": \"1\"," + + "\"RoomId\": \"2\"," + + "\"TeamId\": \"1\"," + + "\"Location\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_Location\"" + + "}," + + "\"City\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_City\"" + + "}," + + "\"PostalCode\": \"69190\"," + + "\"CityName\": \"Walldorf\"" + + "}," + + "\"Country\": \"Germany\"" + + "}," + + "\"Age\": 56," + + "\"EntryDate\": null," + + "\"ImageUrl\": \"Employees('3')/$value\"," + + "\"ne_Manager\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\"" + + "}" + + "}," + + "\"ne_Team\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\"" + + "}" + + "}," + + "\"ne_Room\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\"" + + "}" + + "}" + + "}]" + + "}" + + "}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + ODataDeltaFeed feed = (ODataDeltaFeed) result; + List<ODataEntry> entries = feed.getEntries(); + int size = entries.size(); + assertEquals(1, size); + String id = (String) entries.get(0).getProperties().get("EmployeeId"); + assertEquals("3", id); + } + + @Test + public void readMultipleEntityJSONFunctionImport2() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("EmployeeSearch"); + InputStream content = new ByteArrayInputStream( + ("{" + + "\"results\": [{" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.Employee\"," + + "\"content_type\": \"image/jpeg\"," + + "\"media_src\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"," + + "\"edit_media\":\"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/$value\"" + + "}," + + "\"EmployeeId\": \"3\"," + + "\"EmployeeName\": \"Jonathan Smith\"," + + "\"ManagerId\": \"1\"," + + "\"RoomId\": \"2\"," + + "\"TeamId\": \"1\"," + + "\"Location\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_Location\"" + + "}," + + "\"City\": {" + + "\"__metadata\": {" + + "\"type\": \"RefScenario.c_City\"" + + "}," + + "\"PostalCode\": \"69190\"," + + "\"CityName\": \"Walldorf\"" + + "}," + + "\"Country\": \"Germany\"" + + "}," + + "\"Age\": 56," + + "\"EntryDate\": null," + + "\"ImageUrl\": \"Employees('3')/$value\"," + + "\"ne_Manager\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Manager\"" + + "}" + + "}," + + "\"ne_Team\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Team\"" + + "}" + + "}," + + "\"ne_Room\": {" + + "\"__deferred\": {" + + "\"uri\": \"http://localhost:19000/abc/FunctionImportJsonTest/Employees('3')/ne_Room\"" + + "}" + + "}" + + "}]" + + "}").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + final Object result = executeFunctionImport(functionImport, entityStream, JSON); + ODataDeltaFeed feed = (ODataDeltaFeed) result; + List<ODataEntry> entries = feed.getEntries(); + int size = entries.size(); + assertEquals(1, size); + String id = (String) entries.get(0).getProperties().get("EmployeeId"); + assertEquals("3", id); + } + + @SuppressWarnings("unchecked") + @Test + public void readMultipleEntityXMLFunctionImport() throws Exception { + final EdmFunctionImport functionImport = MockFacade.getMockEdm().getDefaultEntityContainer() + .getFunctionImport("EmployeeSearch"); + InputStream content = new ByteArrayInputStream( + ("<?xml version='1.0' encoding='utf-8'?>" + + "<feed xmlns=\"http://www.w3.org/2005/Atom\" " + + "xmlns:m=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\" " + + "xmlns:d=\"http://schemas.microsoft.com/ado/2007/08/dataservices\" " + + "xml:base=\"http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/\">" + + "<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees</id>" + + "<title type=\"text\">Employees</title><updated>2017-10-26T09:17:27.113+05:30</updated>" + + "<author><name/></author><link href=\"Employees\" rel=\"self\" title=\"Employees\"/>" + + "<entry>" + + "<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('1')</id>" + + "<title type=\"text\">Walter Winter</title>" + + "<updated>1999-01-01T00:00:00Z</updated><category term=\"RefScenario.Employee\" " + + "scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>" + + "<link href=\"Employees('1')\" rel=\"edit\" title=\"Employee\"/>" + + "<link href=\"Employees('1')/$value\" rel=\"edit-media\" type=\"image/jpeg\"/>" + + "<link href=\"Employees('1')/ne_Manager\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\" " + + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('1')/ne_Team\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\" " + + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('1')/ne_Room\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\" " + + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>" + + "<content type=\"image/jpeg\" src=\"Employees('1')/$value\"/>" + + "<m:properties><d:EmployeeId>1</d:EmployeeId>" + + "<d:EmployeeName>Walter Winter</d:EmployeeName>" + + "<d:ManagerId>1</d:ManagerId><d:RoomId>1</d:RoomId><d:TeamId>1</d:TeamId>" + + "<d:Location m:type=\"RefScenario.c_Location\"><d:City m:type=\"RefScenario.c_City\">" + + "</d:City>" + + "<d:Country>Germany</d:Country></d:Location><d:Age>52</d:Age>" + + "<d:EntryDate>1999-01-01T00:00:00</d:EntryDate>" + + "<d:ImageUrl>Employees('1')/$value</d:ImageUrl>" + + "</m:properties></entry>" + + "<entry>" + + "<id>http://localhost:8083/olingo-odata2-ref-web/ReferenceScenarioNonJaxrs.svc/Employees('2')</id>" + + "<title type=\"text\">Frederic Fall</title>" + + "<updated>2003-07-01T00:00:00Z</updated>" + + "<category term=\"RefScenario.Employee\" " + + "scheme=\"http://schemas.microsoft.com/ado/2007/08/dataservices/scheme\"/>" + + "<link href=\"Employees('2')\" rel=\"edit\" title=\"Employee\"/>" + + "<link href=\"Employees('2')/$value\" rel=\"edit-media\" " + + "type=\"image/jpeg\"/><link href=\"Employees('2')/ne_Manager\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Manager\" " + + "title=\"ne_Manager\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('2')/ne_Team\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Team\" " + + "title=\"ne_Team\" type=\"application/atom+xml;type=entry\"/>" + + "<link href=\"Employees('2')/ne_Room\" " + + "rel=\"http://schemas.microsoft.com/ado/2007/08/dataservices/related/ne_Room\" " + + "title=\"ne_Room\" type=\"application/atom+xml;type=entry\"/>" + + "<content type=\"image/jpeg\" src=\"Employees('2')/$value\"/>" + + "<m:properties><d:EmployeeId>2</d:EmployeeId>" + + "<d:EmployeeName>Frederic Fall</d:EmployeeName>" + + "<d:ManagerId>1</d:ManagerId><d:RoomId>2</d:RoomId>" + + "<d:TeamId>1</d:TeamId>" + + "<d:Location m:type=\"RefScenario.c_Location\" m:null=\"true\">" + + "</d:Location><d:Age>32</d:Age>" + + "<d:EntryDate>2003-07-01T00:00:00</d:EntryDate>" + + "</m:properties></entry></feed>").getBytes("UTF-8")); + EntityStream entityStream = new EntityStream(); + entityStream.setReadProperties(DEFAULT_READ_PROPERTIES); + entityStream.setContent(content); + final Object result = executeFunctionImport(functionImport, entityStream, XML); + ODataDeltaFeed feed = (ODataDeltaFeed) result; + List<ODataEntry> entries = feed.getEntries(); + int size = entries.size(); + assertEquals(2, size); + assertEquals(9, entries.get(0).getProperties().size()); + assertEquals(8, entries.get(1).getProperties().size()); + assertEquals(0, ((Map<String, Object>) + ((Map<String, Object>)entries.get(0).getProperties().get("Location")).get("City")).size()); + assertEquals(null, entries.get(1).getProperties().get("Location")); + String id = (String) entries.get(0).getProperties().get("EmployeeId"); + assertEquals("1", id); + } + + /** + * @param functionImport + * @param entityStream + * @return + * @throws EntityProviderException + */ + private Object executeFunctionImport(final EdmFunctionImport functionImport, + EntityStream entityStream, String contentType) + throws EntityProviderException { + return ODataClient.newInstance(). + createDeserializer(contentType).readFunctionImport(functionImport, entityStream); + } +}
http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java new file mode 100644 index 0000000..32ec72c --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/SerializerPropertiesTest.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.olingo.odata2.client.api.ep.EntityCollectionSerializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntitySerializerProperties; +import org.apache.olingo.odata2.testutil.fit.BaseTest; +import org.junit.Test; + +/** + * + */ +public class SerializerPropertiesTest extends BaseTest { + + @Test + public void buildFeedProperties() throws Exception { + URI serviceRoot = new URI("http://localhost:80/"); + EntitySerializerProperties properties = EntitySerializerProperties.serviceRoot(serviceRoot) + .build(); + + assertEquals("Wrong base uri.", "http://localhost:80/", properties.getServiceRoot().toASCIIString()); + } + + @Test + public void buildPropertiesDefault() throws Exception { + URI serviceRoot = new URI("http://localhost:80/"); + final EntitySerializerProperties properties + = EntitySerializerProperties.serviceRoot(serviceRoot).build(); + + assertFalse(properties.isIncludeMetadata()); + assertTrue(properties.isValidatingFacets()); + } + + @Test + public void buildPropertiesAllSet() throws Exception { + URI serviceRoot = new URI("http://localhost:80/"); + Map<String, Map<String, Object>> links = new HashMap<String, Map<String, Object>>(); + links.put("aNavigationProperty", Collections.<String, Object> emptyMap()); + final EntitySerializerProperties properties = EntitySerializerProperties + .serviceRoot(serviceRoot) + .includeMetadata(true) + .validatingFacets(false) + .build(); + + assertEquals("Wrong base uri.", "http://localhost:80/", properties.getServiceRoot().toASCIIString()); + assertTrue("Metadata in content should be set", properties.isIncludeMetadata()); + assertFalse("validating facets should be not set", properties.isValidatingFacets()); + } + + @Test + public void buildPropertiesForEntityCollectionAllSet() throws Exception { + URI serviceRoot = new URI("http://localhost:80/"); + URI selfLink = new URI("http://some.uri"); + final EntityCollectionSerializerProperties properties = + EntityCollectionSerializerProperties.serviceRoot(serviceRoot) + .selfLink(selfLink) + .build(); + + assertEquals("Wrong base uri.", "http://localhost:80/", properties.getServiceRoot().toASCIIString()); + assertEquals(selfLink, properties.getSelfLink()); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java new file mode 100644 index 0000000..df82949 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractDeserializerTest.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.edm.EdmException; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.api.exception.ODataException; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.testutil.fit.BaseTest; +import org.apache.olingo.odata2.testutil.mock.MockFacade; + +/** + * + */ +public abstract class AbstractDeserializerTest extends BaseTest { + + protected static final DeserializerProperties DEFAULT_PROPERTIES = DeserializerProperties.init() + .build(); + + protected XMLStreamReader createReaderForTest(final String input) throws XMLStreamException { + return createReaderForTest(input, false); + } + + protected XMLStreamReader createReaderForTest(final String input, final boolean namespaceAware) + throws XMLStreamException { + XMLInputFactory factory = XMLInputFactory.newInstance(); + factory.setProperty(XMLInputFactory.IS_VALIDATING, false); + factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, namespaceAware); + + XMLStreamReader streamReader = factory.createXMLStreamReader(new StringReader(input)); + + return streamReader; + } + + protected Map<String, Object> createTypeMappings(final String key, final Object value) { + Map<String, Object> typeMappings = new HashMap<String, Object>(); + typeMappings.put(key, value); + return typeMappings; + } + + protected InputStream getFileAsStream(final String filename) throws IOException { + InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename); + if (in == null) { + throw new IOException("Requested file '" + filename + "' was not found."); + } + return in; + } + + protected String readFile(final String filename) throws IOException { + InputStream in = getFileAsStream(filename); + + byte[] tmp = new byte[8192]; + int count = in.read(tmp); + StringBuilder b = new StringBuilder(); + while (count >= 0) { + b.append(new String(tmp, 0, count)); + count = in.read(tmp); + } + + return b.toString(); + } + + /** + * Create a map with a 'String' to 'Class<?>' mapping based on given parameters. + * Therefore parameters MUST be a set of such pairs. + * As example an correct method call would be: + * <p> + * <code> + * createTypeMappings("someKey", Integer.class, "anotherKey", Long.class); + * </code> + * </p> + * + * @param firstKeyThenMappingClass + * @return + */ + protected Map<String, Object> createTypeMappings(final Object... firstKeyThenMappingClass) { + Map<String, Object> typeMappings = new HashMap<String, Object>(); + if (firstKeyThenMappingClass.length % 2 != 0) { + throw new IllegalArgumentException("Got odd number of parameters. Please read javadoc."); + } + for (int i = 0; i < firstKeyThenMappingClass.length; i += 2) { + String key = (String) firstKeyThenMappingClass[i]; + Class<?> mappingClass = (Class<?>) firstKeyThenMappingClass[i + 1]; + typeMappings.put(key, mappingClass); + } + return typeMappings; + } + + protected InputStream createContentAsStream(final String content) throws UnsupportedEncodingException { + return new ByteArrayInputStream(content.getBytes("UTF-8")); + } + + /** + * + * @param content + * @param replaceWhitespaces if <code>true</code> all XML not necessary whitespaces between tags are + * @return + * @throws UnsupportedEncodingException + */ + protected InputStream createContentAsStream(final String content, final boolean replaceWhitespaces) + throws UnsupportedEncodingException { + String contentForStream = content; + if (replaceWhitespaces) { + contentForStream = content.replaceAll(">\\s.<", "><"); + } + + return new ByteArrayInputStream(contentForStream.getBytes("UTF-8")); + } + + protected ODataEntry prepareAndExecuteEntry(final String fileName, final String entitySetName, + final DeserializerProperties readProperties) throws IOException, EdmException, ODataException, + UnsupportedEncodingException, EntityProviderException { + // prepare + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet(entitySetName); + String content = readFile(fileName); + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(readProperties); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = xec.readEntry(entitySet, entityStream); + assertNotNull(result); + return result; + } + + protected ODataFeed prepareAndExecuteFeed(final String fileName, final String entitySetName, + final DeserializerProperties readProperties) throws IOException, EdmException, ODataException, + UnsupportedEncodingException, EntityProviderException { + // prepare + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet(entitySetName); + String content = readFile(fileName); + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(readProperties); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataFeed result = xec.readFeed(entitySet, entityStream); + assertNotNull(result); + return result; + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java new file mode 100644 index 0000000..bfd3c6c --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/AbstractXmlDeserializerTest.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep.deserializer; + +import java.util.Arrays; +import java.util.List; + +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public abstract class AbstractXmlDeserializerTest extends AbstractDeserializerTest { + + public enum StreamWriterImplType { + WOODSTOCKIMPL, SUNINTERNALIMPL; + } + + // CHECKSTYLE:OFF + public AbstractXmlDeserializerTest(final StreamWriterImplType type) { + switch (type) { + case WOODSTOCKIMPL: + System.setProperty("javax.xml.stream.XMLInputFactory", "com.ctc.wstx.stax.WstxInputFactory"); // NOSONAR + System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory"); // NOSONAR + break; + case SUNINTERNALIMPL: + System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl"); // NOSONAR + System.setProperty("javax.xml.stream.XMLOutputFactory", "com.sun.xml.internal.stream.XMLOutputFactoryImpl"); // NOSONAR + break; + default: + System.setProperty("javax.xml.stream.XMLOutputFactory", "com.sun.xml.internal.stream.XMLOutputFactoryImpl"); // NOSONAR + System.setProperty("javax.xml.stream.XMLInputFactory", "com.sun.xml.internal.stream.XMLInputFactoryImpl"); // NOSONAR + break; + } + } + + // CHECKSTYLE:On + + @Parameterized.Parameters + public static List<Object[]> data() { + // If desired this can be made dependent on runtime variables + Object[][] a = new Object[2][1]; + a[0][0] = StreamWriterImplType.WOODSTOCKIMPL; + a[1][0] = StreamWriterImplType.SUNINTERNALIMPL; + + return Arrays.asList(a); + } +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java new file mode 100644 index 0000000..2d1bf91 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/Callback.java @@ -0,0 +1,21 @@ +package org.apache.olingo.odata2.client.core.ep.deserializer; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.olingo.odata2.api.edm.EdmNavigationProperty; +import org.apache.olingo.odata2.api.exception.ODataApplicationException; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.callback.OnDeserializeInlineContent; + +public class Callback implements OnDeserializeInlineContent { + + @Override + public DeserializerProperties receiveReadProperties(DeserializerProperties readProperties, + EdmNavigationProperty navigationProperty) throws ODataApplicationException { + Map<String, Object> typeMappings = new HashMap<String, Object>(); + return DeserializerProperties.init().addTypeMappings(typeMappings). + callback(new Callback()).build(); + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java new file mode 100644 index 0000000..d6f25a7 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertEntryTest.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.InputStream; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.edm.EdmMultiplicity; +import org.apache.olingo.odata2.api.edm.EdmNavigationProperty; +import org.apache.olingo.odata2.api.edm.EdmType; +import org.apache.olingo.odata2.api.edm.EdmTypeKind; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.client.api.ep.callback.OnDeserializeInlineContent; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +public class JsonEntryDeepInsertEntryTest extends AbstractDeserializerTest { + + private static final String EMPLOYEE_WITH_INLINE_TEAM = "JsonEmployeeWithInlineTeam.json"; + private static final String INLINE_ROOM_WITH_INLINE_BUILDING = "JsonInlineRoomWithInlineBuilding.json"; + private static final String INLINE_ROOM_WITH_INLINE_NULL = "JsonInlineRoomWithInlineNull.json"; + + @Test + public void innerEntryNoMediaResource() throws Exception { + ODataEntry outerEntry = prepareAndExecuteEntry(EMPLOYEE_WITH_INLINE_TEAM, "Employees", DEFAULT_PROPERTIES); + assertTrue(outerEntry.containsInlineEntry()); + + ODataEntry innerTeam = (ODataEntry) outerEntry.getProperties().get("ne_Team"); + assertNotNull(innerTeam); + assertFalse(innerTeam.containsInlineEntry()); + + Map<String, Object> innerTeamProperties = innerTeam.getProperties(); + + assertEquals("1", innerTeamProperties.get("Id")); + assertEquals("Team 1", innerTeamProperties.get("Name")); + assertEquals(Boolean.FALSE, innerTeamProperties.get("isScrumTeam")); + assertNull(innerTeamProperties.get("nt_Employees")); + + List<String> associationUris = innerTeam.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees", associationUris.get(0)); + } + + @Test + public void innerEntryWithOptionalNavigationProperty() throws Exception { + // prepare + DeserializerProperties readProperties = + DeserializerProperties.init().build(); + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + // modify edm for test case (change multiplicity to ZERO_TO_ONE) + EdmType navigationType = mock(EdmType.class); + when(navigationType.getKind()).thenReturn(EdmTypeKind.ENTITY); + + EdmNavigationProperty navigationProperty = mock(EdmNavigationProperty.class); + when(navigationProperty.getName()).thenReturn("ne_Team"); + when(navigationProperty.getType()).thenReturn(navigationType); + when(navigationProperty.getMultiplicity()).thenReturn(EdmMultiplicity.ZERO_TO_ONE); + + when(entitySet.getEntityType().getProperty("ne_Team")).thenReturn(navigationProperty); + EdmEntitySet targetEntitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + when(entitySet.getRelatedEntitySet(navigationProperty)).thenReturn(targetEntitySet); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + InputStream contentBody = getFileAsStream(EMPLOYEE_WITH_INLINE_TEAM); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(readProperties); + ODataEntry outerEntry = xec.readEntry(entitySet, entityStream); + + ODataEntry innerTeam = (ODataEntry) outerEntry.getProperties().get("ne_Team"); + Map<String, Object> innerTeamProperties = innerTeam.getProperties(); + + assertEquals("1", innerTeamProperties.get("Id")); + assertEquals("Team 1", innerTeamProperties.get("Name")); + assertEquals(Boolean.FALSE, innerTeamProperties.get("isScrumTeam")); + assertNull(innerTeamProperties.get("nt_Employees")); + + List<String> associationUris = innerTeam.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees", associationUris.get(0)); + } + + @Test + public void inlineRoomWithInlineBuilding() throws Exception { + OnDeserializeInlineContent callback = new Callback(); + DeserializerProperties readProperties = DeserializerProperties.init().callback(callback).build(); + ODataEntry outerEntry = prepareAndExecuteEntry(INLINE_ROOM_WITH_INLINE_BUILDING, "Employees", readProperties); + assertTrue(outerEntry.containsInlineEntry()); + + ODataEntry innerRoom = (ODataEntry) outerEntry.getProperties().get("ne_Room"); + assertNotNull(innerRoom); + assertTrue(innerRoom.containsInlineEntry()); + + Map<String, Object> innerRoomProperties = innerRoom.getProperties(); + + assertEquals(5, innerRoomProperties.size()); + assertEquals("1", innerRoomProperties.get("Id")); + assertEquals("Room 1", innerRoomProperties.get("Name")); + assertEquals(Short.valueOf("1"), innerRoomProperties.get("Version")); + assertEquals(Short.valueOf("1"), innerRoomProperties.get("Seats")); + assertNull(innerRoomProperties.get("nr_Employees")); + + List<String> associationUris = innerRoom.getMetadata().getAssociationUris("nr_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees", associationUris.get(0)); + + associationUris = innerRoom.getMetadata().getAssociationUris("nr_Building"); + assertEquals(Collections.emptyList(), associationUris); + + assertEquals("W/\"1\"", innerRoom.getMetadata().getEtag()); + + ODataEntry innerBuilding = (ODataEntry) innerRoomProperties.get("nr_Building"); + assertNotNull(innerBuilding); + assertFalse(innerBuilding.containsInlineEntry()); + + Map<String, Object> innerBuildingProperties = innerBuilding.getProperties(); + assertEquals(3, innerBuildingProperties.size()); + assertEquals("1", innerBuildingProperties.get("Id")); + assertEquals("Building 1", innerBuildingProperties.get("Name")); + assertEquals(null, innerBuildingProperties.get("Image")); + assertNull(innerBuildingProperties.get("nb_Rooms")); + + associationUris = innerBuilding.getMetadata().getAssociationUris("nb_Rooms"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Buildings('1')/nb_Rooms", associationUris.get(0)); + } + + @Test + public void inlineRoomWithInlineNull() throws Exception { + DeserializerProperties readProperties = + DeserializerProperties.init().build(); + ODataEntry outerEntry = prepareAndExecuteEntry(INLINE_ROOM_WITH_INLINE_NULL, "Employees", readProperties); + + ODataEntry innerRoom = (ODataEntry) outerEntry.getProperties().get("ne_Room"); + assertNull(innerRoom); + } + +} http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/9e949e40/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java new file mode 100644 index 0000000..b1a8d0b --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeepInsertFeedTest.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.olingo.odata2.client.core.ep.deserializer; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.api.ep.feed.FeedMetadata; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.client.core.ep.deserializer.JsonEntityDeserializer; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +/** + * + */ +public class JsonEntryDeepInsertFeedTest extends AbstractDeserializerTest { + + private static final String BUILDING_WITH_INLINE_ROOMS = "JsonBuildingWithInlineRooms.json"; + private static final String BUILDING_WITH_INLINE_ROOMS_CLIENT_CASE = "JsonBuildingWithInlineRoomsClientCase.json"; + private static final String TEAM_WITH_INLINE_EMPLOYEES = "JsonTeamsWithInlineEmployees.json"; + private static final String BUILDING_WITH_INLINE_ROOMS_NEXTLINK_AND_COUNT = + "JsonBuildingWithInlineRoomsAndNextLinkAndCount.json"; + + @Test + public void innerFeedWithoutResultsWrapperClientUseCase() throws Exception { + ODataEntry outerEntry = prepareAndExecuteEntry( + BUILDING_WITH_INLINE_ROOMS_CLIENT_CASE, "Buildings", DEFAULT_PROPERTIES); + + ODataFeed innerRoomFeed = (ODataFeed) outerEntry.getProperties().get("nb_Rooms"); + assertNotNull(innerRoomFeed); + + List<ODataEntry> rooms = innerRoomFeed.getEntries(); + assertNotNull(rooms); + assertEquals(1, rooms.size()); + + ODataEntry room = rooms.get(0); + Map<String, Object> roomProperties = room.getProperties(); + + assertEquals(4, roomProperties.size()); + assertEquals("1", roomProperties.get("Id")); + assertEquals("Room 1", roomProperties.get("Name")); + assertEquals(Short.valueOf("1"), roomProperties.get("Version")); + assertEquals(Short.valueOf("1"), roomProperties.get("Seats")); + + List<String> associationUris = room.getMetadata().getAssociationUris("nr_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees", associationUris.get(0)); + + associationUris = room.getMetadata().getAssociationUris("nr_Building"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building", associationUris.get(0)); + } + + @Test + public void innerFeedNoMediaResource() throws Exception { + ODataEntry outerEntry = prepareAndExecuteEntry(BUILDING_WITH_INLINE_ROOMS, "Buildings", DEFAULT_PROPERTIES); + + ODataFeed innerRoomFeed = (ODataFeed) outerEntry.getProperties().get("nb_Rooms"); + assertNotNull(innerRoomFeed); + + List<ODataEntry> rooms = innerRoomFeed.getEntries(); + assertNotNull(rooms); + assertEquals(1, rooms.size()); + + ODataEntry room = rooms.get(0); + Map<String, Object> roomProperties = room.getProperties(); + + assertEquals(4, roomProperties.size()); + assertEquals("1", roomProperties.get("Id")); + assertEquals("Room 1", roomProperties.get("Name")); + assertEquals(Short.valueOf("1"), roomProperties.get("Version")); + assertEquals(Short.valueOf("1"), roomProperties.get("Seats")); + + List<String> associationUris = room.getMetadata().getAssociationUris("nr_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees", associationUris.get(0)); + + associationUris = room.getMetadata().getAssociationUris("nr_Building"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building", associationUris.get(0)); + } + + @Test + public void innerFeedNoMediaResourceContainsNextLinkAndCount() throws Exception { + ODataEntry outerEntry = + prepareAndExecuteEntry(BUILDING_WITH_INLINE_ROOMS_NEXTLINK_AND_COUNT, "Buildings", DEFAULT_PROPERTIES); + + ODataFeed innerRoomFeed = (ODataFeed) outerEntry.getProperties().get("nb_Rooms"); + assertNotNull(innerRoomFeed); + + List<ODataEntry> rooms = innerRoomFeed.getEntries(); + assertNotNull(rooms); + assertEquals(1, rooms.size()); + + FeedMetadata roomsMetadata = innerRoomFeed.getFeedMetadata(); + assertEquals(Integer.valueOf(1), roomsMetadata.getInlineCount()); + assertEquals("nextLink", roomsMetadata.getNextLink()); + } + + @Test + public void innerFeedNoMediaResourceSimpleArray() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Buildings"); + String content = "{\"d\":{\"Id\":\"1\",\"Name\":\"Building 1\"," + + "\"nb_Rooms\":[{\"Id\":\"1\",\"Name\":\"Room 1\"}]}}"; + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + final ODataEntry outerEntry = new JsonEntityDeserializer().readEntry(entitySet, entityStream); + assertNotNull(outerEntry); + final ODataFeed innerRoomFeed = (ODataFeed) outerEntry.getProperties().get("nb_Rooms"); + assertNotNull(innerRoomFeed); + + final List<ODataEntry> rooms = innerRoomFeed.getEntries(); + assertNotNull(rooms); + assertEquals(1, rooms.size()); + } + + @Test + public void innerFeedMediaResource() throws Exception { + ODataEntry outerEntry = prepareAndExecuteEntry(TEAM_WITH_INLINE_EMPLOYEES, "Teams", DEFAULT_PROPERTIES); + + ODataFeed innerEmployeeFeed = (ODataFeed) outerEntry.getProperties().get("nt_Employees"); + assertNotNull(innerEmployeeFeed); + + List<ODataEntry> employees = innerEmployeeFeed.getEntries(); + assertNotNull(employees); + assertEquals(3, employees.size()); + } +}
