public void testBrokenCoordinateCanBeSetWithIgnoreMalformed() {
    PointTester[] testers = {
      new TopTester(), new LeftTester(), new BottomTester(), new RightTester()
    };

    GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
    builder.setValidationMethod(GeoValidationMethod.IGNORE_MALFORMED);

    for (PointTester tester : testers) {
      tester.invalidateCoordinate(builder, true);
    }
  }
  public void testBrokenCoordinateCannotBeSet() {
    PointTester[] testers = {
      new TopTester(), new LeftTester(), new BottomTester(), new RightTester()
    };
    GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
    builder.setValidationMethod(GeoValidationMethod.STRICT);

    for (PointTester tester : testers) {
      expectThrows(
          IllegalArgumentException.class, () -> tester.invalidateCoordinate(builder, true));
    }
  }
 public void testNormalization() throws IOException {
   assumeTrue("test runs only when at least a type is registered", getCurrentTypes().length > 0);
   GeoBoundingBoxQueryBuilder qb = createTestQueryBuilder();
   if (getCurrentTypes().length != 0 && "mapped_geo".equals(qb.fieldName())) {
     // only execute this test if we are running on a valid geo field
     qb.setCorners(200, 200, qb.bottomRight().getLat(), qb.bottomRight().getLon());
     qb.setValidationMethod(GeoValidationMethod.COERCE);
     Query query = qb.toQuery(createShardContext());
     if (query instanceof ConstantScoreQuery) {
       ConstantScoreQuery result = (ConstantScoreQuery) query;
       BooleanQuery bboxFilter = (BooleanQuery) result.getQuery();
       for (BooleanClause clause : bboxFilter.clauses()) {
         LegacyNumericRangeQuery boundary = (LegacyNumericRangeQuery) clause.getQuery();
         if (boundary.getMax() != null) {
           assertTrue(
               "If defined, non of the maximum range values should be larger than 180",
               boundary.getMax().intValue() <= 180);
         }
       }
     } else {
       assertTrue(
           "memory queries should result in LegacyInMemoryGeoBoundingBoxQuery",
           query instanceof LegacyInMemoryGeoBoundingBoxQuery);
     }
   }
 }
  public void testValidation() {
    PointTester[] testers = {
      new TopTester(), new LeftTester(), new BottomTester(), new RightTester()
    };

    for (PointTester tester : testers) {
      QueryValidationException except = null;

      GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
      tester.invalidateCoordinate(builder.setValidationMethod(GeoValidationMethod.COERCE), false);
      except = builder.checkLatLon(true);
      assertNull(
          "Inner post 2.0 validation w/ coerce should ignore invalid "
              + tester.getClass().getName()
              + " coordinate: "
              + tester.invalidCoordinate
              + " ",
          except);

      tester.invalidateCoordinate(builder.setValidationMethod(GeoValidationMethod.COERCE), false);
      except = builder.checkLatLon(false);
      assertNull(
          "Inner pre 2.0 validation w/ coerce should ignore invalid coordinate: "
              + tester.getClass().getName()
              + " coordinate: "
              + tester.invalidCoordinate
              + " ",
          except);

      tester.invalidateCoordinate(builder.setValidationMethod(GeoValidationMethod.STRICT), false);
      except = builder.checkLatLon(true);
      assertNull(
          "Inner pre 2.0 validation w/o coerce should ignore invalid coordinate for old indexes: "
              + tester.getClass().getName()
              + " coordinate: "
              + tester.invalidCoordinate,
          except);

      tester.invalidateCoordinate(builder.setValidationMethod(GeoValidationMethod.STRICT), false);
      except = builder.checkLatLon(false);
      assertNotNull(
          "Inner post 2.0 validation w/o coerce should detect invalid coordinate: "
              + tester.getClass().getName()
              + " coordinate: "
              + tester.invalidCoordinate,
          except);
    }
  }
  @Override
  protected GeoBoundingBoxQueryBuilder doCreateTestQueryBuilder() {
    GeoBoundingBoxQueryBuilder builder = new GeoBoundingBoxQueryBuilder(GEO_POINT_FIELD_NAME);
    Rectangle box =
        RandomShapeGenerator.xRandomRectangle(
            random(), RandomShapeGenerator.xRandomPoint(random()));

    if (randomBoolean()) {
      // check the top-left/bottom-right combination of setters
      int path = randomIntBetween(0, 2);
      switch (path) {
        case 0:
          builder.setCorners(
              new GeoPoint(box.getMaxY(), box.getMinX()),
              new GeoPoint(box.getMinY(), box.getMaxX()));
          break;
        case 1:
          builder.setCorners(
              GeohashUtils.encodeLatLon(box.getMaxY(), box.getMinX()),
              GeohashUtils.encodeLatLon(box.getMinY(), box.getMaxX()));
          break;
        default:
          builder.setCorners(box.getMaxY(), box.getMinX(), box.getMinY(), box.getMaxX());
      }
    } else {
      // check the bottom-left/ top-right combination of setters
      if (randomBoolean()) {
        builder.setCornersOGC(
            new GeoPoint(box.getMinY(), box.getMinX()), new GeoPoint(box.getMaxY(), box.getMaxX()));
      } else {
        builder.setCornersOGC(
            GeohashUtils.encodeLatLon(box.getMinY(), box.getMinX()),
            GeohashUtils.encodeLatLon(box.getMaxY(), box.getMaxX()));
      }
    }

    if (randomBoolean()) {
      builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
    }

    if (randomBoolean()) {
      builder.ignoreUnmapped(randomBoolean());
    }

    builder.type(randomFrom(GeoExecType.values()));
    return builder;
  }
  public void testLeftRightCanBeFlipped() {
    GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
    double top = builder.topLeft().getLat();
    double left = builder.topLeft().getLon();
    double bottom = builder.bottomRight().getLat();
    double right = builder.bottomRight().getLon();

    builder
        .setValidationMethod(GeoValidationMethod.IGNORE_MALFORMED)
        .setCorners(top, right, bottom, left);
    builder.setValidationMethod(GeoValidationMethod.STRICT).setCorners(top, right, bottom, left);
  }
 @Override
 protected void doAssertLuceneQuery(
     GeoBoundingBoxQueryBuilder queryBuilder, Query query, SearchContext searchContext)
     throws IOException {
   QueryShardContext context = searchContext.getQueryShardContext();
   MappedFieldType fieldType = context.fieldMapper(queryBuilder.fieldName());
   if (fieldType == null) {
     assertTrue("Found no indexed geo query.", query instanceof MatchNoDocsQuery);
   } else {
     if (context.indexVersionCreated().before(Version.V_2_2_0)) {
       if (queryBuilder.type() == GeoExecType.INDEXED) {
         assertTrue("Found no indexed geo query.", query instanceof ConstantScoreQuery);
       } else {
         assertTrue(
             "Found no indexed geo query.", query instanceof LegacyInMemoryGeoBoundingBoxQuery);
       }
     } else if (context.indexVersionCreated().before(Version.V_5_0_0_beta1)) {
       assertTrue("Found no indexed geo query.", query instanceof GeoPointInBBoxQuery);
     } else {
       assertTrue("Found no indexed geo query.", query instanceof Query);
     }
   }
 }
  public void testTopBottomCannotBeFlipped() {
    GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
    double top = builder.topLeft().getLat();
    double left = builder.topLeft().getLon();
    double bottom = builder.bottomRight().getLat();
    double right = builder.bottomRight().getLon();

    assumeTrue("top should not be equal to bottom for flip check", top != bottom);
    logger.info("top: {} bottom: {}", top, bottom);
    builder.setValidationMethod(GeoValidationMethod.STRICT);
    IllegalArgumentException e =
        expectThrows(
            IllegalArgumentException.class, () -> builder.setCorners(bottom, left, top, right));
    assertThat(e.getMessage(), containsString("top is below bottom corner:"));
  }
  public void testTopBottomCanBeFlippedOnIgnoreMalformed() {
    GeoBoundingBoxQueryBuilder builder = createTestQueryBuilder();
    double top = builder.topLeft().getLat();
    double left = builder.topLeft().getLon();
    double bottom = builder.bottomRight().getLat();
    double right = builder.bottomRight().getLon();

    assumeTrue("top should not be equal to bottom for flip check", top != bottom);
    builder
        .setValidationMethod(GeoValidationMethod.IGNORE_MALFORMED)
        .setCorners(bottom, left, top, right);
  }
  public void testIgnoreUnmapped() throws IOException {
    final GeoBoundingBoxQueryBuilder queryBuilder =
        new GeoBoundingBoxQueryBuilder("unmapped").setCorners(1.0, 0.0, 0.0, 1.0);
    queryBuilder.ignoreUnmapped(true);
    QueryShardContext shardContext = createShardContext();
    Query query = queryBuilder.toQuery(shardContext);
    assertThat(query, notNullValue());
    assertThat(query, instanceOf(MatchNoDocsQuery.class));

    final GeoBoundingBoxQueryBuilder failingQueryBuilder =
        new GeoBoundingBoxQueryBuilder("unmapped").setCorners(1.0, 0.0, 0.0, 1.0);
    failingQueryBuilder.ignoreUnmapped(false);
    QueryShardException e =
        expectThrows(QueryShardException.class, () -> failingQueryBuilder.toQuery(shardContext));
    assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
  }
 public void testFromJson() throws IOException {
   String json =
       "{\n"
           + "  \"geo_bounding_box\" : {\n"
           + "    \"pin.location\" : {\n"
           + "      \"top_left\" : [ -74.1, 40.73 ],\n"
           + "      \"bottom_right\" : [ -71.12, 40.01 ]\n"
           + "    },\n"
           + "    \"validation_method\" : \"STRICT\",\n"
           + "    \"type\" : \"MEMORY\",\n"
           + "    \"ignore_unmapped\" : false,\n"
           + "    \"boost\" : 1.0\n"
           + "  }\n"
           + "}";
   GeoBoundingBoxQueryBuilder parsed = (GeoBoundingBoxQueryBuilder) parseQuery(json);
   checkGeneratedJson(json, parsed);
   assertEquals(json, "pin.location", parsed.fieldName());
   assertEquals(json, -74.1, parsed.topLeft().getLon(), 0.0001);
   assertEquals(json, 40.73, parsed.topLeft().getLat(), 0.0001);
   assertEquals(json, -71.12, parsed.bottomRight().getLon(), 0.0001);
   assertEquals(json, 40.01, parsed.bottomRight().getLat(), 0.0001);
   assertEquals(json, 1.0, parsed.boost(), 0.0001);
   assertEquals(json, GeoExecType.MEMORY, parsed.type());
 }
 @Override
 public void fillIn(double coordinate, GeoBoundingBoxQueryBuilder qb) {
   qb.setCorners(
       qb.topLeft().getLat(), qb.topLeft().getLon(), qb.bottomRight().getLat(), coordinate);
 }
 public void testValidationNullTypeString() {
   GeoBoundingBoxQueryBuilder qb = new GeoBoundingBoxQueryBuilder("teststring");
   IllegalArgumentException e =
       expectThrows(IllegalArgumentException.class, () -> qb.type((String) null));
   assertEquals("cannot parse type from null string", e.getMessage());
 }
 public void testValidationNullType() {
   GeoBoundingBoxQueryBuilder qb = new GeoBoundingBoxQueryBuilder("teststring");
   IllegalArgumentException e =
       expectThrows(IllegalArgumentException.class, () -> qb.type((GeoExecType) null));
   assertEquals("Type is not allowed to be null.", e.getMessage());
 }