Removed async
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
"""
|
||||
Test suite for FileDocumentRepository with async/await support.
|
||||
Test suite for FileDocumentRepository with async/support.
|
||||
|
||||
This module contains comprehensive tests for all FileDocumentRepository methods
|
||||
using mongomock-motor for in-memory MongoDB testing.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
from typing import Dict, Any
|
||||
|
||||
import pytest_asyncio
|
||||
import pytest
|
||||
from bson import ObjectId
|
||||
from pymongo.errors import DuplicateKeyError, PyMongoError
|
||||
from mongomock_motor import AsyncMongoMockClient
|
||||
from mongomock.mongo_client import MongoClient
|
||||
from pymongo.errors import PyMongoError
|
||||
|
||||
from app.database.repositories.document_repository import (
|
||||
FileDocumentRepository,
|
||||
@@ -23,13 +21,13 @@ from app.database.repositories.document_repository import (
|
||||
from app.models.document import FileDocument, FileType, ExtractionMethod
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def in_memory_repository():
|
||||
@pytest.fixture
|
||||
def in_memory_repository():
|
||||
"""Create an in-memory FileDocumentRepository for testing."""
|
||||
client = AsyncMongoMockClient()
|
||||
client = MongoClient()
|
||||
db = client.test_database
|
||||
repo = FileDocumentRepository(db)
|
||||
await repo.initialize()
|
||||
repo.initialize()
|
||||
return repo
|
||||
|
||||
|
||||
@@ -107,14 +105,13 @@ def multiple_sample_files():
|
||||
class TestFileDocumentRepositoryInitialization:
|
||||
"""Tests for repository initialization."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_initialize_repository(self):
|
||||
def test_i_can_initialize_repository(self):
|
||||
"""Test repository initialization."""
|
||||
# Arrange
|
||||
client = AsyncMongoMockClient()
|
||||
client = MongoClient()
|
||||
db = client.test_database
|
||||
repo = FileDocumentRepository(db)
|
||||
await repo.initialize()
|
||||
repo.initialize()
|
||||
|
||||
# Act & Assert (should not raise any exception)
|
||||
assert repo.db is not None
|
||||
@@ -125,11 +122,10 @@ class TestFileDocumentRepositoryInitialization:
|
||||
class TestFileDocumentRepositoryCreation:
|
||||
"""Tests for file document creation functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_create_file_document(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_create_file_document(self, in_memory_repository, sample_file_document):
|
||||
"""Test successful file document creation."""
|
||||
# Act
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Assert
|
||||
assert created_file is not None
|
||||
@@ -144,54 +140,28 @@ class TestFileDocumentRepositoryCreation:
|
||||
assert created_file.id is not None
|
||||
assert isinstance(created_file.id, ObjectId)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_create_file_document_without_id(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_create_file_document_without_id(self, in_memory_repository, sample_file_document):
|
||||
"""Test creating file document with _id set to None (should be removed)."""
|
||||
# Arrange
|
||||
sample_file_document.id = None
|
||||
|
||||
# Act
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Assert
|
||||
assert created_file is not None
|
||||
assert created_file.id is not None
|
||||
assert isinstance(created_file.id, ObjectId)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_create_duplicate_file_document(self, in_memory_repository, sample_file_document):
|
||||
"""Test that creating file document with duplicate filepath raises DuplicateKeyError."""
|
||||
# Arrange
|
||||
await in_memory_repository.create_document(sample_file_document)
|
||||
duplicate_file = FileDocument(
|
||||
filename="different_name.pdf",
|
||||
filepath=sample_file_document.filepath, # Same filepath
|
||||
file_type=FileType.PDF,
|
||||
extraction_method=ExtractionMethod.OCR,
|
||||
metadata={"different": "metadata"},
|
||||
detected_at=datetime.now(),
|
||||
file_hash="different_hash_123456789012345678901234567890123456789012345678",
|
||||
encoding="utf-8",
|
||||
file_size=2000,
|
||||
mime_type="application/pdf"
|
||||
)
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(DuplicateKeyError) as exc_info:
|
||||
await in_memory_repository.create_document(duplicate_file)
|
||||
|
||||
assert "already exists" in str(exc_info.value)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_create_file_document_with_pymongo_error(self, in_memory_repository,
|
||||
sample_file_document, mocker):
|
||||
def test_i_cannot_create_file_document_with_pymongo_error(self, in_memory_repository,
|
||||
sample_file_document, mocker):
|
||||
"""Test handling of PyMongo errors during file document creation."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'insert_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(ValueError) as exc_info:
|
||||
await in_memory_repository.create_document(sample_file_document)
|
||||
in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
assert "Failed to create file document" in str(exc_info.value)
|
||||
|
||||
@@ -199,14 +169,13 @@ class TestFileDocumentRepositoryCreation:
|
||||
class TestFileDocumentRepositoryFinding:
|
||||
"""Tests for file document finding functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_document_by_valid_id(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_find_document_by_valid_id(self, in_memory_repository, sample_file_document):
|
||||
"""Test finding file document by valid ObjectId."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_id(str(created_file.id))
|
||||
found_file = in_memory_repository.find_document_by_id(str(created_file.id))
|
||||
|
||||
# Assert
|
||||
assert found_file is not None
|
||||
@@ -214,81 +183,74 @@ class TestFileDocumentRepositoryFinding:
|
||||
assert found_file.filename == created_file.filename
|
||||
assert found_file.filepath == created_file.filepath
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_document_with_invalid_id(self, in_memory_repository):
|
||||
def test_i_cannot_find_document_with_invalid_id(self, in_memory_repository):
|
||||
"""Test that invalid ObjectId returns None."""
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_id("invalid_id")
|
||||
found_file = in_memory_repository.find_document_by_id("invalid_id")
|
||||
|
||||
# Assert
|
||||
assert found_file is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_document_by_nonexistent_id(self, in_memory_repository):
|
||||
def test_i_cannot_find_document_by_nonexistent_id(self, in_memory_repository):
|
||||
"""Test that nonexistent but valid ObjectId returns None."""
|
||||
# Arrange
|
||||
nonexistent_id = str(ObjectId())
|
||||
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_id(nonexistent_id)
|
||||
found_file = in_memory_repository.find_document_by_id(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert found_file is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_document_by_file_hash(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_find_document_by_file_hash(self, in_memory_repository, sample_file_document):
|
||||
"""Test finding file document by file hash."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_hash(sample_file_document.file_hash)
|
||||
found_file = in_memory_repository.find_document_by_hash(sample_file_document.file_hash)
|
||||
|
||||
# Assert
|
||||
assert found_file is not None
|
||||
assert found_file.file_hash == created_file.file_hash
|
||||
assert found_file.id == created_file.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_document_with_nonexistent_file_hash(self, in_memory_repository):
|
||||
def test_i_cannot_find_document_with_nonexistent_file_hash(self, in_memory_repository):
|
||||
"""Test that nonexistent file hash returns None."""
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_hash("nonexistent_hash")
|
||||
found_file = in_memory_repository.find_document_by_hash("nonexistent_hash")
|
||||
|
||||
# Assert
|
||||
assert found_file is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_document_by_filepath(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_find_document_by_filepath(self, in_memory_repository, sample_file_document):
|
||||
"""Test finding file document by filepath."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_filepath(sample_file_document.filepath)
|
||||
found_file = in_memory_repository.find_document_by_filepath(sample_file_document.filepath)
|
||||
|
||||
# Assert
|
||||
assert found_file is not None
|
||||
assert found_file.filepath == created_file.filepath
|
||||
assert found_file.id == created_file.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_document_with_nonexistent_filepath(self, in_memory_repository):
|
||||
def test_i_cannot_find_document_with_nonexistent_filepath(self, in_memory_repository):
|
||||
"""Test that nonexistent filepath returns None."""
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_filepath("/nonexistent/path/file.pdf")
|
||||
found_file = in_memory_repository.find_document_by_filepath("/nonexistent/path/file.pdf")
|
||||
|
||||
# Assert
|
||||
assert found_file is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_document_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_find_document_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during file document finding."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
found_file = await in_memory_repository.find_document_by_hash("test_hash")
|
||||
found_file = in_memory_repository.find_document_by_hash("test_hash")
|
||||
|
||||
# Assert
|
||||
assert found_file is None
|
||||
@@ -297,16 +259,15 @@ class TestFileDocumentRepositoryFinding:
|
||||
class TestFileDocumentRepositoryNameMatching:
|
||||
"""Tests for file document name matching functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_documents_by_name_with_fuzzy_matching(self, in_memory_repository, multiple_sample_files):
|
||||
def test_i_can_find_documents_by_name_with_fuzzy_matching(self, in_memory_repository, multiple_sample_files):
|
||||
"""Test finding file documents by filename using fuzzy matching."""
|
||||
# Arrange
|
||||
for file_doc in multiple_sample_files:
|
||||
await in_memory_repository.create_document(file_doc)
|
||||
in_memory_repository.create_document(file_doc)
|
||||
|
||||
# Act
|
||||
fuzzy_method = FuzzyMatching(threshold=0.5)
|
||||
found_files = await in_memory_repository.find_document_by_name("document", fuzzy_method)
|
||||
found_files = in_memory_repository.find_document_by_name("document", fuzzy_method)
|
||||
|
||||
# Assert
|
||||
assert len(found_files) >= 1
|
||||
@@ -315,44 +276,41 @@ class TestFileDocumentRepositoryNameMatching:
|
||||
found_filenames = [f.filename for f in found_files]
|
||||
assert any("document" in fname.lower() for fname in found_filenames)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_documents_by_name_with_subsequence_matching(self, in_memory_repository,
|
||||
multiple_sample_files):
|
||||
def test_i_can_find_documents_by_name_with_subsequence_matching(self, in_memory_repository,
|
||||
multiple_sample_files):
|
||||
"""Test finding file documents by filename using subsequence matching."""
|
||||
# Arrange
|
||||
for file_doc in multiple_sample_files:
|
||||
await in_memory_repository.create_document(file_doc)
|
||||
in_memory_repository.create_document(file_doc)
|
||||
|
||||
# Act
|
||||
subsequence_method = SubsequenceMatching()
|
||||
found_files = await in_memory_repository.find_document_by_name("doc", subsequence_method)
|
||||
found_files = in_memory_repository.find_document_by_name("doc", subsequence_method)
|
||||
|
||||
# Assert
|
||||
assert len(found_files) >= 1
|
||||
assert all(isinstance(file_doc, FileDocument) for file_doc in found_files)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_documents_by_name_with_default_method(self, in_memory_repository, multiple_sample_files):
|
||||
def test_i_can_find_documents_by_name_with_default_method(self, in_memory_repository, multiple_sample_files):
|
||||
"""Test finding file documents by filename with default matching method."""
|
||||
# Arrange
|
||||
for file_doc in multiple_sample_files:
|
||||
await in_memory_repository.create_document(file_doc)
|
||||
in_memory_repository.create_document(file_doc)
|
||||
|
||||
# Act
|
||||
found_files = await in_memory_repository.find_document_by_name("first")
|
||||
found_files = in_memory_repository.find_document_by_name("first")
|
||||
|
||||
# Assert
|
||||
assert len(found_files) >= 0
|
||||
assert all(isinstance(file_doc, FileDocument) for file_doc in found_files)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_documents_by_name_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_find_documents_by_name_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during document name matching."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
found_files = await in_memory_repository.find_document_by_name("test")
|
||||
found_files = in_memory_repository.find_document_by_name("test")
|
||||
|
||||
# Assert
|
||||
assert found_files == []
|
||||
@@ -361,30 +319,28 @@ class TestFileDocumentRepositoryNameMatching:
|
||||
class TestFileDocumentRepositoryListing:
|
||||
"""Tests for file document listing functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_list_documents_with_default_pagination(self, in_memory_repository, multiple_sample_files):
|
||||
def test_i_can_list_documents_with_default_pagination(self, in_memory_repository, multiple_sample_files):
|
||||
"""Test listing file documents with default pagination."""
|
||||
# Arrange
|
||||
for file_doc in multiple_sample_files:
|
||||
await in_memory_repository.create_document(file_doc)
|
||||
in_memory_repository.create_document(file_doc)
|
||||
|
||||
# Act
|
||||
files = await in_memory_repository.list_documents()
|
||||
files = in_memory_repository.list_documents()
|
||||
|
||||
# Assert
|
||||
assert len(files) == len(multiple_sample_files)
|
||||
assert all(isinstance(file_doc, FileDocument) for file_doc in files)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_list_documents_with_custom_pagination(self, in_memory_repository, multiple_sample_files):
|
||||
def test_i_can_list_documents_with_custom_pagination(self, in_memory_repository, multiple_sample_files):
|
||||
"""Test listing file documents with custom pagination."""
|
||||
# Arrange
|
||||
for file_doc in multiple_sample_files:
|
||||
await in_memory_repository.create_document(file_doc)
|
||||
in_memory_repository.create_document(file_doc)
|
||||
|
||||
# Act
|
||||
files_page1 = await in_memory_repository.list_documents(skip=0, limit=2)
|
||||
files_page2 = await in_memory_repository.list_documents(skip=2, limit=2)
|
||||
files_page1 = in_memory_repository.list_documents(skip=0, limit=2)
|
||||
files_page2 = in_memory_repository.list_documents(skip=2, limit=2)
|
||||
|
||||
# Assert
|
||||
assert len(files_page1) == 2
|
||||
@@ -395,8 +351,7 @@ class TestFileDocumentRepositoryListing:
|
||||
page2_ids = [file_doc.id for file_doc in files_page2]
|
||||
assert len(set(page1_ids).intersection(set(page2_ids))) == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_list_documents_sorted_by_detected_at(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_list_documents_sorted_by_detected_at(self, in_memory_repository, sample_file_document):
|
||||
"""Test that file documents are sorted by detected_at in descending order."""
|
||||
# Arrange
|
||||
file1 = sample_file_document.model_copy()
|
||||
@@ -411,11 +366,11 @@ class TestFileDocumentRepositoryListing:
|
||||
file2.file_hash = "hash2" + "0" * 58
|
||||
file2.detected_at = datetime(2024, 1, 2, 10, 0, 0) # Later date
|
||||
|
||||
created_file1 = await in_memory_repository.create_document(file1)
|
||||
created_file2 = await in_memory_repository.create_document(file2)
|
||||
created_file1 = in_memory_repository.create_document(file1)
|
||||
created_file2 = in_memory_repository.create_document(file2)
|
||||
|
||||
# Act
|
||||
files = await in_memory_repository.list_documents()
|
||||
files = in_memory_repository.list_documents()
|
||||
|
||||
# Assert
|
||||
assert len(files) == 2
|
||||
@@ -423,23 +378,21 @@ class TestFileDocumentRepositoryListing:
|
||||
assert files[0].id == created_file2.id
|
||||
assert files[1].id == created_file1.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_list_empty_documents(self, in_memory_repository):
|
||||
def test_i_can_list_empty_documents(self, in_memory_repository):
|
||||
"""Test listing file documents from empty collection."""
|
||||
# Act
|
||||
files = await in_memory_repository.list_documents()
|
||||
files = in_memory_repository.list_documents()
|
||||
|
||||
# Assert
|
||||
assert files == []
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_list_documents_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_list_documents_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during file document listing."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
files = await in_memory_repository.list_documents()
|
||||
files = in_memory_repository.list_documents()
|
||||
|
||||
# Assert
|
||||
assert files == []
|
||||
@@ -448,15 +401,14 @@ class TestFileDocumentRepositoryListing:
|
||||
class TestFileDocumentRepositoryUpdate:
|
||||
"""Tests for file document update functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_document_successfully(self, in_memory_repository, sample_file_document,
|
||||
sample_update_data):
|
||||
def test_i_can_update_document_successfully(self, in_memory_repository, sample_file_document,
|
||||
sample_update_data):
|
||||
"""Test successful file document update."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
updated_file = await in_memory_repository.update_document(str(created_file.id), sample_update_data)
|
||||
updated_file = in_memory_repository.update_document(str(created_file.id), sample_update_data)
|
||||
|
||||
# Assert
|
||||
assert updated_file is not None
|
||||
@@ -467,15 +419,14 @@ class TestFileDocumentRepositoryUpdate:
|
||||
assert updated_file.filename == created_file.filename # Unchanged fields remain
|
||||
assert updated_file.filepath == created_file.filepath
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_document_with_partial_data(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_update_document_with_partial_data(self, in_memory_repository, sample_file_document):
|
||||
"""Test updating file document with partial data."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
partial_update = {"file_size": 999999}
|
||||
|
||||
# Act
|
||||
updated_file = await in_memory_repository.update_document(str(created_file.id), partial_update)
|
||||
updated_file = in_memory_repository.update_document(str(created_file.id), partial_update)
|
||||
|
||||
# Assert
|
||||
assert updated_file is not None
|
||||
@@ -483,30 +434,28 @@ class TestFileDocumentRepositoryUpdate:
|
||||
assert updated_file.filename == created_file.filename # Should remain unchanged
|
||||
assert updated_file.metadata == created_file.metadata # Should remain unchanged
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_document_filtering_none_values(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_update_document_filtering_none_values(self, in_memory_repository, sample_file_document):
|
||||
"""Test that None values are filtered out from update data."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
update_with_none = {"file_size": 777777, "metadata": None}
|
||||
|
||||
# Act
|
||||
updated_file = await in_memory_repository.update_document(str(created_file.id), update_with_none)
|
||||
updated_file = in_memory_repository.update_document(str(created_file.id), update_with_none)
|
||||
|
||||
# Assert
|
||||
assert updated_file is not None
|
||||
assert updated_file.file_size == 777777
|
||||
assert updated_file.metadata == created_file.metadata # Should remain unchanged (None filtered out)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_document_with_empty_data(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_update_document_with_empty_data(self, in_memory_repository, sample_file_document):
|
||||
"""Test updating file document with empty data returns current document."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
empty_update = {}
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.update_document(str(created_file.id), empty_update)
|
||||
result = in_memory_repository.update_document(str(created_file.id), empty_update)
|
||||
|
||||
# Assert
|
||||
assert result is not None
|
||||
@@ -514,38 +463,35 @@ class TestFileDocumentRepositoryUpdate:
|
||||
assert result.filepath == created_file.filepath
|
||||
assert result.metadata == created_file.metadata
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_document_with_invalid_id(self, in_memory_repository, sample_update_data):
|
||||
def test_i_cannot_update_document_with_invalid_id(self, in_memory_repository, sample_update_data):
|
||||
"""Test that updating with invalid ID returns None."""
|
||||
# Act
|
||||
result = await in_memory_repository.update_document("invalid_id", sample_update_data)
|
||||
result = in_memory_repository.update_document("invalid_id", sample_update_data)
|
||||
|
||||
# Assert
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_nonexistent_document(self, in_memory_repository, sample_update_data):
|
||||
def test_i_cannot_update_nonexistent_document(self, in_memory_repository, sample_update_data):
|
||||
"""Test that updating nonexistent file document returns None."""
|
||||
# Arrange
|
||||
nonexistent_id = str(ObjectId())
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.update_document(nonexistent_id, sample_update_data)
|
||||
result = in_memory_repository.update_document(nonexistent_id, sample_update_data)
|
||||
|
||||
# Assert
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_document_with_pymongo_error(self, in_memory_repository, sample_file_document,
|
||||
sample_update_data, mocker):
|
||||
def test_i_cannot_update_document_with_pymongo_error(self, in_memory_repository, sample_file_document,
|
||||
sample_update_data, mocker):
|
||||
"""Test handling of PyMongo errors during file document update."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
mocker.patch.object(in_memory_repository.collection, 'find_one_and_update',
|
||||
side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.update_document(str(created_file.id), sample_update_data)
|
||||
result = in_memory_repository.update_document(str(created_file.id), sample_update_data)
|
||||
|
||||
# Assert
|
||||
assert result is None
|
||||
@@ -554,52 +500,48 @@ class TestFileDocumentRepositoryUpdate:
|
||||
class TestFileDocumentRepositoryDeletion:
|
||||
"""Tests for file document deletion functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_delete_existing_document(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_delete_existing_document(self, in_memory_repository, sample_file_document):
|
||||
"""Test successful file document deletion."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
deletion_result = await in_memory_repository.delete_document(str(created_file.id))
|
||||
deletion_result = in_memory_repository.delete_document(str(created_file.id))
|
||||
|
||||
# Assert
|
||||
assert deletion_result is True
|
||||
|
||||
# Verify document is actually deleted
|
||||
found_file = await in_memory_repository.find_document_by_id(str(created_file.id))
|
||||
found_file = in_memory_repository.find_document_by_id(str(created_file.id))
|
||||
assert found_file is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_document_with_invalid_id(self, in_memory_repository):
|
||||
def test_i_cannot_delete_document_with_invalid_id(self, in_memory_repository):
|
||||
"""Test that deleting with invalid ID returns False."""
|
||||
# Act
|
||||
result = await in_memory_repository.delete_document("invalid_id")
|
||||
result = in_memory_repository.delete_document("invalid_id")
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_nonexistent_document(self, in_memory_repository):
|
||||
def test_i_cannot_delete_nonexistent_document(self, in_memory_repository):
|
||||
"""Test that deleting nonexistent file document returns False."""
|
||||
# Arrange
|
||||
nonexistent_id = str(ObjectId())
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.delete_document(nonexistent_id)
|
||||
result = in_memory_repository.delete_document(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_document_with_pymongo_error(self, in_memory_repository, sample_file_document, mocker):
|
||||
def test_i_cannot_delete_document_with_pymongo_error(self, in_memory_repository, sample_file_document, mocker):
|
||||
"""Test handling of PyMongo errors during file document deletion."""
|
||||
# Arrange
|
||||
created_file = await in_memory_repository.create_document(sample_file_document)
|
||||
created_file = in_memory_repository.create_document(sample_file_document)
|
||||
mocker.patch.object(in_memory_repository.collection, 'delete_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.delete_document(str(created_file.id))
|
||||
result = in_memory_repository.delete_document(str(created_file.id))
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
@@ -608,36 +550,33 @@ class TestFileDocumentRepositoryDeletion:
|
||||
class TestFileDocumentRepositoryUtilities:
|
||||
"""Tests for utility methods."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_count_documents(self, in_memory_repository, sample_file_document):
|
||||
def test_i_can_count_documents(self, in_memory_repository, sample_file_document):
|
||||
"""Test counting file documents."""
|
||||
# Arrange
|
||||
initial_count = await in_memory_repository.count_documents()
|
||||
await in_memory_repository.create_document(sample_file_document)
|
||||
initial_count = in_memory_repository.count_documents()
|
||||
in_memory_repository.create_document(sample_file_document)
|
||||
|
||||
# Act
|
||||
final_count = await in_memory_repository.count_documents()
|
||||
final_count = in_memory_repository.count_documents()
|
||||
|
||||
# Assert
|
||||
assert final_count == initial_count + 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_count_zero_documents(self, in_memory_repository):
|
||||
def test_i_can_count_zero_documents(self, in_memory_repository):
|
||||
"""Test counting file documents in empty collection."""
|
||||
# Act
|
||||
count = await in_memory_repository.count_documents()
|
||||
count = in_memory_repository.count_documents()
|
||||
|
||||
# Assert
|
||||
assert count == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_count_documents_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_count_documents_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during file document counting."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'count_documents', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act
|
||||
count = await in_memory_repository.count_documents()
|
||||
count = in_memory_repository.count_documents()
|
||||
|
||||
# Assert
|
||||
assert count == 0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
Test suite for JobRepository with async/await support.
|
||||
Test suite for JobRepository with async/support.
|
||||
|
||||
This module contains comprehensive tests for all JobRepository methods
|
||||
using mongomock-motor for in-memory MongoDB testing.
|
||||
@@ -8,8 +8,8 @@ using mongomock-motor for in-memory MongoDB testing.
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from bson import ObjectId
|
||||
from mongomock.mongo_client import MongoClient
|
||||
from mongomock_motor import AsyncMongoMockClient
|
||||
from pymongo.errors import PyMongoError
|
||||
|
||||
@@ -19,13 +19,13 @@ from app.models.job import ProcessingJob, ProcessingStatus
|
||||
from app.models.types import PyObjectId
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def in_memory_repository():
|
||||
@pytest.fixture
|
||||
def in_memory_repository():
|
||||
"""Create an in-memory JobRepository for testing."""
|
||||
client = AsyncMongoMockClient()
|
||||
client = MongoClient()
|
||||
db = client.test_database
|
||||
repo = JobRepository(db)
|
||||
await repo.initialize()
|
||||
repo.initialize()
|
||||
return repo
|
||||
|
||||
|
||||
@@ -82,8 +82,7 @@ def multiple_sample_jobs():
|
||||
class TestJobRepositoryInitialization:
|
||||
"""Tests for repository initialization."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_initialize_repository(self):
|
||||
def test_i_can_initialize_repository(self):
|
||||
"""Test repository initialization."""
|
||||
# Arrange
|
||||
client = AsyncMongoMockClient()
|
||||
@@ -91,7 +90,7 @@ class TestJobRepositoryInitialization:
|
||||
repo = JobRepository(db)
|
||||
|
||||
# Act
|
||||
initialized_repo = await repo.initialize()
|
||||
initialized_repo = repo.initialize()
|
||||
|
||||
# Assert
|
||||
assert initialized_repo is repo
|
||||
@@ -102,11 +101,10 @@ class TestJobRepositoryInitialization:
|
||||
class TestJobRepositoryCreation:
|
||||
"""Tests for job creation functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_create_job_with_task_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
def test_i_can_create_job_with_task_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
"""Test successful job creation with task ID."""
|
||||
# Act
|
||||
created_job = await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
|
||||
# Assert
|
||||
assert created_job is not None
|
||||
@@ -120,11 +118,10 @@ class TestJobRepositoryCreation:
|
||||
assert created_job.id is not None
|
||||
assert isinstance(created_job.id, ObjectId)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_create_job_without_task_id(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_create_job_without_task_id(self, in_memory_repository, sample_document_id):
|
||||
"""Test successful job creation without task ID."""
|
||||
# Act
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
|
||||
# Assert
|
||||
assert created_job is not None
|
||||
@@ -138,28 +135,26 @@ class TestJobRepositoryCreation:
|
||||
assert created_job.id is not None
|
||||
assert isinstance(created_job.id, ObjectId)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_create_duplicate_job_for_document(self, in_memory_repository, sample_document_id,
|
||||
sample_task_id):
|
||||
def test_i_cannot_create_duplicate_job_for_document(self, in_memory_repository, sample_document_id,
|
||||
sample_task_id):
|
||||
"""Test that creating job with duplicate document_id raises DuplicateKeyError."""
|
||||
# Arrange
|
||||
await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.create_job(sample_document_id, "different-task-id")
|
||||
in_memory_repository.create_job(sample_document_id, "different-task-id")
|
||||
|
||||
assert "create_job" in str(exc_info.value)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_create_job_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
def test_i_cannot_create_job_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
"""Test handling of PyMongo errors during job creation."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'insert_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.create_job(sample_document_id)
|
||||
in_memory_repository.create_job(sample_document_id)
|
||||
|
||||
assert "create_job" in str(exc_info.value)
|
||||
|
||||
@@ -167,14 +162,13 @@ class TestJobRepositoryCreation:
|
||||
class TestJobRepositoryFinding:
|
||||
"""Tests for job finding functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_job_by_valid_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
def test_i_can_find_job_by_valid_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
"""Test finding job by valid ObjectId."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
|
||||
# Act
|
||||
found_job = await in_memory_repository.find_job_by_id(created_job.id)
|
||||
found_job = in_memory_repository.find_job_by_id(created_job.id)
|
||||
|
||||
# Assert
|
||||
assert found_job is not None
|
||||
@@ -183,97 +177,90 @@ class TestJobRepositoryFinding:
|
||||
assert found_job.task_id == created_job.task_id
|
||||
assert found_job.status == created_job.status
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_job_by_nonexistent_id(self, in_memory_repository):
|
||||
def test_i_cannot_find_job_by_nonexistent_id(self, in_memory_repository):
|
||||
"""Test that nonexistent ObjectId returns None."""
|
||||
# Arrange
|
||||
nonexistent_id = PyObjectId()
|
||||
|
||||
# Act
|
||||
found_job = await in_memory_repository.find_job_by_id(nonexistent_id)
|
||||
found_job = in_memory_repository.find_job_by_id(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert found_job is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_job_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_find_job_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during job finding."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.find_job_by_id(PyObjectId())
|
||||
in_memory_repository.find_job_by_id(PyObjectId())
|
||||
|
||||
assert "get_job_by_id" in str(exc_info.value)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_jobs_by_document_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
def test_i_can_find_jobs_by_document_id(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
"""Test finding jobs by document ID."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
|
||||
# Act
|
||||
found_jobs = await in_memory_repository.find_jobs_by_document_id(sample_document_id)
|
||||
found_jobs = in_memory_repository.find_jobs_by_document_id(sample_document_id)
|
||||
|
||||
# Assert
|
||||
assert len(found_jobs) == 1
|
||||
assert found_jobs[0].id == created_job.id
|
||||
assert found_jobs[0].document_id == sample_document_id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_empty_jobs_list_for_nonexistent_document(self, in_memory_repository):
|
||||
def test_i_can_find_empty_jobs_list_for_nonexistent_document(self, in_memory_repository):
|
||||
"""Test that nonexistent document ID returns empty list."""
|
||||
# Arrange
|
||||
nonexistent_id = ObjectId()
|
||||
|
||||
# Act
|
||||
found_jobs = await in_memory_repository.find_jobs_by_document_id(nonexistent_id)
|
||||
found_jobs = in_memory_repository.find_jobs_by_document_id(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert found_jobs == []
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_jobs_by_document_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_find_jobs_by_document_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during finding jobs by document ID."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.find_jobs_by_document_id(PyObjectId())
|
||||
in_memory_repository.find_jobs_by_document_id(PyObjectId())
|
||||
|
||||
assert "get_jobs_by_file_id" in str(exc_info.value)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize("status", [
|
||||
ProcessingStatus.PENDING,
|
||||
ProcessingStatus.PROCESSING,
|
||||
ProcessingStatus.COMPLETED
|
||||
])
|
||||
async def test_i_can_find_jobs_by_pending_status(self, in_memory_repository, sample_document_id, status):
|
||||
def test_i_can_find_jobs_by_pending_status(self, in_memory_repository, sample_document_id, status):
|
||||
"""Test finding jobs by PENDING status."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
await in_memory_repository.update_job_status(created_job.id, status)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
in_memory_repository.update_job_status(created_job.id, status)
|
||||
|
||||
# Act
|
||||
found_jobs = await in_memory_repository.get_jobs_by_status(status)
|
||||
found_jobs = in_memory_repository.get_jobs_by_status(status)
|
||||
|
||||
# Assert
|
||||
assert len(found_jobs) == 1
|
||||
assert found_jobs[0].id == created_job.id
|
||||
assert found_jobs[0].status == status
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_jobs_by_failed_status(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_find_jobs_by_failed_status(self, in_memory_repository, sample_document_id):
|
||||
"""Test finding jobs by FAILED status."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.FAILED, "Test error")
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
in_memory_repository.update_job_status(created_job.id, ProcessingStatus.FAILED, "Test error")
|
||||
|
||||
# Act
|
||||
found_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.FAILED)
|
||||
found_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.FAILED)
|
||||
|
||||
# Assert
|
||||
assert len(found_jobs) == 1
|
||||
@@ -281,24 +268,22 @@ class TestJobRepositoryFinding:
|
||||
assert found_jobs[0].status == ProcessingStatus.FAILED
|
||||
assert found_jobs[0].error_message == "Test error"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_empty_jobs_list_for_unused_status(self, in_memory_repository):
|
||||
def test_i_can_find_empty_jobs_list_for_unused_status(self, in_memory_repository):
|
||||
"""Test that unused status returns empty list."""
|
||||
# Act
|
||||
found_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.COMPLETED)
|
||||
found_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.COMPLETED)
|
||||
|
||||
# Assert
|
||||
assert found_jobs == []
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_jobs_by_status_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
def test_i_cannot_find_jobs_by_status_with_pymongo_error(self, in_memory_repository, mocker):
|
||||
"""Test handling of PyMongo errors during finding jobs by status."""
|
||||
# Arrange
|
||||
mocker.patch.object(in_memory_repository.collection, 'find', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.get_jobs_by_status(ProcessingStatus.PENDING)
|
||||
in_memory_repository.get_jobs_by_status(ProcessingStatus.PENDING)
|
||||
|
||||
assert "get_jobs_by_status" in str(exc_info.value)
|
||||
|
||||
@@ -306,14 +291,13 @@ class TestJobRepositoryFinding:
|
||||
class TestJobRepositoryStatusUpdate:
|
||||
"""Tests for job status update functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_job_status_to_processing(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_update_job_status_to_processing(self, in_memory_repository, sample_document_id):
|
||||
"""Test updating job status to PROCESSING with started_at timestamp."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
|
||||
# Act
|
||||
updated_job = await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.PROCESSING)
|
||||
updated_job = in_memory_repository.update_job_status(created_job.id, ProcessingStatus.PROCESSING)
|
||||
|
||||
# Assert
|
||||
assert updated_job is not None
|
||||
@@ -323,15 +307,14 @@ class TestJobRepositoryStatusUpdate:
|
||||
assert updated_job.completed_at is None
|
||||
assert updated_job.error_message is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_job_status_to_completed(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_update_job_status_to_completed(self, in_memory_repository, sample_document_id):
|
||||
"""Test updating job status to COMPLETED with completed_at timestamp."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.PROCESSING)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
in_memory_repository.update_job_status(created_job.id, ProcessingStatus.PROCESSING)
|
||||
|
||||
# Act
|
||||
updated_job = await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.COMPLETED)
|
||||
updated_job = in_memory_repository.update_job_status(created_job.id, ProcessingStatus.COMPLETED)
|
||||
|
||||
# Assert
|
||||
assert updated_job is not None
|
||||
@@ -341,15 +324,14 @@ class TestJobRepositoryStatusUpdate:
|
||||
assert updated_job.completed_at is not None
|
||||
assert updated_job.error_message is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_job_status_to_failed_with_error(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_update_job_status_to_failed_with_error(self, in_memory_repository, sample_document_id):
|
||||
"""Test updating job status to FAILED with error message and completed_at timestamp."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
error_message = "Processing failed due to invalid format"
|
||||
|
||||
# Act
|
||||
updated_job = await in_memory_repository.update_job_status(
|
||||
updated_job = in_memory_repository.update_job_status(
|
||||
created_job.id, ProcessingStatus.FAILED, error_message
|
||||
)
|
||||
|
||||
@@ -360,14 +342,13 @@ class TestJobRepositoryStatusUpdate:
|
||||
assert updated_job.completed_at is not None
|
||||
assert updated_job.error_message == error_message
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_job_status_to_failed_without_error(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_update_job_status_to_failed_without_error(self, in_memory_repository, sample_document_id):
|
||||
"""Test updating job status to FAILED without error message."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
|
||||
# Act
|
||||
updated_job = await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.FAILED)
|
||||
updated_job = in_memory_repository.update_job_status(created_job.id, ProcessingStatus.FAILED)
|
||||
|
||||
# Assert
|
||||
assert updated_job is not None
|
||||
@@ -376,29 +357,27 @@ class TestJobRepositoryStatusUpdate:
|
||||
assert updated_job.completed_at is not None
|
||||
assert updated_job.error_message is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_nonexistent_job_status(self, in_memory_repository):
|
||||
def test_i_cannot_update_nonexistent_job_status(self, in_memory_repository):
|
||||
"""Test that updating nonexistent job returns None."""
|
||||
# Arrange
|
||||
nonexistent_id = ObjectId()
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.update_job_status(nonexistent_id, ProcessingStatus.COMPLETED)
|
||||
result = in_memory_repository.update_job_status(nonexistent_id, ProcessingStatus.COMPLETED)
|
||||
|
||||
# Assert
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_job_status_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
def test_i_cannot_update_job_status_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
"""Test handling of PyMongo errors during job status update."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
mocker.patch.object(in_memory_repository.collection, 'find_one_and_update',
|
||||
side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.update_job_status(created_job.id, ProcessingStatus.COMPLETED)
|
||||
in_memory_repository.update_job_status(created_job.id, ProcessingStatus.COMPLETED)
|
||||
|
||||
assert "update_job_status" in str(exc_info.value)
|
||||
|
||||
@@ -406,44 +385,41 @@ class TestJobRepositoryStatusUpdate:
|
||||
class TestJobRepositoryDeletion:
|
||||
"""Tests for job deletion functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_delete_existing_job(self, in_memory_repository, sample_document_id):
|
||||
def test_i_can_delete_existing_job(self, in_memory_repository, sample_document_id):
|
||||
"""Test successful job deletion."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
|
||||
# Act
|
||||
deletion_result = await in_memory_repository.delete_job(created_job.id)
|
||||
deletion_result = in_memory_repository.delete_job(created_job.id)
|
||||
|
||||
# Assert
|
||||
assert deletion_result is True
|
||||
|
||||
# Verify job is actually deleted
|
||||
found_job = await in_memory_repository.find_job_by_id(created_job.id)
|
||||
found_job = in_memory_repository.find_job_by_id(created_job.id)
|
||||
assert found_job is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_nonexistent_job(self, in_memory_repository):
|
||||
def test_i_cannot_delete_nonexistent_job(self, in_memory_repository):
|
||||
"""Test that deleting nonexistent job returns False."""
|
||||
# Arrange
|
||||
nonexistent_id = ObjectId()
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.delete_job(nonexistent_id)
|
||||
result = in_memory_repository.delete_job(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_job_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
def test_i_cannot_delete_job_with_pymongo_error(self, in_memory_repository, sample_document_id, mocker):
|
||||
"""Test handling of PyMongo errors during job deletion."""
|
||||
# Arrange
|
||||
created_job = await in_memory_repository.create_job(sample_document_id)
|
||||
created_job = in_memory_repository.create_job(sample_document_id)
|
||||
mocker.patch.object(in_memory_repository.collection, 'delete_one', side_effect=PyMongoError("Database error"))
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(JobRepositoryError) as exc_info:
|
||||
await in_memory_repository.delete_job(created_job.id)
|
||||
in_memory_repository.delete_job(created_job.id)
|
||||
|
||||
assert "delete_job" in str(exc_info.value)
|
||||
|
||||
@@ -451,38 +427,36 @@ class TestJobRepositoryDeletion:
|
||||
class TestJobRepositoryComplexScenarios:
|
||||
"""Tests for complex job repository scenarios."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_handle_complete_job_lifecycle(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
def test_i_can_handle_complete_job_lifecycle(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
"""Test complete job lifecycle from creation to completion."""
|
||||
# Create job
|
||||
job = await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
job = in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
assert job.status == ProcessingStatus.PENDING
|
||||
assert job.started_at is None
|
||||
assert job.completed_at is None
|
||||
|
||||
# Start processing
|
||||
job = await in_memory_repository.update_job_status(job.id, ProcessingStatus.PROCESSING)
|
||||
job = in_memory_repository.update_job_status(job.id, ProcessingStatus.PROCESSING)
|
||||
assert job.status == ProcessingStatus.PROCESSING
|
||||
assert job.started_at is not None
|
||||
assert job.completed_at is None
|
||||
|
||||
# Complete job
|
||||
job = await in_memory_repository.update_job_status(job.id, ProcessingStatus.COMPLETED)
|
||||
job = in_memory_repository.update_job_status(job.id, ProcessingStatus.COMPLETED)
|
||||
assert job.status == ProcessingStatus.COMPLETED
|
||||
assert job.started_at is not None
|
||||
assert job.completed_at is not None
|
||||
assert job.error_message is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_handle_job_failure_scenario(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
def test_i_can_handle_job_failure_scenario(self, in_memory_repository, sample_document_id, sample_task_id):
|
||||
"""Test job failure scenario with error message."""
|
||||
# Create and start job
|
||||
job = await in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
job = await in_memory_repository.update_job_status(job.id, ProcessingStatus.PROCESSING)
|
||||
job = in_memory_repository.create_job(sample_document_id, sample_task_id)
|
||||
job = in_memory_repository.update_job_status(job.id, ProcessingStatus.PROCESSING)
|
||||
|
||||
# Fail job with error
|
||||
error_msg = "File format not supported"
|
||||
job = await in_memory_repository.update_job_status(job.id, ProcessingStatus.FAILED, error_msg)
|
||||
job = in_memory_repository.update_job_status(job.id, ProcessingStatus.FAILED, error_msg)
|
||||
|
||||
# Assert failure state
|
||||
assert job.status == ProcessingStatus.FAILED
|
||||
@@ -490,28 +464,27 @@ class TestJobRepositoryComplexScenarios:
|
||||
assert job.completed_at is not None
|
||||
assert job.error_message == error_msg
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_handle_multiple_documents_with_different_statuses(self, in_memory_repository):
|
||||
def test_i_can_handle_multiple_documents_with_different_statuses(self, in_memory_repository):
|
||||
"""Test managing multiple jobs for different documents with various statuses."""
|
||||
# Create jobs for different documents
|
||||
doc1 = PyObjectId()
|
||||
doc2 = PyObjectId()
|
||||
doc3 = PyObjectId()
|
||||
|
||||
job1 = await in_memory_repository.create_job(doc1, "task-1")
|
||||
job2 = await in_memory_repository.create_job(doc2, "task-2")
|
||||
job3 = await in_memory_repository.create_job(doc3, "task-3")
|
||||
job1 = in_memory_repository.create_job(doc1, "task-1")
|
||||
job2 = in_memory_repository.create_job(doc2, "task-2")
|
||||
job3 = in_memory_repository.create_job(doc3, "task-3")
|
||||
|
||||
# Update to different statuses
|
||||
await in_memory_repository.update_job_status(job1.id, ProcessingStatus.PROCESSING)
|
||||
await in_memory_repository.update_job_status(job2.id, ProcessingStatus.COMPLETED)
|
||||
await in_memory_repository.update_job_status(job3.id, ProcessingStatus.FAILED, "Error occurred")
|
||||
in_memory_repository.update_job_status(job1.id, ProcessingStatus.PROCESSING)
|
||||
in_memory_repository.update_job_status(job2.id, ProcessingStatus.COMPLETED)
|
||||
in_memory_repository.update_job_status(job3.id, ProcessingStatus.FAILED, "Error occurred")
|
||||
|
||||
# Verify status queries
|
||||
pending_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.PENDING)
|
||||
processing_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.PROCESSING)
|
||||
completed_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.COMPLETED)
|
||||
failed_jobs = await in_memory_repository.get_jobs_by_status(ProcessingStatus.FAILED)
|
||||
pending_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.PENDING)
|
||||
processing_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.PROCESSING)
|
||||
completed_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.COMPLETED)
|
||||
failed_jobs = in_memory_repository.get_jobs_by_status(ProcessingStatus.FAILED)
|
||||
|
||||
assert len(pending_jobs) == 0
|
||||
assert len(processing_jobs) == 1
|
||||
|
||||
@@ -1,29 +1,26 @@
|
||||
"""
|
||||
Test suite for UserRepository with async/await support.
|
||||
Test suite for UserRepository with async/support.
|
||||
|
||||
This module contains comprehensive tests for all UserRepository methods
|
||||
using mongomock-motor for in-memory MongoDB testing.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from datetime import datetime
|
||||
|
||||
import pytest_asyncio
|
||||
from bson import ObjectId
|
||||
from mongomock.mongo_client import MongoClient
|
||||
from pymongo.errors import DuplicateKeyError
|
||||
from mongomock_motor import AsyncMongoMockClient
|
||||
|
||||
from app.database.repositories.user_repository import UserRepository
|
||||
from app.models.user import UserCreate, UserUpdate, UserInDB
|
||||
from app.models.user import UserCreate, UserUpdate
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def in_memory_repository():
|
||||
@pytest.fixture
|
||||
def in_memory_repository():
|
||||
"""Create an in-memory UserRepository for testing."""
|
||||
client = AsyncMongoMockClient()
|
||||
client = MongoClient()
|
||||
db = client.test_database
|
||||
repo = UserRepository(db)
|
||||
await repo.initialize()
|
||||
repo.initialize()
|
||||
return repo
|
||||
|
||||
|
||||
@@ -51,11 +48,10 @@ def sample_user_update():
|
||||
class TestUserRepositoryCreation:
|
||||
"""Tests for user creation functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_create_user(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_create_user(self, in_memory_repository, sample_user_create):
|
||||
"""Test successful user creation."""
|
||||
# Act
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Assert
|
||||
assert created_user is not None
|
||||
@@ -68,15 +64,14 @@ class TestUserRepositoryCreation:
|
||||
assert created_user.updated_at is not None
|
||||
assert created_user.hashed_password != sample_user_create.password # Should be hashed
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_create_user_with_duplicate_username(self, in_memory_repository, sample_user_create):
|
||||
def test_i_cannot_create_user_with_duplicate_username(self, in_memory_repository, sample_user_create):
|
||||
"""Test that creating user with duplicate username raises DuplicateKeyError."""
|
||||
# Arrange
|
||||
await in_memory_repository.create_user(sample_user_create)
|
||||
in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act & Assert
|
||||
with pytest.raises(DuplicateKeyError) as exc_info:
|
||||
await in_memory_repository.create_user(sample_user_create)
|
||||
in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
assert "already exists" in str(exc_info.value)
|
||||
|
||||
@@ -84,14 +79,13 @@ class TestUserRepositoryCreation:
|
||||
class TestUserRepositoryFinding:
|
||||
"""Tests for user finding functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_user_by_id(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_find_user_by_id(self, in_memory_repository, sample_user_create):
|
||||
"""Test finding user by valid ID."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_id(str(created_user.id))
|
||||
found_user = in_memory_repository.find_user_by_id(str(created_user.id))
|
||||
|
||||
# Assert
|
||||
assert found_user is not None
|
||||
@@ -99,69 +93,63 @@ class TestUserRepositoryFinding:
|
||||
assert found_user.username == created_user.username
|
||||
assert found_user.email == created_user.email
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_user_by_invalid_id(self, in_memory_repository):
|
||||
def test_i_cannot_find_user_by_invalid_id(self, in_memory_repository):
|
||||
"""Test that invalid ObjectId returns None."""
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_id("invalid_id")
|
||||
found_user = in_memory_repository.find_user_by_id("invalid_id")
|
||||
|
||||
# Assert
|
||||
assert found_user is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_user_by_nonexistent_id(self, in_memory_repository):
|
||||
def test_i_cannot_find_user_by_nonexistent_id(self, in_memory_repository):
|
||||
"""Test that nonexistent but valid ObjectId returns None."""
|
||||
# Arrange
|
||||
nonexistent_id = str(ObjectId())
|
||||
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_id(nonexistent_id)
|
||||
found_user = in_memory_repository.find_user_by_id(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert found_user is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_user_by_username(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_find_user_by_username(self, in_memory_repository, sample_user_create):
|
||||
"""Test finding user by username."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_username(sample_user_create.username)
|
||||
found_user = in_memory_repository.find_user_by_username(sample_user_create.username)
|
||||
|
||||
# Assert
|
||||
assert found_user is not None
|
||||
assert found_user.username == created_user.username
|
||||
assert found_user.id == created_user.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_user_by_nonexistent_username(self, in_memory_repository):
|
||||
def test_i_cannot_find_user_by_nonexistent_username(self, in_memory_repository):
|
||||
"""Test that nonexistent username returns None."""
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_username("nonexistent")
|
||||
found_user = in_memory_repository.find_user_by_username("nonexistent")
|
||||
|
||||
# Assert
|
||||
assert found_user is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_find_user_by_email(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_find_user_by_email(self, in_memory_repository, sample_user_create):
|
||||
"""Test finding user by email."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_email(str(sample_user_create.email))
|
||||
found_user = in_memory_repository.find_user_by_email(str(sample_user_create.email))
|
||||
|
||||
# Assert
|
||||
assert found_user is not None
|
||||
assert found_user.email == created_user.email
|
||||
assert found_user.id == created_user.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_find_user_by_nonexistent_email(self, in_memory_repository):
|
||||
def test_i_cannot_find_user_by_nonexistent_email(self, in_memory_repository):
|
||||
"""Test that nonexistent email returns None."""
|
||||
# Act
|
||||
found_user = await in_memory_repository.find_user_by_email("nonexistent@example.com")
|
||||
found_user = in_memory_repository.find_user_by_email("nonexistent@example.com")
|
||||
|
||||
# Assert
|
||||
assert found_user is None
|
||||
@@ -170,15 +158,14 @@ class TestUserRepositoryFinding:
|
||||
class TestUserRepositoryUpdate:
|
||||
"""Tests for user update functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_user(self, in_memory_repository, sample_user_create, sample_user_update):
|
||||
def test_i_can_update_user(self, in_memory_repository, sample_user_create, sample_user_update):
|
||||
"""Test successful user update."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
original_updated_at = created_user.updated_at
|
||||
|
||||
# Act
|
||||
updated_user = await in_memory_repository.update_user(str(created_user.id), sample_user_update)
|
||||
updated_user = in_memory_repository.update_user(str(created_user.id), sample_user_update)
|
||||
|
||||
# Assert
|
||||
assert updated_user is not None
|
||||
@@ -187,24 +174,22 @@ class TestUserRepositoryUpdate:
|
||||
assert updated_user.role == sample_user_update.role
|
||||
assert updated_user.id == created_user.id
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_update_user_with_invalid_id(self, in_memory_repository, sample_user_update):
|
||||
def test_i_cannot_update_user_with_invalid_id(self, in_memory_repository, sample_user_update):
|
||||
"""Test that updating with invalid ID returns None."""
|
||||
# Act
|
||||
result = await in_memory_repository.update_user("invalid_id", sample_user_update)
|
||||
result = in_memory_repository.update_user("invalid_id", sample_user_update)
|
||||
|
||||
# Assert
|
||||
assert result is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_user_with_partial_data(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_update_user_with_partial_data(self, in_memory_repository, sample_user_create):
|
||||
"""Test updating user with partial data."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
partial_update = UserUpdate(username="newusername")
|
||||
|
||||
# Act
|
||||
updated_user = await in_memory_repository.update_user(str(created_user.id), partial_update)
|
||||
updated_user = in_memory_repository.update_user(str(created_user.id), partial_update)
|
||||
|
||||
# Assert
|
||||
assert updated_user is not None
|
||||
@@ -212,15 +197,14 @@ class TestUserRepositoryUpdate:
|
||||
assert updated_user.email == created_user.email # Should remain unchanged
|
||||
assert updated_user.role == created_user.role # Should remain unchanged
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_update_user_with_empty_data(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_update_user_with_empty_data(self, in_memory_repository, sample_user_create):
|
||||
"""Test updating user with empty data returns current user."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
empty_update = UserUpdate()
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.update_user(str(created_user.id), empty_update)
|
||||
result = in_memory_repository.update_user(str(created_user.id), empty_update)
|
||||
|
||||
# Assert
|
||||
assert result is not None
|
||||
@@ -231,39 +215,36 @@ class TestUserRepositoryUpdate:
|
||||
class TestUserRepositoryDeletion:
|
||||
"""Tests for user deletion functionality."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_delete_user(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_delete_user(self, in_memory_repository, sample_user_create):
|
||||
"""Test successful user deletion."""
|
||||
# Arrange
|
||||
created_user = await in_memory_repository.create_user(sample_user_create)
|
||||
created_user = in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
deletion_result = await in_memory_repository.delete_user(str(created_user.id))
|
||||
deletion_result = in_memory_repository.delete_user(str(created_user.id))
|
||||
|
||||
# Assert
|
||||
assert deletion_result is True
|
||||
|
||||
# Verify user is actually deleted
|
||||
found_user = await in_memory_repository.find_user_by_id(str(created_user.id))
|
||||
found_user = in_memory_repository.find_user_by_id(str(created_user.id))
|
||||
assert found_user is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_user_with_invalid_id(self, in_memory_repository):
|
||||
def test_i_cannot_delete_user_with_invalid_id(self, in_memory_repository):
|
||||
"""Test that deleting with invalid ID returns False."""
|
||||
# Act
|
||||
result = await in_memory_repository.delete_user("invalid_id")
|
||||
result = in_memory_repository.delete_user("invalid_id")
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_cannot_delete_nonexistent_user(self, in_memory_repository):
|
||||
def test_i_cannot_delete_nonexistent_user(self, in_memory_repository):
|
||||
"""Test that deleting nonexistent user returns False."""
|
||||
# Arrange
|
||||
nonexistent_id = str(ObjectId())
|
||||
|
||||
# Act
|
||||
result = await in_memory_repository.delete_user(nonexistent_id)
|
||||
result = in_memory_repository.delete_user(nonexistent_id)
|
||||
|
||||
# Assert
|
||||
assert result is False
|
||||
@@ -272,30 +253,27 @@ class TestUserRepositoryDeletion:
|
||||
class TestUserRepositoryUtilities:
|
||||
"""Tests for utility methods."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_count_users(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_count_users(self, in_memory_repository, sample_user_create):
|
||||
"""Test counting users."""
|
||||
# Arrange
|
||||
initial_count = await in_memory_repository.count_users()
|
||||
await in_memory_repository.create_user(sample_user_create)
|
||||
initial_count = in_memory_repository.count_users()
|
||||
in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
final_count = await in_memory_repository.count_users()
|
||||
final_count = in_memory_repository.count_users()
|
||||
|
||||
# Assert
|
||||
assert final_count == initial_count + 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_i_can_check_user_exists(self, in_memory_repository, sample_user_create):
|
||||
def test_i_can_check_user_exists(self, in_memory_repository, sample_user_create):
|
||||
"""Test checking if user exists."""
|
||||
# Arrange
|
||||
await in_memory_repository.create_user(sample_user_create)
|
||||
in_memory_repository.create_user(sample_user_create)
|
||||
|
||||
# Act
|
||||
exists = await in_memory_repository.user_exists(sample_user_create.username)
|
||||
not_exists = await in_memory_repository.user_exists("nonexistent")
|
||||
exists = in_memory_repository.user_exists(sample_user_create.username)
|
||||
not_exists = in_memory_repository.user_exists("nonexistent")
|
||||
|
||||
# Assert
|
||||
assert exists is True
|
||||
assert not_exists is False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user