You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by sk...@apache.org on 2014/05/23 12:58:49 UTC

[54/59] [abbrv] git commit: [OLINGO-267] JSON conformance test added

[OLINGO-267] JSON conformance test added


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/3ba5cb36
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/3ba5cb36
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/3ba5cb36

Branch: refs/heads/olingo-266-tecsvc
Commit: 3ba5cb36d155876fd53ba3a5822cf190ce268788
Parents: 19f3792
Author: Francesco Chicchiriccò <--global>
Authored: Thu May 22 17:05:11 2014 +0200
Committer: Francesco Chicchiriccò <--global>
Committed: Thu May 22 17:05:11 2014 +0200

----------------------------------------------------------------------
 .../fit/v4/JSONFormatConformanceTestITCase.java | 332 +++++++++++++++++++
 .../olingo/commons/api/format/ContentType.java  |   1 -
 .../core/data/AbstractJsonDeserializer.java     |   2 +-
 3 files changed, 333 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ba5cb36/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
----------------------------------------------------------------------
diff --git a/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
new file mode 100644
index 0000000..9dcff7f
--- /dev/null
+++ b/fit/src/test/java/org/apache/olingo/fit/v4/JSONFormatConformanceTestITCase.java
@@ -0,0 +1,332 @@
+/*
+ * 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.fit.v4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.net.URI;
+import org.apache.commons.io.IOUtils;
+import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest;
+import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
+import org.apache.olingo.commons.api.data.Entity;
+import org.apache.olingo.commons.api.data.EntitySet;
+import org.apache.olingo.commons.api.data.ResWrap;
+import org.apache.olingo.commons.api.domain.ODataLinkType;
+import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
+import org.apache.olingo.commons.api.domain.v4.ODataEntity;
+import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
+import org.apache.olingo.commons.api.domain.v4.ODataLink;
+import org.apache.olingo.commons.api.domain.v4.ODataProperty;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
+import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeKind;
+import org.apache.olingo.commons.api.format.ODataPubFormat;
+import org.junit.Test;
+
+/**
+ * The test cases in this class are inspired by client conformance criteria defined in the <a
+ * href="http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793094">specs
+ * </a>.
+ */
+public class JSONFormatConformanceTestITCase extends AbstractTestITCase {
+
+  /**
+   * MUST either:
+   * <ol>
+   * <li>understand <tt>odata.metadata=minimal</tt> (section 3.1.1) or</li>
+   * <li>explicitly specify <tt>odata.metadata=none</tt>(section 3.1.3) or <tt>odata.metadata=full</tt> (section 3.1.2)
+   * in the request (client)</li>
+   * </ol>
+   * .
+   */
+  @Test
+  public void item1() throws EdmPrimitiveTypeException {
+    final URI uri = edmClient.newURIBuilder().
+            appendEntitySetSegment("Accounts").appendKeySegment(102).
+            appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
+    final ODataEntityRequest<ODataEntity> req = edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
+
+    // request format (via Accept header) is set to minimal by default
+    assertEquals("application/json;odata.metadata=minimal", req.getAccept());
+
+    final ODataRetrieveResponse<ODataEntity> res = req.execute();
+
+    // response is odata.metadata=minimal
+    assertFalse(res.getContentType().contains("odata.metadata=none"));
+    assertFalse(res.getContentType().contains("odata.metadata=full"));
+
+    // response payload is understood
+    final ODataEntity entity = res.getBody();
+    assertNotNull(entity);
+    assertEquals("Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument", entity.getTypeName().toString());
+    assertEquals(102902, entity.getProperty("PaymentInstrumentID").getPrimitiveValue().toCastValue(Integer.class), 0);
+    assertEquals("Edm.DateTimeOffset", entity.getProperty("CreatedDate").getPrimitiveValue().getTypeName());
+  }
+
+  /**
+   * MUST be prepared to consume a response with full metadata.
+   */
+  @Test
+  public void item2() {
+    final URI uri = edmClient.newURIBuilder(testStaticServiceRootURL).
+            appendEntitySetSegment("Accounts").appendKeySegment(102).build();
+    final ODataEntityRequest<ODataEntity> req = edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
+    req.setFormat(ODataPubFormat.JSON_FULL_METADATA);
+
+    // request format (via Accept header) is set to full metadata
+    assertEquals("application/json;odata.metadata=full", req.getAccept());
+
+    final ODataRetrieveResponse<ODataEntity> res = req.execute();
+
+    // response is odata.metadata=full
+    assertTrue(res.getContentType().contains("odata.metadata=full"));
+
+    // response payload is understood (including links, only returned with full metadata)
+    final ODataEntity entity = res.getBody();
+    assertNotNull(entity);
+    assertEquals(ODataLinkType.ENTITY_SET_NAVIGATION, entity.getNavigationLink("MyPaymentInstruments").getType());
+    assertEquals(ODataLinkType.ENTITY_SET_NAVIGATION, entity.getNavigationLink("ActiveSubscriptions").getType());
+  }
+
+  /**
+   * MUST be prepared to receive all data types (section 7.1)
+   * <ol>
+   * <li>defined in this specification (client)</li>
+   * <li>exposed by the service (service)</li>
+   * </ol>
+   * .
+   */
+  @Test
+  public void item3() throws EdmPrimitiveTypeException {
+    final String fromSection71 = "{"
+            + "\"NullValue\": null,"
+            + "\"TrueValue\": true,"
+            + "\"FalseValue\": false,"
+            + "\"BinaryValue@odata.type\": \"Binary\","
+            + "\"BinaryValue\": \"T0RhdGE\","
+            + "\"IntegerValue\": -128,"
+            + "\"DoubleValue\": 3.1415926535897931,"
+            + "\"SingleValue@odata.type\": \"Single\","
+            + "\"SingleValue\": \"INF\","
+            + "\"DecimalValue@odata.type\": \"Decimal\","
+            + "\"DecimalValue\": 34.95,"
+            + "\"StringValue\": \"Say \\\"Hello\\\",\\nthen go\","
+            + "\"DateValue@odata.type\": \"Date\","
+            + "\"DateValue\": \"2012-12-03\","
+            + "\"DateTimeOffsetValue@odata.type\": \"DateTimeOffset\","
+            + "\"DateTimeOffsetValue\": \"2012-12-03T07:16:23Z\","
+            + "\"DurationValue@odata.type\": \"Duration\","
+            + "\"DurationValue\": \"P12DT23H59M59.999999999999S\","
+            + "\"TimeOfDayValue@odata.type\": \"TimeOfDay\","
+            + "\"TimeOfDayValue\": \"07:59:59.999\","
+            + "\"GuidValue@odata.type\": \"Guid\","
+            + "\"GuidValue\": \"01234567-89ab-cdef-0123-456789abcdef\","
+            + "\"Int64Value@odata.type\": \"Int64\","
+            + "\"Int64Value\": 0,"
+            + "\"ColorEnumValue@odata.type\": \"Test.Color\","
+            + "\"ColorEnumValue\": \"Yellow\","
+            + "\"GeographyPoint\": {\"type\": \"Point\",\"coordinates\":[142.1,64.1]}"
+            + "}";
+
+    final ODataEntity entity = client.getReader().readEntity(IOUtils.toInputStream(fromSection71), ODataPubFormat.JSON);
+
+    assertTrue(entity.getProperty("NullValue").hasNullValue());
+
+    assertEquals(EdmPrimitiveTypeKind.Boolean, entity.getProperty("TrueValue").getPrimitiveValue().getTypeKind());
+    assertEquals(Boolean.TRUE, entity.getProperty("TrueValue").getPrimitiveValue().toCastValue(Boolean.class));
+
+    assertEquals(EdmPrimitiveTypeKind.Boolean, entity.getProperty("FalseValue").getPrimitiveValue().getTypeKind());
+    assertEquals(Boolean.FALSE, entity.getProperty("FalseValue").getPrimitiveValue().toCastValue(Boolean.class));
+
+    assertEquals(EdmPrimitiveTypeKind.Binary, entity.getProperty("BinaryValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.Int32, entity.getProperty("IntegerValue").getPrimitiveValue().getTypeKind());
+    assertEquals(-128, entity.getProperty("IntegerValue").getPrimitiveValue().toCastValue(Integer.class), 0);
+
+    assertEquals(EdmPrimitiveTypeKind.Double, entity.getProperty("DoubleValue").getPrimitiveValue().getTypeKind());
+    assertEquals(3.1415926535897931,
+            entity.getProperty("DoubleValue").getPrimitiveValue().toCastValue(Double.class), 0);
+
+    assertEquals(EdmPrimitiveTypeKind.Single, entity.getProperty("SingleValue").getPrimitiveValue().getTypeKind());
+    assertEquals(Float.POSITIVE_INFINITY,
+            entity.getProperty("SingleValue").getPrimitiveValue().toCastValue(Float.class), 0);
+
+    assertEquals(EdmPrimitiveTypeKind.Decimal, entity.getProperty("DecimalValue").getPrimitiveValue().getTypeKind());
+    assertEquals(BigDecimal.valueOf(34.95),
+            entity.getProperty("DecimalValue").getPrimitiveValue().toCastValue(BigDecimal.class));
+
+    assertEquals(EdmPrimitiveTypeKind.String, entity.getProperty("StringValue").getPrimitiveValue().getTypeKind());
+    assertEquals("Say \"Hello\",\nthen go",
+            entity.getProperty("StringValue").getPrimitiveValue().toCastValue(String.class));
+
+    assertEquals(EdmPrimitiveTypeKind.Date, entity.getProperty("DateValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.DateTimeOffset,
+            entity.getProperty("DateTimeOffsetValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.Duration, entity.getProperty("DurationValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.TimeOfDay,
+            entity.getProperty("TimeOfDayValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.Guid, entity.getProperty("GuidValue").getPrimitiveValue().getTypeKind());
+
+    assertEquals(EdmPrimitiveTypeKind.Int64, entity.getProperty("Int64Value").getPrimitiveValue().getTypeKind());
+
+    assertTrue(entity.getProperty("ColorEnumValue").hasEnumValue());
+
+    assertEquals(EdmPrimitiveTypeKind.GeographyPoint,
+            entity.getProperty("GeographyPoint").getPrimitiveValue().getTypeKind());
+  }
+
+  /**
+   * MUST interpret all odata annotations defined according to the OData-Version header of the payload (section 4.5).
+   */
+  @Test
+  public void item4() {
+    final String fromSection45_1 = "{"
+            + "\"@odata.context\": \"http://host/service/$metadata#Customers/$entity\","
+            + "\"@odata.metadataEtag\": \"W/\\\"A1FF3E230954908F\\\"\","
+            + "\"@odata.etag\": \"W/\\\"A1FF3E230954908G\\\"\","
+            + "\"@odata.type\": \"#Model.VipCustomer\","
+            + "\"@odata.id\": \"http://host/service/Employees(PersonID=3)\","
+            + "\"@odata.editLink\": \"People(976)\","
+            + "\"@odata.mediaEditLink\": \"Employees(1)/$value\","
+            + "\"@odata.mediaContentType\": \"image/jpeg\","
+            + "\"@odata.mediaEtag\": \"W/\\\"A1FF3E230954908H\\\"\","
+            + "\"Parent@odata.navigationLink\": \"People(976)/Parent\","
+            + "\"Parent@odata.associationLink\": \"People(976)/Parent\""
+            + "}";
+
+    final ResWrap<Entity> entity =
+            client.getDeserializer().toEntity(IOUtils.toInputStream(fromSection45_1), ODataPubFormat.JSON);
+
+    assertEquals("http://host/service/$metadata#Customers/$entity", entity.getContextURL().getURI().toASCIIString());
+    assertEquals("W/\"A1FF3E230954908F\"", entity.getMetadataETag());
+    assertEquals("W/\"A1FF3E230954908G\"", entity.getPayload().getETag());
+    assertEquals("Model.VipCustomer", entity.getPayload().getType());
+    assertEquals("http://host/service/Employees(PersonID=3)", entity.getPayload().getId());
+    assertEquals("People(976)", entity.getPayload().getEditLink().getHref());
+    assertEquals("Employees(1)/$value", entity.getPayload().getMediaContentSource().toASCIIString());
+    assertEquals("image/jpeg", entity.getPayload().getMediaContentType());
+    assertEquals("W/\"A1FF3E230954908H\"", entity.getPayload().getMediaETag());
+    assertEquals("People(976)/Parent", entity.getPayload().getNavigationLink("Parent").getHref());
+    assertEquals("People(976)/Parent", entity.getPayload().getAssociationLink("Parent").getHref());
+
+    final String fromSection45_2 = "{"
+            + "  \"@odata.count\": 5,"
+            + "  \"value\": [],"
+            + "  \"@odata.nextLink\": \"Customers?$expand=Orders&$skipToken=5\","
+            + "  \"@odata.deltaLink\": \"Customers?$expand=Orders&$deltatoken=8015\""
+            + "}";
+
+    final ResWrap<EntitySet> entitySet =
+            client.getDeserializer().toEntitySet(IOUtils.toInputStream(fromSection45_2), ODataPubFormat.JSON);
+
+    assertEquals(5, entitySet.getPayload().getCount(), 0);
+    assertEquals("Customers?$expand=Orders&$skipToken=5", entitySet.getPayload().getNext().toASCIIString());
+    assertEquals("Customers?$expand=Orders&$deltatoken=8015", entitySet.getPayload().getDeltaLink().toASCIIString());
+  }
+
+  /**
+   * MUST be prepared to receive any annotations, including custom annotations and <tt>odata</tt> annotations not
+   * defined in the <tt>OData-Version</tt> header of the payload (section 20).
+   */
+  @Test
+  public void item5() throws EdmPrimitiveTypeException {
+    final String sample = "{"
+            + "  \"@odata.context\": \"http://host/service/$metadata#Customers\","
+            + "  \"@odata.notdefined\": 11,"
+            + "  \"@com.contoso.customer.setkind\": \"VIPs\","
+            + "  \"value\": ["
+            + "    {"
+            + "      \"@com.contoso.display.highlight\": true,"
+            + "      \"ID\": \"ALFKI\","
+            + "      \"CompanyName@com.contoso.display.style\": { \"title\": true, \"order\": 1 },"
+            + "      \"CompanyName\": \"Alfreds Futterkiste\","
+            + "      \"Orders@com.contoso.display.style\": { \"order\": 2 },"
+            + "      \"Orders@odata.navigationLink\": \"People(976)/Orders\""
+            + "    }"
+            + "  ]"
+            + "}";
+
+    final ODataEntitySet entitySet = client.getReader().
+            readEntitySet(IOUtils.toInputStream(sample), ODataPubFormat.JSON);
+
+    assertEquals(2, entitySet.getAnnotations().size());
+
+    final ODataAnnotation notdefined = entitySet.getAnnotations().get(0);
+    assertEquals("odata.notdefined", notdefined.getTerm());
+    assertEquals(11, notdefined.getPrimitiveValue().toCastValue(Integer.class), 0);
+
+    final ODataAnnotation setkind = entitySet.getAnnotations().get(1);
+    assertEquals("com.contoso.customer.setkind", setkind.getTerm());
+    assertEquals("VIPs", setkind.getPrimitiveValue().toCastValue(String.class));
+
+    final ODataEntity entity = entitySet.getEntities().get(0);
+    assertEquals(1, entity.getAnnotations().size());
+
+    final ODataAnnotation highlight = entity.getAnnotations().get(0);
+    assertEquals("com.contoso.display.highlight", highlight.getTerm());
+    assertEquals(Boolean.TRUE, highlight.getPrimitiveValue().toCastValue(Boolean.class));
+
+    final ODataProperty property = entity.getProperty("CompanyName");
+    assertEquals(1, property.getAnnotations().size());
+
+    final ODataAnnotation style = property.getAnnotations().get(0);
+    assertEquals("com.contoso.display.style", style.getTerm());
+    assertTrue(style.hasComplexValue());
+    assertEquals(Boolean.TRUE, style.getComplexValue().get("title").getPrimitiveValue().toCastValue(Boolean.class));
+    assertEquals(1, style.getComplexValue().get("order").getPrimitiveValue().toCastValue(Integer.class), 0);
+
+    final ODataLink orders = (ODataLink) entity.getNavigationLink("Orders");
+    assertEquals(1, orders.getAnnotations().size());
+
+    final ODataAnnotation style2 = orders.getAnnotations().get(0);
+    assertEquals("com.contoso.display.style", style2.getTerm());
+    assertTrue(style2.hasComplexValue());
+    assertEquals(2, style2.getComplexValue().get("order").getPrimitiveValue().toCastValue(Integer.class), 0);
+  }
+
+  /**
+   * MUST NOT require <tt>odata.streaming=true</tt> in the <tt>Content-Type</tt> header (section 4.4).
+   */
+  @Test
+  public void item6() throws EdmPrimitiveTypeException {
+    final URI uri = edmClient.newURIBuilder().
+            appendEntitySetSegment("Accounts").appendKeySegment(102).
+            appendNavigationSegment("MyPaymentInstruments").appendKeySegment(102902).build();
+    final ODataEntityRequest<ODataEntity> req = edmClient.getRetrieveRequestFactory().getEntityRequest(uri);
+
+    // request format (via Accept header) does not contain odata.streaming=true
+    assertEquals("application/json;odata.metadata=minimal", req.getAccept());
+
+    final ODataRetrieveResponse<ODataEntity> res = req.execute();
+
+    // response payload is understood
+    final ODataEntity entity = res.getBody();
+    assertNotNull(entity);
+    assertEquals("Microsoft.Test.OData.Services.ODataWCFService.PaymentInstrument", entity.getTypeName().toString());
+    assertEquals(102902, entity.getProperty("PaymentInstrumentID").getPrimitiveValue().toCastValue(Integer.class), 0);
+    assertEquals("Edm.DateTimeOffset", entity.getProperty("CreatedDate").getPrimitiveValue().getTypeName());
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ba5cb36/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java
----------------------------------------------------------------------
diff --git a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java
index 9e6cfed..8e5f27d 100644
--- a/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java
+++ b/lib/commons-api/src/main/java/org/apache/olingo/commons/api/format/ContentType.java
@@ -55,7 +55,6 @@ public abstract class ContentType {
           new EnumMap<ODataServiceVersion, Map<String, String>>(ODataServiceVersion.class);
 
   static {
-
     final Map<String, String> v3 = new HashMap<String, String>();
     v3.put(ODataPubFormat.JSON_NO_METADATA.name(), ContentType.APPLICATION_JSON + ";odata=nometadata");
     v3.put(ODataPubFormat.JSON.name(), ContentType.APPLICATION_JSON + ";odata=minimalmetadata");

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/3ba5cb36/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
----------------------------------------------------------------------
diff --git a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
index 33d8243..133c916 100644
--- a/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
+++ b/lib/commons-core/src/main/java/org/apache/olingo/commons/core/data/AbstractJsonDeserializer.java
@@ -197,7 +197,7 @@ abstract class AbstractJsonDeserializer<T> extends ODataJacksonDeserializer<ResW
     } else if (node.isArray()) {
       type = ODataPropertyType.COLLECTION;
     } else if (node.isObject()) {
-      if (node.has(Constants.ATTR_TYPE) && node.has(Constants.JSON_CRS)) {
+      if (node.has(Constants.ATTR_TYPE)) {
         type = ODataPropertyType.PRIMITIVE;
         typeInfo = new EdmTypeInfo.Builder().
                 setTypeExpression("Edm.Geography" + node.get(Constants.ATTR_TYPE).asText()).build();