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/JsonEntryDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializerTest.java new file mode 100644 index 0000000..ac8d934 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonEntryDeserializerTest.java @@ -0,0 +1,539 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TimeZone; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.ep.entry.EntryMetadata; +import org.apache.olingo.odata2.api.ep.entry.MediaMetadata; +import org.apache.olingo.odata2.api.ep.entry.ODataEntry; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.api.uri.ExpandSelectTreeNode; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +/** + * + */ +public class JsonEntryDeserializerTest extends AbstractDeserializerTest { + + private static final String SIMPLE_ENTRY_BUILDING = "JsonBuilding.json"; + private static final String SIMPLE_ENTRY_ROOM = "JsonRoom.json"; + private static final String SIMPLE_ENTRY_EMPLOYEE = "JsonEmployee.json"; + private static final String SIMPLE_ENTRY_TEAM = "JsonTeam.json"; + private static final String INVALID_ENTRY_TEAM_DOUBLE_NAME_PROPERTY = "JsonInvalidTeamDoubleNameProperty.json"; + private static final String SIMPLE_ENTRY_BUILDING_WITHOUT_D = "JsonBuildingWithoutD.json"; + + // Negative Test jsonStart + private static final String negativeJsonStart_1 = "{ \"abc\": {"; + private static final String negativeJsonStart_2 = "{ \"d\": [a: 1, b: 2] }"; + + @Test + public void readContentOnlyEmployee() throws Exception { + // prepare + String content = readFile("JsonEmployeeContentOnly.json"); + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + InputStream contentBody = createContentAsStream(content); + EntityStream contentStream = new EntityStream(); + contentStream.setContent(contentBody); + contentStream.setReadProperties(DeserializerProperties.init().build()); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, contentStream); + + // verify + assertEquals(9, result.getProperties().size()); + } + + @Test + public void readContentOnlyRoom() throws Exception { + // prepare + String content = readFile("JsonRoomContentOnly.json"); + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DeserializerProperties.init().build()); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + + // verify + assertEquals(4, result.getProperties().size()); + } + + @Test + public void readContentOnlyEmployeeWithAdditionalLink() throws Exception { + // prepare + String content = readFile("JsonEmployeeContentOnlyWithAdditionalLink.json"); + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DeserializerProperties.init().build()); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + + // verify + assertEquals(9, result.getProperties().size()); + List<String> associationUris = result.getMetadata().getAssociationUris("ne_Manager"); + assertEquals(1, associationUris.size()); + assertEquals("http://host:8080/ReferenceScenario.svc/Managers('1')", associationUris.get(0)); + } + + @Test + public void readContentOnlyRoomWithAdditionalLink() throws Exception { + // prepare + String content = readFile("JsonRoomContentOnlyWithAdditionalLink.json"); + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DeserializerProperties.init().build()); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + + // verify + assertEquals(4, result.getProperties().size()); + List<String> associationUris = result.getMetadata().getAssociationUris("nr_Building"); + assertEquals(1, associationUris.size()); + assertEquals("http://host:8080/ReferenceScenario.svc/Buildings('1')", associationUris.get(0)); + } + + @Test(expected = EntityProviderException.class) + public void doubleClosingBracketsAtTheEnd() throws Exception { + String invalidJson = "{ \"Id\" : \"1\", \"Seats\" : 1, \"Version\" : 1}}"; + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + InputStream contentBody = createContentAsStream(invalidJson); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + xec.readEntry(entitySet, entityStream); + } + + @Test + public void readSimpleRoomEntry() throws Exception { + ODataEntry roomEntry = prepareAndExecuteEntry(SIMPLE_ENTRY_ROOM, "Rooms", DEFAULT_PROPERTIES); + + // verify + Map<String, Object> properties = roomEntry.getProperties(); + assertEquals(4, properties.size()); + + assertEquals("1", properties.get("Id")); + assertEquals("Room 1", properties.get("Name")); + assertEquals((short) 1, properties.get("Seats")); + assertEquals((short) 1, properties.get("Version")); + + List<String> associationUris = roomEntry.getMetadata().getAssociationUris("nr_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Employees", associationUris.get(0)); + + associationUris = roomEntry.getMetadata().getAssociationUris("nr_Building"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms('1')/nr_Building", associationUris.get(0)); + + EntryMetadata metadata = roomEntry.getMetadata(); + assertEquals("W/\"1\"", metadata.getEtag()); + } + + @SuppressWarnings("unchecked") + @Test + public void readSimpleEmployeeEntry() throws Exception { + ODataEntry result = prepareAndExecuteEntry(SIMPLE_ENTRY_EMPLOYEE, "Employees", DEFAULT_PROPERTIES); + + // verify + Map<String, Object> properties = result.getProperties(); + assertEquals(9, properties.size()); + + assertEquals("1", properties.get("EmployeeId")); + assertEquals("Walter Winter", properties.get("EmployeeName")); + assertEquals("1", properties.get("ManagerId")); + assertEquals("1", properties.get("RoomId")); + assertEquals("1", properties.get("TeamId")); + Map<String, Object> location = (Map<String, Object>) properties.get("Location"); + assertEquals(2, location.size()); + assertEquals("Germany", location.get("Country")); + Map<String, Object> city = (Map<String, Object>) location.get("City"); + assertEquals(2, city.size()); + assertEquals("69124", city.get("PostalCode")); + assertEquals("Heidelberg", city.get("CityName")); + assertEquals(Integer.valueOf(52), properties.get("Age")); + Calendar entryDate = (Calendar) properties.get("EntryDate"); + assertEquals(915148800000L, entryDate.getTimeInMillis()); + assertEquals(TimeZone.getTimeZone("GMT"), entryDate.getTimeZone()); + assertEquals("Employees('1')/$value", properties.get("ImageUrl")); + + List<String> associationUris = result.getMetadata().getAssociationUris("ne_Manager"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Employees('1')/ne_Manager", associationUris.get(0)); + + associationUris = result.getMetadata().getAssociationUris("ne_Team"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Employees('1')/ne_Team", associationUris.get(0)); + + associationUris = result.getMetadata().getAssociationUris("ne_Room"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Employees('1')/ne_Room", associationUris.get(0)); + + MediaMetadata mediaMetadata = result.getMediaMetadata(); + assertEquals("image/jpeg", mediaMetadata.getContentType()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Employees('1')/$value", mediaMetadata.getEditLink()); + assertEquals("Employees('1')/$value", mediaMetadata.getSourceLink()); + assertNull(mediaMetadata.getEtag()); + } + + @Test + public void readSimpleTeamEntry() throws Exception { + ODataEntry result = prepareAndExecuteEntry(SIMPLE_ENTRY_TEAM, "Teams", DEFAULT_PROPERTIES); + + Map<String, Object> properties = result.getProperties(); + assertNotNull(properties); + assertEquals("1", properties.get("Id")); + assertEquals("Team 1", properties.get("Name")); + assertEquals(Boolean.FALSE, properties.get("isScrumTeam")); + assertNull(properties.get("nt_Employees")); + + List<String> associationUris = result.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees", associationUris.get(0)); + + checkMediaDataInitial(result.getMediaMetadata()); + } + + @Test + public void readSimpleBuildingEntry() throws Exception { + ODataEntry result = prepareAndExecuteEntry(SIMPLE_ENTRY_BUILDING, "Buildings", DEFAULT_PROPERTIES); + // verify + Map<String, Object> properties = result.getProperties(); + assertNotNull(properties); + assertEquals("1", properties.get("Id")); + assertEquals("Building 1", properties.get("Name")); + assertNull(properties.get("Image")); + assertNull(properties.get("nb_Rooms")); + + List<String> associationUris = result.getMetadata().getAssociationUris("nb_Rooms"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Buildings('1')/nb_Rooms", associationUris.get(0)); + + checkMediaDataInitial(result.getMediaMetadata()); + } + + @Test + public void readSimpleBuildingEntryWithoutD() throws Exception { + ODataEntry result = prepareAndExecuteEntry(SIMPLE_ENTRY_BUILDING_WITHOUT_D, "Buildings", DEFAULT_PROPERTIES); + // verify + Map<String, Object> properties = result.getProperties(); + assertNotNull(properties); + assertEquals("1", properties.get("Id")); + assertEquals("Building 1", properties.get("Name")); + assertNull(properties.get("Image")); + assertNull(properties.get("nb_Rooms")); + + List<String> associationUris = result.getMetadata().getAssociationUris("nb_Rooms"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Buildings('1')/nb_Rooms", associationUris.get(0)); + + checkMediaDataInitial(result.getMediaMetadata()); + } + + @Test + public void readMinimalEntry() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(createContentAsStream("{\"Id\":\"99\"}")); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + final ODataEntry result = + new JsonEntityDeserializer().readEntry(entitySet, entityStream); + + final Map<String, Object> properties = result.getProperties(); + assertNotNull(properties); + assertEquals(1, properties.size()); + assertEquals("99", properties.get("Id")); + + assertTrue(result.getMetadata().getAssociationUris("nt_Employees").isEmpty()); + checkMediaDataInitial(result.getMediaMetadata()); + } + + @Test + public void readEntryWithNullProperty() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + final String content = "{\"Id\":\"99\",\"Seats\":null}"; + + EntityStream entityStream = new EntityStream(); + entityStream.setContent(createContentAsStream(content)); + entityStream.setReadProperties(DeserializerProperties.init().build()); + final ODataEntry result = new JsonEntityDeserializer().readEntry(entitySet, entityStream); + + final Map<String, Object> properties = result.getProperties(); + assertNotNull(properties); + assertEquals(2, properties.size()); + assertEquals("99", properties.get("Id")); + assertTrue(properties.containsKey("Seats")); + assertNull(properties.get("Seats")); + + assertTrue(result.getMetadata().getAssociationUris("nr_Employees").isEmpty()); + checkMediaDataInitial(result.getMediaMetadata()); + + } + + @Test + public void readWithDoublePropertyOnTeam() throws Exception { + // The file contains the name property two times + try { + prepareAndExecuteEntry(INVALID_ENTRY_TEAM_DOUBLE_NAME_PROPERTY, "Teams", DEFAULT_PROPERTIES); + fail("Exception has to be thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.DOUBLE_PROPERTY.getKey(), e.getMessageReference().getKey()); + } + } + + @Test + public void entryWithMetadataElementProperties() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream( + "{\"__metadata\":{\"properties\":{\"nt_Employees\":{\"associationuri\":" + + "\"http://some.host.com/service.root/Teams('1')/$links/nt_Employees\"}}}," + + "\"Id\":\"1\"}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + ODataEntry result = new JsonEntityDeserializer().readEntry(entitySet, entityStream); + checkMediaDataInitial(result.getMediaMetadata()); + } + + private void checkMediaDataInitial(final MediaMetadata mediaMetadata) { + assertNull(mediaMetadata.getContentType()); + assertNull(mediaMetadata.getEditLink()); + assertNull(mediaMetadata.getEtag()); + assertNull(mediaMetadata.getSourceLink()); + } + + @Test(expected = EntityProviderException.class) + public void emptyEntry() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(createContentAsStream("{}")); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readEntry(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongStart() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream(negativeJsonStart_1); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readEntry(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongStart2() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream(negativeJsonStart_2); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readEntry(entitySet, entityStream); + } + + /** + * Employee with inline entity Room with inline entity Buildings + * Scenario of 1:1:1 navigation + * E.g: Employees('1')?$expand=ne_Room/nr_Building + * @throws Exception + */ + @Test + public void employeesEntryWithEmployeeToRoomToBuilding() throws Exception { + InputStream stream = getFileAsStream("JsonEmployeeInlineRoomBuilding.json"); + assertNotNull(stream); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + assertNotNull(result); + assertEquals(10, result.getProperties().size()); + assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size()); + assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties() + .get("nr_Building")).getProperties().size()); + } + /** + * Employee with inline entity Room with inline entity Buildings + * Scenario of 1:1:1 navigation + * E.g: Employees('1')?$expand=ne_Room/nr_Building + * @throws Exception + */ + @Test + public void employeesEntryWithEmployeeToRoomToBuildingWithTypeMappings() throws Exception { + InputStream stream = getFileAsStream("JsonEmployeeInlineRoomBuilding.json"); + assertNotNull(stream); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + Map<String, Object> typeMappings = new HashMap<String, Object>(); + typeMappings.put("EntryDate", java.sql.Timestamp.class); + typeMappings.put("Name", String.class); + entityStream.setReadProperties(DeserializerProperties.init().addTypeMappings(typeMappings) + .build()); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + assertNotNull(result); + assertEquals(10, result.getProperties().size()); + assertEquals(5, ((ODataEntry)result.getProperties().get("ne_Room")).getProperties().size()); + assertEquals(3, ((ODataEntry)((ODataEntry)result.getProperties().get("ne_Room")).getProperties() + .get("nr_Building")).getProperties().size()); + } + /** + * Room has inline entity to Employees and has inline entry To Team + * Scenario of 1:n:1 navigation + * E.g: Rooms('1')?$expand=nr_Employees/ne_Team + * @throws Exception + */ + @Test + public void RoomEntryWithInlineEmployeeInlineTeam() throws Exception { + InputStream stream = getFileAsStream("JsonRoom_InlineEmployeesToTeam.json"); + assertNotNull(stream); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + assertNotNull(result); + assertEquals(5, result.getProperties().size()); + for (ODataEntry employeeEntry : ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries()) { + assertEquals(10, employeeEntry.getProperties().size()); + assertEquals(3, ((ODataEntry)employeeEntry.getProperties().get("ne_Team")).getProperties().size()); + } + } + /** + * Room has empty inline entity to Employees and has inline entry To Team + * E.g: Rooms('10')?$expand=nr_Employees/ne_Team + * @throws Exception + */ + @Test + public void RoomEntryWithEmptyInlineEmployeeInlineTeam() throws Exception { + InputStream stream = getFileAsStream("JsonRoom_EmptyInlineEmployeesToTeam.json"); + assertNotNull(stream); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataEntry result = + xec.readEntry(entitySet, entityStream); + assertNotNull(result); + assertEquals(5, result.getProperties().size()); + assertEquals(0, ((ODataFeed)result.getProperties().get("nr_Employees")).getEntries().size()); + } + /** + * @param inlineEntries + * @param feed + * @param entry + */ + private void getExpandedData(Map<String, Object> inlineEntries, ODataEntry entry) { + assertNotNull(entry); + Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks(); + for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) { + assertNotNull(expand.getKey()); + if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) { + if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) { + ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId()); + assertNotNull(innerFeed); + getExpandedData(inlineEntries, innerFeed); + entry.getProperties().put(expand.getKey(), innerFeed); + } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) { + ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId()); + assertNotNull(innerEntry); + getExpandedData(inlineEntries, innerEntry); + entry.getProperties().put(expand.getKey(), innerEntry); + } + } + } + } + /** + * @param inlineEntries + * @param feed + * @param entry + */ + private void getExpandedData(Map<String, Object> inlineEntries, ODataFeed feed) { + assertNotNull(feed.getEntries()); + List<ODataEntry> entries = feed.getEntries(); + for (ODataEntry entry : entries) { + Map<String, ExpandSelectTreeNode> expandNodes = entry.getExpandSelectTree().getLinks(); + for (Entry<String, ExpandSelectTreeNode> expand : expandNodes.entrySet()) { + assertNotNull(expand.getKey()); + if (inlineEntries.containsKey(expand.getKey() + entry.getMetadata().getId())) { + if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataFeed) { + ODataFeed innerFeed = (ODataFeed) inlineEntries.get(expand.getKey() + entry.getMetadata().getId()); + assertNotNull(innerFeed); + getExpandedData(inlineEntries, innerFeed); + feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerFeed); + } else if (inlineEntries.get(expand.getKey() + entry.getMetadata().getId()) instanceof ODataEntry) { + ODataEntry innerEntry = (ODataEntry) inlineEntries.get(expand.getKey() + entry.getMetadata().getId()); + assertNotNull(innerEntry); + getExpandedData(inlineEntries, innerEntry); + feed.getEntries().get(feed.getEntries().indexOf(entry)).getProperties().put(expand.getKey(), innerEntry); + } + } + } + } + } +}
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/JsonErrorDocumentDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializerTest.java new file mode 100644 index 0000000..1548bd7 --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonErrorDocumentDeserializerTest.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * 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.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.util.Locale; + +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.processor.ODataErrorContext; +import org.apache.olingo.odata2.client.core.ep.deserializer.JsonErrorDocumentDeserializer; +import org.apache.olingo.odata2.testutil.helper.StringHelper; +import org.junit.Test; + +/** + * + */ +public class JsonErrorDocumentDeserializerTest extends AbstractDeserializerTest { + + private static final String JSON_ERROR_DOCUMENT_SIMPLE = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}"; + private static final String JSON_ERROR_DOCUMENT_NULL_LOCALE = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":null,\"value\":\"Message\"}}}"; + private static final String JSON_ERROR_DOCUMENT_INNER_ERROR = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, \"innererror\":\"Some InnerError\"}}"; + private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"moreInner\":\"More Inner Error\"}}}"; + private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_OBJECT = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}}}"; + private static final String JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_ARRAY = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}, " + + "\"innererror\":{\"innerArray\":[\"More Inner Error\",\"Second\"]}}}"; + private static final String JSON_ERROR_DOCUMENT_INVALID_JSON = "\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}"; + /* error document with name 'locale' instead of 'lang' for message object */ + private static final String JSON_ERROR_DOCUMENT_UNKNOWN_CONTENT = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"locale\":\"en-US\",\"value\":\"Message\"}}}"; + /* error document without value for message object */ + private static final String JSON_ERROR_DOCUMENT_INVALID_CONTENT = "{\"error\":{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\"}}}"; + private static final String JSON_ERROR_DOCUMENT_MISSING_MESSAGE = "{\"error\":{\"code\":\"ErrorCode\"}}"; + private static final String JSON_ERROR_DOCUMENT_MISSING_CODE = "{\"error\":{" + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}}"; + private static final String JSON_ERROR_DOCUMENT_MISSING_ERROR = "{\"code\":\"ErrorCode\"," + + "\"message\":{\"lang\":\"en-US\",\"value\":\"Message\"}}"; + private JsonErrorDocumentDeserializer jedc = new JsonErrorDocumentDeserializer(); + + @Test + public void simpleErrorDocument() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_SIMPLE); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong locale for lang", Locale.US, error.getLocale()); + } + + @Test + public void localeNull() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_NULL_LOCALE); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertNull("Expected NULL for locale", error.getLocale()); + } + + @Test + public void innerError() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INNER_ERROR); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", "Some InnerError", error.getInnerError()); + } + + @Test + public void innerErrorComplex() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", "{\"moreInner\":\"More Inner Error\"}", error.getInnerError()); + } + + @Test + public void innerErrorComplexObject() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_OBJECT); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", + "{\"moreInner\":\"More Inner Error\",\"secondInner\":\"Second\"}", error.getInnerError()); + } + + @Test + public void innerErrorComplexArray() throws Exception { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INNER_ERROR_COMPLEX_ARRAY); + ODataErrorContext error = jedc.readError(in); + + assertEquals("Wrong content type", "application/json", error.getContentType()); + assertEquals("Wrong message", "Message", error.getMessage()); + assertEquals("Wrong error code", "ErrorCode", error.getErrorCode()); + assertEquals("Wrong inner error", + "{\"innerArray\":[\"More Inner Error\"\"Second\"]}", error.getInnerError()); + } + + @Test(expected = EntityProviderException.class) + public void invalidJson() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INVALID_JSON); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.EXCEPTION_OCCURRED, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidEmptyDocument() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(""); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.EXCEPTION_OCCURRED, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void nullParameter() throws EntityProviderException { + try { + jedc.readError(null); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentUnknown() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_UNKNOWN_CONTENT); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocument() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_INVALID_CONTENT); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingError() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_MISSING_ERROR); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_STATE, e.getMessageReference()); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingCode() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_MISSING_CODE); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + assertTrue(e.getMessage().contains("code")); + throw e; + } + } + + @Test(expected = EntityProviderException.class) + public void invalidErrorDocumentMissingMessage() throws EntityProviderException { + InputStream in = StringHelper.encapsulate(JSON_ERROR_DOCUMENT_MISSING_MESSAGE); + try { + jedc.readError(in); + fail("Expected exception was not thrown"); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.MISSING_PROPERTY, e.getMessageReference()); + assertTrue(e.getMessage().contains("message")); + throw e; + } + } +} 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/JsonFeedDeserializerTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializerTest.java b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializerTest.java new file mode 100644 index 0000000..cb77d4e --- /dev/null +++ b/odata2-lib/odata-client-core/src/test/java/org/apache/olingo/odata2/client/core/ep/deserializer/JsonFeedDeserializerTest.java @@ -0,0 +1,689 @@ +/******************************************************************************* + * 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 static org.junit.Assert.assertNull; + +import java.io.InputStream; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.olingo.odata2.api.edm.EdmEntitySet; +import org.apache.olingo.odata2.api.ep.EntityProviderException; +import org.apache.olingo.odata2.api.ep.entry.DeletedEntryMetadata; +import org.apache.olingo.odata2.api.ep.entry.MediaMetadata; +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.ODataDeltaFeed; +import org.apache.olingo.odata2.api.ep.feed.ODataFeed; +import org.apache.olingo.odata2.client.api.ep.DeserializerProperties; +import org.apache.olingo.odata2.client.api.ep.EntityStream; +import org.apache.olingo.odata2.testutil.mock.MockFacade; +import org.junit.Test; + +import junit.framework.Assert; + +/** + * + */ +public class JsonFeedDeserializerTest extends AbstractDeserializerTest { + + @Test + public void teamsFeed() throws Exception { + ODataFeed feed = prepareAndExecuteFeed("JsonTeams.json", "Teams", DEFAULT_PROPERTIES); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(2, entries.size()); + + // Team1 + ODataEntry entry = entries.get(0); + Map<String, Object> properties = entry.getProperties(); + assertNotNull(properties); + assertEquals("1", properties.get("Id")); + assertEquals("Team 1", properties.get("Name")); + assertEquals(Boolean.FALSE, properties.get("isScrumTeam")); + assertNull(properties.get("nt_Employees")); + + List<String> associationUris = entry.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees", associationUris.get(0)); + + checkMediaDataInitial(entry.getMediaMetadata()); + + // Team2 + entry = entries.get(1); + properties = entry.getProperties(); + assertNotNull(properties); + assertEquals("2", properties.get("Id")); + assertEquals("Team 2", properties.get("Name")); + assertEquals(Boolean.TRUE, properties.get("isScrumTeam")); + assertNull(properties.get("nt_Employees")); + + associationUris = entry.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('2')/nt_Employees", associationUris.get(0)); + + checkMediaDataInitial(entry.getMediaMetadata()); + + // Check FeedMetadata + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertNull(feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test + public void teamsFeedWithoutD() throws Exception { + ODataFeed feed = prepareAndExecuteFeed("JsonTeamsWithoutD.json", "Teams", DEFAULT_PROPERTIES); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(2, entries.size()); + + // Team1 + ODataEntry entry = entries.get(0); + Map<String, Object> properties = entry.getProperties(); + assertNotNull(properties); + assertEquals("1", properties.get("Id")); + assertEquals("Team 1", properties.get("Name")); + assertEquals(Boolean.FALSE, properties.get("isScrumTeam")); + assertNull(properties.get("nt_Employees")); + + List<String> associationUris = entry.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees", associationUris.get(0)); + + checkMediaDataInitial(entry.getMediaMetadata()); + + // Team2 + entry = entries.get(1); + properties = entry.getProperties(); + assertNotNull(properties); + assertEquals("2", properties.get("Id")); + assertEquals("Team 2", properties.get("Name")); + assertEquals(Boolean.TRUE, properties.get("isScrumTeam")); + assertNull(properties.get("nt_Employees")); + + associationUris = entry.getMetadata().getAssociationUris("nt_Employees"); + assertEquals(1, associationUris.size()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams('2')/nt_Employees", associationUris.get(0)); + + checkMediaDataInitial(entry.getMediaMetadata()); + + // Check FeedMetadata + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertNull(feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test(expected = EntityProviderException.class) + public void invalidDoubleClosingBrackets() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = "{\"d\":{\"results\":[]}}}"; + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + xec.readFeed(entitySet, entityStream); + } + + @Test + public void emptyFeed() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = "{\"d\":{\"results\":[]}}"; + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataFeed feed = xec.readFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(0, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertNull(feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test + public void emptyFeedWithoutDAndResults() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("[]"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + final ODataFeed feed = new JsonEntityDeserializer().readFeed(entitySet, entityStream); + assertNotNull(feed); + final List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(0, entries.size()); + final FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertNull(feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test + public void emptyFeedWithoutResults() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":[]}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + final ODataFeed feed = new JsonEntityDeserializer().readFeed(entitySet, entityStream); + assertNotNull(feed); + final List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(0, entries.size()); + final FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertNull(feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test(expected = EntityProviderException.class) + public void resultsNotPresent() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void countButNoResults() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__count\":\"1\"}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongCountType() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__count\":1,\"results\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongCountContent() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__count\":\"one\",\"results\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void negativeCount() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__count\":\"-1\",\"results\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongNextType() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"results\":[],\"__next\":false}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void wrongTag() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__results\":null}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void doubleCount() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"__count\":\"1\",\"__count\":\"2\",\"results\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void doubleNext() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"results\":[],\"__next\":\"a\",\"__next\":\"b\"}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void doubleResults() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"results\":{\"results\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test(expected = EntityProviderException.class) + public void doubleD() throws Exception { + final EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + InputStream contentBody = createContentAsStream("{\"d\":{\"d\":[]}}"); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + new JsonEntityDeserializer().readFeed(entitySet, entityStream); + } + + @Test + public void teamsFeedWithCount() throws Exception { + ODataFeed feed = prepareAndExecuteFeed("JsonTeamsWithCount.json", "Teams", DEFAULT_PROPERTIES); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(2, entries.size()); + + // Check FeedMetadata + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals(Integer.valueOf(3), feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test + public void teamsFeedWithCountWithoutD() throws Exception { + ODataFeed feed = prepareAndExecuteFeed("JsonTeamsWithCountWithoutD.json", "Teams", DEFAULT_PROPERTIES); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(2, entries.size()); + + // Check FeedMetadata + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals(Integer.valueOf(3), feedMetadata.getInlineCount()); + assertNull(feedMetadata.getNextLink()); + } + + @Test + public void feedWithInlineCountAndNextAndDelta() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"__count\":\"3\",\"results\":[{" + + "\"__metadata\":{\"id\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\"," + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\",\"type\":\"RefScenario.Team\"}," + + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false,\"nt_Employees\":{\"__deferred\":{" + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees\"}}}]," + + "\"__next\":\"Rooms?$skiptoken=98&$inlinecount=allpages\",\"__delta\":\"deltalink\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataFeed feed = xec.readFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(1, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals(Integer.valueOf(3), feedMetadata.getInlineCount()); + assertEquals("Rooms?$skiptoken=98&$inlinecount=allpages", feedMetadata.getNextLink()); + assertEquals("deltalink", feedMetadata.getDeltaLink()); + } + + @Test + public void feedWithTeamAndNextAndDelta() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"results\":[{" + + "\"__metadata\":{\"id\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\"," + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\",\"type\":\"RefScenario.Team\"}," + + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false,\"nt_Employees\":{\"__deferred\":{" + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees\"}}}]," + + "\"__next\":\"Rooms?$skiptoken=98\"," + + "\"__delta\":\"http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataFeed feed = xec.readFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(1, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals("Rooms?$skiptoken=98", feedMetadata.getNextLink()); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711", feedMetadata.getDeltaLink()); + } + + @Test + public void feedWithTeamAndDeltaAndDeletedEntriesWithoutWhen() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"results\":[{" + + "\"__metadata\":{\"id\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\"," + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\",\"type\":\"RefScenario.Team\"}," + + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false,\"nt_Employees\":{\"__deferred\":{" + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees\"}}}" + + ",{ \"@odata.context\":\"$metadata#Teams/$deletedEntity\",\"id\":\"/Teams('2')\"}" + + "]," + + "\"__delta\":\"http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(1, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711", feedMetadata.getDeltaLink()); + + List<DeletedEntryMetadata> deletedEntries = feed.getDeletedEntries(); + assertEquals(1, deletedEntries.size()); + assertEquals("/Teams('2')", deletedEntries.get(0).getUri()); + assertNull(deletedEntries.get(0).getWhen()); + } + + @Test + public void feedWithTeamAndDeltaAndDeletedEntries() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"results\":[{" + + "\"__metadata\":{\"id\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\"," + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')\",\"type\":\"RefScenario.Team\"}," + + "\"Id\":\"1\",\"Name\":\"Team 1\",\"isScrumTeam\":false,\"nt_Employees\":{\"__deferred\":{" + + "\"uri\":\"http://localhost:8080/ReferenceScenario.svc/Teams('1')/nt_Employees\"}}}" + + ",{ \"@odata.context\":\"$metadata#Teams/$deletedEntity\"," + + "\"id\":\"/Teams('2')\"," + + "\"when\":\"\\/Date(1297187419617)\\/\" }" + + "]," + + "\"__delta\":\"http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(1, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711", feedMetadata.getDeltaLink()); + + List<DeletedEntryMetadata> deletedEntries = feed.getDeletedEntries(); + assertEquals(1, deletedEntries.size()); + assertEquals("/Teams('2')", deletedEntries.get(0).getUri()); + assertEquals(new Date(1297187419617l), deletedEntries.get(0).getWhen()); + } + + @Test + public void feedWithOnlyDeletedEntries() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"results\":[" + + "{ \"@odata.context\":\"$metadata#Teams/$deletedEntity\"," + + "\"id\":\"/Teams('2')\"," + + "\"when\":\"\\/Date(1297187419617)\\/\" }" + + "]," + + "\"__delta\":\"http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(0, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711", feedMetadata.getDeltaLink()); + + List<DeletedEntryMetadata> deletedEntries = feed.getDeletedEntries(); + assertEquals(1, deletedEntries.size()); + assertEquals("/Teams('2')", deletedEntries.get(0).getUri()); + assertEquals(new Date(1297187419617l), deletedEntries.get(0).getWhen()); + } + + @Test(expected = EntityProviderException.class) + public void feedWithInvalidDeletedEntryWhenValue() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Teams"); + String content = + "{\"d\":{\"results\":[" + + "{ \"@odata.context\":\"$metadata#Teams/$deletedEntity\"," + + "\"id\":\"/Teams('2')\"," + + "\"when\":\"1297187419617\" }" + + "]," + + "\"__delta\":\"http://localhost:8080/ReferenceScenario.svc/Teams?!deltatoken=4711\"}}"; + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + try { + xec.readDeltaFeed(entitySet, entityStream); + } catch (EntityProviderException e) { + assertEquals(EntityProviderException.INVALID_DELETED_ENTRY_METADATA, e.getMessageReference()); + throw e; + } + } + + @Test + public void feedWithRoomAndDeltaAndDeletedEntries() throws Exception { + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + String content = readFile("JsonWithDeletedEntries.json"); + assertNotNull(content); + InputStream contentBody = createContentAsStream(content); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(contentBody); + entityStream.setReadProperties(DEFAULT_PROPERTIES); + + // execute + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + + List<ODataEntry> entries = feed.getEntries(); + assertNotNull(entries); + assertEquals(1, entries.size()); + + FeedMetadata feedMetadata = feed.getFeedMetadata(); + assertNotNull(feedMetadata); + assertEquals("http://localhost:8080/ReferenceScenario.svc/Rooms?!deltatoken=4711", feedMetadata.getDeltaLink()); + + assertEquals("W/\"2\"", entries.get(0).getMetadata().getEtag()); + + List<DeletedEntryMetadata> deletedEntries = feed.getDeletedEntries(); + assertEquals(2, deletedEntries.size()); + for (DeletedEntryMetadata deletedEntry : deletedEntries) { + String uri = deletedEntry.getUri(); + if (uri.contains("Rooms('4')")) { + assertEquals("http://host:80/service/Rooms('4')", deletedEntry.getUri()); + assertEquals(new Date(3509636760000l), deletedEntry.getWhen()); + } else if (uri.contains("Rooms('3')")) { + assertEquals("http://host:80/service/Rooms('3')", deletedEntry.getUri()); + assertEquals(new Date(1300561560000l), deletedEntry.getWhen()); + } else { + Assert.fail("Found unknown DeletedEntry with value: " + deletedEntry); + } + } + } + + private void checkMediaDataInitial(final MediaMetadata mediaMetadata) { + assertNull(mediaMetadata.getContentType()); + assertNull(mediaMetadata.getEditLink()); + assertNull(mediaMetadata.getEtag()); + assertNull(mediaMetadata.getSourceLink()); + } + /** + * Room has an Inline Feed Employees and Employee has an inline Entry Team + * E.g: Rooms?$expand=nr_Employees/ne_Team + * Empty Inline entity is also part of payload + * @throws Exception + */ + @Test + public void roomsFeedWithRoomInlineEmployeesWithTeams() throws Exception { + InputStream stream = getFileAsStream("JsonRooms_InlineEmployeesTeams.json"); + assertNotNull(stream); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + + assertEquals(3, feed.getEntries().size()); + + for (ODataEntry entry : feed.getEntries()) { + assertEquals(5, entry.getProperties().size()); + for (ODataEntry innerEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) { + assertEquals(10, innerEntry.getProperties().size()); + assertEquals(3, ((ODataEntry)innerEntry.getProperties().get("ne_Team")).getProperties().size()); + } + } + } + + /** + * Rooms has an inline feed Employees and Rooms has Inline entry Buildings + * E.g: Rooms?$expand=nr_Employees,nr_Building + * Empty Inline entity is also part of payload + * @throws Exception + */ + @Test + public void roomsFeedWithRoomInlineEmployeesInlineBuildings() throws Exception { + InputStream stream = getFileAsStream("JsonRooms_InlineEmployees_InlineBuilding.json"); + assertNotNull(stream); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Rooms"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + assertEquals(3, feed.getEntries().size()); + + for (ODataEntry entry : feed.getEntries()) { + assertEquals(6, entry.getProperties().size()); + for (ODataEntry employeeEntry : ((ODataFeed)entry.getProperties().get("nr_Employees")).getEntries()) { + assertEquals(9, employeeEntry.getProperties().size()); + } + assertEquals(3, ((ODataEntry)entry.getProperties().get("nr_Building")).getProperties().size()); + } + } + + /** + * Rooms navigate to Employees and has inline entry Teams + * E.g: Rooms('1')/nr_Employees?$expand=ne_Team + * @throws Exception + */ + @Test + public void roomsFeedWithRoomsToEmployeesInlineTeams() throws Exception { + InputStream stream = getFileAsStream("JsonRoomsToEmployeesWithInlineTeams.json"); + assertNotNull(stream); + + EdmEntitySet entitySet = MockFacade.getMockEdm().getDefaultEntityContainer().getEntitySet("Employees"); + JsonEntityDeserializer xec = new JsonEntityDeserializer(); + EntityStream entityStream = new EntityStream(); + entityStream.setContent(stream); + entityStream.setReadProperties(DeserializerProperties.init() + .build()); + ODataDeltaFeed feed = xec.readDeltaFeed(entitySet, entityStream); + assertNotNull(feed); + assertEquals(2, feed.getEntries().size()); + + for (ODataEntry entry : feed.getEntries()) { + assertEquals(10, entry.getProperties().size()); + assertEquals(3, ((ODataEntry)entry.getProperties().get("ne_Team")).getProperties().size()); + } + } +}