Skip to content

Commit

Permalink
HSEARCH-3885 Test exceptions when attempting to use predicate with in…
Browse files Browse the repository at this point in the history
…compatible nested path hierarchy in a nested predicate
  • Loading branch information
yrodiere committed Apr 8, 2020
1 parent f8fb683 commit ba348ec
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 0 deletions.
Expand Up @@ -6,6 +6,7 @@
*/
package org.hibernate.search.integrationtest.backend.tck.search.predicate;

import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.hibernate.search.util.impl.integrationtest.common.assertion.SearchResultAssert.assertThat;
import static org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMapperUtils.referenceProvider;

Expand All @@ -16,6 +17,7 @@
import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaObjectField;
import org.hibernate.search.engine.backend.document.model.dsl.ObjectFieldStorage;
import org.hibernate.search.engine.backend.work.execution.spi.IndexIndexingPlan;
import org.hibernate.search.util.common.SearchException;
import org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMappingIndexManager;
import org.hibernate.search.util.impl.integrationtest.mapper.stub.StubMappingScope;
import org.hibernate.search.integrationtest.backend.tck.testsupport.util.rule.SearchSetupHelper;
Expand Down Expand Up @@ -219,6 +221,64 @@ public void search_nestedOnTwoLevels_separatePredicates() {
.hasTotalHitCount( 1 );
}

@Test
public void invalidNestedPath_parent() {
StubMappingScope scope = indexManager.createScope();

String objectFieldPath = "nestedObject";
String fieldInParentPath = "string";

assertThatThrownBy( () -> scope.query()
.where( f -> f.nested().objectField( objectFieldPath )
.nest( f.bool()
.must( f.match()
.field( fieldInParentPath )
.matching( "irrelevant_because_this_will_fail" )
)
.must( f.match()
.field( fieldInParentPath )
.matching( "irrelevant_because_this_will_fail" )
)
)
)
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInParentPath + "]",
"Only fields that are contained in the nested object with path '" + objectFieldPath + "'"
+ " are allowed here."
);
}

@Test
public void invalidNestedPath_sibling() {
StubMappingScope scope = indexManager.createScope();

String objectFieldPath = "nestedObject";
String fieldInSiblingPath = "nestedObject2.string";

assertThatThrownBy( () -> scope.query()
.where( f -> f.nested().objectField( objectFieldPath )
.nest( f.bool()
.must( f.match()
.field( fieldInSiblingPath )
.matching( "irrelevant_because_this_will_fail" )
)
.must( f.match()
.field( fieldInSiblingPath )
.matching( "irrelevant_because_this_will_fail" )
)
)
)
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInSiblingPath + "]",
"Only fields that are contained in the nested object with path '" + objectFieldPath + "'"
+ " are allowed here."
);
}

private void initData() {
IndexIndexingPlan<?> plan = indexManager.createIndexingPlan();
plan.add( referenceProvider( DOCUMENT_1 ), document -> {
Expand Down Expand Up @@ -348,12 +408,19 @@ private void initData() {
}

private static class IndexMapping {
final IndexFieldReference<String> string;
final ObjectMapping nestedObject;
final ObjectMapping nestedObject2;

IndexMapping(IndexSchemaElement root) {
string = root.field( "string", f -> f.asString() ).toReference();

IndexSchemaObjectField nestedObjectField = root.objectField( "nestedObject", ObjectFieldStorage.NESTED )
.multiValued();
nestedObject = new ObjectMapping( nestedObjectField );
IndexSchemaObjectField nestedObject2Field = root.objectField( "nestedObject2", ObjectFieldStorage.NESTED )
.multiValued();
nestedObject2 = new ObjectMapping( nestedObject2Field );
}
}

Expand Down
Expand Up @@ -71,6 +71,40 @@ public void nonNested() {
);
}

@Test
public void invalidNestedPath_parent() {
String fieldPath = indexMapping.nestedObject1.relativeFieldName + ".geoPoint";
String fieldInParentPath = "geoPoint";

assertThatThrownBy(
() -> matchAllQuery( f -> f.distance( fieldPath, GeoPoint.of( 42.0, 42.0 ) )
.filter( pf -> pf.exists().field( fieldInParentPath ) ) )
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInParentPath + "]",
"Only fields that are contained in the nested object with path '" + indexMapping.nestedObject1.relativeFieldName + "'"
+ " are allowed here."
);
}

@Test
public void invalidNestedPath_sibling() {
String fieldPath = indexMapping.nestedObject1.relativeFieldName + ".geoPoint";
String fieldInSiblingPath = indexMapping.nestedObject2.relativeFieldName + ".geoPoint";

assertThatThrownBy(
() -> matchAllQuery( f -> f.distance( fieldPath, GeoPoint.of( 42.0, 42.0 ) )
.filter( pf -> pf.exists().field( fieldInSiblingPath ) ) )
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInSiblingPath + "]",
"Only fields that are contained in the nested object with path '" + indexMapping.nestedObject1.relativeFieldName + "'"
+ " are allowed here."
);
}

private SearchQuery<DocumentReference> matchAllQuery(
Function<? super SearchSortFactory, ? extends SortFinalStep> sortContributor) {
return matchAllQuery( sortContributor, indexManager.createScope() );
Expand All @@ -95,12 +129,18 @@ private static class AbstractObjectMapping {

private static class IndexMapping extends AbstractObjectMapping {
final FirstLevelObjectMapping flattenedObject;
final FirstLevelObjectMapping nestedObject1;
final FirstLevelObjectMapping nestedObject2;

IndexMapping(IndexSchemaElement root) {
super( root );

flattenedObject = FirstLevelObjectMapping.create( root, "flattenedObject",
ObjectFieldStorage.FLATTENED );
nestedObject1 = FirstLevelObjectMapping.create( root, "nestedObject1",
ObjectFieldStorage.NESTED );
nestedObject2 = FirstLevelObjectMapping.create( root, "nestedObject2",
ObjectFieldStorage.NESTED );
}
}

Expand Down
Expand Up @@ -98,6 +98,41 @@ public void nonNested() {
);
}

@Test
public void invalidNestedPath_parent() {
String fieldPath = indexMapping.nestedObject1.relativeFieldName + "."
+ indexMapping.nestedObject1.fieldModels.get( fieldTypeDescriptor ).relativeFieldName;
String fieldInParentPath = indexMapping.fieldModels.get( fieldTypeDescriptor ).relativeFieldName;

assertThatThrownBy(
() -> matchAllQuery( f -> f.field( fieldPath ).filter( pf -> pf.exists().field( fieldInParentPath ) ) )
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInParentPath + "]",
"Only fields that are contained in the nested object with path '" + indexMapping.nestedObject1.relativeFieldName + "'"
+ " are allowed here."
);
}

@Test
public void invalidNestedPath_sibling() {
String fieldPath = indexMapping.nestedObject1.relativeFieldName + "."
+ indexMapping.nestedObject1.fieldModels.get( fieldTypeDescriptor ).relativeFieldName;
String fieldInSiblingPath = indexMapping.nestedObject2.relativeFieldName + "."
+ indexMapping.nestedObject2.fieldModels.get( fieldTypeDescriptor ).relativeFieldName;

assertThatThrownBy(
() -> matchAllQuery( f -> f.field( fieldPath ).filter( pf -> pf.exists().field( fieldInSiblingPath ) ) )
)
.isInstanceOf( SearchException.class )
.hasMessageContainingAll(
"Predicate targets unexpected fields [" + fieldInSiblingPath + "]",
"Only fields that are contained in the nested object with path '" + indexMapping.nestedObject1.relativeFieldName + "'"
+ " are allowed here."
);
}

private SearchQuery<DocumentReference> matchAllQuery(
Function<? super SearchSortFactory, ? extends SortFinalStep> sortContributor) {
return matchAllQuery( sortContributor, indexManager.createScope() );
Expand All @@ -122,12 +157,18 @@ private static class AbstractObjectMapping {

private static class IndexMapping extends AbstractObjectMapping {
final FirstLevelObjectMapping flattenedObject;
final FirstLevelObjectMapping nestedObject1;
final FirstLevelObjectMapping nestedObject2;

IndexMapping(IndexSchemaElement root) {
super( root );

flattenedObject = FirstLevelObjectMapping.create( root, "flattenedObject",
ObjectFieldStorage.FLATTENED );
nestedObject1 = FirstLevelObjectMapping.create( root, "nestedObject1",
ObjectFieldStorage.NESTED );
nestedObject2 = FirstLevelObjectMapping.create( root, "nestedObject2",
ObjectFieldStorage.NESTED );
}
}

Expand Down

0 comments on commit ba348ec

Please sign in to comment.