Skip to content

Commit 1bd30fa

Browse files
committed
peng - add more IT for highlight cases
Signed-off-by: Jialiang Liang <jiallian@amazon.com>
1 parent 1b07536 commit 1bd30fa

2 files changed

Lines changed: 145 additions & 0 deletions

File tree

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteHighlightIT.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,67 @@ public void testHighlightWithStats() throws IOException {
213213
assertTrue("Response should contain datarows", result.has("datarows"));
214214
}
215215

216+
@Test
217+
public void testHighlightBooleanOrSearch() throws IOException {
218+
JSONObject result =
219+
executeQueryWithHighlight(
220+
"source=" + TEST_INDEX_ACCOUNT + " \"Holmes\" OR \"Bond\"", "[\"*\"]");
221+
JSONArray dataRows = result.getJSONArray("datarows");
222+
assertTrue("OR search should return results", dataRows.length() > 0);
223+
assertHighlightsExist(result);
224+
// Verify highlights contain fragments for both search terms
225+
JSONArray highlights = result.getJSONArray("highlights");
226+
boolean foundHolmes = false;
227+
boolean foundBond = false;
228+
for (int i = 0; i < highlights.length(); i++) {
229+
String hlStr = highlights.getJSONObject(i).toString();
230+
if (hlStr.contains("Holmes")) foundHolmes = true;
231+
if (hlStr.contains("Bond")) foundBond = true;
232+
}
233+
assertTrue("Highlights should contain Holmes fragments", foundHolmes);
234+
assertTrue("Highlights should contain Bond fragments", foundBond);
235+
}
236+
237+
@Test
238+
public void testHighlightBooleanAndSearch() throws IOException {
239+
JSONObject result =
240+
executeQueryWithHighlight(
241+
"source=" + TEST_INDEX_ACCOUNT + " \"Holmes\" AND \"Lane\"", "[\"*\"]");
242+
JSONArray dataRows = result.getJSONArray("datarows");
243+
assertTrue("AND search should return results", dataRows.length() > 0);
244+
assertHighlightsExist(result);
245+
// Verify highlights contain fragments for both terms
246+
JSONArray highlights = result.getJSONArray("highlights");
247+
boolean foundHolmes = false;
248+
boolean foundLane = false;
249+
for (int i = 0; i < highlights.length(); i++) {
250+
String hlStr = highlights.getJSONObject(i).toString();
251+
if (hlStr.contains("Holmes")) foundHolmes = true;
252+
if (hlStr.contains("Lane")) foundLane = true;
253+
}
254+
assertTrue("Highlights should contain Holmes fragments", foundHolmes);
255+
assertTrue("Highlights should contain Lane fragments", foundLane);
256+
}
257+
258+
@Test
259+
public void testHighlightNotSearch() throws IOException {
260+
// NOT queries negate the match — the query succeeds but highlights are empty
261+
// because there are no positive matches to highlight
262+
JSONObject result =
263+
executeQueryWithHighlight("source=" + TEST_INDEX_ACCOUNT + " NOT \"Holmes\"", "[\"*\"]");
264+
JSONArray dataRows = result.getJSONArray("datarows");
265+
assertTrue("NOT search should return results", dataRows.length() > 0);
266+
}
267+
268+
@Test
269+
public void testHighlightBooleanOrWithFilter() throws IOException {
270+
JSONObject result =
271+
executeQueryWithHighlight(
272+
"source=" + TEST_INDEX_ACCOUNT + " \"Holmes\" OR \"Bond\" | where age > 30", "[\"*\"]");
273+
assertTrue("Response should contain datarows", result.has("datarows"));
274+
assertHighlightsExist(result);
275+
}
276+
216277
@Test
217278
public void testHighlightNoSearchQuery() throws IOException {
218279
// Without a search query, request should still succeed (highlights may or may not be present)

ppl/src/test/java/org/opensearch/sql/ppl/domain/PPLQueryRequestTest.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import static org.junit.Assert.assertEquals;
99
import static org.junit.Assert.assertNotNull;
1010
import static org.junit.Assert.assertNull;
11+
import static org.junit.Assert.assertThrows;
1112
import static org.junit.Assert.assertTrue;
1213

1314
import java.util.List;
@@ -198,4 +199,87 @@ public void testGetHighlightConfigPerFieldOptions() {
198199
assertEquals(3, config.fields().get("title").get("number_of_fragments"));
199200
assertEquals("plain", config.fields().get("body").get("type"));
200201
}
202+
203+
@Test
204+
public void testGetHighlightConfigEmptyFieldNameThrows() {
205+
JSONObject json = new JSONObject("{\"query\": \"source=t\", \"highlight\": [\"\"]}");
206+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
207+
IllegalArgumentException e =
208+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
209+
assertTrue(e.getMessage().contains("non-empty"));
210+
}
211+
212+
@Test
213+
public void testGetHighlightConfigNegativeFragmentSizeThrows() {
214+
JSONObject json =
215+
new JSONObject(
216+
"{\"query\": \"source=t\", \"highlight\": {"
217+
+ "\"fields\": {\"*\": {}}, \"fragment_size\": -1}}");
218+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
219+
IllegalArgumentException e =
220+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
221+
assertTrue(e.getMessage().contains("fragment_size must be a positive integer"));
222+
}
223+
224+
@Test
225+
public void testGetHighlightConfigZeroFragmentSizeThrows() {
226+
JSONObject json =
227+
new JSONObject(
228+
"{\"query\": \"source=t\", \"highlight\": {"
229+
+ "\"fields\": {\"*\": {}}, \"fragment_size\": 0}}");
230+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
231+
IllegalArgumentException e =
232+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
233+
assertTrue(e.getMessage().contains("fragment_size must be a positive integer"));
234+
}
235+
236+
@Test
237+
public void testGetHighlightConfigExceedMaxFieldsArrayThrows() {
238+
// Build an array with 101 fields
239+
StringBuilder sb = new StringBuilder("{\"query\": \"source=t\", \"highlight\": [");
240+
for (int i = 0; i < 101; i++) {
241+
if (i > 0) sb.append(",");
242+
sb.append("\"field").append(i).append("\"");
243+
}
244+
sb.append("]}");
245+
JSONObject json = new JSONObject(sb.toString());
246+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
247+
IllegalArgumentException e =
248+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
249+
assertTrue(e.getMessage().contains("fields count exceeds maximum"));
250+
}
251+
252+
@Test
253+
public void testGetHighlightConfigExceedMaxFieldsObjectThrows() {
254+
// Build an object with 101 fields
255+
StringBuilder sb = new StringBuilder("{\"query\": \"source=t\", \"highlight\": {\"fields\": {");
256+
for (int i = 0; i < 101; i++) {
257+
if (i > 0) sb.append(",");
258+
sb.append("\"field").append(i).append("\": {}");
259+
}
260+
sb.append("}}}");
261+
JSONObject json = new JSONObject(sb.toString());
262+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
263+
IllegalArgumentException e =
264+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
265+
assertTrue(e.getMessage().contains("fields count exceeds maximum"));
266+
}
267+
268+
@Test
269+
public void testGetHighlightConfigExceedMaxTagsThrows() {
270+
// Build pre_tags array with 11 entries
271+
StringBuilder sb =
272+
new StringBuilder(
273+
"{\"query\": \"source=t\", \"highlight\": {\"fields\": {\"*\": {}}, \"pre_tags\": [");
274+
for (int i = 0; i < 11; i++) {
275+
if (i > 0) sb.append(",");
276+
sb.append("\"tag").append(i).append("\"");
277+
}
278+
sb.append("]}}");
279+
JSONObject json = new JSONObject(sb.toString());
280+
PPLQueryRequest request = new PPLQueryRequest("source=t", json, "/_plugins/_ppl");
281+
IllegalArgumentException e =
282+
assertThrows(IllegalArgumentException.class, request::getHighlightConfig);
283+
assertTrue(e.getMessage().contains("pre_tags count exceeds maximum"));
284+
}
201285
}

0 commit comments

Comments
 (0)