/** test exception on missing `end` and `match` parameter in parser */
  public void testParseEnd() throws IOException {
    {
      XContentBuilder builder = XContentFactory.jsonBuilder();
      builder.startObject();
      builder.startObject(SpanFirstQueryBuilder.NAME);
      builder.field("match");
      spanTermQuery("description", "jumped").toXContent(builder, null);
      builder.endObject();
      builder.endObject();

      ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(builder.string()));
      assertTrue(e.getMessage().contains("spanFirst must have [end] set"));
    }
    {
      XContentBuilder builder = XContentFactory.jsonBuilder();
      builder.startObject();
      builder.startObject(SpanFirstQueryBuilder.NAME);
      builder.field("end", 10);
      builder.endObject();
      builder.endObject();

      ParsingException e = expectThrows(ParsingException.class, () -> parseQuery(builder.string()));
      assertTrue(e.getMessage().contains("spanFirst must have [match] span query clause"));
    }
  }
 /**
  * Replace the generic test from superclass, wrapper query only expects to find `query` field with
  * nested query and should throw exception for anything else.
  */
 @Override
 public void testUnknownField() throws IOException {
   try {
     parseQuery("{ \"" + WrapperQueryBuilder.NAME + "\" : {\"bogusField\" : \"someValue\"} }");
     fail("ParsingException expected.");
   } catch (ParsingException e) {
     assertTrue(e.getMessage().contains("bogusField"));
   }
 }
  /**
   * Test that the template query parser can parse and evaluate template expressed as a single
   * string but still it expects only the query specification (thus this test should fail with
   * specific exception).
   */
  public void testParseTemplateFailsToParseCompleteQueryAsSingleString() throws IOException {
    String templateString =
        "{"
            + "  \"inline\" : \"{ \\\"size\\\": \\\"{{size}}\\\", \\\"query\\\":{\\\"match_all\\\":{}}}\","
            + "  \"params\":{"
            + "    \"size\":2"
            + "  }\n"
            + "}";

    XContentParser templateSourceParser =
        XContentFactory.xContent(templateString).createParser(templateString);
    context.reset();

    try {
      TemplateQueryBuilder.fromXContent(context.newParseContext(templateSourceParser))
          .rewrite(context);
      fail("Expected ParsingException");
    } catch (ParsingException e) {
      assertThat(e.getMessage(), containsString("query malformed, no field after start_object"));
    }
  }
  public void testReverseOptionFailsWhenNonStringField() throws IOException {
    String json =
        "{\n"
            + "  \"testname\" : [ {\n"
            + "    \"lat\" : -6.046997540714173,\n"
            + "    \"lon\" : -51.94128329747579\n"
            + "  } ],\n"
            + "  \"reverse\" : true\n"
            + "}";
    XContentParser itemParser = XContentHelper.createParser(new BytesArray(json));
    itemParser.nextToken();

    QueryParseContext context =
        new QueryParseContext(indicesQueriesRegistry, itemParser, ParseFieldMatcher.STRICT);

    try {
      GeoDistanceSortBuilder.fromXContent(context, "");
      fail("adding reverse sorting option should fail with an exception");
    } catch (ParsingException e) {
      assertEquals("Only geohashes of type string supported for field [reverse]", e.getMessage());
    }
  }
 public void testParseRequestFailure() throws Exception {
   AtomicBoolean called = new AtomicBoolean();
   Consumer<Response> checkResponse =
       r -> {
         assertFalse(r.isTimedOut());
         assertNull(r.getScrollId());
         assertEquals(0, r.getTotalHits());
         assertThat(r.getFailures(), hasSize(1));
         assertThat(r.getFailures().get(0).getReason(), instanceOf(ParsingException.class));
         ParsingException failure = (ParsingException) r.getFailures().get(0).getReason();
         assertEquals("Unknown key for a VALUE_STRING in [invalid].", failure.getMessage());
         assertEquals(2, failure.getLineNumber());
         assertEquals(14, failure.getColumnNumber());
         called.set(true);
       };
   sourceWithMockedRemoteCall("request_failure.json").doStart(checkResponse);
   assertTrue(called.get());
   called.set(false);
   sourceWithMockedRemoteCall("request_failure.json")
       .doStartNextScroll("scroll", timeValueMillis(0), checkResponse);
   assertTrue(called.get());
 }