@@ -220,3 +220,119 @@ async def test_update_index(search_service, full_entity):
220220 # Search for new title
221221 results = await search_service .search (SearchQuery (text = "OMG I AM UPDATED" ))
222222 assert len (results ) > 1
223+
224+
225+ @pytest .mark .asyncio
226+ async def test_boolean_and_search (search_service , test_graph ):
227+ """Test boolean AND search."""
228+ # Create an entity with specific terms for testing
229+ # This assumes the test_graph fixture already has entities with relevant terms
230+
231+ # Test AND operator - both terms must be present
232+ results = await search_service .search (SearchQuery (text = "Root AND Entity" ))
233+ assert len (results ) >= 1
234+
235+ # Verify the result contains both terms
236+ found = False
237+ for result in results :
238+ if (result .title and "Root" in result .title and "Entity" in result .title ) or (
239+ result .content_snippet
240+ and "Root" in result .content_snippet
241+ and "Entity" in result .content_snippet
242+ ):
243+ found = True
244+ break
245+ assert found , "Boolean AND search failed to find items containing both terms"
246+
247+ # Verify that items with only one term are not returned
248+ results = await search_service .search (SearchQuery (text = "NonexistentTerm AND Root" ))
249+ assert len (results ) == 0 , "Boolean AND search returned results when it shouldn't have"
250+
251+
252+ @pytest .mark .asyncio
253+ async def test_boolean_or_search (search_service , test_graph ):
254+ """Test boolean OR search."""
255+ # Test OR operator - either term can be present
256+ results = await search_service .search (SearchQuery (text = "Root OR Connected" ))
257+
258+ # Should find both "Root Entity" and "Connected Entity"
259+ assert len (results ) >= 2
260+
261+ # Verify we find items with either term
262+ root_found = False
263+ connected_found = False
264+
265+ for result in results :
266+ if result .permalink == "test/root" :
267+ root_found = True
268+ elif "connected" in result .permalink .lower ():
269+ connected_found = True
270+
271+ assert root_found , "Boolean OR search failed to find 'Root' term"
272+ assert connected_found , "Boolean OR search failed to find 'Connected' term"
273+
274+
275+ @pytest .mark .asyncio
276+ async def test_boolean_not_search (search_service , test_graph ):
277+ """Test boolean NOT search."""
278+ # Test NOT operator - exclude certain terms
279+ results = await search_service .search (SearchQuery (text = "Entity NOT Connected" ))
280+
281+ # Should find "Root Entity" but not "Connected Entity"
282+ for result in results :
283+ assert "connected" not in result .permalink .lower (), (
284+ "Boolean NOT search returned excluded term"
285+ )
286+
287+
288+ @pytest .mark .asyncio
289+ async def test_boolean_group_search (search_service , test_graph ):
290+ """Test boolean grouping with parentheses."""
291+ # Test grouping - (A OR B) AND C
292+ results = await search_service .search (SearchQuery (title = "(Root OR Connected) AND Entity" ))
293+
294+ # Should find both entities that contain "Entity" and either "Root" or "Connected"
295+ assert len (results ) >= 2
296+
297+ for result in results :
298+ # Each result should contain "Entity" and either "Root" or "Connected"
299+ contains_entity = "entity" in result .title .lower ()
300+ contains_root_or_connected = (
301+ "root" in result .title .lower () or "connected" in result .title .lower ()
302+ )
303+
304+ assert contains_entity and contains_root_or_connected , (
305+ "Boolean grouped search returned incorrect results"
306+ )
307+
308+
309+ @pytest .mark .asyncio
310+ async def test_boolean_operators_detection (search_service ):
311+ """Test detection of boolean operators in query."""
312+ # Test various queries that should be detected as boolean
313+ boolean_queries = [
314+ "term1 AND term2" ,
315+ "term1 OR term2" ,
316+ "term1 NOT term2" ,
317+ "(term1 OR term2) AND term3" ,
318+ "complex (nested OR grouping) AND term" ,
319+ ]
320+
321+ for query_text in boolean_queries :
322+ query = SearchQuery (text = query_text )
323+ assert query .has_boolean_operators (), f"Failed to detect boolean operators in: { query_text } "
324+
325+ # Test queries that should not be detected as boolean
326+ non_boolean_queries = [
327+ "normal search query" ,
328+ "brand name" , # Should not detect "AND" within "brand"
329+ "understand this concept" , # Should not detect "AND" within "understand"
330+ "command line" ,
331+ "sandbox testing" ,
332+ ]
333+
334+ for query_text in non_boolean_queries :
335+ query = SearchQuery (text = query_text )
336+ assert not query .has_boolean_operators (), (
337+ f"Incorrectly detected boolean operators in: { query_text } "
338+ )
0 commit comments