/*******************************************************************************
* Copyright 2013 SAP AG
*
* Licensed 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 com.sap.core.odata.core.ep.consumer;
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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import javax.xml.stream.XMLStreamReader;
import org.junit.Test;
import com.sap.core.odata.api.edm.Edm;
import com.sap.core.odata.api.edm.EdmComplexType;
import com.sap.core.odata.api.edm.EdmFacets;
import com.sap.core.odata.api.edm.EdmProperty;
import com.sap.core.odata.api.edm.EdmSimpleTypeException;
import com.sap.core.odata.api.edm.EdmSimpleTypeKind;
import com.sap.core.odata.api.ep.EntityProviderException;
import com.sap.core.odata.testutil.mock.MockFacade;
/**
* @author SAP AG
*/
public class XmlPropertyConsumerTest extends AbstractConsumerTest {
@Test
public void readIntegerProperty() throws Exception {
String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">67</Age>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertEquals(Integer.valueOf(67), resultMap.get("Age"));
}
@Test
public void readIntegerPropertyAsLong() throws Exception {
String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">67</Age>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
Map<String, Object> typeMappings = createTypeMappings("Age", Long.class);
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings);
assertEquals(Long.valueOf(67), resultMap.get("Age"));
}
@Test
public void readIntegerPropertyWithNullMapping() throws Exception {
String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">67</Age>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
Map<String, Object> typeMappings = null;
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings);
assertEquals(Integer.valueOf(67), resultMap.get("Age"));
}
@Test
public void readIntegerPropertyWithEmptyMapping() throws Exception {
String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">67</Age>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
Map<String, Object> typeMappings = new HashMap<String, Object>();
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false, typeMappings);
assertEquals(Integer.valueOf(67), resultMap.get("Age"));
}
@Test
public void readStringProperty() throws Exception {
String xml = "<EmployeeName xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">Max Mustermann</EmployeeName>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName");
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertEquals("Max Mustermann", resultMap.get("EmployeeName"));
}
@Test
public void readStringPropertyEmpty() throws Exception {
final String xml = "<EmployeeName xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EmployeeName");
final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertTrue(resultMap.containsKey("EmployeeName"));
assertEquals("", resultMap.get("EmployeeName"));
}
@Test
public void readStringPropertyNull() throws Exception {
final String xml = "<EntryDate xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertTrue(resultMap.containsKey("EntryDate"));
assertNull(resultMap.get("EntryDate"));
}
@Test
public void readStringPropertyNullFalse() throws Exception {
final String xml = "<EntryDate xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"false\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\">1970-01-02T00:00:00</EntryDate>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("EntryDate");
final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertEquals(86400000L, ((Calendar) resultMap.get("EntryDate")).getTimeInMillis());
}
@Test(expected = EntityProviderException.class)
public void invalidSimplePropertyName() throws Exception {
final String xml = "<Invalid xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\">67</Invalid>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void invalidNullAttribute() throws Exception {
final String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"wrong\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void nullValueNotAllowed() throws Exception {
final String xml = "<Age xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Age");
EdmFacets facets = mock(EdmFacets.class);
when(facets.isNullable()).thenReturn(false);
when(property.getFacets()).thenReturn(facets);
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test
@SuppressWarnings("unchecked")
public void readComplexProperty() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
assertEquals("Germany", locationMap.get("Country"));
Map<String, Object> cityMap = (Map<String, Object>) locationMap.get("City");
assertEquals("69124", cityMap.get("PostalCode"));
assertEquals("Heidelberg", cityMap.get("CityName"));
}
@Test
@SuppressWarnings("unchecked")
public void readComplexPropertyWithLineBreaks() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
" " +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"\n" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>" +
"\n \n ";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
assertEquals("Germany", locationMap.get("Country"));
Map<String, Object> cityMap = (Map<String, Object>) locationMap.get("City");
assertEquals("69124", cityMap.get("PostalCode"));
assertEquals("Heidelberg", cityMap.get("CityName"));
}
@Test(expected = EntityProviderException.class)
public void readComplexPropertyInvalidMapping() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" type=\"RefScenario.c_Location\">" +
"<Country>Germany</Country>" +
"<City type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
try {
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false,
createTypeMappings("Location", createTypeMappings("City", createTypeMappings("PostalCode", Integer.class))));
assertNotNull(resultMap);
} catch (EntityProviderException e) {
assertTrue(e.getCause() instanceof EdmSimpleTypeException);
throw e;
}
}
@Test
@SuppressWarnings("unchecked")
public void readComplexPropertyWithMappings() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
" <PostalCode>69124</PostalCode>" +
" <CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
EdmProperty locationComplexProperty = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
EdmProperty cityProperty = (EdmProperty) ((EdmComplexType) locationComplexProperty.getType()).getProperty("City");
EdmProperty postalCodeProperty = (EdmProperty) ((EdmComplexType) cityProperty.getType()).getProperty("PostalCode");
// Change the type of the PostalCode property to one that allows different Java types.
when(postalCodeProperty.getType()).thenReturn(EdmSimpleTypeKind.Int32.getEdmSimpleTypeInstance());
// Execute test
Map<String, Object> typeMappings =
createTypeMappings("Location",
createTypeMappings("City",
createTypeMappings("CityName", String.class, "PostalCode", Long.class)));
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, locationComplexProperty, false, typeMappings);
// verify
Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
assertEquals("Germany", locationMap.get("Country"));
Map<String, Object> cityMap = (Map<String, Object>) locationMap.get("City");
assertEquals(Long.valueOf("69124"), cityMap.get("PostalCode"));
assertEquals("Heidelberg", cityMap.get("CityName"));
}
@SuppressWarnings("unchecked")
@Test
public void readComplexPropertyWithNamespace() throws Exception {
String xml =
"<d:Location m:type=\"RefScenario.c_Location\" " +
" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\"" +
" xmlns:d=\"" + Edm.NAMESPACE_D_2007_08 + "\">" +
" <d:Country>Germany</d:Country>" +
" <d:City m:type=\"RefScenario.c_City\">" +
" <d:PostalCode>69124</d:PostalCode>" +
" <d:CityName>Heidelberg</d:CityName>" +
" </d:City>" +
"</d:Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
Object prop = new XmlPropertyConsumer().readProperty(reader, property, false);
Map<String, Object> resultMap = (Map<String, Object>) prop;
Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
assertEquals("Germany", locationMap.get("Country"));
Map<String, Object> cityMap = (Map<String, Object>) locationMap.get("City");
assertEquals("69124", cityMap.get("PostalCode"));
assertEquals("Heidelberg", cityMap.get("CityName"));
}
@Test(expected = EntityProviderException.class)
public void readComplexPropertyWithInvalidChild() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
"<Invalid>Germany</Invalid>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void readComplexPropertyWithInvalidDeepChild() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<Invalid>69124</Invalid>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void readComplexPropertyWithInvalidName() throws Exception {
String xml =
"<Invalid xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"RefScenario.c_Location\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Invalid>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void readComplexPropertyWithInvalidTypeAttribute() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" m:type=\"Invalid\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test
@SuppressWarnings("unchecked")
public void readComplexPropertyWithoutTypeAttribute() throws Exception {
String xml =
"<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\""
+ " xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\">" +
"<Country>Germany</Country>" +
"<City m:type=\"RefScenario.c_City\">" +
"<PostalCode>69124</PostalCode>" +
"<CityName>Heidelberg</CityName>" +
"</City>" +
"</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
Map<String, Object> locationMap = (Map<String, Object>) resultMap.get("Location");
assertEquals("Germany", locationMap.get("Country"));
Map<String, Object> cityMap = (Map<String, Object>) locationMap.get("City");
assertEquals("69124", cityMap.get("PostalCode"));
assertEquals("Heidelberg", cityMap.get("CityName"));
}
@Test
public void complexPropertyNull() throws Exception {
String xml = "<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertTrue(resultMap.containsKey("Location"));
assertNull(resultMap.get("Location"));
}
@Test(expected = EntityProviderException.class)
public void complexPropertyNullValueNotAllowed() throws Exception {
final String xml = "<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
EdmFacets facets = mock(EdmFacets.class);
when(facets.isNullable()).thenReturn(false);
when(property.getFacets()).thenReturn(facets);
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test(expected = EntityProviderException.class)
public void complexPropertyNullWithContent() throws Exception {
String xml = "<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08
+ "\" m:null=\"true\" xmlns:m=\"" + Edm.NAMESPACE_M_2007_08 + "\">"
+ "<City><PostalCode/><CityName/></City><Country>Germany</Country>"
+ "</Location>";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
new XmlPropertyConsumer().readProperty(reader, property, false);
}
@Test
public void complexPropertyEmpty() throws Exception {
final String xml = "<Location xmlns=\"" + Edm.NAMESPACE_D_2007_08 + "\" />";
XMLStreamReader reader = createReaderForTest(xml, true);
final EdmProperty property = (EdmProperty) MockFacade.getMockEdm().getEntityType("RefScenario", "Employee").getProperty("Location");
final Map<String, Object> resultMap = new XmlPropertyConsumer().readProperty(reader, property, false);
assertNotNull(resultMap.get("Location"));
@SuppressWarnings("unchecked")
final Map<String, Object> innerMap = (Map<String, Object>) resultMap.get("Location");
assertTrue(innerMap.isEmpty());
}
}