123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892 |
- import uuid
- import pytest
- from core.base import Message, SearchMode
- from r2r import R2RClient, R2RException
- @pytest.fixture(scope="session")
- def config():
- class TestConfig:
- base_url = "http://localhost:7272"
- superuser_email = "admin@example.com"
- superuser_password = "change_me_immediately"
- return TestConfig()
- @pytest.fixture(scope="session")
- def client(config):
- """Create a client instance and log in as a superuser."""
- client = R2RClient(config.base_url)
- client.users.login(config.superuser_email, config.superuser_password)
- return client
- def test_search_basic_mode(client: R2RClient):
- results = client.retrieval.search(query="Aristotle",
- search_mode="basic").results
- assert results is not None, "No results field in search response"
- def test_search_advanced_mode_with_filters(client: R2RClient):
- filters = {"metadata.document_type": {"$eq": "txt"}}
- results = client.retrieval.search(
- query="Philosophy",
- search_mode="advanced",
- search_settings={
- "filters": filters,
- "limit": 5
- },
- ).results
- assert results is not None, "No results in advanced mode search"
- def test_search_custom_mode(client: R2RClient):
- results = client.retrieval.search(
- query="Greek philosophers",
- search_mode="custom",
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- ).results
- assert results is not None, "No results in custom mode search"
- def test_rag_query(client: R2RClient):
- results = client.retrieval.rag(
- query="Summarize Aristotle's contributions to logic",
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- ).results
- assert results.completion is not None, "RAG response missing 'completion'"
- def test_rag_with_filter(client: R2RClient):
- # Ensure a doc with metadata.tier='test' is created
- # generate a random string
- suffix = str(uuid.uuid4())
- client.documents.create(
- raw_text=
- f"Aristotle was a Greek philosopher, contributions to philosophy were in logic, {suffix}.",
- metadata={"tier": "test"},
- )
- results = client.retrieval.rag(
- query="What were aristotle's contributions to philosophy?",
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "filters": {
- "metadata.tier": {
- "$eq": "test"
- }
- },
- "use_semantic_search": True,
- "limit": 3,
- },
- ).results
- assert results.completion is not None, "RAG response missing 'completion'"
- def test_rag_stream_query(client: R2RClient):
- resp = client.retrieval.rag(
- query="Detail the philosophical schools Aristotle influenced",
- rag_generation_config={
- "stream": True,
- "max_tokens": 50
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 2
- },
- )
- # Consume a few chunks from the async generator
- def consume_stream():
- count = 0
- for chunk in resp:
- count += 1
- if count > 1:
- break
- return count
- # count = asyncio.run(consume_stream())
- count = consume_stream()
- assert count > 0, "No chunks received from streamed RAG query"
- def test_agent_query(client: R2RClient):
- msg = Message(role="user", content="What is Aristotle known for?")
- results = client.retrieval.agent(
- message=msg,
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- ).results
- assert results is not None, "Agent response missing 'results'"
- assert len(results.messages) > 0, "No messages returned by agent"
- def test_agent_query_stream(client: R2RClient):
- msg = Message(role="user", content="Explain Aristotle's logic in steps.")
- resp = client.retrieval.agent(
- message=msg,
- rag_generation_config={
- "stream": True,
- "max_tokens": 50
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- )
- def consume_stream():
- count = 0
- for chunk in resp:
- count += 1
- if count > 1:
- break
- return count
- count = consume_stream() # asyncio.run(consume_stream())
- assert count > 0, "No streaming chunks received from agent"
- def test_completion(client: R2RClient):
- messages = [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "What is the capital of France?"
- },
- {
- "role": "assistant",
- "content": "The capital of France is Paris."
- },
- {
- "role": "user",
- "content": "What about Italy?"
- },
- ]
- resp = client.retrieval.completion(
- messages,
- generation_config={
- "max_tokens": 50,
- "model": "openai/gpt-4.1"
- },
- )
- assert resp.results is not None, "Completion response missing 'results'"
- assert resp.results.choices is not None, "No choices in completion result"
- def test_embedding(client: R2RClient):
- text = "Who is Aristotle?"
- resp = client.retrieval.embedding(text=text).results
- assert len(resp) > 0, "No embedding vector returned"
- def test_error_handling(client: R2RClient):
- # Missing query should raise an error
- with pytest.raises(R2RException) as exc_info:
- client.retrieval.search(query=None) # type: ignore
- assert exc_info.value.status_code in [
- 400,
- 422,
- ], "Expected validation error for missing query"
- def test_no_results_scenario(client: R2RClient):
- results = client.retrieval.search(
- query="aslkfjaldfjal",
- search_mode="custom",
- search_settings={
- "limit": 5,
- "use_semantic_search": False,
- "use_fulltext_search": True,
- },
- ).results
- results = results.chunk_search_results
- assert len(results) == 0, "Expected no results for nonsense query"
- def test_pagination_limit_one(client: R2RClient):
- client.documents.create(chunks=[
- "a" + " " + str(uuid.uuid4()),
- "b" + " " + str(uuid.uuid4()),
- "c" + " " + str(uuid.uuid4()),
- ])
- results = client.retrieval.search(query="Aristotle",
- search_mode="basic",
- search_settings={
- "limit": 1
- }).results
- assert len(results.chunk_search_results) == 1, (
- "Expected one result with limit=1")
- def test_pagination_offset(client: R2RClient):
- resp0 = client.retrieval.search(
- query="Aristotle",
- search_mode="basic",
- search_settings={
- "limit": 1,
- "offset": 0
- },
- ).results
- resp1 = client.retrieval.search(
- query="Aristotle",
- search_mode="basic",
- search_settings={
- "limit": 1,
- "offset": 1
- },
- ).results
- assert (resp0.chunk_search_results[0].text
- != resp1.chunk_search_results[0].text
- ), "Offset should return different results"
- def test_rag_task_prompt(client: R2RClient):
- custom_prompt = """
- Answer the query given immediately below given the context. End your answer with: [END-TEST-PROMPT]
- ### Query:
- {query}
- ### Context:
- {context}
- """
- results = client.retrieval.rag(
- query="Tell me about Aristotle",
- rag_generation_config={"stream": False}, # , "max_tokens": 50},
- search_settings={"use_semantic_search": True, "limit": 3},
- task_prompt=custom_prompt,
- ).results
- answer = results.completion
- assert "[END-TEST-PROMPT]" in answer, (
- "Custom prompt override not reflected in RAG answer")
- def test_agent_conversation_id(client: R2RClient):
- conversation_id = client.conversations.create().results.id
- msg = Message(role="user", content="What is Aristotle known for?")
- results = client.retrieval.agent(
- message=msg,
- rag_generation_config={
- "stream": False,
- "max_tokens": 50
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- conversation_id=str(conversation_id),
- ).results
- assert len(
- results.messages) > 0, ("No results from agent with conversation_id")
- msg2 = Message(role="user", content="Can you elaborate more?")
- results2 = client.retrieval.agent(
- message=msg2,
- rag_generation_config={
- "stream": False,
- "max_tokens": 50
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 3
- },
- conversation_id=str(conversation_id),
- ).results
- assert len(results2.messages) > 0, (
- "No results from agent in second turn of conversation")
- def test_complex_filters_and_fulltext(client: R2RClient, test_collection):
- # collection_id, doc_ids = _setup_collection_with_documents(client)
- user_id = client.users.me().results.id
- # rating > 5
- # include owner id and collection ids to make robust against other database interactions from other users
- filters = {
- "rating": {
- "$gt": 5
- },
- "owner_id": {
- "$eq": str(user_id)
- },
- "collection_ids": {
- "$overlap": [str(test_collection["collection_id"])]
- },
- }
- results = client.retrieval.search(
- query="a",
- search_mode=SearchMode.custom,
- search_settings={
- "use_semantic_search": True,
- "filters": filters
- },
- ).results
- results = results.chunk_search_results
- assert len(results) == 2, (
- f"Expected 2 docs with rating > 5, got {len(results)}")
- # category in [ancient, modern]
- filters = {
- "metadata.category": {
- "$in": ["ancient", "modern"]
- },
- "owner_id": {
- "$eq": str(user_id)
- },
- "collection_ids": {
- "$overlap": [str(test_collection["collection_id"])]
- },
- }
- results = client.retrieval.search(
- query="b",
- search_mode=SearchMode.custom,
- search_settings={
- "use_semantic_search": True,
- "filters": filters
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 4, (
- f"Expected all 4 docs, got {len(chunk_search_results)}")
- # rating > 5 AND category=modern
- filters = {
- "$and": [
- {
- "metadata.rating": {
- "$gt": 5
- }
- },
- {
- "metadata.category": {
- "$eq": "modern"
- }
- },
- {
- "owner_id": {
- "$eq": str(user_id)
- }
- },
- {
- "collection_ids": {
- "$overlap": [str(test_collection["collection_id"])]
- }
- },
- ],
- }
- results = client.retrieval.search(
- query="d",
- search_mode=SearchMode.custom,
- search_settings={
- "filters": filters
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 2, (
- f"Expected 2 modern docs with rating>5, got {len(chunk_search_results)}"
- )
- results = client.retrieval.search(
- query="unique_philosopher",
- search_mode=SearchMode.custom,
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "owner_id": {
- "$eq": str(user_id)
- },
- "collection_ids": {
- "$overlap": [str(test_collection["collection_id"])]
- },
- },
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 1, (
- f"Expected 1 doc for unique_philosopher, got {len(chunk_search_results)}"
- )
- def test_complex_nested_filters(client: R2RClient, test_collection):
- # Setup docs
- # _setup_collection_with_documents(client)
- # ((category=ancient OR rating<5) AND tags contains 'philosophy')
- filters = {
- "$and": [
- {
- "$or": [
- {
- "metadata.category": {
- "$eq": "ancient"
- }
- },
- {
- "metadata.rating": {
- "$lt": 5
- }
- },
- ]
- },
- {
- "metadata.tags": {
- "$contains": ["philosophy"]
- }
- },
- {
- "owner_id": {
- "$eq": str(client.users.me().results.id)
- }
- },
- {
- "collection_ids": {
- "$overlap": [str(test_collection["collection_id"])]
- }
- },
- ],
- }
- results = client.retrieval.search(
- query="complex",
- search_settings={
- "filters": filters
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert (
- len(chunk_search_results) == 2
- ), f"Expected 2 docs, got {len(chunk_search_results)}"
- def test_filters_no_match(client: R2RClient):
- filters = {"metadata.category": {"$in": ["nonexistent"]}}
- results = client.retrieval.search(
- query="noresults",
- search_mode="custom",
- search_settings={
- "filters": filters
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 0, (
- f"Expected 0 docs, got {len(chunk_search_results)}")
- def test_pagination_extremes(client: R2RClient):
- total_entries = client.chunks.list().total_entries
- offset = total_entries + 100
- results = client.retrieval.search(
- query="Aristotle",
- search_mode="basic",
- search_settings={
- "limit": 10,
- "offset": offset
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 0, (
- f"Expected no results at large offset, got {len(chunk_search_results)}"
- )
- def test_full_text_stopwords(client: R2RClient):
- resp = client.retrieval.search(
- query="the",
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "limit": 5,
- },
- )
- assert resp.results is not None, (
- "No results field in stopword query response")
- def test_full_text_non_ascii(client: R2RClient):
- resp = client.retrieval.search(
- query="Aristotélēs",
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "limit": 3,
- },
- )
- assert resp.results is not None, (
- "No results field in non-ASCII query response")
- def test_missing_fields(client: R2RClient):
- filters = {"metadata.someNonExistentField": {"$eq": "anything"}}
- results = client.retrieval.search(
- query="missingfield",
- search_mode="custom",
- search_settings={
- "filters": filters
- },
- ).results
- chunk_search_results = results.chunk_search_results
- assert len(chunk_search_results) == 0, (
- f"Expected 0 docs for a non-existent field, got {len(chunk_search_results)}"
- )
- def test_rag_with_large_context(client: R2RClient):
- results = client.retrieval.rag(
- query="Explain the contributions of Kant in detail",
- rag_generation_config={
- "stream": False,
- "max_tokens": 200
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 10
- },
- ).results
- assert results.completion is not None, (
- "RAG large context missing 'completion'")
- completion = results.completion
- assert len(completion) > 0, "RAG large context returned empty answer"
- def test_agent_long_conversation(client: R2RClient):
- conversation_id = client.conversations.create().results.id
- msg1 = Message(role="user", content="What were Aristotle's main ideas?")
- resp1 = client.retrieval.agent(
- message=msg1,
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 5
- },
- conversation_id=str(conversation_id),
- )
- assert resp1.results is not None, (
- "No results in first turn of conversation")
- msg2 = Message(role="user",
- content="How did these ideas influence modern philosophy?")
- resp2 = client.retrieval.agent(
- message=msg2,
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 5
- },
- conversation_id=str(conversation_id),
- )
- assert resp2.results is not None, (
- "No results in second turn of conversation")
- msg3 = Message(role="user", content="Now tell me about Descartes.")
- resp3 = client.retrieval.agent(
- message=msg3,
- rag_generation_config={
- "stream": False,
- "max_tokens": 100
- },
- search_settings={
- "use_semantic_search": True,
- "limit": 5
- },
- conversation_id=str(conversation_id),
- )
- assert resp3.results is not None, (
- "No results in third turn of conversation")
- def test_filter_by_document_type(client: R2RClient):
- random_suffix = str(uuid.uuid4())
- client.documents.create(chunks=[
- f"a {random_suffix}",
- f"b {random_suffix}",
- f"c {random_suffix}",
- ])
- filters = {"document_type": {"$eq": "txt"}}
- results = client.retrieval.search(query="a",
- search_settings={
- "filters": filters
- }).results
- chunk_search_results = results.chunk_search_results
- assert (
- len(chunk_search_results) > 0
- ), "No results found for filter by document type"
- def test_search_hyde_mode(client: R2RClient):
- """
- Integration test for HyDE search. We create a doc, then query with
- search_strategy='hyde'. We expect the system to generate hypothetical docs,
- embed them, and return chunk search results.
- """
- # 1) Create a test doc containing "Aristotle" text
- suffix = str(uuid.uuid4())
- client.documents.create(
- chunks=[
- f"Aristotle. Fulltext test doc. {uuid.uuid4()}",
- f"Plato. Fulltext test doc. {uuid.uuid4()}",
- f"Socrates. Fulltext test doc. {uuid.uuid4()}",
- f"Pythagoras. Fulltext test doc. {uuid.uuid4()}",
- f"Euclid. Fulltext test doc. {uuid.uuid4()}",
- ],
- metadata={"category": "test_hyde_fulltext"},
- )
- # 2) Perform a HyDE search
- resp = client.retrieval.search(
- query="Aristotle achievements?",
- search_mode="custom", # or 'basic'—the key is in search_settings below
- search_settings={
- "search_strategy": "hyde",
- "use_semantic_search": True,
- "limit": 5,
- # If you want multiple hypothetical docs:
- "num_sub_queries": 5,
- },
- )
- # 3) Validate the results
- results = resp.results
- assert results is not None, "No results returned by HyDE search"
- assert (
- len(results.chunk_search_results) == 25
- ), "Expected 25 chunk search results"
- chunk_results = results.chunk_search_results
- # We can't guarantee you have actual matches in your DB,
- # but we can at least confirm the structure is correct.
- # If your DB has a doc referencing "Aristotle," we might get hits:
- assert (
- chunk_results is not None
- ), "No chunk_search_results in HyDE search response"
- # Optionally you can assert chunk_results is not empty if you expect a match
- # but that depends on your environment.
- def test_search_rag_fusion_mode(client: R2RClient):
- """
- Integration test for RAG-Fusion search. For now, your code is a placeholder
- that calls _basic_search. But this ensures it doesn't error out and returns
- valid results.
- """
- suffix = str(uuid.uuid4())
- client.documents.create(
- raw_text=f"Plato was another Greek philosopher. RAGFusionTestDoc: {suffix}",
- metadata={"category": "test_rag_fusion"},
- )
- # 2) Perform a RAG-Fusion search
- resp = client.retrieval.search(
- query="Plato's contributions?",
- search_mode="custom",
- search_settings={
- "search_strategy": "rag_fusion",
- "use_semantic_search": True,
- "limit": 5,
- # "num_sub_queries": 3 if you actually implement it
- },
- )
- # 3) Validate the results
- results = resp.results
- assert results is not None, "No results returned by RAG-Fusion search"
- chunk_results = results.chunk_search_results
- assert chunk_results is not None, "No chunk_search_results for RAG-Fusion"
- # Possibly check if chunk_results is not empty if you have data
- assert (
- len(results.chunk_search_results) == 5
- ), "Expected 5 chunk search results"
- def test_rag_fusion_mode_with_subqueries(client: R2RClient):
- """
- If/when you actually implement multi-subquery logic for rag_fusion,
- you'd pass 'num_sub_queries': 3, etc.
- Currently it's a placeholder, but let's just confirm the service doesn't error out.
- """
- resp = client.retrieval.search(
- query="What are Plato's main dialogues?",
- search_mode="custom",
- search_settings={
- "search_strategy": "rag_fusion",
- "use_semantic_search": True,
- "limit": 5,
- "num_sub_queries": 3,
- },
- )
- results = resp.results
- assert (
- results is not None
- ), "No results returned by RAG-Fusion with subqueries"
- # When fully implemented, you can check if the chunk results are non-empty, etc.
- def test_collection_id_filters(client: R2RClient):
- """
- Test both collection_id and collection_ids filters to ensure they work properly
- with the updated filters.py code.
- """
- # Create a new collection for this test
- collection_response = client.collections.create(
- name=f"Collection Filter Test {uuid.uuid4()}"
- )
- collection_id = collection_response.results.id
- # Create a second collection to verify filtering works correctly
- other_collection_response = client.collections.create(
- name=f"Other Collection {uuid.uuid4()}"
- )
- other_collection_id = other_collection_response.results.id
- # Add unique identifier to track the test documents
- unique_marker = str(uuid.uuid4())
- # Create documents in the first collection
- for i in range(3):
- doc_response = client.documents.create(
- raw_text=f"Test document {i} for collection filter test with marker {unique_marker}",
- metadata={"test_group": "collection_filter_test"}
- )
- doc_id = doc_response.results.document_id
- # Add document to the first collection
- client.collections.add_document(
- id=collection_id,
- document_id=doc_id
- )
- # Create a document in the second collection
- doc_response = client.documents.create(
- raw_text=f"Test document in second collection with marker {unique_marker}",
- metadata={"test_group": "collection_filter_test"}
- )
- doc_id = doc_response.results.document_id
- # Add document to the second collection
- client.collections.add_document(
- id=other_collection_id,
- document_id=doc_id
- )
- # Wait for indexing to complete
- import time
- time.sleep(2)
- # Test 1: Using collection_id filter (singular form)
- results1 = client.retrieval.search(
- query=unique_marker,
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "collection_id": {"$eq": str(collection_id)}
- }
- }
- ).results
- # Test 2: Using collection_ids filter (plural form)
- results2 = client.retrieval.search(
- query=unique_marker,
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "collection_ids": {"$overlap": [str(collection_id)]}
- }
- }
- ).results
- # Test 3: Using $in operator with collection_id
- results3 = client.retrieval.search(
- query=unique_marker,
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "collection_id": {"$in": [str(collection_id)]}
- }
- }
- ).results
- # Test 4: Using both collections with $overlap
- results4 = client.retrieval.search(
- query=unique_marker,
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "collection_ids": {"$overlap": [str(collection_id), str(other_collection_id)]}
- }
- }
- ).results
- # Test 5: Using a non-existent collection ID
- results5 = client.retrieval.search(
- query=unique_marker,
- search_mode="custom",
- search_settings={
- "use_fulltext_search": True,
- "use_semantic_search": False,
- "filters": {
- "collection_id": {"$eq": str(uuid.uuid4())}
- }
- }
- ).results
- # Verify results
- # First three tests should return exactly 3 chunks from the first collection
- assert len(results1.chunk_search_results) == 3, f"collection_id $eq filter returned {len(results1.chunk_search_results)} results, expected 3"
- assert len(results2.chunk_search_results) == 3, f"collection_ids $overlap filter returned {len(results2.chunk_search_results)} results, expected 3"
- assert len(results3.chunk_search_results) == 3, f"collection_id $in filter returned {len(results3.chunk_search_results)} results, expected 3"
- # Test 4 should return all 4 chunks from both collections
- assert len(results4.chunk_search_results) == 4, f"collection_ids $overlap with multiple IDs returned {len(results4.chunk_search_results)} results, expected 4"
- # Test 5 should return no results for non-existent collection
- assert len(results5.chunk_search_results) == 0, f"Non-existent collection ID filter returned {len(results5.chunk_search_results)} results, expected 0"
- # Clean up
- client.collections.delete(id=collection_id)
- client.collections.delete(id=other_collection_id)
|