test_collections.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import uuid
  2. import pytest
  3. from r2r import R2RClient, R2RException
  4. @pytest.fixture(scope="session")
  5. def test_document_2(client):
  6. """Create and yield a test document, then clean up."""
  7. doc_resp = client.documents.create(
  8. raw_text="Another test doc for collections",
  9. run_with_orchestration=False,
  10. )
  11. doc_id = doc_resp["results"]["document_id"]
  12. yield doc_id
  13. # Cleanup: Try deleting the document if it still exists
  14. try:
  15. client.documents.delete(id=doc_id)
  16. except R2RException:
  17. pass
  18. def test_create_collection(client):
  19. resp = client.collections.create(
  20. name="Test Collection Creation", description="Desc"
  21. )
  22. coll_id = resp["results"]["id"]
  23. assert coll_id is not None, "No collection_id returned"
  24. # Cleanup
  25. client.collections.delete(coll_id)
  26. def test_list_collections(client, test_collection):
  27. listed = client.collections.list(limit=10, offset=0)
  28. results = listed["results"]
  29. assert len(results) >= 1, "Expected at least one collection, none found"
  30. def test_retrieve_collection(client, test_collection):
  31. # Retrieve the collection just created
  32. retrieved = client.collections.retrieve(test_collection["collection_id"])[
  33. "results"
  34. ]
  35. assert (
  36. retrieved["id"] == test_collection["collection_id"]
  37. ), "Retrieved wrong collection ID"
  38. def test_update_collection(client, test_collection):
  39. updated_name = "Updated Test Collection"
  40. updated_desc = "Updated description"
  41. updated = client.collections.update(
  42. test_collection["collection_id"],
  43. name=updated_name,
  44. description=updated_desc,
  45. )["results"]
  46. assert updated["name"] == updated_name, "Collection name not updated"
  47. assert (
  48. updated["description"] == updated_desc
  49. ), "Collection description not updated"
  50. def test_add_document_to_collection(client, test_collection, test_document_2):
  51. # Add the test document to the test collection
  52. client.collections.add_document(
  53. test_collection["collection_id"], test_document_2
  54. )
  55. # Verify by listing documents
  56. docs_in_collection = client.collections.list_documents(
  57. test_collection["collection_id"]
  58. )["results"]
  59. found = any(doc["id"] == test_document_2 for doc in docs_in_collection)
  60. assert found, "Added document not found in collection"
  61. def test_list_documents_in_collection(client, test_collection, test_document):
  62. # Document should be in the collection already from previous test
  63. docs_in_collection = client.collections.list_documents(
  64. test_collection["collection_id"]
  65. )["results"]
  66. found = any(doc["id"] == test_document for doc in docs_in_collection)
  67. assert found, "Expected document not found in collection"
  68. def test_remove_document_from_collection(
  69. client, test_collection, test_document
  70. ):
  71. # Remove the document from the collection
  72. client.collections.remove_document(
  73. test_collection["collection_id"], test_document
  74. )
  75. docs_in_collection = client.collections.list_documents(
  76. test_collection["collection_id"]
  77. )["results"]
  78. found = any(doc["id"] == test_document for doc in docs_in_collection)
  79. assert not found, "Document still present in collection after removal"
  80. def test_remove_non_member_user_from_collection(mutable_client):
  81. # Create a user and a collection
  82. user_email = f"user_{uuid.uuid4()}@test.com"
  83. password = "pwd123"
  84. mutable_client.users.create(user_email, password)
  85. mutable_client.users.login(user_email, password)
  86. # Create a collection by the same user
  87. collection_resp = mutable_client.collections.create(
  88. name="User Owned Collection"
  89. )["results"]
  90. collection_id = collection_resp["id"]
  91. mutable_client.users.logout()
  92. # Create another user who will not be added to the collection
  93. another_user_email = f"user2_{uuid.uuid4()}@test.com"
  94. mutable_client.users.create(another_user_email, password)
  95. mutable_client.users.login(another_user_email, password)
  96. another_user_id = mutable_client.users.me()["results"]["id"]
  97. mutable_client.users.logout()
  98. # Re-login as collection owner
  99. mutable_client.users.login(user_email, password)
  100. # Attempt to remove the other user (who was never added)
  101. with pytest.raises(R2RException) as exc_info:
  102. mutable_client.collections.remove_user(collection_id, another_user_id)
  103. assert exc_info.value.status_code in [
  104. 400,
  105. 404,
  106. ], "Wrong error code for removing non-member user"
  107. # Cleanup
  108. mutable_client.collections.delete(collection_id)
  109. def test_delete_collection(client):
  110. # Create a collection and delete it
  111. coll = client.collections.create(name="Delete Me")["results"]
  112. coll_id = coll["id"]
  113. client.collections.delete(coll_id)
  114. # Verify retrieval fails
  115. with pytest.raises(R2RException) as exc_info:
  116. client.collections.retrieve(coll_id)
  117. assert (
  118. exc_info.value.status_code == 404
  119. ), "Wrong error code retrieving deleted collection"
  120. def test_add_user_to_non_existent_collection(mutable_client):
  121. # Create a regular user
  122. user_email = f"test_user_{uuid.uuid4()}@test.com"
  123. user_password = "test_password"
  124. mutable_client.users.create(user_email, user_password)
  125. mutable_client.users.login(user_email, user_password)
  126. user_id = mutable_client.users.me()["results"]["id"]
  127. mutable_client.users.logout()
  128. # Re-login as superuser to try adding user to a non-existent collection
  129. # (Assumes superuser credentials are already in the client fixture)
  130. fake_collection_id = str(uuid.uuid4()) # Non-existent collection ID
  131. with pytest.raises(R2RException) as exc_info:
  132. result = mutable_client.collections.add_user(
  133. fake_collection_id, user_id
  134. )
  135. assert (
  136. exc_info.value.status_code == 404
  137. ), "Wrong error code for non-existent collection"
  138. # def test_remove_non_member_user_from_collection_duplicate(client):
  139. # # Similar to the previous non-member removal test but just to ensure coverage.
  140. # owner_email = f"owner_{uuid.uuid4()}@test.com"
  141. # owner_password = "password123"
  142. # client.users.create(owner_email, owner_password)
  143. # client.users.login(owner_email, owner_password)
  144. # # Create a collection by this owner
  145. # coll = client.collections.create(name="Another Non-member Test")["results"]
  146. # collection_id = coll["id"]
  147. # # Create another user who will NOT be added
  148. # other_user_email = f"other_{uuid.uuid4()}@test.com"
  149. # other_password = "password456"
  150. # client.users.create(other_user_email, other_password)
  151. # client.users.login(other_user_email, other_password)
  152. # other_user_id = client.users.me()["results"]["id"]
  153. # client.users.logout()
  154. # # Re-login as collection owner
  155. # client.users.login(owner_email, owner_password)
  156. # # Attempt to remove non-member
  157. # with pytest.raises(R2RException) as exc_info:
  158. # client.collections.remove_user(collection_id, other_user_id)
  159. # assert exc_info.value.status_code in [400, 404], "Wrong error code for removing non-member user"
  160. # # Cleanup
  161. # client.collections.delete(collection_id)
  162. def test_create_collection_without_name(client):
  163. # Attempt to create a collection without a name
  164. with pytest.raises(R2RException) as exc_info:
  165. client.collections.create(name="", description="No name")
  166. # TODO - Error should be a 400 or 422, not 409
  167. assert exc_info.value.status_code in [
  168. 400,
  169. 422,
  170. 409,
  171. ], "Expected validation error for empty name"
  172. def test_create_collection_with_invalid_data(client):
  173. # Placeholder: If your API supports different data validation,
  174. # you'd try invalid inputs here. If strongly typed, this might not be feasible.
  175. # For now, we skip since the example client might prevent invalid data from being sent.
  176. pass
  177. def test_filter_collections_by_non_existent_id(client):
  178. # Filter collections by an ID that does not exist
  179. random_id = str(uuid.uuid4())
  180. resp = client.collections.list(ids=[random_id])
  181. assert (
  182. len(resp["results"]) == 0
  183. ), "Expected no collections for a non-existent ID"
  184. def test_list_documents_in_empty_collection(client):
  185. # Create a new collection with no documents
  186. resp = client.collections.create(name="Empty Collection")["results"]
  187. empty_coll_id = resp["id"]
  188. docs = client.collections.list_documents(empty_coll_id)["results"]
  189. assert len(docs) == 0, "Expected no documents in a new empty collection"
  190. client.collections.delete(empty_coll_id)
  191. def test_remove_document_not_in_collection(client, test_document):
  192. # Create collection without adding the test_document
  193. resp = client.collections.create(name="NoDocCollection")["results"]
  194. coll_id = resp["id"]
  195. # Try removing the test_document that was never added
  196. with pytest.raises(R2RException) as exc_info:
  197. client.collections.remove_document(coll_id, test_document)
  198. # Expect 404 or 400 since doc not in collection
  199. assert exc_info.value.status_code in [
  200. 400,
  201. 404,
  202. ], "Expected error removing doc not in collection"
  203. client.collections.delete(coll_id)
  204. def test_add_non_existent_document_to_collection(client):
  205. # Create a collection
  206. resp = client.collections.create(name="AddNonExistentDoc")["results"]
  207. coll_id = resp["id"]
  208. # Try adding a non-existent document
  209. fake_doc_id = str(uuid.uuid4())
  210. with pytest.raises(R2RException) as exc_info:
  211. client.collections.add_document(coll_id, fake_doc_id)
  212. assert exc_info.value.status_code in [
  213. 400,
  214. 404,
  215. ], "Expected error adding non-existent document"
  216. client.collections.delete(coll_id)
  217. def test_delete_non_existent_collection(client):
  218. # Try deleting a collection that doesn't exist
  219. fake_collection_id = str(uuid.uuid4())
  220. with pytest.raises(R2RException) as exc_info:
  221. client.collections.delete(fake_collection_id)
  222. assert (
  223. exc_info.value.status_code == 404
  224. ), "Expected 404 when deleting non-existent collection"