""" Token Repository Integration Tests Tests TokenRepository with real database operations. """ from datetime import datetime, timezone, timedelta import pytest from backend.data.repositories.token_repository import TokenRepository class TestTokenCreate: """Tests for token creation.""" def test_create_new_token(self, patched_session): """Test creating a new admin token.""" repo = TokenRepository() repo.create( token="new-test-token-abc123", name="New Test Admin", ) token = repo.get("new-test-token-abc123") assert token is not None assert token.token == "new-test-token-abc123" assert token.name == "New Test Admin" assert token.is_active is True assert token.expires_at is None def test_create_token_with_expiration(self, patched_session): """Test creating token with expiration date.""" repo = TokenRepository() expiry = datetime.now(timezone.utc) + timedelta(days=30) repo.create( token="expiring-token-xyz789", name="Expiring Token", expires_at=expiry, ) token = repo.get("expiring-token-xyz789") assert token is not None assert token.expires_at is not None def test_create_updates_existing_token(self, patched_session, admin_token): """Test creating with existing token updates it.""" repo = TokenRepository() new_expiry = datetime.now(timezone.utc) + timedelta(days=60) repo.create( token=admin_token.token, name="Updated Admin Name", expires_at=new_expiry, ) token = repo.get(admin_token.token) assert token is not None assert token.name == "Updated Admin Name" assert token.is_active is True class TestTokenValidation: """Tests for token validation.""" def test_is_valid_active_token(self, patched_session, admin_token): """Test that active token is valid.""" repo = TokenRepository() result = repo.is_valid(admin_token.token) assert result is True def test_is_valid_nonexistent_token(self, patched_session): """Test that nonexistent token is invalid.""" repo = TokenRepository() result = repo.is_valid("nonexistent-token-12345") assert result is False def test_is_valid_deactivated_token(self, patched_session, admin_token): """Test that deactivated token is invalid.""" repo = TokenRepository() repo.deactivate(admin_token.token) result = repo.is_valid(admin_token.token) assert result is False def test_is_valid_expired_token(self, patched_session): """Test that expired token is invalid.""" repo = TokenRepository() past_expiry = datetime.now(timezone.utc) - timedelta(days=1) repo.create( token="expired-token-test", name="Expired Token", expires_at=past_expiry, ) result = repo.is_valid("expired-token-test") assert result is False def test_is_valid_not_yet_expired_token(self, patched_session): """Test that not-yet-expired token is valid.""" repo = TokenRepository() future_expiry = datetime.now(timezone.utc) + timedelta(days=7) repo.create( token="valid-expiring-token", name="Valid Expiring Token", expires_at=future_expiry, ) result = repo.is_valid("valid-expiring-token") assert result is True class TestTokenGet: """Tests for token retrieval.""" def test_get_existing_token(self, patched_session, admin_token): """Test getting an existing token.""" repo = TokenRepository() token = repo.get(admin_token.token) assert token is not None assert token.token == admin_token.token assert token.name == admin_token.name def test_get_nonexistent_token(self, patched_session): """Test getting a token that doesn't exist.""" repo = TokenRepository() token = repo.get("nonexistent-token-xyz") assert token is None class TestTokenDeactivate: """Tests for token deactivation.""" def test_deactivate_existing_token(self, patched_session, admin_token): """Test deactivating an existing token.""" repo = TokenRepository() result = repo.deactivate(admin_token.token) assert result is True token = repo.get(admin_token.token) assert token is not None assert token.is_active is False def test_deactivate_nonexistent_token(self, patched_session): """Test deactivating a token that doesn't exist.""" repo = TokenRepository() result = repo.deactivate("nonexistent-token-abc") assert result is False def test_reactivate_deactivated_token(self, patched_session, admin_token): """Test reactivating a deactivated token via create.""" repo = TokenRepository() # Deactivate first repo.deactivate(admin_token.token) assert repo.is_valid(admin_token.token) is False # Reactivate via create repo.create( token=admin_token.token, name="Reactivated Admin", ) assert repo.is_valid(admin_token.token) is True class TestTokenUsageTracking: """Tests for token usage tracking.""" def test_update_usage(self, patched_session, admin_token): """Test updating token last used timestamp.""" repo = TokenRepository() # Initially last_used_at might be None initial_token = repo.get(admin_token.token) initial_last_used = initial_token.last_used_at repo.update_usage(admin_token.token) updated_token = repo.get(admin_token.token) assert updated_token.last_used_at is not None if initial_last_used: assert updated_token.last_used_at >= initial_last_used def test_update_usage_nonexistent_token(self, patched_session): """Test updating usage for nonexistent token does nothing.""" repo = TokenRepository() # Should not raise, just does nothing repo.update_usage("nonexistent-token-usage") token = repo.get("nonexistent-token-usage") assert token is None class TestTokenWorkflow: """Tests for complete token workflows.""" def test_full_token_lifecycle(self, patched_session): """Test complete token lifecycle: create, validate, use, deactivate.""" repo = TokenRepository() token_str = "lifecycle-test-token" # 1. Create token repo.create(token=token_str, name="Lifecycle Token") assert repo.is_valid(token_str) is True # 2. Use token repo.update_usage(token_str) token = repo.get(token_str) assert token.last_used_at is not None # 3. Update token info new_expiry = datetime.now(timezone.utc) + timedelta(days=90) repo.create( token=token_str, name="Updated Lifecycle Token", expires_at=new_expiry, ) token = repo.get(token_str) assert token.name == "Updated Lifecycle Token" # 4. Deactivate token result = repo.deactivate(token_str) assert result is True assert repo.is_valid(token_str) is False # 5. Reactivate token repo.create(token=token_str, name="Reactivated Token") assert repo.is_valid(token_str) is True def test_multiple_tokens(self, patched_session): """Test managing multiple tokens.""" repo = TokenRepository() # Create multiple tokens tokens = [ ("token-a", "Admin A"), ("token-b", "Admin B"), ("token-c", "Admin C"), ] for token_str, name in tokens: repo.create(token=token_str, name=name) # Verify all are valid for token_str, _ in tokens: assert repo.is_valid(token_str) is True # Deactivate one repo.deactivate("token-b") # Verify states assert repo.is_valid("token-a") is True assert repo.is_valid("token-b") is False assert repo.is_valid("token-c") is True