"""Unit tests for User model properties. Tests the computed properties on the User model that don't require database access. """ from datetime import UTC, datetime from unittest.mock import MagicMock from uuid import uuid4 import pytest from app.db.models.user import User @pytest.fixture def user(): """Create a test user with minimal attributes. Returns a User model instance without database persistence. """ user = User( email="test@example.com", display_name="Test User", avatar_url=None, oauth_provider="google", oauth_id="google-123", is_premium=False, premium_until=None, ) user.id = uuid4() user.created_at = datetime.now(UTC) user.updated_at = datetime.now(UTC) user.decks = [] user.linked_accounts = [] return user class TestHasStarterDeck: """Tests for the has_starter_deck computed property.""" def test_returns_false_when_no_decks(self, user): """Test has_starter_deck is False when user has no decks. New users start with no decks, so has_starter_deck should be False. This is used by the frontend to redirect to starter selection. """ user.decks = [] assert user.has_starter_deck is False def test_returns_false_when_only_regular_decks(self, user): """Test has_starter_deck is False when user only has regular decks. Users can create custom decks without selecting a starter. has_starter_deck should only be True for actual starter decks. """ regular_deck = MagicMock() regular_deck.is_starter = False user.decks = [regular_deck] assert user.has_starter_deck is False def test_returns_true_when_has_starter_deck(self, user): """Test has_starter_deck is True when user has selected a starter. After selecting a starter deck, the property should return True. This allows the frontend to skip the starter selection page. """ starter_deck = MagicMock() starter_deck.is_starter = True user.decks = [starter_deck] assert user.has_starter_deck is True def test_returns_true_when_starter_among_multiple_decks(self, user): """Test has_starter_deck is True even with mixed deck types. Users can have both starter and custom decks. As long as one starter deck exists, the property should return True. """ regular_deck = MagicMock() regular_deck.is_starter = False starter_deck = MagicMock() starter_deck.is_starter = True user.decks = [regular_deck, starter_deck] assert user.has_starter_deck is True class TestMaxDecks: """Tests for the max_decks computed property.""" def test_returns_5_for_free_users(self, user): """Test free users have 5 deck slots. Free users should be limited to 5 decks to encourage premium upgrades. """ user.is_premium = False assert user.max_decks == 5 def test_returns_999_for_premium_users(self, user): """Test premium users have unlimited deck slots. Premium users get 999 slots (effectively unlimited) as a benefit. """ from datetime import timedelta user.is_premium = True user.premium_until = datetime.now(UTC) + timedelta(days=30) assert user.max_decks == 999 def test_returns_5_for_expired_premium(self, user): """Test expired premium users revert to free limits. When premium expires, users should be treated as free users. """ from datetime import timedelta user.is_premium = True user.premium_until = datetime.now(UTC) - timedelta(days=1) # Expired assert user.max_decks == 5