I'm implementing a web service respecting version 4 of the OData standard in Java language with the framework Olingo. I need to customize the response of $filter
. I've implemented a Visitor as documented in the quick start. I need to implement an integration Test to try a different kind of grammar and to prevent regression bug in case of future maintenance.
For the V2, I found the following tutorial and the following code :
@Test
public void printExpressionWithProperty() throws Exception {
//Use a mocked edmProvider for this tutorial
TestEdmProvider provider = new TestEdmProvider();
Edm edm = RuntimeDelegate.createEdm(provider);
EdmEntityType entityType = edm.getEntityType(TestEdmProvider.NAMESPACE_1, TestEdmProvider.ENTITY_TYPE_1_1.getName());
String rawExpression = "EmployeeId eq '1'";
FilterExpression expression = UriParser.parseFilter (null, entityType, rawExpression);
String whereClause = (String) expression.accept(new JdbcSimpleStringVisitor());
System.out.println("Raw: " + rawExpression + " ------> Whereclause: " + whereClause);
System.out.println();
}
Unfortunately, UriParser.parseFilter
doesn't exist in the v4.
I tried this :
public class MyVisitorTest {
private final FullQualifiedName NAME1 = new FullQualifiedName("testNamespace1", "myfield");
private final OData odata = OData.newInstance();
public EdmEntityType createEntityType(final FullQualifiedName fqn) {
if (NAME1.equals(fqn)) {
EdmEntityType entityType = mock(EdmEntityType.class);
when(entityType.getNamespace()).thenReturn(fqn.getNamespace());
when(entityType.getName()).thenReturn(fqn.getName());
return entityType;
}
return null;
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
EdmEntityType entityType = createEntityType(NAME1);
Edm edm = mock(Edm.class);
when(edm.getEntityType(NAME1)).thenReturn(entityType);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, null, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
@Test
public void simpleTest() throws UriParserException, UriValidationException, ODataApplicationException, ExpressionVisitException {
String exp = "myfield gt 2019-01-01T00:00:00Z";
Expression e = parseExpression(exp);
MyVisitor myVisitor = new MyVisitor();
String result = (String) e.accept(startEndMeasureVisitor);
assertEquals(result.toString(), "MyResult");
}
}
And it doesn't work, it sends me the following message :
Property paths must follow a structured type.
So I'm looking for any ideas to make my unit test to work or if you've got working example to share...
Here we go, thanks to tracing function of mockup (very usefull with legacy code), I've got the new version of parseExpression
method that answer my question.
class A implements EdmStructuredType, EdmPrimitiveType {
@Override
public boolean isCompatible(EdmPrimitiveType edmPrimitiveType) {
return false;
}
@Override
public Class<?> getDefaultType() {
return null;
}
@Override
public boolean validate(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) {
return false;
}
@Override
public <T> T valueOfString(String s, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1, Class<T> aClass) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String valueToString(Object o, Boolean aBoolean, Integer integer, Integer integer1, Integer integer2, Boolean aBoolean1) throws EdmPrimitiveTypeException {
return null;
}
@Override
public String toUriLiteral(String s) {
return null;
}
@Override
public String fromUriLiteral(String s) throws EdmPrimitiveTypeException {
return null;
}
@Override
public EdmElement getProperty(String s) {
return null;
}
@Override
public List<String> getPropertyNames() {
return null;
}
@Override
public EdmProperty getStructuralProperty(String s) {
return null;
}
@Override
public EdmNavigationProperty getNavigationProperty(String s) {
return null;
}
@Override
public List<String> getNavigationPropertyNames() {
return null;
}
@Override
public EdmStructuredType getBaseType() {
return null;
}
@Override
public boolean compatibleTo(EdmType edmType) {
return false;
}
@Override
public boolean isOpenType() {
return false;
}
@Override
public boolean isAbstract() {
return false;
}
@Override
public EdmAnnotation getAnnotation(EdmTerm edmTerm, String s) {
return null;
}
@Override
public List<EdmAnnotation> getAnnotations() {
return null;
}
@Override
public FullQualifiedName getFullQualifiedName() {
return null;
}
@Override
public String getNamespace() {
return null;
}
@Override
public EdmTypeKind getKind() {
return null;
}
@Override
public String getName() {
return null;
}
}
private Expression parseExpression(final String expressionString)
throws UriParserException, UriValidationException {
UriTokenizer tokenizer = new UriTokenizer(expressionString);
Edm edm = mock(A.class, withSettings().defaultAnswer(RETURNS_SMART_NULLS));
EdmProperty employeeIdTypeEdmElement = mock(EdmProperty.class, RETURNS_SMART_NULLS);
when(edmType.getProperty("EmployeeId")).thenReturn(measureTypeEdmElement);
when(edmType.getKind()).thenReturn(EdmTypeKind.PRIMITIVE);
when(edmType.isCompatible(new EdmDate())).thenReturn(true);
when(employeeIdTypeEdmElement.getName()).thenReturn("EmployeeId");
when(employeeIdTypeEdmElement.getType()).thenReturn(edmType);
when(employeeIdTypeEdmElement.isCollection()).thenReturn(false);
final Expression expression = new ExpressionParser(edm, odata).parse(tokenizer, edmType, null, null);
assertNotNull(expression);
assertTrue(tokenizer.next(UriTokenizer.TokenKind.EOF));
return expression;
}
In case it helps someone, maybee it can be optimized, fill free to propose.