""" Integration tests for Firestore database operations. These tests require: 1. Real Firestore credentials 2. A test Firestore database 3. Network connectivity to Google Cloud Run with: pytest tests/integration/ -v --integration """ import pytest import asyncio import os from src.db.providers.firestore_provider import FirestoreProvider from src.db.repositories.firestore_team_repository import FirestoreTeamRepository from src.models.team import TeamModel from src.config.config import settings @pytest.mark.integration class TestFirestoreIntegration: """Integration tests for real Firestore operations""" @pytest.fixture(scope="class") def provider(self): """Create a real FirestoreProvider for integration testing""" if not os.getenv("FIRESTORE_INTEGRATION_TEST"): pytest.skip("Integration tests disabled. Set FIRESTORE_INTEGRATION_TEST=1 to enable") provider = FirestoreProvider() provider.connect() yield provider provider.disconnect() @pytest.fixture(scope="class") def team_repository(self, provider): """Create a real team repository for testing""" return FirestoreTeamRepository() @pytest.mark.asyncio async def test_real_firestore_connection(self, provider): """Test actual connection to Firestore""" assert provider.client is not None # Test getting a collection reference collection = provider.get_collection("test_teams") assert collection is not None @pytest.mark.asyncio async def test_real_document_crud(self, provider): """Test real CRUD operations on Firestore""" collection_name = "integration_test_teams" # Create test data test_data = { "name": "Integration Test Team", "description": "Created by integration test", "created_at": "2024-01-01T00:00:00Z" } try: # CREATE doc_id = await provider.add_document(collection_name, test_data) assert doc_id is not None # READ retrieved_doc = await provider.get_document(collection_name, doc_id) assert retrieved_doc is not None assert retrieved_doc["name"] == "Integration Test Team" assert retrieved_doc["_id"] == doc_id # UPDATE update_data = {"name": "Updated Integration Test Team"} success = await provider.update_document(collection_name, doc_id, update_data) assert success is True # Verify update updated_doc = await provider.get_document(collection_name, doc_id) assert updated_doc["name"] == "Updated Integration Test Team" # LIST all_docs = await provider.list_documents(collection_name) assert len(all_docs) >= 1 assert any(doc["_id"] == doc_id for doc in all_docs) finally: # CLEANUP - Delete test document await provider.delete_document(collection_name, doc_id) # Verify deletion deleted_doc = await provider.get_document(collection_name, doc_id) assert deleted_doc is None @pytest.mark.asyncio async def test_real_team_repository_operations(self, team_repository): """Test real team repository operations""" # Create test team test_team = TeamModel( name="Integration Test Team Repository", description="Created by repository integration test" ) try: # CREATE created_team = await team_repository.create(test_team) assert created_team.name == test_team.name assert hasattr(created_team, 'id') team_id = str(created_team.id) # READ retrieved_team = await team_repository.get_by_id(team_id) assert retrieved_team is not None assert retrieved_team.name == test_team.name # UPDATE update_data = {"description": "Updated by integration test"} updated_team = await team_repository.update(team_id, update_data) assert updated_team.description == "Updated by integration test" # LIST all_teams = await team_repository.get_all() assert len(all_teams) >= 1 assert any(team.name == "Integration Test Team Repository" for team in all_teams) finally: # CLEANUP if 'team_id' in locals(): await team_repository.delete(team_id) @pytest.mark.asyncio async def test_real_error_handling(self, provider): """Test error handling with real Firestore""" # Test getting non-existent document result = await provider.get_document("test_collection", "non_existent_id") assert result is None # Test updating non-existent document success = await provider.update_document("test_collection", "non_existent_id", {"test": "data"}) assert success is True # Firestore creates the document if it doesn't exist # Cleanup await provider.delete_document("test_collection", "non_existent_id") # Configuration for integration tests @pytest.fixture(scope="session", autouse=True) def setup_integration_test_environment(): """Setup environment for integration tests""" if os.getenv("FIRESTORE_INTEGRATION_TEST"): # Ensure we're using a test database if not settings.FIRESTORE_DATABASE_NAME.endswith("-test"): pytest.fail("Integration tests must use a test database (name should end with '-test')") # Ensure credentials are available if not settings.FIRESTORE_CREDENTIALS_FILE or not os.path.exists(settings.FIRESTORE_CREDENTIALS_FILE): pytest.fail("Integration tests require valid Firestore credentials") # Pytest configuration for integration tests def pytest_configure(config): """Configure pytest for integration tests""" config.addinivalue_line( "markers", "integration: mark test as integration test (requires real database)" )