""" Demonstration of data isolation in tests. This shows how our test infrastructure prevents data interference between tests. """ import pytest from sqlmodel import select from app.models.player import Player from tests.factories.player_factory import PlayerFactory class TestDataIsolationDemo: """Demonstrate how data isolation works between tests.""" def test_first_creates_player(self, db_session): """First test creates a player - this data should not affect other tests.""" # Create player with specific name player = PlayerFactory.create(db_session, name="Test Player Alpha", cost=100) # Verify it exists in this test's transaction result = db_session.exec(select(Player).where(Player.name == "Test Player Alpha")).first() assert result is not None assert result.cost == 100 print(f"Created player with ID: {player.id} in first test") def test_second_cannot_see_first_player(self, db_session): """Second test runs in separate transaction - cannot see first test's data.""" # Try to find the player from the first test result = db_session.exec(select(Player).where(Player.name == "Test Player Alpha")).first() # Should be None because first test's transaction was rolled back assert result is None # Create our own player with same name but different cost player = PlayerFactory.create(db_session, name="Test Player Alpha", cost=200) assert player.cost == 200 print(f"Cannot see first test's player - created new one with ID: {player.id}") def test_third_also_isolated(self, db_session): """Third test is also completely isolated from previous tests.""" # Should not see players from either previous test results = db_session.exec(select(Player).where(Player.name == "Test Player Alpha")).all() assert len(results) == 0 # Can create multiple players without conflict player1 = PlayerFactory.create(db_session, name="Test Player Alpha", cost=300) player2 = PlayerFactory.create(db_session, name="Test Player Beta", cost=400) # Both exist in this test's transaction all_results = db_session.exec(select(Player)).all() assert len(all_results) == 2 print(f"Third test: created players with IDs {player1.id} and {player2.id}") class TestDataIsolationWithFreshSession: """Demonstrate fresh_db_session behavior (real commits).""" def test_with_fresh_session_persists_data(self, fresh_db_session): """Test using fresh_db_session - data actually commits to test database.""" # Create player with real commit player = PlayerFactory.create(fresh_db_session, name="Persistent Player", cost=500) fresh_db_session.commit() # Real commit to test database # Verify it's committed fresh_db_session.refresh(player) assert player.id is not None print(f"Committed player with ID: {player.id} to test database") # Manual cleanup for this demonstration fresh_db_session.delete(player) fresh_db_session.commit() print("Manually cleaned up persistent player") def test_after_fresh_session_cleanup(self, db_session): """This test should not see the fresh session data (it was cleaned up).""" result = db_session.exec(select(Player).where(Player.name == "Persistent Player")).first() assert result is None print("Confirmed: Fresh session data was properly cleaned up") class TestDataIsolationFactories: """Demonstrate how factories prevent ID conflicts.""" def test_factory_generates_unique_ids(self, db_session): """Factories generate unique IDs to prevent conflicts.""" # Create multiple players - factories ensure unique IDs players = [ PlayerFactory.create(db_session, name=f"Player {i}") for i in range(5) ] # All should have different IDs player_ids = [p.id for p in players] assert len(set(player_ids)) == 5 # All unique print(f"Generated unique IDs: {player_ids}") def test_can_create_same_names_different_ids(self, db_session): """Different tests can create objects with same names but different IDs.""" # This won't conflict with previous test because transaction is isolated players = [ PlayerFactory.create(db_session, name="Player 1"), PlayerFactory.create(db_session, name="Player 2"), ] # IDs will be different from previous test print(f"Same names, different IDs: {[p.id for p in players]}") # Names can be the same across tests, IDs will always be unique assert players[0].name == "Player 1" assert players[1].name == "Player 2"