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);
  }
  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);
    }
  }
 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 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 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 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:"));
  }
  @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;
  }