Repository: olingo-odata4 Updated Branches: refs/heads/master 4acc6bfbc -> 436a431a2
[OLINGO-545] Tests added to TecSvc, changed the status codes of failed navigation property bindings Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/436a431a Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/436a431a Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/436a431a Branch: refs/heads/master Commit: 436a431a25312277430088d95b49feea0c8f0429 Parents: 4acc6bf Author: Christian Holzer <[email protected]> Authored: Mon Mar 9 15:16:08 2015 +0100 Committer: Christian Holzer <[email protected]> Committed: Mon Mar 9 15:17:29 2015 +0100 ---------------------------------------------------------------------- .../olingo/fit/tecsvc/client/BindingITCase.java | 46 ++++++++++++++++++++ .../tecsvc/client/FilterSystemQueryITCase.java | 29 +++++++++--- .../olingo/server/tecsvc/data/DataProvider.java | 15 ++++--- .../operation/MethodCallOperator.java | 12 +++-- 4 files changed, 88 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/436a431a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java index 2e80a2c..09dcaa0 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/BindingITCase.java @@ -19,12 +19,14 @@ package org.apache.olingo.fit.tecsvc.client; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import java.net.URI; import java.util.HashMap; import java.util.Iterator; import org.apache.olingo.client.api.ODataClient; +import org.apache.olingo.client.api.communication.ODataClientErrorException; import org.apache.olingo.client.api.communication.request.cud.UpdateType; import org.apache.olingo.client.api.communication.request.retrieve.ODataEntityRequest; import org.apache.olingo.client.api.communication.response.ODataEntityCreateResponse; @@ -39,6 +41,7 @@ import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException; import org.apache.olingo.commons.api.edm.FullQualifiedName; import org.apache.olingo.commons.api.format.ODataFormat; import org.apache.olingo.commons.api.http.HttpHeader; +import org.apache.olingo.commons.api.http.HttpStatusCode; import org.apache.olingo.fit.AbstractBaseTestITCase; import org.apache.olingo.fit.tecsvc.TecSvcConst; import org.junit.Test; @@ -215,6 +218,49 @@ public class BindingITCase extends AbstractBaseTestITCase { assertEquals(3, iterator.next().asComplex().get(PROPERTY_INT16).getPrimitiveValue().toValue()); } + @Test + @SuppressWarnings("unused") + public void testMissingEntity() { + // Update an existing entity, use a URI to a not existing entity + // Perform the request to a single navigation property and a collection navigation property as well. + // Expected: Not Found (404) + + final ODataClient client = getClient(); + final URI entityURI = + client.newURIBuilder(SERVICE_URI).appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(1).build(); + final ODataObjectFactory of = client.getObjectFactory(); + + // Request to single (non collection) navigation property + ODataEntity entity = of.newEntity(ET_KEY_NAV); + final ODataLink navLinkOne = + of.newEntityNavigationLink(NAV_PROPERTY_ET_KEY_NAV_ONE, client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(42).build()); + entity.addLink(navLinkOne); + + ODataEntityUpdateResponse<ODataEntity> updateResponse = null; + try { + updateResponse = + client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute(); + fail(); + } catch (ODataClientErrorException e) { + assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode()); + } + + // Request to collection navigation propetry + entity = of.newEntity(ET_KEY_NAV); + final ODataLink navLinkMany = + of.newEntitySetNavigationLink(NAV_PROPERTY_ET_KEY_NAV_MANY, client.newURIBuilder(SERVICE_URI) + .appendEntitySetSegment(ES_KEY_NAV).appendKeySegment(3).build()); + entity.addLink(navLinkMany); + + try { + updateResponse = + client.getCUDRequestFactory().getEntityUpdateRequest(entityURI, UpdateType.PATCH, entity).execute(); + } catch (ODataClientErrorException e) { + assertEquals(HttpStatusCode.NOT_FOUND.getStatusCode(), e.getStatusLine().getStatusCode()); + } + } + @Override protected ODataClient getClient() { ODataClient odata = ODataClientFactory.getClient(); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/436a431a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java ---------------------------------------------------------------------- diff --git a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java index 262f9a8..58fd14b 100644 --- a/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java +++ b/fit/src/test/java/org/apache/olingo/fit/tecsvc/client/FilterSystemQueryITCase.java @@ -63,24 +63,24 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { ODataEntity oDataEntity = result.getBody().getEntities().get(0); assertEquals("32767", ((ODataValuable) oDataEntity.getProperty("PropertyInt16")).getValue().toString()); } - + @Test public void testBooleanLiteral() { ODataRetrieveResponse<ODataEntitySet> response = sendRequest(ES_ALL_PRIM, "PropertyBoolean eq false"); assertEquals(2, response.getBody().getEntities().size()); - + ODataEntity oDataEntity = response.getBody().getEntities().get(0); assertEquals("-32768", ((ODataValuable) oDataEntity.getProperty("PropertyInt16")).getValue().toString()); oDataEntity = response.getBody().getEntities().get(1); assertEquals("0", ((ODataValuable) oDataEntity.getProperty("PropertyInt16")).getValue().toString()); - + response = sendRequest(ES_ALL_PRIM, "PropertyBoolean eq true"); assertEquals(1, response.getBody().getEntities().size()); - + oDataEntity = response.getBody().getEntities().get(0); assertEquals("32767", ((ODataValuable) oDataEntity.getProperty("PropertyInt16")).getValue().toString()); } - + @Test public void testDateLiteral() { ODataRetrieveResponse<ODataEntitySet> result = sendRequest(ES_ALL_PRIM, "PropertyDate eq 2012-12-03"); @@ -246,6 +246,23 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { } @Test + public void testSubstringWithNegativeValues() { + // See OASIS JIRA ODATA-781 + + // -1 should be treated as 0 + ODataRetrieveResponse<ODataEntitySet> response = + sendRequest(ES_ALL_PRIM, "substring(PropertyString, -1, 1) eq 'F'"); + assertEquals(1, response.getBody().getEntities().size()); + + assertEquals(32767, response.getBody().getEntities().get(0).getProperty("PropertyInt16").getPrimitiveValue() + .toValue()); + + // -1 should be treated as 0, Same values substring(PropertyString, 0, 0) returns the empty String + response = sendRequest(ES_ALL_PRIM, "substring(PropertyString, 0, -1) eq ''"); + assertEquals(3, response.getBody().getEntities().size()); + } + + @Test public void testUnknownLiteral() { // Check if the error code is equals to 400 fail(ES_ALL_PRIM, "PropertyInt16 eq ThisIsNotAValidLiteral", HttpStatusCode.BAD_REQUEST); @@ -949,7 +966,7 @@ public class FilterSystemQueryITCase extends AbstractBaseTestITCase { result = sendRequest("ESKeyNav", "PropertyCompComp/PropertyComp/PropertyInt16 eq null", cookie); assertEquals(1, result.getBody().getEntities().size()); } - + @Test public void testSringFunctionWithoutStringParameters() { fail("ESServerSidePaging", "filter=contains(PropertyInt16, 3) eq 'hallo'", HttpStatusCode.BAD_REQUEST); http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/436a431a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java index bc9b68f..f18a0de 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/data/DataProvider.java @@ -172,7 +172,7 @@ public class DataProvider { i++; } } else { - throw new DataProviderException("Key type not supported"); + throw new DataProviderException("Key type not supported", HttpStatusCode.NOT_IMPLEMENTED); } keys.put(keyName, newValue); @@ -274,12 +274,12 @@ public class DataProvider { final Entity entity = read(edmEntitySetTarget, keys); if (entity == null) { - throw new DataProviderException("Entity " + bindingLink + " not found"); + throw new DataProviderException("Entity " + bindingLink + " not found", HttpStatusCode.NOT_FOUND); } return entity; } catch (DeserializerException e) { - throw new DataProviderException("Invalid entity binding link", e); + throw new DataProviderException("Invalid entity binding link", HttpStatusCode.BAD_REQUEST); } } @@ -356,13 +356,14 @@ public class DataProvider { if (newProperty != null || !patch) { final Object value = newProperty == null ? null : newProperty.getValue(); if (value == null && edmProperty.isNullable() != null && !edmProperty.isNullable()) { - throw new DataProviderException("Cannot null non-nullable property!"); + throw new DataProviderException("Cannot null non-nullable property!", HttpStatusCode.BAD_REQUEST); } property.setValue(property.getValueType(), value); } } else if (edmProperty.isCollection()) { if (newProperty != null && !newProperty.asCollection().isEmpty()) { - throw new DataProviderException("Update of a complex-collection property not supported!"); + throw new DataProviderException("Update of a complex-collection property not supported!", + HttpStatusCode.NOT_IMPLEMENTED); } else { property.asCollection().clear(); } @@ -431,5 +432,9 @@ public class DataProvider { public DataProviderException(final String message) { super(message, HttpStatusCode.INTERNAL_SERVER_ERROR.getStatusCode(), Locale.ROOT); } + + public DataProviderException(final String message, HttpStatusCode statusCode) { + super(message, statusCode.getStatusCode(), Locale.ROOT); + } } } http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/436a431a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/MethodCallOperator.java ---------------------------------------------------------------------- diff --git a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/MethodCallOperator.java b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/MethodCallOperator.java index ff952e4..62fbb6d 100644 --- a/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/MethodCallOperator.java +++ b/lib/server-tecsvc/src/main/java/org/apache/olingo/server/tecsvc/processor/queryoptions/expression/operation/MethodCallOperator.java @@ -64,6 +64,7 @@ public class MethodCallOperator { return stringFunction(new StringFunction() { @Override public Object perform(List<String> params) { + // If the first string do not contain the second string, return -1. See OASIS JIRA ODATA-780 return params.get(0).indexOf(params.get(1)); } }, EdmInt32.getInstance()); @@ -106,6 +107,8 @@ public class MethodCallOperator { } public VisitorOperand substring() throws ODataApplicationException { + // See OASIS JIRA ODATA-781 + final TypedOperand valueOperand = parameters.get(0).asTypedOperand(); final TypedOperand startOperand = parameters.get(1).asTypedOperand(); @@ -113,7 +116,9 @@ public class MethodCallOperator { return new TypedOperand(null, EdmString.getInstance()); } else if (valueOperand.is(EdmString.getInstance()) && startOperand.isIntegerType()) { final String value = valueOperand.getTypedValue(String.class); - final BigInteger start = startOperand.getTypedValue(BigInteger.class); + int start = Math.min(startOperand.getTypedValue(BigInteger.class).intValue(), value.length()); + start = start < 0 ? 0 : start; + int end = value.length(); if (parameters.size() == 3) { @@ -122,14 +127,15 @@ public class MethodCallOperator { if (lengthOperand.isNull()) { return new TypedOperand(null, EdmString.getInstance()); } else if (lengthOperand.isIntegerType()) { - end = Math.min(start.add(lengthOperand.getTypedValue(BigInteger.class)).intValue(), value.length()); + end = Math.min(start + lengthOperand.getTypedValue(BigInteger.class).intValue(), value.length()); + end = end < 0 ? 0 : end; } else { throw new ODataApplicationException("Third substring parameter should be Edm.Int32", HttpStatusCode.BAD_REQUEST.getStatusCode(), Locale.ROOT); } } - return new TypedOperand(value.substring(Math.min(start.intValue(), value.length()), end), + return new TypedOperand(value.substring(start, end), EdmString.getInstance()); } else { throw new ODataApplicationException("Substring has invalid parameters. First parameter should be Edm.String,"
