162 lines
5.1 KiB
Python
162 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Unit tests for Habit Bot
|
|
Tests: habit tracking, food logging, data persistence
|
|
"""
|
|
|
|
import pytest
|
|
import sys
|
|
import os
|
|
import json
|
|
from datetime import datetime, timedelta
|
|
from unittest.mock import Mock, patch, MagicMock
|
|
from io import StringIO
|
|
|
|
# Add parent directory to path
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
# Test data directory
|
|
TEST_DATA_DIR = '/tmp/test_habit_bot'
|
|
os.makedirs(TEST_DATA_DIR, exist_ok=True)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_data():
|
|
"""Create mock data for testing"""
|
|
return {
|
|
'users': {},
|
|
'habits': {},
|
|
'habit_logs': {},
|
|
'food_logs': {},
|
|
'sessions': {}
|
|
}
|
|
|
|
|
|
class TestHabitBot:
|
|
"""Test habit tracking functionality"""
|
|
|
|
def test_add_habit(self, mock_data):
|
|
"""Test adding a new habit"""
|
|
habit_name = "morning workout"
|
|
|
|
# Simulate adding habit
|
|
user_id = "12345"
|
|
if user_id not in mock_data['habits']:
|
|
mock_data['habits'][user_id] = {}
|
|
|
|
mock_data['habits'][user_id][habit_name] = {
|
|
'name': habit_name,
|
|
'streak': 0,
|
|
'created_at': datetime.now().isoformat(),
|
|
'is_active': True
|
|
}
|
|
|
|
assert user_id in mock_data['habits']
|
|
assert habit_name in mock_data['habits'][user_id]
|
|
|
|
def test_habit_streak_increment(self, mock_data):
|
|
"""Test habit streak increment"""
|
|
user_id = "12345"
|
|
habit_name = "morning workout"
|
|
|
|
# Initial streak
|
|
mock_data['habits'][user_id] = {
|
|
habit_name: {
|
|
'name': habit_name,
|
|
'streak': 0,
|
|
'last_completed': None
|
|
}
|
|
}
|
|
|
|
# Increment streak
|
|
mock_data['habits'][user_id][habit_name]['streak'] += 1
|
|
mock_data['habits'][user_id][habit_name]['last_completed'] = datetime.now().isoformat()
|
|
|
|
assert mock_data['habits'][user_id][habit_name]['streak'] == 1
|
|
|
|
def test_habit_completion_reset(self, mock_data):
|
|
"""Test resetting habit streak when day changes"""
|
|
user_id = "12345"
|
|
habit_name = "morning workout"
|
|
|
|
# Set streak
|
|
mock_data['habits'][user_id] = {
|
|
habit_name: {
|
|
'name': habit_name,
|
|
'streak': 5,
|
|
'last_completed': (datetime.now() - timedelta(days=2)).isoformat()
|
|
}
|
|
}
|
|
|
|
# Check if streak should reset (more than 1 day since last completion)
|
|
last_completed = datetime.fromisoformat(mock_data['habits'][user_id][habit_name]['last_completed'])
|
|
days_since = (datetime.now() - last_completed).days
|
|
|
|
if days_since > 1:
|
|
mock_data['habits'][user_id][habit_name]['streak'] = 0
|
|
|
|
assert mock_data['habits'][user_id][habit_name]['streak'] == 0
|
|
|
|
def test_food_logging(self, mock_data):
|
|
"""Test food logging functionality"""
|
|
user_id = "12345"
|
|
food_entry = {
|
|
'food': "grilled chicken",
|
|
'calories': 300,
|
|
'protein': 50,
|
|
'carbs': 0,
|
|
'fat': 10,
|
|
'logged_at': datetime.now().isoformat()
|
|
}
|
|
|
|
if user_id not in mock_data['food_logs']:
|
|
mock_data['food_logs'][user_id] = []
|
|
|
|
mock_data['food_logs'][user_id].append(food_entry)
|
|
|
|
assert len(mock_data['food_logs'][user_id]) == 1
|
|
assert mock_data['food_logs'][user_id][0]['food'] == "grilled chicken"
|
|
assert mock_data['food_logs'][user_id][0]['calories'] == 300
|
|
|
|
def test_daily_calorie_calculation(self, mock_data):
|
|
"""Test daily calorie calculation"""
|
|
user_id = "12345"
|
|
|
|
mock_data['food_logs'][user_id] = [
|
|
{'calories': 500, 'protein': 50, 'carbs': 20, 'fat': 15},
|
|
{'calories': 700, 'protein': 70, 'carbs': 30, 'fat': 20},
|
|
{'calories': 400, 'protein': 40, 'carbs': 10, 'fat': 12}
|
|
]
|
|
|
|
total_calories = sum(entry['calories'] for entry in mock_data['food_logs'][user_id])
|
|
|
|
assert total_calories == 1600
|
|
|
|
def test_user_session_tracking(self, mock_data):
|
|
"""Test user session tracking"""
|
|
user_id = "12345"
|
|
session = {
|
|
'start_time': datetime.now().isoformat(),
|
|
'end_time': None,
|
|
'commands_executed': 0
|
|
}
|
|
|
|
mock_data['sessions'][user_id] = session
|
|
mock_data['sessions'][user_id]['commands_executed'] += 1
|
|
|
|
assert 'start_time' in mock_data['sessions'][user_id]
|
|
assert mock_data['sessions'][user_id]['commands_executed'] == 1
|
|
|
|
def test_data_persistence(self, mock_data):
|
|
"""Test mock data persistence in fixture"""
|
|
# Add multiple entries
|
|
for i in range(5):
|
|
habit_name = f"habit_{i}"
|
|
mock_data['habits']['user1'][habit_name] = {
|
|
'name': habit_name,
|
|
'streak': i,
|
|
'created_at': datetime.now().isoformat()
|
|
}
|
|
|
|
assert len(mock_data['habits']['user1']) == 5
|