/** 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"));
    }
  }
 public void testTwoTypes() throws Exception {
   String source =
       JsonXContent.contentBuilder()
           .startObject()
           .startObject("in_stock")
           .startObject("filter")
           .startObject("range")
           .startObject("stock")
           .field("gt", 0)
           .endObject()
           .endObject()
           .endObject()
           .startObject("terms")
           .field("field", "stock")
           .endObject()
           .endObject()
           .endObject()
           .string();
   try {
     XContentParser parser = XContentFactory.xContent(source).createParser(source);
     QueryParseContext parseContext =
         new QueryParseContext(queriesRegistry, parser, parseFieldMatcher);
     assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
     aggParsers.parseAggregators(parseContext);
     fail();
   } catch (ParsingException e) {
     assertThat(
         e.toString(),
         containsString(
             "Found two aggregation type definitions in [in_stock]: [filter] and [terms]"));
   }
 }
 /**
  * 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"));
   }
 }
  public void testInvalidAggregationName() throws Exception {
    Matcher matcher = Pattern.compile("[^\\[\\]>]+").matcher("");
    String name;
    Random rand = random();
    int len = randomIntBetween(1, 5);
    char[] word = new char[len];
    while (true) {
      for (int i = 0; i < word.length; i++) {
        word[i] = (char) rand.nextInt(127);
      }
      name = String.valueOf(word);
      if (!matcher.reset(name).matches()) {
        break;
      }
    }

    String source =
        JsonXContent.contentBuilder()
            .startObject()
            .startObject(name)
            .startObject("filter")
            .startObject("range")
            .startObject("stock")
            .field("gt", 0)
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .endObject()
            .string();
    try {
      XContentParser parser = XContentFactory.xContent(source).createParser(source);
      QueryParseContext parseContext =
          new QueryParseContext(queriesRegistry, parser, parseFieldMatcher);
      assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
      aggParsers.parseAggregators(parseContext);
      fail();
    } catch (ParsingException e) {
      assertThat(e.toString(), containsString("Invalid aggregation name [" + name + "]"));
    }
  }
  /**
   * 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());
 }
 public void testTwoAggs() throws Exception {
   String source =
       JsonXContent.contentBuilder()
           .startObject()
           .startObject("by_date")
           .startObject("date_histogram")
           .field("field", "timestamp")
           .field("interval", "month")
           .endObject()
           .startObject("aggs")
           .startObject("tag_count")
           .startObject("cardinality")
           .field("field", "tag")
           .endObject()
           .endObject()
           .endObject()
           .startObject("aggs") // 2nd "aggs": illegal
           .startObject("tag_count2")
           .startObject("cardinality")
           .field("field", "tag")
           .endObject()
           .endObject()
           .endObject()
           .endObject()
           .endObject()
           .string();
   try {
     XContentParser parser = XContentFactory.xContent(source).createParser(source);
     QueryParseContext parseContext =
         new QueryParseContext(queriesRegistry, parser, parseFieldMatcher);
     assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
     aggParsers.parseAggregators(parseContext);
     fail();
   } catch (ParsingException e) {
     assertThat(
         e.toString(), containsString("Found two sub aggregation definitions under [by_date]"));
   }
 }
  /**
   * test exceptions for three types of broken json, missing include / exclude and both dist and
   * pre/post specified
   */
  public void testParserExceptions() throws IOException {
    {
      XContentBuilder builder = XContentFactory.jsonBuilder();
      builder.startObject();
      builder.startObject(SpanNotQueryBuilder.NAME);
      builder.field("exclude");
      spanTermQuery("description", "jumped").toXContent(builder, null);
      builder.field("dist", 2);
      builder.endObject();
      builder.endObject();

      try {
        parseQuery(builder.string());
        fail("ParsingException should have been caught");
      } catch (ParsingException e) {
        assertThat(
            "ParsingException should have been caught",
            e.getDetailedMessage(),
            containsString("spanNot must have [include]"));
      }
    }
    {
      XContentBuilder builder = XContentFactory.jsonBuilder();
      builder.startObject();
      builder.startObject(SpanNotQueryBuilder.NAME);
      builder.field("include");
      spanNearQuery(QueryBuilders.spanTermQuery("description", "quick"), 1)
          .clause(QueryBuilders.spanTermQuery("description", "fox"))
          .toXContent(builder, null);
      builder.field("dist", 2);
      builder.endObject();
      builder.endObject();

      try {
        parseQuery(builder.string());
        fail("ParsingException should have been caught");
      } catch (ParsingException e) {
        assertThat(
            "ParsingException should have been caught",
            e.getDetailedMessage(),
            containsString("spanNot must have [exclude]"));
      }
    }
    {
      XContentBuilder builder = XContentFactory.jsonBuilder();
      builder.startObject();
      builder.startObject(SpanNotQueryBuilder.NAME);
      builder.field("include");
      spanNearQuery(QueryBuilders.spanTermQuery("description", "quick"), 1)
          .clause(QueryBuilders.spanTermQuery("description", "fox"))
          .toXContent(builder, null);
      builder.field("exclude");
      spanTermQuery("description", "jumped").toXContent(builder, null);
      builder.field("dist", 2);
      builder.field("pre", 2);
      builder.endObject();
      builder.endObject();

      try {
        parseQuery(builder.string());
        fail("ParsingException should have been caught");
      } catch (ParsingException e) {
        assertThat(
            "ParsingException should have been caught",
            e.getDetailedMessage(),
            containsString("spanNot can either use [dist] or [pre] & [post] (or none)"));
      }
    }
  }