[OLINGO-663] conditional header required for property updates
Signed-off-by: Christian Amend <christian.amend@sap.com>
This commit is contained in:
parent
01425faf1c
commit
bfb5c93836
|
@ -194,6 +194,15 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
|
|||
assertEquals(HttpStatusCode.NOT_MODIFIED.getStatusCode(), request.execute().getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePropertyWithoutIfMatch() throws Exception {
|
||||
final ODataPropertyUpdateRequest request = client.getCUDRequestFactory().getPropertyPrimitiveValueUpdateRequest(
|
||||
uriProperty,
|
||||
client.getObjectFactory().newPrimitiveProperty("PropertyDuration",
|
||||
client.getObjectFactory().newPrimitiveValueBuilder().buildString("PT42S")));
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePropertyWithWrongIfMatch() throws Exception {
|
||||
ODataPropertyUpdateRequest request = client.getCUDRequestFactory().getPropertyPrimitiveValueUpdateRequest(
|
||||
|
@ -204,6 +213,15 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
|
|||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePropertyValueWithoutIfMatch() throws Exception {
|
||||
final ODataValueUpdateRequest request = client.getCUDRequestFactory().getValueUpdateRequest(
|
||||
uriPropertyValue,
|
||||
UpdateType.REPLACE,
|
||||
client.getObjectFactory().newPrimitiveValueBuilder().buildString("PT42S"));
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePropertyValueWithWrongIfMatch() throws Exception {
|
||||
ODataValueUpdateRequest request = client.getCUDRequestFactory().getValueUpdateRequest(
|
||||
|
@ -214,6 +232,12 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
|
|||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyWithoutIfMatch() throws Exception {
|
||||
final ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriProperty);
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriProperty);
|
||||
|
@ -231,6 +255,12 @@ public final class ConditionalITCase extends AbstractBaseTestITCase {
|
|||
assertNotEquals(request.getIfMatch(), response.getETag());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyValueWithoutIfMatch() throws Exception {
|
||||
final ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriPropertyValue);
|
||||
executeAndExpectError(request, HttpStatusCode.PRECONDITION_REQUIRED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deletePropertyValueWithWrongIfMatch() throws Exception {
|
||||
ODataDeleteRequest request = client.getCUDRequestFactory().getDeleteRequest(uriPropertyValue);
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.olingo.server.api.ODataApplicationException;
|
|||
import org.apache.olingo.server.api.ODataLibraryException;
|
||||
import org.apache.olingo.server.api.ODataRequest;
|
||||
import org.apache.olingo.server.api.ODataResponse;
|
||||
import org.apache.olingo.server.api.etag.CustomETagSupport;
|
||||
import org.apache.olingo.server.api.etag.PreconditionException;
|
||||
import org.apache.olingo.server.api.processor.ActionComplexCollectionProcessor;
|
||||
import org.apache.olingo.server.api.processor.ActionComplexProcessor;
|
||||
|
@ -203,7 +204,7 @@ public class ODataDispatcher {
|
|||
final UriResourceAction uriResourceAction) throws ODataApplicationException, ODataLibraryException {
|
||||
final EdmAction action = uriResourceAction.getAction();
|
||||
if (action.isBound()) {
|
||||
// Only bound actions can have etag control for the binding parameter
|
||||
// Only bound actions can have ETag control for the binding parameter.
|
||||
validatePreconditions(request, false);
|
||||
}
|
||||
final EdmReturnType returnType = action.getReturnType();
|
||||
|
@ -322,6 +323,7 @@ public class ODataDispatcher {
|
|||
handler.selectProcessor(PrimitiveValueProcessor.class)
|
||||
.readPrimitiveValue(request, response, uriInfo, requestedContentType);
|
||||
} else if (method == HttpMethod.PUT && resource instanceof UriResourceProperty) {
|
||||
validatePreconditions(request, false);
|
||||
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
|
||||
checkContentTypeSupport(requestFormat, valueRepresentationType);
|
||||
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
|
@ -329,6 +331,7 @@ public class ODataDispatcher {
|
|||
handler.selectProcessor(PrimitiveValueProcessor.class)
|
||||
.updatePrimitiveValue(request, response, uriInfo, requestFormat, responseFormat);
|
||||
} else if (method == HttpMethod.DELETE && resource instanceof UriResourceProperty) {
|
||||
validatePreconditions(request, false);
|
||||
handler.selectProcessor(PrimitiveValueProcessor.class)
|
||||
.deletePrimitiveValue(request, response, uriInfo);
|
||||
} else {
|
||||
|
@ -375,6 +378,7 @@ public class ODataDispatcher {
|
|||
.readComplex(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else if (method == HttpMethod.PUT || method == HttpMethod.PATCH) {
|
||||
validatePreconditions(request, false);
|
||||
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
|
||||
checkContentTypeSupport(requestFormat, complexRepresentationType);
|
||||
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
|
@ -387,6 +391,7 @@ public class ODataDispatcher {
|
|||
.updateComplex(request, response, uriInfo, requestFormat, responseFormat);
|
||||
}
|
||||
} else if (method == HttpMethod.DELETE) {
|
||||
validatePreconditions(request, false);
|
||||
if (isCollection) {
|
||||
handler.selectProcessor(ComplexCollectionProcessor.class)
|
||||
.deleteComplexCollection(request, response, uriInfo);
|
||||
|
@ -416,6 +421,7 @@ public class ODataDispatcher {
|
|||
.readPrimitive(request, response, uriInfo, requestedContentType);
|
||||
}
|
||||
} else if (method == HttpMethod.PUT || method == HttpMethod.PATCH) {
|
||||
validatePreconditions(request, false);
|
||||
final ContentType requestFormat = ContentType.parse(request.getHeader(HttpHeader.CONTENT_TYPE));
|
||||
checkContentTypeSupport(requestFormat, representationType);
|
||||
final ContentType responseFormat = ContentNegotiator.doContentNegotiation(uriInfo.getFormatOption(),
|
||||
|
@ -428,6 +434,7 @@ public class ODataDispatcher {
|
|||
.updatePrimitive(request, response, uriInfo, requestFormat, responseFormat);
|
||||
}
|
||||
} else if (method == HttpMethod.DELETE) {
|
||||
validatePreconditions(request, false);
|
||||
if (isCollection) {
|
||||
handler.selectProcessor(PrimitiveCollectionProcessor.class)
|
||||
.deletePrimitiveCollection(request, response, uriInfo);
|
||||
|
@ -443,27 +450,21 @@ public class ODataDispatcher {
|
|||
|
||||
private void handleCountDispatching(final ODataRequest request, final ODataResponse response,
|
||||
final int lastPathSegmentIndex) throws ODataApplicationException, ODataLibraryException {
|
||||
final HttpMethod method = request.getMethod();
|
||||
if (method == HttpMethod.GET) {
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceEntitySet
|
||||
|| resource instanceof UriResourceNavigation
|
||||
|| resource instanceof UriResourceFunction
|
||||
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.ENTITY) {
|
||||
handler.selectProcessor(CountEntityCollectionProcessor.class)
|
||||
.countEntityCollection(request, response, uriInfo);
|
||||
} else if (resource instanceof UriResourcePrimitiveProperty
|
||||
|| resource instanceof UriResourceFunction
|
||||
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.PRIMITIVE) {
|
||||
handler.selectProcessor(CountPrimitiveCollectionProcessor.class)
|
||||
.countPrimitiveCollection(request, response, uriInfo);
|
||||
} else {
|
||||
handler.selectProcessor(CountComplexCollectionProcessor.class)
|
||||
.countComplexCollection(request, response, uriInfo);
|
||||
}
|
||||
final UriResource resource = uriInfo.getUriResourceParts().get(lastPathSegmentIndex - 1);
|
||||
if (resource instanceof UriResourceEntitySet
|
||||
|| resource instanceof UriResourceNavigation
|
||||
|| resource instanceof UriResourceFunction
|
||||
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.ENTITY) {
|
||||
handler.selectProcessor(CountEntityCollectionProcessor.class)
|
||||
.countEntityCollection(request, response, uriInfo);
|
||||
} else if (resource instanceof UriResourcePrimitiveProperty
|
||||
|| resource instanceof UriResourceFunction
|
||||
&& ((UriResourceFunction) resource).getType().getKind() == EdmTypeKind.PRIMITIVE) {
|
||||
handler.selectProcessor(CountPrimitiveCollectionProcessor.class)
|
||||
.countPrimitiveCollection(request, response, uriInfo);
|
||||
} else {
|
||||
throw new ODataHandlerException("HTTP method " + method + " is not allowed for count.",
|
||||
ODataHandlerException.MessageKeys.HTTP_METHOD_NOT_ALLOWED, method.toString());
|
||||
handler.selectProcessor(CountComplexCollectionProcessor.class)
|
||||
.countComplexCollection(request, response, uriInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -517,12 +518,16 @@ public class ODataDispatcher {
|
|||
}
|
||||
}
|
||||
|
||||
private void validatePreconditions(ODataRequest request, boolean isMediaValue) throws PreconditionException {
|
||||
// If needed perform preconditions validation
|
||||
if (handler.getCustomETagSupport() != null) {
|
||||
new PreconditionsValidator(handler.getCustomETagSupport(), uriInfo,
|
||||
request.getHeader(HttpHeader.IF_MATCH),
|
||||
request.getHeader(HttpHeader.IF_NONE_MATCH)).validatePreconditions(isMediaValue);
|
||||
private void validatePreconditions(final ODataRequest request, final boolean isMediaValue)
|
||||
throws PreconditionException {
|
||||
// If needed perform preconditions validation.
|
||||
final CustomETagSupport eTagSupport = handler.getCustomETagSupport();
|
||||
if (eTagSupport != null
|
||||
&& new PreconditionsValidator(uriInfo).mustValidatePreconditions(eTagSupport, isMediaValue)
|
||||
&& request.getHeader(HttpHeader.IF_MATCH) == null
|
||||
&& request.getHeader(HttpHeader.IF_NONE_MATCH) == null) {
|
||||
throw new PreconditionException("Expected an if-match or if-none-match header.",
|
||||
PreconditionException.MessageKeys.MISSING_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,37 +32,20 @@ import org.apache.olingo.server.api.uri.UriResourceSingleton;
|
|||
|
||||
public class PreconditionsValidator {
|
||||
|
||||
private final CustomETagSupport customETagSupport;
|
||||
private final UriInfo uriInfo;
|
||||
private final String ifMatch;
|
||||
private final String ifNoneMatch;
|
||||
private final EdmBindingTarget affectedEntitySetOrSingleton;
|
||||
|
||||
public PreconditionsValidator(CustomETagSupport customETagSupport, UriInfo uriInfo, String ifMatch,
|
||||
String ifNoneMatch) {
|
||||
this.customETagSupport = customETagSupport;
|
||||
this.uriInfo = uriInfo;
|
||||
this.ifMatch = ifMatch;
|
||||
this.ifNoneMatch = ifNoneMatch;
|
||||
public PreconditionsValidator(final UriInfo uriInfo) throws PreconditionException {
|
||||
affectedEntitySetOrSingleton = extractInformation(uriInfo);
|
||||
}
|
||||
|
||||
public void validatePreconditions(boolean isMediaValue) throws PreconditionException {
|
||||
EdmBindingTarget affectedEntitySetOrSingleton = extractInformation();
|
||||
if (affectedEntitySetOrSingleton != null) {
|
||||
if ((isMediaValue && customETagSupport.hasMediaETag(affectedEntitySetOrSingleton)) ||
|
||||
(!isMediaValue && customETagSupport.hasETag(affectedEntitySetOrSingleton))) {
|
||||
checkETagHeaderPresent();
|
||||
}
|
||||
}
|
||||
public boolean mustValidatePreconditions(final CustomETagSupport customETagSupport, final boolean isMediaValue) {
|
||||
return affectedEntitySetOrSingleton != null
|
||||
&& (isMediaValue ?
|
||||
customETagSupport.hasMediaETag(affectedEntitySetOrSingleton) :
|
||||
customETagSupport.hasETag(affectedEntitySetOrSingleton));
|
||||
}
|
||||
|
||||
private void checkETagHeaderPresent() throws PreconditionException {
|
||||
if (ifMatch == null && ifNoneMatch == null) {
|
||||
throw new PreconditionException("Expected an if-match or if-none-match header",
|
||||
PreconditionException.MessageKeys.MISSING_HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
private EdmBindingTarget extractInformation() throws PreconditionException {
|
||||
private EdmBindingTarget extractInformation(final UriInfo uriInfo) throws PreconditionException {
|
||||
EdmBindingTarget lastFoundEntitySetOrSingleton = null;
|
||||
int counter = 0;
|
||||
for (UriResource uriResourcePart : uriInfo.getUriResourceParts()) {
|
||||
|
@ -78,13 +61,16 @@ public class PreconditionsValidator {
|
|||
break;
|
||||
case navigationProperty:
|
||||
lastFoundEntitySetOrSingleton = getEntitySetFromNavigation(lastFoundEntitySetOrSingleton,
|
||||
(UriResourceNavigation) uriResourcePart);
|
||||
(UriResourceNavigation) uriResourcePart);
|
||||
break;
|
||||
case primitiveProperty:
|
||||
case complexProperty:
|
||||
break;
|
||||
case value:
|
||||
case action:
|
||||
// This should not be possible since the URI Parser validates this but to be sure we throw an exception.
|
||||
if (counter != uriInfo.getUriResourceParts().size() - 1) {
|
||||
throw new PreconditionException("$Value or Action must be the last segment in the URI.",
|
||||
throw new PreconditionException("$value or Action must be the last segment in the URI.",
|
||||
PreconditionException.MessageKeys.INVALID_URI);
|
||||
}
|
||||
break;
|
||||
|
@ -111,14 +97,11 @@ public class PreconditionsValidator {
|
|||
}
|
||||
|
||||
private EdmBindingTarget getEntitySet(UriResourceEntitySet uriResourceEntitySet) {
|
||||
if (!uriResourceEntitySet.isCollection()) {
|
||||
return uriResourceEntitySet.getEntitySet();
|
||||
}
|
||||
return null;
|
||||
return uriResourceEntitySet.isCollection() ? null : uriResourceEntitySet.getEntitySet();
|
||||
}
|
||||
|
||||
private EdmBindingTarget getEntitySetFromNavigation(EdmBindingTarget lastFoundEntitySetOrSingleton,
|
||||
UriResourceNavigation uriResourceNavigation) {
|
||||
UriResourceNavigation uriResourceNavigation) {
|
||||
if (lastFoundEntitySetOrSingleton != null && !uriResourceNavigation.isCollection()) {
|
||||
EdmNavigationProperty navProp = uriResourceNavigation.getProperty();
|
||||
return lastFoundEntitySetOrSingleton.getRelatedBindingTarget(navProp.getName());
|
||||
|
|
|
@ -371,7 +371,7 @@ public class EntityTypeProvider {
|
|||
PropertyProvider.collectionNavPropertyETKeyNavMany_ETKeyNav,
|
||||
PropertyProvider.navPropertyETTwoKeyNavOne_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertyETTwoKeyNavMany_ETTwoKeyNav,
|
||||
PropertyProvider.collectionNavPropertySINav));
|
||||
PropertyProvider.navPropertySINav));
|
||||
|
||||
} else if (entityTypeName.equals(nameETBaseTwoKeyNav)) {
|
||||
return new CsdlEntityType()
|
||||
|
|
|
@ -687,9 +687,9 @@ public class PropertyProvider {
|
|||
.setType(EntityTypeProvider.nameETAllPrim)
|
||||
.setCollection(true);
|
||||
|
||||
public static final CsdlNavigationProperty collectionNavPropertySINav = new CsdlNavigationProperty()
|
||||
public static final CsdlNavigationProperty navPropertySINav = new CsdlNavigationProperty()
|
||||
.setName("NavPropertySINav")
|
||||
.setCollection(true)
|
||||
.setCollection(false)
|
||||
.setType(EntityTypeProvider.nameETTwoKeyNav);
|
||||
|
||||
public static final CsdlNavigationProperty collectionNavPropertyETKeyNavContMany_CT_ETKeyNav =
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
package org.apache.olingo.server.core;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -52,144 +53,146 @@ public class PreconditionsValidatorTest {
|
|||
|
||||
@Test
|
||||
public void simpleEntity() throws Exception {
|
||||
validate("ESAllPrim(1)", null, "*", "*");
|
||||
assertTrue(mustValidate("ESAllPrim(1)", "ESAllPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleEntityValue() throws Exception {
|
||||
validate("ESMedia(1)/$value", null, "*", "*");
|
||||
assertTrue(mustValidate("ESMedia(1)/$value", "ESMedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void property() throws Exception {
|
||||
assertTrue(mustValidate("ESAllPrim(1)/PropertyInt16", "ESAllPrim"));
|
||||
assertTrue(mustValidate("ESMixPrimCollComp(0)/PropertyComp", "ESMixPrimCollComp"));
|
||||
assertTrue(mustValidate("ESMixPrimCollComp(0)/PropertyComp/PropertyString", "ESMixPrimCollComp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyValue() throws Exception {
|
||||
assertTrue(mustValidate("ESAllPrim(1)/PropertyInt16/$value", "ESAllPrim"));
|
||||
assertTrue(mustValidate("ESMixPrimCollComp(0)/PropertyComp/PropertyString/$value", "ESMixPrimCollComp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void EntityAndToOneNavigation() throws Exception {
|
||||
validate("ESAllPrim(1)/NavPropertyETTwoPrimOne", "ESTwoPrim", "*", "*");
|
||||
assertTrue(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimOne", "ESTwoPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void EntityAndToManyNavigationWithKey() throws Exception {
|
||||
validate("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", "ESTwoPrim", "*", "*");
|
||||
assertTrue(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)", "ESTwoPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void EntityAndToOneNavigationValue() throws Exception {
|
||||
validate("ESKeyNav(1)/NavPropertyETMediaOne/$value", "ESMedia", "*", "*");
|
||||
assertTrue(mustValidate("ESKeyNav(1)/NavPropertyETMediaOne/$value", "ESMedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationOnProperty() throws Exception {
|
||||
assertTrue(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimOne/PropertyInt16", "ESTwoPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationOnFunction() throws Exception {
|
||||
assertTrue(mustValidate("FICRTESTwoKeyNav()(PropertyInt16=1,PropertyString='1')/NavPropertySINav", "SINav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boundActionOnEsKeyNav() throws Exception {
|
||||
validate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav", "*", "*");
|
||||
assertTrue(mustValidate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void boundActionOnEsKeyNavWithNavigation() throws Exception {
|
||||
validate("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav",
|
||||
"ESKeyNav", "*", "*");
|
||||
assertTrue(
|
||||
mustValidate("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleton() throws Exception {
|
||||
validate("SI", "SI", "*", "*");
|
||||
assertTrue(mustValidate("SI", "SI"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonWithNavigation() throws Exception {
|
||||
validate("SINav/NavPropertyETKeyNavOne", "ESKeyNav", "*", "*");
|
||||
assertTrue(mustValidate("SINav/NavPropertyETKeyNavOne", "ESKeyNav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonWithNavigationValue() throws Exception {
|
||||
validate("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", "ESMedia", "*", "*");
|
||||
assertTrue(mustValidate("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value", "ESMedia"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonWithAction() throws Exception {
|
||||
validate("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "SINav", "*", "*");
|
||||
assertTrue(mustValidate("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "SINav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singletonWithActionAndNavigation() throws Exception {
|
||||
validate("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav", "*", "*");
|
||||
assertTrue(mustValidate("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav", "ESKeyNav"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleEntityValueValidationNotActiveForMedia() throws Exception {
|
||||
final UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, edm);
|
||||
|
||||
CustomETagSupport support = mock(CustomETagSupport.class);
|
||||
when(support.hasETag(any(EdmBindingTarget.class))).thenReturn(true);
|
||||
when(support.hasMediaETag(any(EdmBindingTarget.class))).thenReturn(false);
|
||||
|
||||
final UriInfo uriInfo = new Parser().parseUri("ESMedia(1)/$value", null, null, edm);
|
||||
new PreconditionsValidator(support, uriInfo, null, null).validatePreconditions(true);
|
||||
assertFalse(new PreconditionsValidator(uriInfo).mustValidatePreconditions(support, true));
|
||||
}
|
||||
|
||||
// -------------- IGNORE VALIDATION TESTS -----------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void entitySetMustNotLeadToException() throws Exception {
|
||||
validate("ESAllPrim", null, null, null);
|
||||
public void entitySetMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("ESAllPrim", "ESAllPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyMustNotLeadToException() throws Exception {
|
||||
validate("ESAllPrim(1)/PropertyInt16", null, null, null);
|
||||
public void navigationToManyMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimMany", "ESTwoPrim"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void propertyValueMustNotLeadToException() throws Exception {
|
||||
validate("ESAllPrim(1)/PropertyInt16/$value", null, null, null);
|
||||
public void navigationOnFunctionWithoutEntitySetMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("FICRTETTwoKeyNavParam(ParameterInt16=1)/NavPropertyETKeyNavOne", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationToManyMustNotLeadToException() throws Exception {
|
||||
validate("ESAllPrim(1)/NavPropertyETTwoPrimMany", null, null, null);
|
||||
public void navigationToManyToActionMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("ESTwoPrim(1)/NavPropertyETAllPrimMany/Namespace1_Alias.BAESAllPrimRTETAllPrim", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationOnPropertyMustNotLeadToException() throws Exception {
|
||||
validate("ESAllPrim(1)/NavPropertyETTwoPrimOne/PropertyInt16", null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationToManyOnActionMustNotLeadToException() throws Exception {
|
||||
validate("ESTwoPrim(1)/NavPropertyETAllPrimMany/Namespace1_Alias.BAESAllPrimRTETAllPrim", null, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void navigationWithoutBindingMustNotLeadToException() throws Exception {
|
||||
validate("ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='test')"
|
||||
public void navigationWithoutBindingMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("ESTwoBaseTwoKeyNav(PropertyInt16=1,PropertyString='test')"
|
||||
+ "/NavPropertyETBaseTwoKeyNavMany(PropertyInt16=1,PropertyString='test')",
|
||||
null, null, null);
|
||||
null));
|
||||
}
|
||||
|
||||
// -------------- NEGATIVE TESTS --------------------------------------------------------------------------------
|
||||
|
||||
@Test
|
||||
public void positiveTestsMustLeadToAnExceptionIfNoHeaderIsPresent() throws Exception {
|
||||
runException("ESAllPrim(1)");
|
||||
runException("ESMedia(1)/$value");
|
||||
runException("ESAllPrim(1)/NavPropertyETTwoPrimOne");
|
||||
runException("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)");
|
||||
runException("ESKeyNav(1)/NavPropertyETMediaOne/$value");
|
||||
runException("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
|
||||
runException("ESKeyNav(1)/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
|
||||
|
||||
runException("SI");
|
||||
runException("SINav/NavPropertyETKeyNavOne");
|
||||
runException("SINav/NavPropertyETKeyNavOne/NavPropertyETMediaOne/$value");
|
||||
runException("SINav/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
|
||||
runException("SINav/NavPropertyETKeyNavOne/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav");
|
||||
public void referencesMustBeIgnored() throws Exception {
|
||||
assertFalse(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimOne/$ref", "ESTwoPrim"));
|
||||
assertFalse(mustValidate("ESAllPrim(1)/NavPropertyETTwoPrimMany(1)/$ref", "ESTwoPrim"));
|
||||
assertFalse(mustValidate("SINav/NavPropertyETKeyNavOne/$ref", "ESKeyNav"));
|
||||
}
|
||||
|
||||
@Test(expected = UriParserSemanticException.class)
|
||||
public void resourceSegmentAfterActionMustLeadToUriParserException() throws Exception {
|
||||
validate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16", "ESKeyNav", "*", "*");
|
||||
mustValidate("ESKeyNav(1)/Namespace1_Alias.BAETTwoKeyNavRTETTwoKeyNav/PropertyInt16", "ESKeyNav");
|
||||
}
|
||||
|
||||
@Test(expected = UriParserSemanticException.class)
|
||||
public void valueMustBeLastSegment() throws Exception {
|
||||
validate("ESMedia(1)/$value/PropertyInt16", null, null, null);
|
||||
mustValidate("ESMedia(1)/$value/PropertyInt16", "ESMedia");
|
||||
}
|
||||
|
||||
private void validate(final String uri, final String entitySetName, final String ifMatch, final String ifNoneMatch)
|
||||
private boolean mustValidate(final String uri, final String entitySetName)
|
||||
throws UriParserException, PreconditionException {
|
||||
final UriInfo uriInfo = new Parser().parseUri(uri, null, null, edm);
|
||||
final List<UriResource> parts = uriInfo.getUriResourceParts();
|
||||
|
@ -207,15 +210,6 @@ public class PreconditionsValidatorTest {
|
|||
when(support.hasETag(any(EdmBindingTarget.class))).thenAnswer(answer);
|
||||
when(support.hasMediaETag(any(EdmBindingTarget.class))).thenAnswer(answer);
|
||||
|
||||
new PreconditionsValidator(support, uriInfo, ifMatch, ifNoneMatch).validatePreconditions(isMedia);
|
||||
}
|
||||
|
||||
private void runException(final String uri) throws UriParserException {
|
||||
try {
|
||||
validate(uri, null, null, null);
|
||||
fail("Expected a PreconditionRequiredException but was not thrown");
|
||||
} catch (final PreconditionException e) {
|
||||
assertEquals(PreconditionException.MessageKeys.MISSING_HEADER, e.getMessageKey());
|
||||
}
|
||||
return new PreconditionsValidator(uriInfo).mustValidatePreconditions(support, isMedia);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue