test_collections.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import uuid
  2. import pytest
  3. from core.base import R2RException
  4. from core.base.api.models import CollectionResponse
  5. @pytest.mark.asyncio
  6. async def test_create_collection(collections_handler):
  7. owner_id = uuid.uuid4()
  8. resp = await collections_handler.create_collection(
  9. owner_id=owner_id,
  10. name="Test Collection",
  11. description="A test collection",
  12. )
  13. assert isinstance(resp, CollectionResponse)
  14. assert resp.name == "Test Collection"
  15. assert resp.owner_id == owner_id
  16. assert resp.description == "A test collection"
  17. @pytest.mark.asyncio
  18. async def test_create_collection_default_name(collections_handler):
  19. owner_id = uuid.uuid4()
  20. # If no name provided, should use default_collection_name from config
  21. resp = await collections_handler.create_collection(owner_id=owner_id)
  22. assert isinstance(resp, CollectionResponse)
  23. assert resp.name is not None # default collection name should be set
  24. assert resp.owner_id == owner_id
  25. @pytest.mark.asyncio
  26. async def test_update_collection(collections_handler):
  27. owner_id = uuid.uuid4()
  28. coll = await collections_handler.create_collection(
  29. owner_id=owner_id, name="Original Name", description="Original Desc")
  30. updated = await collections_handler.update_collection(
  31. collection_id=coll.id,
  32. name="Updated Name",
  33. description="New Description",
  34. )
  35. assert updated.name == "Updated Name"
  36. assert updated.description == "New Description"
  37. # user_count and document_count should be integers
  38. assert isinstance(updated.user_count, int)
  39. assert isinstance(updated.document_count, int)
  40. @pytest.mark.asyncio
  41. async def test_update_collection_no_fields(collections_handler):
  42. owner_id = uuid.uuid4()
  43. coll = await collections_handler.create_collection(owner_id=owner_id,
  44. name="NoUpdate",
  45. description="No Update")
  46. with pytest.raises(R2RException) as exc:
  47. await collections_handler.update_collection(collection_id=coll.id)
  48. assert exc.value.status_code == 400
  49. @pytest.mark.asyncio
  50. async def test_delete_collection_relational(collections_handler):
  51. owner_id = uuid.uuid4()
  52. coll = await collections_handler.create_collection(owner_id=owner_id,
  53. name="ToDelete")
  54. # Confirm existence
  55. exists = await collections_handler.collection_exists(coll.id)
  56. assert exists is True
  57. await collections_handler.delete_collection_relational(coll.id)
  58. exists = await collections_handler.collection_exists(coll.id)
  59. assert exists is False
  60. @pytest.mark.asyncio
  61. async def test_collection_exists(collections_handler):
  62. owner_id = uuid.uuid4()
  63. coll = await collections_handler.create_collection(owner_id=owner_id)
  64. assert await collections_handler.collection_exists(coll.id) is True
  65. @pytest.mark.asyncio
  66. async def test_documents_in_collection(collections_handler, db_provider):
  67. # Create a collection
  68. owner_id = uuid.uuid4()
  69. coll = await collections_handler.create_collection(owner_id=owner_id,
  70. name="DocCollection")
  71. # Insert some documents related to this collection
  72. # We'll directly insert into the documents table for simplicity
  73. doc_id = uuid.uuid4()
  74. insert_doc_query = f"""
  75. INSERT INTO {db_provider.project_name}.documents (id, collection_ids, owner_id, type, metadata, title, version, size_in_bytes, ingestion_status, extraction_status)
  76. VALUES ($1, $2, $3, 'txt', '{{}}', 'Test Doc', 'v1', 1234, 'pending', 'pending')
  77. """
  78. await db_provider.connection_manager.execute_query(
  79. insert_doc_query, [doc_id, [coll.id], owner_id])
  80. # Now fetch documents in collection
  81. res = await collections_handler.documents_in_collection(coll.id,
  82. offset=0,
  83. limit=10)
  84. assert len(res["results"]) == 1
  85. assert res["total_entries"] == 1
  86. assert res["results"][0].id == doc_id
  87. assert res["results"][0].title == "Test Doc"
  88. @pytest.mark.asyncio
  89. async def test_get_collections_overview(collections_handler, db_provider):
  90. owner_id = uuid.uuid4()
  91. coll1 = await collections_handler.create_collection(owner_id=owner_id,
  92. name="Overview1")
  93. coll2 = await collections_handler.create_collection(owner_id=owner_id,
  94. name="Overview2")
  95. overview = await collections_handler.get_collections_overview(offset=0,
  96. limit=10)
  97. # There should be at least these two
  98. ids = [c.id for c in overview["results"]]
  99. assert coll1.id in ids
  100. assert coll2.id in ids
  101. @pytest.mark.asyncio
  102. async def test_assign_document_to_collection_relational(
  103. collections_handler, db_provider):
  104. owner_id = uuid.uuid4()
  105. coll = await collections_handler.create_collection(owner_id=owner_id,
  106. name="Assign")
  107. # Insert a doc
  108. doc_id = uuid.uuid4()
  109. insert_doc_query = f"""
  110. INSERT INTO {db_provider.project_name}.documents (id, owner_id, type, metadata, title, version, size_in_bytes, ingestion_status, extraction_status, collection_ids)
  111. VALUES ($1, $2, 'txt', '{{}}', 'Standalone Doc', 'v1', 10, 'pending', 'pending', ARRAY[]::uuid[])
  112. """
  113. await db_provider.connection_manager.execute_query(insert_doc_query,
  114. [doc_id, owner_id])
  115. # Assign this doc to the collection
  116. await collections_handler.assign_document_to_collection_relational(
  117. doc_id, coll.id)
  118. # Verify doc is now in collection
  119. docs = await collections_handler.documents_in_collection(coll.id,
  120. offset=0,
  121. limit=10)
  122. assert len(docs["results"]) == 1
  123. assert docs["results"][0].id == doc_id
  124. @pytest.mark.asyncio
  125. async def test_remove_document_from_collection_relational(
  126. collections_handler, db_provider):
  127. owner_id = uuid.uuid4()
  128. coll = await collections_handler.create_collection(owner_id=owner_id,
  129. name="RemoveDoc")
  130. # Insert a doc already in collection
  131. doc_id = uuid.uuid4()
  132. insert_doc_query = f"""
  133. INSERT INTO {db_provider.project_name}.documents
  134. (id, owner_id, type, metadata, title, version, size_in_bytes, ingestion_status, extraction_status, collection_ids)
  135. VALUES ($1, $2, 'txt', '{{}}'::jsonb, 'Another Doc', 'v1', 10, 'pending', 'pending', $3)
  136. """
  137. await db_provider.connection_manager.execute_query(
  138. insert_doc_query, [doc_id, owner_id, [coll.id]])
  139. # Remove it
  140. await collections_handler.remove_document_from_collection_relational(
  141. doc_id, coll.id)
  142. docs = await collections_handler.documents_in_collection(coll.id,
  143. offset=0,
  144. limit=10)
  145. assert len(docs["results"]) == 0
  146. @pytest.mark.asyncio
  147. async def test_delete_nonexistent_collection(collections_handler):
  148. non_existent_id = uuid.uuid4()
  149. with pytest.raises(R2RException) as exc:
  150. await collections_handler.delete_collection_relational(non_existent_id)
  151. assert exc.value.status_code == 404, (
  152. "Should raise 404 for non-existing collection")