You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by fm...@apache.org on 2013/07/26 13:22:12 UTC
[07/51] [partial] initial commit
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
new file mode 100644
index 0000000..4658cf0
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataRequestHandlerValidationTest.java
@@ -0,0 +1,682 @@
+/*******************************************************************************
+ * 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.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.ODataService;
+import org.apache.olingo.odata2.api.ODataServiceFactory;
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.commons.ODataHttpHeaders;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.edm.Edm;
+import org.apache.olingo.odata2.api.edm.EdmEntityType;
+import org.apache.olingo.odata2.api.edm.EdmFacets;
+import org.apache.olingo.odata2.api.edm.EdmFunctionImport;
+import org.apache.olingo.odata2.api.edm.EdmProperty;
+import org.apache.olingo.odata2.api.edm.EdmSimpleTypeKind;
+import org.apache.olingo.odata2.api.exception.ODataException;
+import org.apache.olingo.odata2.api.processor.ODataContext;
+import org.apache.olingo.odata2.api.processor.ODataProcessor;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.api.processor.part.BatchProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityComplexPropertyProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityLinkProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityLinksProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityMediaProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntityProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySetProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySimplePropertyProcessor;
+import org.apache.olingo.odata2.api.processor.part.EntitySimplePropertyValueProcessor;
+import org.apache.olingo.odata2.api.processor.part.FunctionImportProcessor;
+import org.apache.olingo.odata2.api.processor.part.FunctionImportValueProcessor;
+import org.apache.olingo.odata2.api.processor.part.MetadataProcessor;
+import org.apache.olingo.odata2.api.processor.part.ServiceDocumentProcessor;
+import org.apache.olingo.odata2.api.uri.PathInfo;
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.api.uri.UriParser;
+import org.apache.olingo.odata2.core.commons.ContentType;
+import org.apache.olingo.odata2.core.commons.ContentType.ODataFormat;
+import org.apache.olingo.odata2.core.uri.UriInfoImpl;
+import org.apache.olingo.odata2.core.uri.UriType;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+import org.apache.olingo.odata2.testutil.mock.MockFacade;
+
+/**
+ * Tests for the validation of HTTP method, URI path, query options,
+ * and request-body content type.
+ * @author SAP AG
+ */
+public class ODataRequestHandlerValidationTest extends BaseTest {
+
+ private Edm edm = null;
+
+ @Before
+ public void setEdm() throws ODataException {
+ edm = MockFacade.getMockEdm();
+ }
+
+ private List<String> createPathSegments(final UriType uriType, final boolean moreNavigation, final boolean isValue) {
+ List<String> segments = new ArrayList<String>();
+
+ if (uriType == UriType.URI1 || uriType == UriType.URI15) {
+ if (moreNavigation) {
+ segments.add("Managers('1')");
+ segments.add("nm_Employees");
+ } else {
+ segments.add("Employees");
+ }
+ } else if (uriType == UriType.URI2 || uriType == UriType.URI3
+ || uriType == UriType.URI4 || uriType == UriType.URI5
+ || uriType == UriType.URI16 || uriType == UriType.URI17) {
+ if (moreNavigation) {
+ segments.add("Managers('1')");
+ segments.add("nm_Employees('1')");
+ } else {
+ segments.add("Employees('1')");
+ }
+ } else if (uriType == UriType.URI6A || uriType == UriType.URI7A || uriType == UriType.URI50A) {
+ segments.add("Managers('1')");
+ if (moreNavigation) {
+ segments.add("nm_Employees('1')");
+ segments.add("ne_Manager");
+ }
+ if (uriType == UriType.URI7A || uriType == UriType.URI50A) {
+ segments.add("$links");
+ }
+ segments.add("nm_Employees('1')");
+ } else if (uriType == UriType.URI6B || uriType == UriType.URI7B || uriType == UriType.URI50B) {
+ segments.add("Managers('1')");
+ if (moreNavigation) {
+ segments.add("nm_Employees('1')");
+ segments.add("ne_Manager");
+ }
+ if (uriType == UriType.URI7B || uriType == UriType.URI50B) {
+ segments.add("$links");
+ }
+ segments.add("nm_Employees");
+ } else if (uriType == UriType.URI8) {
+ segments.add("$metadata");
+ } else if (uriType == UriType.URI9) {
+ segments.add("$batch");
+ } else if (uriType == UriType.URI10) {
+ segments.add("OldestEmployee");
+ } else if (uriType == UriType.URI11) {
+ segments.add("AllLocations");
+ } else if (uriType == UriType.URI12) {
+ segments.add("MostCommonLocation");
+ } else if (uriType == UriType.URI13) {
+ segments.add("AllUsedRoomIds");
+ } else if (uriType == UriType.URI14) {
+ segments.add("MaximalAge");
+ }
+
+ if (uriType == UriType.URI3 || uriType == UriType.URI4) {
+ segments.add("Location");
+ }
+ if (uriType == UriType.URI4) {
+ segments.add("Country");
+ } else if (uriType == UriType.URI5) {
+ segments.add("EmployeeName");
+ }
+
+ if (uriType == UriType.URI15 || uriType == UriType.URI16
+ || uriType == UriType.URI50A || uriType == UriType.URI50B) {
+ segments.add("$count");
+ }
+
+ if (uriType == UriType.URI17 || isValue) {
+ segments.add("$value");
+ }
+
+ // self-test
+ try {
+ final UriInfoImpl uriInfo = (UriInfoImpl) UriParser.parse(edm,
+ MockFacade.getPathSegmentsAsODataPathSegmentMock(segments),
+ Collections.<String, String> emptyMap());
+ assertEquals(uriType, uriInfo.getUriType());
+ assertEquals(uriType == UriType.URI17 || isValue, uriInfo.isValue());
+ } catch (final ODataException e) {
+ fail();
+ }
+
+ return segments;
+ }
+
+ private static Map<String, String> createOptions(
+ final boolean format,
+ final boolean filter, final boolean inlineCount, final boolean orderBy,
+ final boolean skipToken, final boolean skip, final boolean top,
+ final boolean expand, final boolean select) {
+
+ Map<String, String> map = new HashMap<String, String>();
+
+ if (format) {
+ map.put("$format", ODataFormat.XML.toString());
+ }
+ if (filter) {
+ map.put("$filter", "true");
+ }
+ if (inlineCount) {
+ map.put("$inlinecount", "none");
+ }
+ if (orderBy) {
+ map.put("$orderby", "Age");
+ }
+ if (skipToken) {
+ map.put("$skiptoken", "x");
+ }
+ if (skip) {
+ map.put("$skip", "0");
+ }
+ if (top) {
+ map.put("$top", "0");
+ }
+ if (expand) {
+ map.put("$expand", "ne_Team");
+ }
+ if (select) {
+ map.put("$select", "Age");
+ }
+
+ return map;
+ }
+
+ private ODataRequest mockODataRequest(
+ final ODataHttpMethod method,
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final String requestContentType) throws ODataException {
+ ODataRequest request = mock(ODataRequest.class);
+ when(request.getMethod()).thenReturn(method);
+ PathInfo pathInfo = mock(PathInfo.class);
+ List<PathSegment> segments = new ArrayList<PathSegment>();
+ for (final String pathSegment : pathSegments) {
+ PathSegment segment = mock(PathSegment.class);
+ when(segment.getPath()).thenReturn(pathSegment);
+ segments.add(segment);
+ }
+ when(pathInfo.getODataSegments()).thenReturn(segments);
+ when(request.getPathInfo()).thenReturn(pathInfo);
+ when(request.getQueryParameters())
+ .thenReturn(queryParameters == null ? new HashMap<String, String>() : queryParameters);
+ when(request.getContentType()).thenReturn(requestContentType);
+ return request;
+ }
+
+ private ODataService mockODataService(final ODataServiceFactory serviceFactory) throws ODataException {
+ ODataService service = DispatcherTest.getMockService();
+ when(service.getEntityDataModel()).thenReturn(edm);
+ when(service.getProcessor()).thenReturn(mock(ODataProcessor.class));
+ when(serviceFactory.createService(any(ODataContext.class))).thenReturn(service);
+
+ when(service.getSupportedContentTypes(BatchProcessor.class)).thenReturn(
+ Arrays.asList(HttpContentType.MULTIPART_MIXED));
+
+ when(service.getSupportedContentTypes(EntityProcessor.class)).thenReturn(Arrays.asList(
+ HttpContentType.APPLICATION_ATOM_XML_ENTRY_UTF8,
+ HttpContentType.APPLICATION_ATOM_XML_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8_VERBOSE,
+ HttpContentType.APPLICATION_XML_UTF8));
+
+ final List<String> jsonAndXml = Arrays.asList(
+ HttpContentType.APPLICATION_JSON_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8_VERBOSE,
+ HttpContentType.APPLICATION_XML_UTF8);
+ when(service.getSupportedContentTypes(FunctionImportProcessor.class)).thenReturn(jsonAndXml);
+ when(service.getSupportedContentTypes(EntityLinkProcessor.class)).thenReturn(jsonAndXml);
+ when(service.getSupportedContentTypes(EntityLinksProcessor.class)).thenReturn(jsonAndXml);
+ when(service.getSupportedContentTypes(EntitySimplePropertyProcessor.class)).thenReturn(jsonAndXml);
+ when(service.getSupportedContentTypes(EntityComplexPropertyProcessor.class)).thenReturn(jsonAndXml);
+
+ final List<String> wildcard = Arrays.asList(HttpContentType.WILDCARD);
+ when(service.getSupportedContentTypes(EntityMediaProcessor.class)).thenReturn(wildcard);
+ when(service.getSupportedContentTypes(EntitySimplePropertyValueProcessor.class)).thenReturn(wildcard);
+ when(service.getSupportedContentTypes(FunctionImportValueProcessor.class)).thenReturn(wildcard);
+
+ when(service.getSupportedContentTypes(EntitySetProcessor.class)).thenReturn(Arrays.asList(
+ HttpContentType.APPLICATION_ATOM_XML_FEED_UTF8,
+ HttpContentType.APPLICATION_ATOM_XML_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8_VERBOSE,
+ HttpContentType.APPLICATION_XML_UTF8));
+
+ when(service.getSupportedContentTypes(MetadataProcessor.class)).thenReturn(Arrays.asList(
+ HttpContentType.APPLICATION_XML_UTF8));
+
+ when(service.getSupportedContentTypes(ServiceDocumentProcessor.class)).thenReturn(Arrays.asList(
+ HttpContentType.APPLICATION_ATOM_SVC_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8,
+ HttpContentType.APPLICATION_JSON_UTF8_VERBOSE,
+ HttpContentType.APPLICATION_XML_UTF8));
+
+ return service;
+ }
+
+ private ODataResponse executeRequest(final ODataHttpMethod method,
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final String requestContentType) throws ODataException {
+ ODataServiceFactory serviceFactory = mock(ODataServiceFactory.class);
+ final ODataService service = mockODataService(serviceFactory);
+ when(serviceFactory.createService(any(ODataContext.class))).thenReturn(service);
+
+ final ODataRequest request = mockODataRequest(method, pathSegments, queryParameters, requestContentType);
+ final ODataContextImpl context = new ODataContextImpl(request, serviceFactory);
+
+ return new ODataRequestHandler(serviceFactory, service, context).handle(request);
+ }
+
+ private void executeAndValidateRequest(final ODataHttpMethod method,
+ final List<String> pathSegments,
+ final Map<String, String> queryParameters,
+ final String requestContentType,
+ final HttpStatusCodes expectedStatusCode) throws ODataException {
+
+ final ODataResponse response = executeRequest(method, pathSegments, queryParameters, requestContentType);
+ assertNotNull(response);
+ assertEquals(expectedStatusCode == null ? HttpStatusCodes.PAYMENT_REQUIRED : expectedStatusCode,
+ response.getStatus());
+ }
+
+ private void checkValueContentType(final ODataHttpMethod method, final UriType uriType, final String requestContentType) throws Exception {
+ executeAndValidateRequest(method, createPathSegments(uriType, false, true), null, requestContentType, null);
+ }
+
+ private void wrongRequest(final ODataHttpMethod method, final List<String> pathSegments, final Map<String, String> queryParameters) throws ODataException {
+ executeAndValidateRequest(method, pathSegments, queryParameters, null, HttpStatusCodes.METHOD_NOT_ALLOWED);
+ }
+
+ private void wrongOptions(final ODataHttpMethod method, final UriType uriType,
+ final boolean format,
+ final boolean filter, final boolean inlineCount, final boolean orderBy,
+ final boolean skipToken, final boolean skip, final boolean top,
+ final boolean expand, final boolean select) throws ODataException {
+ wrongRequest(method,
+ createPathSegments(uriType, false, false),
+ createOptions(format, filter, inlineCount, orderBy, skipToken, skip, top, expand, select));
+ }
+
+ private void wrongFunctionHttpMethod(final ODataHttpMethod method, final UriType uriType) throws ODataException {
+ wrongRequest(method,
+ uriType == UriType.URI1 ? Arrays.asList("EmployeeSearch") : createPathSegments(uriType, false, false),
+ null);
+ }
+
+ private void wrongProperty(final ODataHttpMethod method, final boolean ofComplex, final Boolean key) throws ODataException {
+ EdmProperty property = (EdmProperty) (ofComplex ?
+ edm.getComplexType("RefScenario", "c_Location").getProperty("Country") :
+ edm.getEntityType("RefScenario", "Employee").getProperty("Age"));
+ EdmFacets facets = mock(EdmFacets.class);
+ when(facets.isNullable()).thenReturn(false);
+ when(property.getFacets()).thenReturn(facets);
+
+ List<String> pathSegments;
+ if (ofComplex) {
+ pathSegments = createPathSegments(UriType.URI4, false, true);
+ } else {
+ pathSegments = createPathSegments(UriType.URI2, false, false);
+ pathSegments.add(key ? "EmployeeId" : "Age");
+ pathSegments.add("$value");
+ }
+
+ wrongRequest(method, pathSegments, null);
+ }
+
+ private void wrongNavigationPath(final ODataHttpMethod method, final UriType uriType, final HttpStatusCodes expectedStatusCode) throws ODataException {
+ executeAndValidateRequest(method, createPathSegments(uriType, true, false), null, null, expectedStatusCode);
+ }
+
+ private void wrongRequestContentType(final ODataHttpMethod method, final UriType uriType, final ContentType requestContentType) throws ODataException {
+ wrongRequestContentType(method, uriType, false, requestContentType);
+ }
+
+ private void wrongRequestContentType(final ODataHttpMethod method, final UriType uriType, final boolean isValue, final ContentType requestContentType) throws ODataException {
+ wrongRequestContentType(method, uriType, isValue, requestContentType.toContentTypeString());
+ }
+
+ private void wrongRequestContentType(final ODataHttpMethod method, final UriType uriType, final boolean isValue, final String requestContentType) throws ODataException {
+ executeAndValidateRequest(method, createPathSegments(uriType, false, isValue), null, requestContentType, HttpStatusCodes.UNSUPPORTED_MEDIA_TYPE);
+ }
+
+ @Test
+ public void dataServiceVersion() throws Exception {
+ ODataServiceFactory serviceFactory = mock(ODataServiceFactory.class);
+ final ODataService service = mockODataService(serviceFactory);
+ when(serviceFactory.createService(any(ODataContext.class))).thenReturn(service);
+
+ ODataRequest request = mockODataRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI0, false, false), null, null);
+ ODataContextImpl context = new ODataContextImpl(request, serviceFactory);
+
+ final ODataRequestHandler handler = new ODataRequestHandler(serviceFactory, service, context);
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("1.0");
+ ODataResponse response = handler.handle(request);
+ assertEquals(HttpStatusCodes.PAYMENT_REQUIRED, response.getStatus());
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("2.0");
+ response = handler.handle(request);
+ assertEquals(HttpStatusCodes.PAYMENT_REQUIRED, response.getStatus());
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("3.0");
+ response = handler.handle(request);
+ assertEquals(HttpStatusCodes.BAD_REQUEST, response.getStatus());
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("4.2");
+ response = handler.handle(request);
+ assertEquals(HttpStatusCodes.BAD_REQUEST, response.getStatus());
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("42");
+ response = handler.handle(request);
+ assertEquals(HttpStatusCodes.BAD_REQUEST, response.getStatus());
+
+ when(request.getRequestHeaderValue(ODataHttpHeaders.DATASERVICEVERSION)).thenReturn("test.2.0");
+ response = handler.handle(request);
+ assertEquals(HttpStatusCodes.BAD_REQUEST, response.getStatus());
+ }
+
+ @Test
+ public void allowedMethods() throws Exception {
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI0, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI1, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI1, false, false), null, HttpContentType.APPLICATION_JSON, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI2, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI3, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI3, false, false), null, HttpContentType.APPLICATION_JSON, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI3, false, false), null, HttpContentType.APPLICATION_JSON, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI4, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI9, false, false), null, HttpContentType.MULTIPART_MIXED, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI15, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.GET, createPathSegments(UriType.URI17, false, false), null, null, null);
+ }
+
+ @Test
+ public void notAllowedMethod() throws Exception {
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI0, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI1, false, false), null);
+ wrongRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI2, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI3, false, false), null);
+ wrongRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI4, false, false), null);
+ wrongRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI5, false, false), null);
+ wrongRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI6A, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI6B, false, false), null);
+ wrongRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI7A, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI7B, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI8, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI9, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI15, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI16, false, false), null);
+ wrongRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI17, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI50A, false, false), null);
+ wrongRequest(ODataHttpMethod.DELETE, createPathSegments(UriType.URI50B, false, false), null);
+ }
+
+ @Test
+ public void notAllowedOptions() throws Exception {
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, true, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, true, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, false, true, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, false, false, true, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, false, false, false, true, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, false, false, false, false, true, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI1, false, false, false, false, false, false, false, false, true);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI2, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI2, false, false, false, false, false, false, false, true, false);
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI2, false, false, false, false, false, false, false, false, true);
+ wrongOptions(ODataHttpMethod.PATCH, UriType.URI2, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.PATCH, UriType.URI2, false, false, false, false, false, false, false, true, false);
+ wrongOptions(ODataHttpMethod.PATCH, UriType.URI2, false, false, false, false, false, false, false, false, true);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI2, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI2, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI2, false, false, false, false, false, false, false, true, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI2, false, false, false, false, false, false, false, false, true);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI3, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.PATCH, UriType.URI3, true, false, false, false, false, false, false, false, false);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI4, true, false, false, false, false, false, false, false, false);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI5, true, false, false, false, false, false, false, false, false);
+
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, true, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, true, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, false, true, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, false, false, true, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, false, false, false, true, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, false, false, false, false, true, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI6B, false, false, false, false, false, false, false, false, true);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI7A, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI7A, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI7A, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI7A, false, true, false, false, false, false, false, false, false);
+
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, true, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, false, true, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, false, false, true, false, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, false, false, false, true, false, false, false);
+ wrongOptions(ODataHttpMethod.POST, UriType.URI7B, false, false, false, false, false, false, true, false, false);
+
+ wrongOptions(ODataHttpMethod.PUT, UriType.URI17, false, true, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI17, true, false, false, false, false, false, false, false, false);
+ wrongOptions(ODataHttpMethod.DELETE, UriType.URI17, false, true, false, false, false, false, false, false, false);
+ }
+
+ @Test
+ public void functionImportWrongHttpMethod() throws Exception {
+ wrongFunctionHttpMethod(ODataHttpMethod.POST, UriType.URI1);
+ wrongFunctionHttpMethod(ODataHttpMethod.PUT, UriType.URI10);
+ wrongFunctionHttpMethod(ODataHttpMethod.POST, UriType.URI11);
+ wrongFunctionHttpMethod(ODataHttpMethod.PATCH, UriType.URI12);
+ wrongFunctionHttpMethod(ODataHttpMethod.POST, UriType.URI13);
+ wrongFunctionHttpMethod(ODataHttpMethod.PUT, UriType.URI14);
+ }
+
+ @Test
+ public void wrongProperty() throws Exception {
+ wrongProperty(ODataHttpMethod.DELETE, true, false);
+
+ wrongProperty(ODataHttpMethod.PUT, false, true);
+ wrongProperty(ODataHttpMethod.PATCH, false, true);
+ wrongProperty(ODataHttpMethod.DELETE, false, true);
+ wrongProperty(ODataHttpMethod.DELETE, false, false);
+ }
+
+ @Test
+ public void wrongNavigationPath() throws Exception {
+ wrongNavigationPath(ODataHttpMethod.PUT, UriType.URI3, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.PATCH, UriType.URI3, HttpStatusCodes.BAD_REQUEST);
+
+ wrongNavigationPath(ODataHttpMethod.PUT, UriType.URI4, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.PATCH, UriType.URI4, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.DELETE, UriType.URI4, HttpStatusCodes.METHOD_NOT_ALLOWED);
+
+ wrongNavigationPath(ODataHttpMethod.PUT, UriType.URI5, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.PATCH, UriType.URI5, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.DELETE, UriType.URI5, HttpStatusCodes.METHOD_NOT_ALLOWED);
+
+ wrongNavigationPath(ODataHttpMethod.PUT, UriType.URI7A, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.PATCH, UriType.URI7A, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.DELETE, UriType.URI7A, HttpStatusCodes.BAD_REQUEST);
+
+ wrongNavigationPath(ODataHttpMethod.POST, UriType.URI6B, HttpStatusCodes.BAD_REQUEST);
+
+ wrongNavigationPath(ODataHttpMethod.POST, UriType.URI7B, HttpStatusCodes.BAD_REQUEST);
+
+ wrongNavigationPath(ODataHttpMethod.PUT, UriType.URI17, HttpStatusCodes.BAD_REQUEST);
+ wrongNavigationPath(ODataHttpMethod.DELETE, UriType.URI17, HttpStatusCodes.BAD_REQUEST);
+ }
+
+ @Test
+ public void requestContentType() throws Exception {
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI2, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI2, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI2, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI3, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI3, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI3, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI4, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI4, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI4, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI5, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI5, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI5, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI6A, false, false), null, HttpContentType.APPLICATION_XML, HttpStatusCodes.BAD_REQUEST);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI6A, false, false), null, HttpContentType.APPLICATION_XML, HttpStatusCodes.BAD_REQUEST);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI6A, false, false), null, HttpContentType.APPLICATION_XML, HttpStatusCodes.BAD_REQUEST);
+
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI6B, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI7A, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.PATCH, createPathSegments(UriType.URI7A, false, false), null, HttpContentType.APPLICATION_XML, null);
+ executeAndValidateRequest(ODataHttpMethod.MERGE, createPathSegments(UriType.URI7A, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI7B, false, false), null, HttpContentType.APPLICATION_XML, null);
+
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI9, false, false), null, HttpContentType.MULTIPART_MIXED, null);
+ }
+
+ @Test
+ public void requestContentTypeMediaResource() throws Exception {
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI1, false, false), null, "image/jpeg", null);
+
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI17, false, true), null, "image/jpeg", null);
+ }
+
+ @Test
+ public void requestContentTypeFunctionImport() throws Exception {
+ EdmFunctionImport function = edm.getDefaultEntityContainer().getFunctionImport("MaximalAge");
+ when(function.getHttpMethod()).thenReturn(ODataHttpMethod.PUT.name());
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI14, false, false), null, null, null);
+ executeAndValidateRequest(ODataHttpMethod.PUT, createPathSegments(UriType.URI14, false, false), null, HttpContentType.WILDCARD, null);
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI14, null);
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI14, HttpContentType.WILDCARD);
+
+ function = edm.getDefaultEntityContainer().getFunctionImport("OldestEmployee");
+ when(function.getHttpMethod()).thenReturn(ODataHttpMethod.POST.name());
+ executeAndValidateRequest(ODataHttpMethod.POST, createPathSegments(UriType.URI10, false, false), null, null, null);
+ }
+
+ @Test
+ public void requestValueContentType() throws Exception {
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI4, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.DELETE, UriType.URI4, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.PATCH, UriType.URI4, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.MERGE, UriType.URI4, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI4, HttpContentType.TEXT_PLAIN_UTF8);
+ checkValueContentType(ODataHttpMethod.DELETE, UriType.URI4, HttpContentType.TEXT_PLAIN_UTF8);
+ checkValueContentType(ODataHttpMethod.PATCH, UriType.URI4, HttpContentType.TEXT_PLAIN_UTF8);
+ checkValueContentType(ODataHttpMethod.MERGE, UriType.URI4, HttpContentType.TEXT_PLAIN_UTF8);
+
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI5, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.DELETE, UriType.URI5, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.PATCH, UriType.URI5, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.MERGE, UriType.URI5, HttpContentType.TEXT_PLAIN);
+
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI17, HttpContentType.TEXT_PLAIN);
+ checkValueContentType(ODataHttpMethod.DELETE, UriType.URI17, HttpContentType.TEXT_PLAIN);
+ }
+
+ @Test
+ public void requestBinaryValueContentType() throws Exception {
+ EdmProperty property = (EdmProperty) edm.getEntityType("RefScenario", "Employee").getProperty("EmployeeName");
+ when(property.getType()).thenReturn(EdmSimpleTypeKind.Binary.getEdmSimpleTypeInstance());
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI5, HttpContentType.TEXT_PLAIN);
+ when(property.getMimeType()).thenReturn("image/png");
+ checkValueContentType(ODataHttpMethod.PUT, UriType.URI5, "image/png");
+ }
+
+ @Test
+ public void wrongRequestContentType() throws Exception {
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI1, ContentType.WILDCARD);
+
+ wrongRequestContentType(ODataHttpMethod.PUT, UriType.URI2, ContentType.APPLICATION_ATOM_SVC);
+ wrongRequestContentType(ODataHttpMethod.PUT, UriType.URI2, ContentType.APPLICATION_ATOM_SVC_CS_UTF_8);
+ wrongRequestContentType(ODataHttpMethod.PUT, UriType.URI2, ContentType.APPLICATION_ATOM_SVC);
+ wrongRequestContentType(ODataHttpMethod.PUT, UriType.URI2, ContentType.APPLICATION_ATOM_SVC_CS_UTF_8);
+
+ ODataHttpMethod[] methodsToTest = { ODataHttpMethod.PUT, ODataHttpMethod.PATCH, ODataHttpMethod.MERGE };
+
+ for (ODataHttpMethod oDataHttpMethod : methodsToTest) {
+ wrongRequestContentType(oDataHttpMethod, UriType.URI2, ContentType.create("image/jpeg"));
+
+ wrongRequestContentType(oDataHttpMethod, UriType.URI3, ContentType.TEXT_PLAIN);
+
+ wrongRequestContentType(oDataHttpMethod, UriType.URI4, false, ContentType.TEXT_PLAIN);
+
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_ATOM_SVC);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_ATOM_SVC_CS_UTF_8);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_XML);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_XML_CS_UTF_8);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_ATOM_XML);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_ATOM_XML_CS_UTF_8);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_JSON);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.APPLICATION_JSON_CS_UTF_8);
+ wrongRequestContentType(oDataHttpMethod, UriType.URI5, true, ContentType.create("image/jpeg"));
+
+ wrongRequestContentType(oDataHttpMethod, UriType.URI6A, ContentType.APPLICATION_ATOM_SVC);
+
+ wrongRequestContentType(oDataHttpMethod, UriType.URI7A, ContentType.APPLICATION_ATOM_SVC);
+ }
+
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI7B, ContentType.APPLICATION_ATOM_SVC);
+
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI9, ContentType.APPLICATION_OCTET_STREAM);
+ }
+
+ @Test
+ public void unsupportedRequestContentTypeNoMediaResource() throws Exception {
+ EdmEntityType entityType = edm.getDefaultEntityContainer().getEntitySet("Employees").getEntityType();
+ when(entityType.hasStream()).thenReturn(false);
+
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI1, ContentType.APPLICATION_ATOM_SVC);
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI1, ContentType.APPLICATION_ATOM_SVC_CS_UTF_8);
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI1, ContentType.APPLICATION_OCTET_STREAM);
+ wrongRequestContentType(ODataHttpMethod.POST, UriType.URI6B, ContentType.APPLICATION_ATOM_SVC);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataResponseTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataResponseTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataResponseTest.java
new file mode 100644
index 0000000..197d74c
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/ODataResponseTest.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * 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.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.commons.HttpContentType;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+
+/**
+ * @author SAP AG
+ */
+public class ODataResponseTest extends BaseTest {
+
+ @Test
+ public void buildStatusResponseTest() {
+ ODataResponse response = ODataResponse.status(HttpStatusCodes.FOUND).build();
+ assertEquals(HttpStatusCodes.FOUND, response.getStatus());
+ }
+
+ @Test
+ public void buildEntityResponseTest() {
+ ODataResponse response = ODataResponse.entity("abc").build();
+ assertNull(response.getStatus());
+ assertEquals("abc", response.getEntity());
+ }
+
+ @Test
+ public void buildHeaderResponseTest() {
+ ODataResponse response = ODataResponse
+ .header("abc", "123")
+ .header("def", "456")
+ .header("ghi", null)
+ .build();
+ assertNull(response.getStatus());
+ assertEquals("123", response.getHeader("abc"));
+ assertEquals("456", response.getHeader("def"));
+ assertNull(response.getHeader("ghi"));
+ }
+
+ @Test
+ public void contentHeader() {
+ final ODataResponse response = ODataResponse.contentHeader(HttpContentType.APPLICATION_OCTET_STREAM).build();
+ assertNull(response.getStatus());
+ assertEquals(HttpContentType.APPLICATION_OCTET_STREAM, response.getContentHeader());
+ assertTrue(response.containsHeader(HttpHeaders.CONTENT_TYPE));
+ assertEquals(HttpContentType.APPLICATION_OCTET_STREAM, response.getHeader(HttpHeaders.CONTENT_TYPE));
+ assertFalse(response.containsHeader(HttpHeaders.CONTENT_LENGTH));
+ assertEquals(new HashSet<String>(Arrays.asList(HttpHeaders.CONTENT_TYPE)), response.getHeaderNames());
+ }
+
+ @Test
+ public void completeResponse() {
+ final ODataResponse response = ODataResponse.newBuilder()
+ .status(HttpStatusCodes.OK)
+ .header("def", "456")
+ .eTag("x")
+ .contentHeader(HttpContentType.TEXT_PLAIN)
+ .idLiteral("id")
+ .entity("body")
+ .build();
+ assertEquals(HttpStatusCodes.OK, response.getStatus());
+ assertEquals("456", response.getHeader("def"));
+ assertEquals("x", response.getETag());
+ assertEquals(HttpContentType.TEXT_PLAIN, response.getContentHeader());
+ assertEquals("id", response.getIdLiteral());
+ assertEquals(4, response.getHeaderNames().size());
+ assertEquals("body", response.getEntity());
+
+ final ODataResponse responseCopy = ODataResponse.fromResponse(response).build();
+ assertEquals(HttpStatusCodes.OK, responseCopy.getStatus());
+ assertEquals("456", responseCopy.getHeader("def"));
+ assertEquals("x", responseCopy.getETag());
+ assertEquals(HttpContentType.TEXT_PLAIN, response.getContentHeader());
+ assertEquals("id", responseCopy.getIdLiteral());
+ assertEquals("body", responseCopy.getEntity());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/PathSegmentTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/PathSegmentTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/PathSegmentTest.java
new file mode 100644
index 0000000..cba2439
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/PathSegmentTest.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.uri.PathSegment;
+import org.apache.olingo.odata2.testutil.fit.BaseTest;
+
+/**
+ * @author SAP AG
+ */
+public class PathSegmentTest extends BaseTest {
+
+ PathSegment segment;
+ PathSegment segmentNoMatrix;
+
+ @Before
+ public void before() {
+ Map<String, List<String>> map = new HashMap<String, List<String>>();
+ map.put("a", Arrays.asList("1"));
+ map.put("b", Arrays.asList("2"));
+ map.put("c", Arrays.asList("3"));
+ map.put("m", Arrays.asList("x", "y", "z"));
+
+ segment = new ODataPathSegmentImpl("segment", map);
+ segmentNoMatrix = new ODataPathSegmentImpl("segment", null);
+ }
+
+ @Test
+ public void testPathSegement() {
+ assertEquals("segment", segment.getPath());
+
+ assertEquals("1", segment.getMatrixParameters().get("a").get(0));
+ assertEquals("2", segment.getMatrixParameters().get("b").get(0));
+ assertEquals("3", segment.getMatrixParameters().get("c").get(0));
+
+ assertEquals("x", segment.getMatrixParameters().get("m").get(0));
+ assertEquals("y", segment.getMatrixParameters().get("m").get(1));
+ assertEquals("z", segment.getMatrixParameters().get("m").get(2));
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void readonlyMatrixParameter() {
+ segment.getMatrixParameters().get("m").clear();
+ }
+
+ @Test
+ public void noMatrixParameter() {
+ assertEquals("segment", segmentNoMatrix.getPath());
+ assertTrue(segmentNoMatrix.getMatrixParameters().isEmpty());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
new file mode 100644
index 0000000..88b3c11
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/AcceptParserTest.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * 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.core.batch;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+
+public class AcceptParserTest {
+ private static final String TAB = "\t";
+
+ @Test
+ public void testAcceptHeader() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ assertNotNull(acceptHeaders);
+ assertEquals(4, acceptHeaders.size());
+ assertEquals("text/html", acceptHeaders.get(0));
+ assertEquals("application/xhtml+xml", acceptHeaders.get(1));
+ assertEquals("application/xml", acceptHeaders.get(2));
+ assertEquals("*/*", acceptHeaders.get(3));
+ }
+
+ @Test
+ public void testAcceptHeaderWithParameter() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json;odata=verbose;q=1.0, */*;q=0.1");
+ assertNotNull(acceptHeaders);
+ assertEquals(2, acceptHeaders.size());
+ assertEquals("application/json;odata=verbose", acceptHeaders.get(0));
+ ;
+ assertEquals("*/*", acceptHeaders.get(1));
+ }
+
+ @Test
+ public void testAcceptHeaderWithParameterAndLws() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json; odata=verbose;q=1.0, */*;q=0.1");
+ assertNotNull(acceptHeaders);
+ assertEquals(2, acceptHeaders.size());
+ assertEquals("application/json; odata=verbose", acceptHeaders.get(0));
+ ;
+ assertEquals("*/*", acceptHeaders.get(1));
+ }
+
+ @Test
+ public void testAcceptHeaderWithTabulator() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/json;\todata=verbose;q=1.0, */*;q=0.1");
+ assertNotNull(acceptHeaders);
+ assertEquals(2, acceptHeaders.size());
+ assertEquals("application/json;" + TAB + "odata=verbose", acceptHeaders.get(0));
+ ;
+ assertEquals("*/*", acceptHeaders.get(1));
+ }
+
+ @Test
+ public void testAcceptHeaderWithTwoParameters() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/xml;another=test ; param=alskdf, */*;q=0.1");
+ assertNotNull(acceptHeaders);
+ assertEquals(2, acceptHeaders.size());
+ assertEquals("application/xml;another=test ; param=alskdf", acceptHeaders.get(0));
+ ;
+ assertEquals("*/*", acceptHeaders.get(1));
+ }
+
+ @Test
+ public void testAcceptHeader2() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("text/html;level=1, application/*, */*;q=0.1");
+ assertNotNull(acceptHeaders);
+ assertEquals(3, acceptHeaders.size());
+ assertEquals("text/html;level=1", acceptHeaders.get(0));
+ assertEquals("application/*", acceptHeaders.get(1));
+ assertEquals("*/*", acceptHeaders.get(2));
+ }
+
+ @Test
+ public void testMoreSpecificMediaType() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/*, application/xml");
+ assertNotNull(acceptHeaders);
+ assertEquals(2, acceptHeaders.size());
+ assertEquals("application/xml", acceptHeaders.get(0));
+ assertEquals("application/*", acceptHeaders.get(1));
+ }
+
+ @Test
+ public void testQualityParameter() throws BatchException {
+ List<String> acceptHeaders = AcceptParser.parseAcceptHeaders("application/*, */*; q=0.012");
+ assertNotNull(acceptHeaders);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidAcceptHeader() throws BatchException {
+ AcceptParser.parseAcceptHeaders("appi cation/*, */*;q=0.1");
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidQualityParameter() throws BatchException {
+ AcceptParser.parseAcceptHeaders("appication/*, */*;q=0,9");
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidQualityParameter2() throws BatchException {
+ AcceptParser.parseAcceptHeaders("appication/*, */*;q=1.0001");
+ }
+
+ @Test
+ public void testAcceptLanguages() throws BatchException {
+ List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("en-US,en;q=0.7,en-UK;q=0.9");
+ assertNotNull(acceptLanguageHeaders);
+ assertEquals(3, acceptLanguageHeaders.size());
+ assertEquals("en-US", acceptLanguageHeaders.get(0));
+ assertEquals("en-UK", acceptLanguageHeaders.get(1));
+ assertEquals("en", acceptLanguageHeaders.get(2));
+ }
+
+ @Test
+ public void testAllAcceptLanguages() throws BatchException {
+ List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("*");
+ assertNotNull(acceptLanguageHeaders);
+ assertEquals(1, acceptLanguageHeaders.size());
+ }
+
+ @Test
+ public void testLongAcceptLanguageValue() throws BatchException {
+ List<String> acceptLanguageHeaders = AcceptParser.parseAcceptableLanguages("english");
+ assertNotNull(acceptLanguageHeaders);
+ assertEquals("english", acceptLanguageHeaders.get(0));
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidAcceptLanguageValue() throws BatchException {
+ AcceptParser.parseAcceptableLanguages("en_US");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
new file mode 100644
index 0000000..edf5f3e
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchRequestParserTest.java
@@ -0,0 +1,593 @@
+/*******************************************************************************
+ * 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.core.batch;
+
+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 java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchPart;
+import org.apache.olingo.odata2.api.commons.HttpHeaders;
+import org.apache.olingo.odata2.api.commons.ODataHttpMethod;
+import org.apache.olingo.odata2.api.ep.EntityProviderBatchProperties;
+import org.apache.olingo.odata2.api.processor.ODataRequest;
+import org.apache.olingo.odata2.core.ODataPathSegmentImpl;
+import org.apache.olingo.odata2.core.PathInfoImpl;
+import org.apache.olingo.odata2.testutil.helper.StringHelper;
+
+/**
+ * @author SAP AG
+ */
+public class BatchRequestParserTest {
+
+ private static final String CONTENT_ID_REFERENCE = "NewEmployee";
+ private static final String PUT_MIME_HEADER_CONTENT_ID = "BBB_MIMEPART1";
+ private static final String PUT_REQUEST_HEADER_CONTENT_ID = "BBB_REQUEST1";
+ private static final String SERVICE_ROOT = "http://localhost/odata/";
+ private static EntityProviderBatchProperties batchProperties;
+ private static final String contentType = "multipart/mixed;boundary=batch_8194-cf13-1f56";
+ private static final String MIME_HEADERS = "Content-Type: application/http" + "\r\n"
+ + "Content-Transfer-Encoding: binary" + "\r\n";
+ private static final String GET_REQUEST = MIME_HEADERS + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "\n";
+
+ @BeforeClass
+ public static void setProperties() throws URISyntaxException {
+ PathInfoImpl pathInfo = new PathInfoImpl();
+ pathInfo.setServiceRoot(new URI(SERVICE_ROOT));
+ batchProperties = EntityProviderBatchProperties.init().pathInfo(pathInfo).build();
+
+ }
+
+ @Test
+ public void test() throws IOException, BatchException, URISyntaxException {
+ String fileName = "/batchWithPost.txt";
+ InputStream in = ClassLoader.class.getResourceAsStream(fileName);
+ if (in == null) {
+ throw new IOException("Requested file '" + fileName + "' was not found.");
+ }
+
+ BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
+ List<BatchPart> batchParts = parser.parse(in);
+ assertNotNull(batchParts);
+ assertEquals(false, batchParts.isEmpty());
+ for (BatchPart object : batchParts) {
+ if (!object.isChangeSet()) {
+ assertEquals(1, object.getRequests().size());
+ ODataRequest retrieveRequest = object.getRequests().get(0);
+ assertEquals(ODataHttpMethod.GET, retrieveRequest.getMethod());
+ if (!retrieveRequest.getAcceptableLanguages().isEmpty()) {
+ assertEquals(3, retrieveRequest.getAcceptableLanguages().size());
+ }
+ assertEquals(new URI(SERVICE_ROOT), retrieveRequest.getPathInfo().getServiceRoot());
+ ODataPathSegmentImpl pathSegment = new ODataPathSegmentImpl("Employees('2')", null);
+ assertEquals(pathSegment.getPath(), retrieveRequest.getPathInfo().getODataSegments().get(0).getPath());
+ if (retrieveRequest.getQueryParameters().get("$format") != null) {
+ assertEquals("json", retrieveRequest.getQueryParameters().get("$format"));
+ }
+ assertEquals(SERVICE_ROOT + "Employees('2')/EmployeeName?$format=json", retrieveRequest.getPathInfo().getRequestUri().toASCIIString());
+ } else {
+ List<ODataRequest> requests = object.getRequests();
+ for (ODataRequest request : requests) {
+
+ assertEquals(ODataHttpMethod.PUT, request.getMethod());
+ assertEquals("100000", request.getRequestHeaderValue(HttpHeaders.CONTENT_LENGTH.toLowerCase()));
+ assertEquals("application/json;odata=verbose", request.getContentType());
+ assertEquals(3, request.getAcceptHeaders().size());
+ assertNotNull(request.getAcceptableLanguages());
+ assertTrue(request.getAcceptableLanguages().isEmpty());
+ assertEquals("*/*", request.getAcceptHeaders().get(2));
+ assertEquals("application/atomsvc+xml", request.getAcceptHeaders().get(0));
+ assertEquals(new URI(SERVICE_ROOT + "Employees('2')/EmployeeName").toASCIIString(), request.getPathInfo().getRequestUri().toASCIIString());
+
+ ODataPathSegmentImpl pathSegment = new ODataPathSegmentImpl("Employees('2')", null);
+ assertEquals(pathSegment.getPath(), request.getPathInfo().getODataSegments().get(0).getPath());
+ ODataPathSegmentImpl pathSegment2 = new ODataPathSegmentImpl("EmployeeName", null);
+ assertEquals(pathSegment2.getPath(), request.getPathInfo().getODataSegments().get(1).getPath());
+
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testImageInContent() throws IOException, BatchException, URISyntaxException {
+ String fileName = "/batchWithContent.txt";
+ InputStream contentInputStream = ClassLoader.class.getResourceAsStream(fileName);
+ if (contentInputStream == null) {
+ throw new IOException("Requested file '" + fileName + "' was not found.");
+ }
+ String content = StringHelper.inputStreamToString(contentInputStream);
+ String batch = "\r\n"
+ + "--batch_8194-cf13-1f56" + "\r" + "\n"
+ + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + "\r\n"
+ + "\r\n"
+ + "--changeset_f980-1cb6-94dd" + "\r\n"
+ + "content-type: Application/http" + "\r\n"
+ + "content-transfer-encoding: Binary" + "\r\n"
+ + "Content-ID: 1" + "\r\n"
+ + "\r\n"
+ + "POST Employees HTTP/1.1" + "\r\n"
+ + "Content-length: 100000" + "\r\n"
+ + "Content-type: application/octet-stream" + "\r\n"
+ + "\r\n"
+ + content + "\r\n"
+ + "\r\n"
+ + "--changeset_f980-1cb6-94dd--" + "\r\n"
+ + "\r\n"
+ + "--batch_8194-cf13-1f56" + "\r\n"
+ + MIME_HEADERS
+ + "\r\n"
+ + "GET Employees?$filter=Age%20gt%2040 HTTP/1.1" + "\r\n"
+ + "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + "\r\n"
+ + "MaxDataServiceVersion: 2.0" + "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "--batch_8194-cf13-1f56--";
+ List<BatchPart> batchParts = parse(batch);
+ for (BatchPart object : batchParts) {
+ if (!object.isChangeSet()) {
+ assertEquals(1, object.getRequests().size());
+ ODataRequest retrieveRequest = object.getRequests().get(0);
+ assertEquals(ODataHttpMethod.GET, retrieveRequest.getMethod());
+ assertEquals("Age gt 40", retrieveRequest.getQueryParameters().get("$filter"));
+ assertEquals(new URI("http://localhost/odata/Employees?$filter=Age%20gt%2040"), retrieveRequest.getPathInfo().getRequestUri());
+ } else {
+ List<ODataRequest> requests = object.getRequests();
+ for (ODataRequest request : requests) {
+ assertEquals(ODataHttpMethod.POST, request.getMethod());
+ assertEquals("100000", request.getRequestHeaderValue(HttpHeaders.CONTENT_LENGTH.toLowerCase()));
+ assertEquals("1", request.getRequestHeaderValue(BatchConstants.MIME_HEADER_CONTENT_ID.toLowerCase()));
+ assertEquals("application/octet-stream", request.getContentType());
+ InputStream body = request.getBody();
+ assertEquals(content, StringHelper.inputStreamToString(body));
+
+ }
+
+ }
+ }
+ }
+
+ @Test
+ public void testPostWithoutBody() throws IOException, BatchException, URISyntaxException {
+ String fileName = "/batchWithContent.txt";
+ InputStream contentInputStream = ClassLoader.class.getResourceAsStream(fileName);
+ if (contentInputStream == null) {
+ throw new IOException("Requested file '" + fileName + "' was not found.");
+ }
+ StringHelper.inputStreamToString(contentInputStream);
+ String batch = "\r\n"
+ + "--batch_8194-cf13-1f56" + "\r" + "\n"
+ + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + "\r\n"
+ + "\r\n"
+ + "--changeset_f980-1cb6-94dd" + "\r\n"
+ + MIME_HEADERS
+ + "\r\n"
+ + "POST Employees('2') HTTP/1.1" + "\r\n"
+ + "Content-Length: 100" + "\r\n"
+ + "Content-Type: application/octet-stream" + "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "--changeset_f980-1cb6-94dd--" + "\r\n"
+ + "\r\n"
+ + "--batch_8194-cf13-1f56--";
+ List<BatchPart> batchParts = parse(batch);
+ for (BatchPart object : batchParts) {
+ if (object.isChangeSet()) {
+ List<ODataRequest> requests = object.getRequests();
+ for (ODataRequest request : requests) {
+ assertEquals(ODataHttpMethod.POST, request.getMethod());
+ assertEquals("100", request.getRequestHeaderValue(HttpHeaders.CONTENT_LENGTH.toLowerCase()));
+ assertEquals("application/octet-stream", request.getContentType());
+ assertNotNull(request.getBody());
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testBoundaryParameterWithQuotas() throws BatchException {
+ String contentType = "multipart/mixed; boundary=\"batch_1.2+34:2j)0?\"";
+
+ String batch = "--batch_1.2+34:2j)0?" + "\n"
+ + GET_REQUEST
+ + "--batch_1.2+34:2j)0?--";
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
+ List<BatchPart> batchParts = parser.parse(in);
+ assertNotNull(batchParts);
+ assertEquals(false, batchParts.isEmpty());
+ }
+
+ @Test(expected = BatchException.class)
+ public void testBatchWithInvalidContentType() throws BatchException {
+ String invalidContentType = "multipart;boundary=batch_1740-bb84-2f7f";
+
+ String batch = "--batch_1740-bb84-2f7f" + "\n"
+ + GET_REQUEST
+ + "--batch_1740-bb84-2f7f--";
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
+ parser.parse(in);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testBatchWithoutBoundaryParameter() throws BatchException {
+ String invalidContentType = "multipart/mixed";
+ String batch = "--batch_1740-bb84-2f7f" + "\n"
+ + GET_REQUEST
+ + "--batch_1740-bb84-2f7f--";
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
+ parser.parse(in);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testBoundaryParameterWithoutQuota() throws BatchException {
+ String invalidContentType = "multipart;boundary=batch_1740-bb:84-2f7f";
+ String batch = "--batch_1740-bb:84-2f7f" + "\n"
+ + GET_REQUEST
+ + "--batch_1740-bb:84-2f7f--";
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(invalidContentType, batchProperties);
+ parser.parse(in);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testWrongBoundaryString() throws BatchException {
+ String batch = "--batch_8194-cf13-1f5" + "\n"
+ + GET_REQUEST
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testBoundaryWithoutHyphen() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + GET_REQUEST
+ + "batch_8194-cf13-1f56" + "\n"
+ + GET_REQUEST
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoBoundaryString() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + GET_REQUEST
+ //+ no boundary string
+ + GET_REQUEST
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testBatchBoundaryEqualsChangeSetBoundary() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: multipart/mixed;boundary=batch_8194-cf13-1f56" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "PUT Employees('2')/EmployeeName HTTP/1.1" + "\n"
+ + "Accept: application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.1" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "MaxDataServiceVersion: 2.0" + "\n"
+ + "\n"
+ + "{\"EmployeeName\":\"Frederic Fall MODIFIED\"}" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoContentType() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Transfer-Encoding: binary" + "\n"
+ + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testMimeHeaderContentType() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: text/plain" + "\n"
+ + "Content-Transfer-Encoding: binary" + "\n"
+ + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testMimeHeaderEncoding() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: application/http" + "\n"
+ + "Content-Transfer-Encoding: 8bit" + "\n"
+ + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testMimeHeaderContentId() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "Content-ID: 1" + "\n"
+ + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidMethodForBatch() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "POST Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoMethod() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + /*GET*/"Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidMethodForChangeset() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + "\n"
+ + "\n"
+ + "--changeset_f980-1cb6-94dd" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees('2')/EmployeeName HTTP/1.1" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "MaxDataServiceVersion: 2.0" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testInvalidChangeSetBoundary() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: multipart/mixed;boundary=changeset_f980-1cb6-94dd" + "\n"
+ + "\n"
+ + "--changeset_f980-1cb6-94d"/*+"d"*/+ "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "POST Employees('2') HTTP/1.1" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "MaxDataServiceVersion: 2.0" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoCloseDelimiter() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + GET_REQUEST;
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoCloseDelimiter2() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees('1')/EmployeeName HTTP/1.1" + "\n"
+ /*--batch_8194-cf13-1f56--*/;
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test(expected = BatchException.class)
+ public void testNoCloseDelimiter3() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n" + GET_REQUEST + "--batch_8194-cf13-1f56-"/*no hash*/;
+ parseInvalidBatchBody(batch);
+ }
+
+ @Test
+ public void testAcceptHeaders() throws BatchException, URISyntaxException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees('2')/EmployeeName HTTP/1.1" + "\n"
+ + "Content-Length: 100000" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "Accept: application/xml;q=0.3, application/atomsvc+xml;q=0.8, application/json;odata=verbose;q=0.5, */*;q=0.001" + "\n"
+ + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ List<BatchPart> batchParts = parse(batch);
+ for (BatchPart multipart : batchParts) {
+ if (!multipart.isChangeSet()) {
+ assertEquals(1, multipart.getRequests().size());
+ ODataRequest retrieveRequest = multipart.getRequests().get(0);
+ assertEquals(ODataHttpMethod.GET, retrieveRequest.getMethod());
+ assertNotNull(retrieveRequest.getAcceptHeaders());
+ assertEquals(4, retrieveRequest.getAcceptHeaders().size());
+ assertEquals("application/atomsvc+xml", retrieveRequest.getAcceptHeaders().get(0));
+ assertEquals("*/*", retrieveRequest.getAcceptHeaders().get(3));
+ }
+
+ }
+ }
+
+ @Test
+ public void testAcceptHeaders2() throws BatchException, URISyntaxException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees('2')/EmployeeName HTTP/1.1" + "\n"
+ + "Content-Length: 100000" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "Accept: */*;q=0.5, application/json;odata=verbose;q=1.0,application/atom+xml" + "\n"
+ + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ List<BatchPart> batchParts = parse(batch);
+ for (BatchPart multipart : batchParts) {
+ if (!multipart.isChangeSet()) {
+ assertEquals(1, multipart.getRequests().size());
+ ODataRequest retrieveRequest = multipart.getRequests().get(0);
+ assertEquals(ODataHttpMethod.GET, retrieveRequest.getMethod());
+ assertNotNull(retrieveRequest.getAcceptHeaders());
+ assertEquals(3, retrieveRequest.getAcceptHeaders().size());
+ assertEquals("application/json;odata=verbose", retrieveRequest.getAcceptHeaders().get(0));
+ assertEquals("application/atom+xml", retrieveRequest.getAcceptHeaders().get(1));
+ assertEquals("*/*", retrieveRequest.getAcceptHeaders().get(2));
+ }
+
+ }
+ }
+
+ @Test
+ public void testAcceptHeaders3() throws BatchException, URISyntaxException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees('2')/EmployeeName HTTP/1.1" + "\n"
+ + "Content-Length: 100000" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "accept: */*,application/atom+xml,application/atomsvc+xml,application/xml" + "\n"
+ + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ List<BatchPart> batchParts = parse(batch);
+ for (BatchPart multipart : batchParts) {
+ if (!multipart.isChangeSet()) {
+ assertEquals(1, multipart.getRequests().size());
+ ODataRequest retrieveRequest = multipart.getRequests().get(0);
+ assertEquals(ODataHttpMethod.GET, retrieveRequest.getMethod());
+ assertNotNull(retrieveRequest.getAcceptHeaders());
+ assertEquals(4, retrieveRequest.getAcceptHeaders().size());
+
+ assertEquals("application/atom+xml", retrieveRequest.getAcceptHeaders().get(0));
+ assertEquals("application/atomsvc+xml", retrieveRequest.getAcceptHeaders().get(1));
+
+ assertEquals("application/xml", retrieveRequest.getAcceptHeaders().get(2));
+ }
+
+ }
+ }
+
+ @Test
+ public void testContentId() throws BatchException {
+ String batch = "--batch_8194-cf13-1f56" + "\n"
+ + MIME_HEADERS
+ + "\n"
+ + "GET Employees HTTP/1.1" + "\n"
+ + "accept: */*,application/atom+xml,application/atomsvc+xml,application/xml" + "\n"
+ + "Content-Id: BBB" + "\n"
+ + "\n" + "\n"
+ + "--batch_8194-cf13-1f56" + "\n"
+ + "Content-Type: multipart/mixed; boundary=changeset_f980-1cb6-94dd" + "\n"
+ + "\n"
+ + "--changeset_f980-1cb6-94dd" + "\n"
+ + MIME_HEADERS
+ + "Content-Id: " + CONTENT_ID_REFERENCE + "\n"
+ + "\n"
+ + "POST Employees HTTP/1.1" + "\n"
+ + "Content-type: application/octet-stream" + "\n"
+ + "\n"
+ + "/9j/4AAQSkZJRgABAQEBLAEsAAD/4RM0RXhpZgAATU0AKgAAAAgABwESAAMAAAABAAEAAAEaAAUAAAABAAAAYgEbAAUAAAA" + "\n"
+ + "\n"
+ + "--changeset_f980-1cb6-94dd" + "\n"
+ + MIME_HEADERS
+ + "Content-ID: " + PUT_MIME_HEADER_CONTENT_ID + "\n"
+ + "\n"
+ + "PUT $" + CONTENT_ID_REFERENCE + "/EmployeeName HTTP/1.1" + "\n"
+ + "Content-Type: application/json;odata=verbose" + "\n"
+ + "Content-Id:" + PUT_REQUEST_HEADER_CONTENT_ID + "\n"
+ + "\n"
+ + "{\"EmployeeName\":\"Peter Fall\"}" + "\n"
+ + "--changeset_f980-1cb6-94dd--" + "\n"
+ + "\n"
+ + "--batch_8194-cf13-1f56--";
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
+ List<BatchPart> batchParts = parser.parse(in);
+ assertNotNull(batchParts);
+ for (BatchPart multipart : batchParts) {
+ if (!multipart.isChangeSet()) {
+ assertEquals(1, multipart.getRequests().size());
+ ODataRequest retrieveRequest = multipart.getRequests().get(0);
+ assertEquals("BBB", retrieveRequest.getRequestHeaderValue(BatchConstants.REQUEST_HEADER_CONTENT_ID.toLowerCase()));
+ } else {
+ for (ODataRequest request : multipart.getRequests()) {
+ if (ODataHttpMethod.POST.equals(request.getMethod())) {
+ assertEquals(CONTENT_ID_REFERENCE, request.getRequestHeaderValue(BatchConstants.MIME_HEADER_CONTENT_ID.toLowerCase()));
+ } else if (ODataHttpMethod.PUT.equals(request.getMethod())) {
+ assertEquals(PUT_MIME_HEADER_CONTENT_ID, request.getRequestHeaderValue(BatchConstants.MIME_HEADER_CONTENT_ID.toLowerCase()));
+ assertEquals(PUT_REQUEST_HEADER_CONTENT_ID, request.getRequestHeaderValue(BatchConstants.REQUEST_HEADER_CONTENT_ID.toLowerCase()));
+ assertNull(request.getPathInfo().getRequestUri());
+ assertEquals("$" + CONTENT_ID_REFERENCE, request.getPathInfo().getODataSegments().get(0).getPath());
+ }
+ }
+ }
+ }
+ }
+
+ private List<BatchPart> parse(final String batch) throws BatchException {
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
+ List<BatchPart> batchParts = parser.parse(in);
+ assertNotNull(batchParts);
+ assertEquals(false, batchParts.isEmpty());
+ return batchParts;
+ }
+
+ private void parseInvalidBatchBody(final String batch) throws BatchException {
+ InputStream in = new ByteArrayInputStream(batch.getBytes());
+ BatchRequestParser parser = new BatchRequestParser(contentType, batchProperties);
+ parser.parse(in);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-olingo-odata2/blob/ff2b0a0e/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
----------------------------------------------------------------------
diff --git a/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
new file mode 100644
index 0000000..f236226
--- /dev/null
+++ b/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/BatchResponseWriterTest.java
@@ -0,0 +1,153 @@
+/*******************************************************************************
+ * 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.core.batch;
+
+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.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.olingo.odata2.api.batch.BatchException;
+import org.apache.olingo.odata2.api.batch.BatchResponsePart;
+import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
+import org.apache.olingo.odata2.api.processor.ODataResponse;
+
+public class BatchResponseWriterTest {
+
+ @Test
+ public void testBatchResponse() throws BatchException, IOException {
+ List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+ ODataResponse response = ODataResponse.entity("Walter Winter")
+ .status(HttpStatusCodes.OK)
+ .contentHeader("application/json")
+ .build();
+ List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+ responses.add(response);
+ parts.add(BatchResponsePart.responses(responses).changeSet(false).build());
+
+ ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+ responses = new ArrayList<ODataResponse>(1);
+ responses.add(changeSetResponse);
+ parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+ BatchResponseWriter writer = new BatchResponseWriter();
+ ODataResponse batchResponse = writer.writeResponse(parts);
+
+ assertEquals(202, batchResponse.getStatus().getStatusCode());
+ assertNotNull(batchResponse.getEntity());
+ String body = (String) batchResponse.getEntity();
+
+ assertTrue(body.contains("--batch"));
+ assertTrue(body.contains("--changeset"));
+ assertTrue(body.contains("HTTP/1.1 200 OK"));
+ assertTrue(body.contains("Content-Type: application/http"));
+ assertTrue(body.contains("Content-Transfer-Encoding: binary"));
+ assertTrue(body.contains("Walter Winter"));
+ assertTrue(body.contains("multipart/mixed; boundary=changeset"));
+ assertTrue(body.contains("HTTP/1.1 204 No Content"));
+
+ }
+
+ @Test
+ public void testResponse() throws BatchException, IOException {
+ List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+ ODataResponse response = ODataResponse.entity("Walter Winter").status(HttpStatusCodes.OK).contentHeader("application/json").build();
+ List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+ responses.add(response);
+ parts.add(BatchResponsePart.responses(responses).changeSet(false).build());
+ BatchResponseWriter writer = new BatchResponseWriter();
+ ODataResponse batchResponse = writer.writeResponse(parts);
+
+ assertEquals(202, batchResponse.getStatus().getStatusCode());
+ assertNotNull(batchResponse.getEntity());
+ String body = (String) batchResponse.getEntity();
+
+ assertTrue(body.contains("--batch"));
+ assertFalse(body.contains("--changeset"));
+ assertTrue(body.contains("HTTP/1.1 200 OK" + "\r\n"));
+ assertTrue(body.contains("Content-Type: application/http" + "\r\n"));
+ assertTrue(body.contains("Content-Transfer-Encoding: binary" + "\r\n"));
+ assertTrue(body.contains("Walter Winter"));
+ assertFalse(body.contains("multipart/mixed; boundary=changeset"));
+
+ }
+
+ @Test
+ public void testChangeSetResponse() throws BatchException, IOException {
+ List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+ ODataResponse changeSetResponse = ODataResponse.status(HttpStatusCodes.NO_CONTENT).build();
+ List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+ responses.add(changeSetResponse);
+ parts.add(BatchResponsePart.responses(responses).changeSet(true).build());
+
+ BatchResponseWriter writer = new BatchResponseWriter();
+ ODataResponse batchResponse = writer.writeResponse(parts);
+
+ assertEquals(202, batchResponse.getStatus().getStatusCode());
+ assertNotNull(batchResponse.getEntity());
+ String body = (String) batchResponse.getEntity();
+ assertTrue(body.contains("--batch"));
+ assertTrue(body.contains("--changeset"));
+ assertTrue(body.indexOf("--changeset") != body.lastIndexOf("--changeset"));
+ assertFalse(body.contains("HTTP/1.1 200 OK" + "\r\n"));
+ assertTrue(body.contains("Content-Type: application/http" + "\r\n"));
+ assertTrue(body.contains("Content-Transfer-Encoding: binary" + "\r\n"));
+ assertTrue(body.contains("HTTP/1.1 204 No Content" + "\r\n"));
+ assertTrue(body.contains("Content-Type: multipart/mixed; boundary=changeset"));
+
+ }
+
+ @Test
+ public void testContentIdEchoing() throws BatchException, IOException {
+ List<BatchResponsePart> parts = new ArrayList<BatchResponsePart>();
+ ODataResponse response = ODataResponse.entity("Walter Winter")
+ .status(HttpStatusCodes.OK)
+ .contentHeader("application/json")
+ .header(BatchConstants.MIME_HEADER_CONTENT_ID, "mimeHeaderContentId123")
+ .header(BatchConstants.REQUEST_HEADER_CONTENT_ID, "requestHeaderContentId123")
+ .build();
+ List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
+ responses.add(response);
+ parts.add(BatchResponsePart.responses(responses).changeSet(false).build());
+ BatchResponseWriter writer = new BatchResponseWriter();
+ ODataResponse batchResponse = writer.writeResponse(parts);
+
+ assertEquals(202, batchResponse.getStatus().getStatusCode());
+ assertNotNull(batchResponse.getEntity());
+ String body = (String) batchResponse.getEntity();
+
+ String mimeHeader = "Content-Type: application/http" + "\r\n"
+ + "Content-Transfer-Encoding: binary" + "\r\n"
+ + "Content-Id: mimeHeaderContentId123" + "\r\n";
+
+ String requestHeader = "Content-Id: requestHeaderContentId123" + "\r\n"
+ + "Content-Type: application/json" + "\r\n"
+ + "Content-Length: 13" + "\r\n";
+
+ assertTrue(body.contains(mimeHeader));
+ assertTrue(body.contains(requestHeader));
+ }
+
+}