""" Unit tests for Phase 1 Daily Helper database models """ import pytest from datetime import datetime, date from app.models.models import ( UserProfile, DailyRoutine, RoutineExecution, Notification, DailyChecklist, HabitTracker ) class TestUserProfile: """Tests for UserProfile model""" def test_user_profile_creation(self): """Test creating a user profile""" profile = UserProfile( email="test@example.com", username="testuser", timezone="EST", preferred_trading_start="09:00", preferred_trading_end="17:00", risk_tolerance="moderate", trading_style="day_trader", daily_target=1000.0, max_loss=500.0, ) assert profile.email == "test@example.com" assert profile.username == "testuser" assert profile.timezone == "EST" assert profile.risk_tolerance == "moderate" assert profile.trading_style == "day_trader" assert profile.notifications_enabled == True assert profile.email_reports == True assert profile.sms_enabled == False def test_user_profile_defaults(self): """Test UserProfile default values""" profile = UserProfile() assert profile.timezone == "UTC" assert profile.preferred_trading_start == "09:00" assert profile.preferred_trading_end == "17:00" assert profile.risk_tolerance == "moderate" assert profile.trading_style == "day_trader" assert profile.notifications_enabled == True assert profile.push_notifications == True class TestDailyRoutine: """Tests for DailyRoutine model""" def test_daily_routine_creation(self): """Test creating a daily routine""" routine = DailyRoutine( user_id="user123", routine_type="morning", scheduled_time="08:30", tasks=["market_brief", "checklist", "review_plan"], enabled=True, ) assert routine.routine_type == "morning" assert routine.scheduled_time == "08:30" assert len(routine.tasks) == 3 assert "market_brief" in routine.tasks assert routine.enabled == True def test_daily_routine_empty_tasks(self): """Test routine with empty tasks list""" routine = DailyRoutine( routine_type="evening", scheduled_time="17:00", enabled=True, ) assert routine.tasks == [] def test_daily_routine_types(self): """Test different routine types""" types = ["morning", "active_trading", "evening"] for routine_type in types: routine = DailyRoutine(routine_type=routine_type) assert routine.routine_type == routine_type class TestRoutineExecution: """Tests for RoutineExecution model""" def test_routine_execution_creation(self): """Test creating a routine execution record""" execution = RoutineExecution( routine_id=1, completion_status="completed", tasks_completed=["market_brief", "checklist"], execution_notes="All tasks completed successfully", ) assert execution.routine_id == 1 assert execution.completion_status == "completed" assert len(execution.tasks_completed) == 2 assert execution.execution_notes is not None def test_execution_status_values(self): """Test different execution status values""" statuses = ["completed", "failed", "partial"] for status in statuses: execution = RoutineExecution(routine_id=1, completion_status=status) assert execution.completion_status == status class TestNotification: """Tests for Notification model""" def test_notification_creation(self): """Test creating a notification""" notification = Notification( notification_type="price_alert", title="Price Alert", message="Gold price exceeded $2000", priority="high", delivery_method="push", read=False, ) assert notification.notification_type == "price_alert" assert notification.title == "Price Alert" assert notification.priority == "high" assert notification.delivery_method == "push" assert notification.read == False def test_notification_read_status(self): """Test notification read/unread status""" notification = Notification( notification_type="news", title="Breaking News", message="Fed announces rate decision", read=False, ) assert notification.read == False # Simulate marking as read notification.read = True notification.read_at = datetime.utcnow() assert notification.read == True assert notification.read_at is not None def test_notification_with_data(self): """Test notification with additional data""" data = { "price": 2010.50, "threshold": 2000.00, "direction": "above" } notification = Notification( notification_type="price_alert", title="Price Alert", message="Gold moved above threshold", data=data, ) assert notification.data == data class TestDailyChecklist: """Tests for DailyChecklist model""" def test_daily_checklist_creation(self): """Test creating a daily checklist""" items = [ {"id": "1", "title": "Check Economic Calendar", "completed": False}, {"id": "2", "title": "Create Trading Plan", "completed": False}, ] checklist = DailyChecklist( checklist_date=date.today(), checklist_type="morning", items=items, completion_percentage=0.0, ) assert checklist.checklist_date == date.today() assert checklist.checklist_type == "morning" assert len(checklist.items) == 2 assert checklist.completion_percentage == 0.0 def test_checklist_completion_percentage(self): """Test checklist completion percentage calculation""" items = [ {"id": "1", "title": "Item 1", "completed": True}, {"id": "2", "title": "Item 2", "completed": True}, {"id": "3", "title": "Item 3", "completed": False}, ] completion = sum(1 for item in items if item["completed"]) / len(items) * 100 checklist = DailyChecklist( checklist_type="morning", items=items, completion_percentage=completion, ) assert checklist.completion_percentage == pytest.approx(66.67, rel=0.1) def test_checklist_types(self): """Test different checklist types""" types = ["morning", "active_trading", "evening", "all"] for checklist_type in types: checklist = DailyChecklist(checklist_type=checklist_type) assert checklist.checklist_type == checklist_type class TestHabitTracker: """Tests for HabitTracker model""" def test_habit_tracker_creation(self): """Test creating a habit tracker""" habit = HabitTracker( habit_name="Daily Planning", frequency="daily", current_streak=5, longest_streak=10, total_completions=25, ) assert habit.habit_name == "Daily Planning" assert habit.frequency == "daily" assert habit.current_streak == 5 assert habit.longest_streak == 10 assert habit.total_completions == 25 def test_habit_defaults(self): """Test habit tracker default values""" habit = HabitTracker(habit_name="Test Habit") assert habit.frequency == "daily" assert habit.current_streak == 0 assert habit.longest_streak == 0 assert habit.total_completions == 0 assert habit.completion_dates == [] def test_habit_completion_dates(self): """Test habit completion dates tracking""" dates = ["2024-11-10", "2024-11-11", "2024-11-12"] habit = HabitTracker( habit_name="Trading Journal", frequency="daily", completion_dates=dates, total_completions=len(dates), ) assert len(habit.completion_dates) == 3 assert habit.total_completions == 3 def test_habit_frequencies(self): """Test different habit frequencies""" frequencies = ["daily", "weekly"] for frequency in frequencies: habit = HabitTracker( habit_name="Test", frequency=frequency ) assert habit.frequency == frequency def test_habit_streak_calculation(self): """Test streak calculation logic""" # Simulate consecutive completions completion_dates = [ "2024-11-10", "2024-11-11", "2024-11-12", "2024-11-13", "2024-11-14", ] habit = HabitTracker( habit_name="Test", completion_dates=completion_dates, current_streak=5, ) assert habit.current_streak == 5 class TestModelRelationships: """Tests for model relationships""" def test_routine_has_executions(self): """Test that routine has executions""" routine = DailyRoutine( routine_type="morning", scheduled_time="08:30", ) execution1 = RoutineExecution(routine_id=1) execution2 = RoutineExecution(routine_id=1) assert execution1.routine_id == execution2.routine_id == 1 def test_notification_structure(self): """Test notification structure""" types = ["price_alert", "routine", "report", "news", "reminder"] for notif_type in types: notification = Notification( notification_type=notif_type, title="Test", message="Test message", ) assert notification.notification_type == notif_type if __name__ == "__main__": pytest.main([__file__, "-v"])