blob: f34acb58bde6ac8bb3a2004f9dd12f4e5c8751cc [file] [log] [blame]
/*******************************************************************************
* 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.fit.ref;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathEvaluatesTo;
import static org.custommonkey.xmlunit.XMLAssert.assertXpathNotExists;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import java.lang.reflect.Field;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.olingo.odata2.api.commons.HttpContentType;
import org.apache.olingo.odata2.api.commons.HttpStatusCodes;
import org.apache.olingo.odata2.ref.model.DataContainer;
import org.apache.olingo.odata2.ref.model.Photo;
import org.apache.olingo.odata2.ref.processor.ListsProcessor;
import org.apache.olingo.odata2.ref.processor.ScenarioDataSource;
import org.apache.olingo.odata2.testutil.server.ServletType;
import org.custommonkey.xmlunit.XMLAssert;
import org.junit.Test;
/**
* Tests employing the reference scenario reading a single entity in XML format.
*
*/
public class EntryXmlReadOnlyTest extends AbstractRefXmlTest {
public EntryXmlReadOnlyTest(final ServletType servletType) {
super(servletType);
}
@Test
public void entry() throws Exception {
HttpResponse response = callUri("Employees('2')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertNull(response.getFirstHeader(HttpHeaders.ETAG));
assertXpathEvaluatesTo(EMPLOYEE_2_NAME, "/atom:entry/m:properties/d:EmployeeName", getBody(response));
response = callUri("Managers('3')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo(EMPLOYEE_3_NAME, "/atom:entry/m:properties/d:EmployeeName", getBody(response));
response = callUri("Teams('2')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo("2", "/atom:entry/atom:content/m:properties/d:Id", getBody(response));
response = callUri("Rooms('1')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
checkEtag(response, "W/\"1\"");
String body = getBody(response);
assertXpathEvaluatesTo("W/\"1\"", "/atom:entry/@m:etag", body);
assertXpathEvaluatesTo("1", "/atom:entry/atom:content/m:properties/d:Id", body);
response = callUri("Rooms('1')?$expand=nr_Employees");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
// assertNull(response.getFirstHeader(HttpHeaders.ETAG));
assertXpathEvaluatesTo(
EMPLOYEE_1_NAME,
"/atom:entry/atom:link[@href=\"Rooms('1')/nr_Employees\"]" +
"/m:inline/atom:feed/atom:entry/m:properties/d:EmployeeName",
getBody(response));
response = callUri("Container2.Photos(Id=1,Type='image%2Fpng')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
body = getBody(response);
assertXpathEvaluatesTo("image/png", "/atom:entry/m:properties/d:Type", body);
assertXpathEvaluatesTo(IMAGE_JPEG, "/atom:entry/m:properties/d:Image/@m:MimeType", body);
assertXpathEvaluatesTo(PHOTO_DEFAULT_IMAGE, "/atom:entry/m:properties/d:Image", body);
response = callUri("Container2.Photos(Id=4,Type='foo')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo("Container2.Photos(Id=4,Type='foo')/$value", "/atom:entry/atom:content/@src",
getBody(response));
notFound("Managers('5')");
notFound("Managers('1%2C2')");
badRequest("Managers('3')?$top=1");
badRequest("Rooms(X'33')");
}
@Test
public void entryWithSpecialKey() throws Exception {
// Ugly hack to create an entity with a key containing special characters just for this test.
ListsProcessor processor = (ListsProcessor) getService().getEntityProcessor();
Field field = getField(processor.getClass(), "dataSource");
field.setAccessible(true);
ScenarioDataSource dataSource = (ScenarioDataSource) field.get(processor);
field = getField(dataSource.getClass(), "dataContainer");
field.setAccessible(true);
DataContainer dataContainer = (DataContainer) field.get(dataSource);
// Add a new Photo where the "Type" property is set to, space-separated,
// a literal percent character, all gen-delims, and all sub-delims
// as specified by RFC 3986.
dataContainer.getPhotos().add(new Photo(42, "strange Photo", "% :/?#[]@ !$&'()*+,;="));
// Check that percent-decoding and -encoding works as expected.
final String url =
"Container2.Photos(Id=42,Type='%25%20%3A%2F%3F%23%5B%5D%40%20%21%24%26%27%28%29%2A%2B%2C%3B%3D')";
final String expected = url.replace("%27", "''");
final HttpResponse response = callUri(url);
final String body = getBody(response);
assertXpathEvaluatesTo("strange Photo", "/atom:entry/m:properties/d:Name", body);
assertXpathEvaluatesTo(expected, "/atom:entry/atom:link[@rel=\"edit\"]/@href", body);
assertXpathEvaluatesTo(expected + "/$value", "/atom:entry/atom:link[@rel=\"edit-media\"]/@href", body);
}
private Field getField(final Class<?> clazz, final String string) throws Exception {
try {
return clazz.getDeclaredField(string);
} catch (NoSuchFieldException e) {
if (clazz == Object.class) {
throw e;
}
return getField(clazz.getSuperclass(), string);
}
}
@Test
public void expand() throws Exception {
HttpResponse response = callUri("Employees('5')?$expand=ne_Manager");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
String body = getBody(response);
assertXpathEvaluatesTo(EMPLOYEE_5_NAME, "/atom:entry/m:properties/d:EmployeeName", body);
assertXpathEvaluatesTo(EMPLOYEE_3_NAME,
"/atom:entry/atom:link[@href=\"Employees('5')/ne_Manager\"]/m:inline/atom:entry/m:properties/d:EmployeeName",
body);
response = callUri("Rooms('3')?$expand=nr_Employees/ne_Manager");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
body = getBody(response);
assertXpathEvaluatesTo("3", "/atom:entry/atom:content[@type=\"application/xml\"]/m:properties/d:Id", body);
assertXpathEvaluatesTo("1",
"count(/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]/m:inline/atom:feed/atom:entry)", body);
assertXpathEvaluatesTo(
EMPLOYEE_5_NAME,
"/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]" +
"/m:inline/atom:feed/atom:entry/m:properties/d:EmployeeName",
body);
assertXpathEvaluatesTo(
EMPLOYEE_3_NAME,
"/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]" +
"/m:inline/atom:feed/atom:entry/atom:link[@href=\"Employees('5')/ne_Manager\"]" +
"/m:inline/atom:entry/m:properties/d:EmployeeName",
body);
notFound("Employees('3')?$expand=noNavProp");
badRequest("Employees('3')?$expand=Age");
badRequest("Employees()?$expand=ne_Room/Seats");
notFound("Employees()?$expand=ne_Room/noNavProp");
}
@Test
public void select() throws Exception {
HttpResponse response = callUri("Employees('6')?$select=EmployeeId,Age");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
String body = getBody(response);
assertXpathEvaluatesTo("6", "/atom:entry/m:properties/d:EmployeeId", body);
assertXpathEvaluatesTo(EMPLOYEE_6_AGE, "/atom:entry/m:properties/d:Age", body);
assertXpathNotExists("/atom:entry/m:properties/d:Location", body);
assertXpathEvaluatesTo("2", "count(/atom:entry/atom:link)", body);
response = callUri("Employees('3')/ne_Room?$select=Seats");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
body = getBody(response);
assertXpathEvaluatesTo("5", "/atom:entry/atom:content/m:properties/d:Seats", body);
assertXpathNotExists("/atom:entry/m:properties/d:Id", body);
final String entry = getBody(callUri("Employees('6')"));
assertEquals(entry, getBody(callUri("Employees('6')?$select=*,Age")));
assertEquals(entry, getBody(callUri("Employees('6')?$select=*,ne_Room")));
checkUri("Container2.Photos(Id=4,Type='foo')?$select=%D0%A1%D0%BE%D0%B4%D0%B5%D1%80%D0%B6" +
"%D0%B0%D0%BD%D0%B8%D0%B5,Id");
response = callUri("Employees('6')?$expand=ne_Room&$select=ne_Room/Version");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
body = getBody(response);
assertXpathEvaluatesTo(
"2",
"/atom:entry/atom:link[@href=\"Employees('6')/ne_Room\"]/m:inline/atom:entry/atom:content" +
"[@type=\"application/xml\"]/m:properties/d:Version",
body);
assertXpathNotExists("/atom:entry/m:properties/d:Location", body);
assertXpathNotExists(
"/atom:entry/atom:link[@href=\"Employees('6')/ne_Room\"]/m:inline/atom:entry/atom:content" +
"[@type=\"application/xml\"]/m:properties/d:Seats",
body);
response = callUri("Rooms('3')?$expand=nr_Employees/ne_Team&$select=nr_Employees/ne_Team/Name");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
body = getBody(response);
assertXpathEvaluatesTo(
"Team 2",
"/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]/m:inline/atom:feed/atom:entry" +
"/atom:link[@href=\"Employees('5')/ne_Team\"]/m:inline/atom:entry/atom:content/m:properties/d:Name",
body);
assertXpathNotExists("/atom:entry/atom:content/m:properties", body);
assertXpathNotExists(
"/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]/m:inline/atom:feed/atom:entry/m:properties", body);
assertXpathNotExists(
"/atom:entry/atom:link[@href=\"Rooms('3')/nr_Employees\"]/m:inline/atom:feed/atom:entry" +
"/atom:link[@href=\"Employees('5')/ne_Team\"]/m:inline/atom:entry/atom:content/m:properties/d:Id",
body);
notFound("Teams('3')?$select=noProp");
notFound("Teams()?$select=nt_Employees/noProp");
notFound("Employees('3')/ne_Room?$select=Age");
notFound("Employees('3')/ne_Room?$select=ne_Room");
}
@Test
public void entryMediaResource() throws Exception {
HttpResponse response = callUri("Employees('2')/$value");
checkMediaType(response, IMAGE_JPEG);
assertNotNull(getBody(response));
response = callUri("Employees('2')/$value?$format=xml", HttpStatusCodes.BAD_REQUEST);
String body = getBody(response);
XMLAssert.assertXpathExists("/m:error/m:message", body);
}
@Test
public void navigationEntry() throws Exception {
HttpResponse response = callUri("Employees('2')/ne_Manager");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo(MANAGER_NAME, "/atom:entry/m:properties/d:EmployeeName", getBody(response));
response = callUri("Employees('2')/ne_Team/nt_Employees('1')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo(EMPLOYEE_1_NAME, "/atom:entry/m:properties/d:EmployeeName", getBody(response));
response = callUri("Employees('2')/ne_Manager/nm_Employees('6')");
checkMediaType(response, HttpContentType.APPLICATION_ATOM_XML_UTF8 + ";type=entry");
assertXpathEvaluatesTo(EMPLOYEE_6_NAME, "/atom:entry/m:properties/d:EmployeeName", getBody(response));
badRequest("Employees('2')/ne_Manager()");
}
}