test_commands.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. """
  2. 向量搜索命令单元测试
  3. 测试向量搜索应用层的命令定义和验证逻辑。
  4. """
  5. import pytest
  6. from src.application.vector_search.commands import (
  7. CreateDocumentCommand,
  8. UpdateDocumentCommand,
  9. DeleteDocumentCommand,
  10. )
  11. class TestCreateDocumentCommand:
  12. """CreateDocumentCommand 单元测试"""
  13. def test_create_with_valid_content(self):
  14. """测试使用有效内容创建命令"""
  15. # Act
  16. command = CreateDocumentCommand(
  17. content="This is a test document",
  18. metadata={"source": "test"}
  19. )
  20. # Assert
  21. assert command.content == "This is a test document"
  22. assert command.metadata == {"source": "test"}
  23. def test_create_with_default_metadata(self):
  24. """测试使用默认元数据创建命令"""
  25. # Act
  26. command = CreateDocumentCommand(content="Test content")
  27. # Assert
  28. assert command.content == "Test content"
  29. assert command.metadata == {}
  30. def test_create_with_empty_content_raises_error(self):
  31. """测试使用空内容创建命令会抛出错误"""
  32. # Act & Assert
  33. with pytest.raises(ValueError, match="Document content cannot be empty"):
  34. CreateDocumentCommand(content="")
  35. def test_create_with_whitespace_only_content_raises_error(self):
  36. """测试使用仅空白字符的内容创建命令会抛出错误"""
  37. # Act & Assert
  38. with pytest.raises(ValueError, match="Document content cannot be whitespace only"):
  39. CreateDocumentCommand(content=" \n\t ")
  40. def test_create_with_non_string_content_raises_error(self):
  41. """测试使用非字符串内容创建命令会抛出错误"""
  42. # Act & Assert
  43. with pytest.raises(ValueError, match="Document content must be a string"):
  44. CreateDocumentCommand(content=123) # type: ignore
  45. def test_create_with_non_dict_metadata_raises_error(self):
  46. """测试使用非字典元数据创建命令会抛出错误"""
  47. # Act & Assert
  48. with pytest.raises(ValueError, match="Document metadata must be a dictionary"):
  49. CreateDocumentCommand(
  50. content="Test content",
  51. metadata="invalid" # type: ignore
  52. )
  53. class TestUpdateDocumentCommand:
  54. """UpdateDocumentCommand 单元测试"""
  55. def test_update_with_content_only(self):
  56. """测试只更新内容"""
  57. # Act
  58. command = UpdateDocumentCommand(
  59. document_id="doc_123",
  60. content="Updated content"
  61. )
  62. # Assert
  63. assert command.document_id == "doc_123"
  64. assert command.content == "Updated content"
  65. assert command.metadata is None
  66. assert command.merge_metadata is True
  67. def test_update_with_metadata_only(self):
  68. """测试只更新元数据"""
  69. # Act
  70. command = UpdateDocumentCommand(
  71. document_id="doc_123",
  72. metadata={"version": "2.0"}
  73. )
  74. # Assert
  75. assert command.document_id == "doc_123"
  76. assert command.content is None
  77. assert command.metadata == {"version": "2.0"}
  78. def test_update_with_content_and_metadata(self):
  79. """测试同时更新内容和元数据"""
  80. # Act
  81. command = UpdateDocumentCommand(
  82. document_id="doc_123",
  83. content="Updated content",
  84. metadata={"version": "2.0"},
  85. merge_metadata=False
  86. )
  87. # Assert
  88. assert command.document_id == "doc_123"
  89. assert command.content == "Updated content"
  90. assert command.metadata == {"version": "2.0"}
  91. assert command.merge_metadata is False
  92. def test_update_with_empty_document_id_raises_error(self):
  93. """测试使用空文档 ID 更新会抛出错误"""
  94. # Act & Assert
  95. with pytest.raises(ValueError, match="Document ID cannot be empty"):
  96. UpdateDocumentCommand(
  97. document_id="",
  98. content="Updated content"
  99. )
  100. def test_update_with_no_content_and_no_metadata_raises_error(self):
  101. """测试不提供内容和元数据会抛出错误"""
  102. # Act & Assert
  103. with pytest.raises(ValueError, match="At least one of content or metadata must be provided"):
  104. UpdateDocumentCommand(document_id="doc_123")
  105. def test_update_with_whitespace_only_content_raises_error(self):
  106. """测试使用仅空白字符的内容更新会抛出错误"""
  107. # Act & Assert
  108. with pytest.raises(ValueError, match="Document content cannot be whitespace only"):
  109. UpdateDocumentCommand(
  110. document_id="doc_123",
  111. content=" \n\t "
  112. )
  113. def test_update_with_non_string_content_raises_error(self):
  114. """测试使用非字符串内容更新会抛出错误"""
  115. # Act & Assert
  116. with pytest.raises(ValueError, match="Document content must be a string"):
  117. UpdateDocumentCommand(
  118. document_id="doc_123",
  119. content=123 # type: ignore
  120. )
  121. def test_update_with_non_dict_metadata_raises_error(self):
  122. """测试使用非字典元数据更新会抛出错误"""
  123. # Act & Assert
  124. with pytest.raises(ValueError, match="Document metadata must be a dictionary"):
  125. UpdateDocumentCommand(
  126. document_id="doc_123",
  127. metadata="invalid" # type: ignore
  128. )
  129. def test_has_content_update_returns_true_when_content_provided(self):
  130. """测试当提供内容时 has_content_update 返回 True"""
  131. # Arrange
  132. command = UpdateDocumentCommand(
  133. document_id="doc_123",
  134. content="Updated content"
  135. )
  136. # Act & Assert
  137. assert command.has_content_update() is True
  138. def test_has_content_update_returns_false_when_content_not_provided(self):
  139. """测试当不提供内容时 has_content_update 返回 False"""
  140. # Arrange
  141. command = UpdateDocumentCommand(
  142. document_id="doc_123",
  143. metadata={"version": "2.0"}
  144. )
  145. # Act & Assert
  146. assert command.has_content_update() is False
  147. def test_has_metadata_update_returns_true_when_metadata_provided(self):
  148. """测试当提供元数据时 has_metadata_update 返回 True"""
  149. # Arrange
  150. command = UpdateDocumentCommand(
  151. document_id="doc_123",
  152. metadata={"version": "2.0"}
  153. )
  154. # Act & Assert
  155. assert command.has_metadata_update() is True
  156. def test_has_metadata_update_returns_false_when_metadata_not_provided(self):
  157. """测试当不提供元数据时 has_metadata_update 返回 False"""
  158. # Arrange
  159. command = UpdateDocumentCommand(
  160. document_id="doc_123",
  161. content="Updated content"
  162. )
  163. # Act & Assert
  164. assert command.has_metadata_update() is False
  165. class TestDeleteDocumentCommand:
  166. """DeleteDocumentCommand 单元测试"""
  167. def test_delete_with_valid_document_id(self):
  168. """测试使用有效文档 ID 创建删除命令"""
  169. # Act
  170. command = DeleteDocumentCommand(document_id="doc_123")
  171. # Assert
  172. assert command.document_id == "doc_123"
  173. def test_delete_with_empty_document_id_raises_error(self):
  174. """测试使用空文档 ID 删除会抛出错误"""
  175. # Act & Assert
  176. with pytest.raises(ValueError, match="Document ID cannot be empty"):
  177. DeleteDocumentCommand(document_id="")
  178. def test_delete_with_non_string_document_id_raises_error(self):
  179. """测试使用非字符串文档 ID 删除会抛出错误"""
  180. # Act & Assert
  181. with pytest.raises(ValueError, match="Document ID must be a string"):
  182. DeleteDocumentCommand(document_id=123) # type: ignore