package org.mongodb.morphia.query.validation;
import com.mongodb.BasicDBObject;
import org.junit.Test;
import org.mongodb.morphia.mapping.MappedClass;
import org.mongodb.morphia.mapping.MappedField;
import org.mongodb.morphia.mapping.Mapper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mongodb.morphia.query.FilterOperator.EQUAL;
import static org.mongodb.morphia.query.FilterOperator.GEO_WITHIN;
public class GeoWithinOperationValidatorTest {
@Test
public void shouldAllowGeoWithinOperatorForGeoEntityWithListOfIntegers() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(GeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("list");
assertThat(GeoWithinOperationValidator.getInstance().apply(mappedField, GEO_WITHIN, new BasicDBObject("$box", 1),
validationFailures), is(true));
}
@Test
public void shouldAllowGeoWithinOperatorWithAllAppropriateTrimmings() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(GeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("array");
// when
assertThat(GeoWithinOperationValidator.getInstance().apply(mappedField, GEO_WITHIN, new BasicDBObject("$box", 1),
validationFailures), is(true));
}
@Test
public void shouldNotApplyValidationWhenOperatorIsNotGeoWithin() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
// when
boolean validationApplied = GeoWithinOperationValidator.getInstance().apply(null, EQUAL, null, validationFailures);
// then
assertThat(validationApplied, is(false));
assertThat(validationFailures.size(), is(0));
}
@Test
public void shouldRejectGeoWithinOperatorWhenMappedFieldIsArrayThatDoesNotContainNumbers() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(InvalidGeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("arrayOfStrings");
// when
boolean validationApplied = GeoWithinOperationValidator.getInstance().apply(mappedField, GEO_WITHIN, new BasicDBObject("$box", 1),
validationFailures);
// then
assertThat(validationApplied, is(true));
assertThat(validationFailures.size(), is(1));
assertThat(validationFailures.get(0).toString(), containsString("is an array or iterable it should have numeric values"));
}
@Test
public void shouldRejectGeoWithinOperatorWhenMappedFieldIsListThatDoesNotContainNumbers() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(InvalidGeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("listOfStrings");
// when
boolean validationApplied = GeoWithinOperationValidator.getInstance().apply(mappedField,
GEO_WITHIN,
new BasicDBObject("$box", 1),
validationFailures);
// then
assertThat(validationApplied, is(true));
assertThat(validationFailures.size(), is(1));
assertThat(validationFailures.get(0).toString(), containsString("is an array or iterable it should have numeric values"));
}
@Test
public void shouldRejectGeoWithinWhenValueDoesNotContainKeyword() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(GeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("array");
// when
boolean validationApplied = GeoWithinOperationValidator.getInstance().apply(mappedField,
GEO_WITHIN,
new BasicDBObject("notValidKey", 1),
validationFailures);
// then
assertThat(validationApplied, is(true));
assertThat(validationFailures.size(), is(1));
assertThat(validationFailures.get(0).toString(),
containsString("For a $geoWithin operation, the value should be a valid geo query"));
}
@Test
public void shouldRejectGeoWithinWhenValueIsNotADBObject() {
// given
List<ValidationFailure> validationFailures = new ArrayList<ValidationFailure>();
MappedClass mappedClass = new MappedClass(GeoEntity.class, new Mapper());
MappedField mappedField = mappedClass.getMappedField("array");
// when
boolean validationApplied = GeoWithinOperationValidator.getInstance().apply(mappedField,
GEO_WITHIN,
"NotAGeoQuery",
validationFailures);
// then
assertThat(validationApplied, is(true));
assertThat(validationFailures.size(), is(1));
assertThat(validationFailures.get(0).toString(),
containsString("For a $geoWithin operation, the value should be a valid geo query"));
}
@SuppressWarnings("unused")
private static class GeoEntity {
private final int[] array = {1};
private final List<Integer> list = Arrays.asList(1);
}
@SuppressWarnings("unused")
private static class InvalidGeoEntity {
private final String[] arrayOfStrings = {"1"};
private final List<String> listOfStrings = Arrays.asList("1");
}
}