from datetime import timedelta from django.test import TestCase from django.utils import timezone from rest_framework.test import APIClient from accounts.authentication import issue_access_token from accounts.models import User from .models import HEART_REFILL_INTERVAL, UserHearts class UserHeartsRegenTests(TestCase): """رگرسیون: قبلاً next_refill_at هیچ‌وقت واقعاً چک نمی‌شد و هارتِ ازدست‌رفته برای همیشه صفر می‌موند.""" def setUp(self): self.client = APIClient() self.user = User.objects.create(device_id='dev-hearts-regen', is_guest=True, name='') self.token = issue_access_token(self.user.id) def _get_hearts(self): return self.client.get('/api/user/hearts', HTTP_AUTHORIZATION=f'Bearer {self.token}') def test_no_refill_before_interval_elapses(self): hearts = UserHearts.objects.create(user_id=self.user.id, current_hearts=3, max_hearts=5) hearts.lose_heart() # شبیه‌سازیِ از دست دادنِ یک هارتِ دیگه؛ تایمر رو ست می‌کنه hearts.save() response = self._get_hearts() self.assertEqual(response.data['currentHearts'], 2) self.assertIsNotNone(response.data['nextRefillAt']) def test_refill_after_interval_elapses(self): hearts = UserHearts.objects.create( user_id=self.user.id, current_hearts=3, max_hearts=5, next_refill_at=timezone.now() - timedelta(seconds=1), ) response = self._get_hearts() self.assertEqual(response.data['currentHearts'], 4) hearts.refresh_from_db() self.assertEqual(hearts.current_hearts, 4) self.assertIsNotNone(hearts.next_refill_at) # هنوز به max نرسیده، تایمرِ بعدی ست شده def test_refill_catches_up_multiple_missed_intervals(self): UserHearts.objects.create( user_id=self.user.id, current_hearts=1, max_hearts=5, next_refill_at=timezone.now() - 3 * HEART_REFILL_INTERVAL, ) response = self._get_hearts() self.assertEqual(response.data['currentHearts'], 5) self.assertIsNone(response.data['nextRefillAt']) # به max رسیده، تایمر خاموش می‌شه def test_full_hearts_have_no_refill_timer(self): UserHearts.objects.create(user_id=self.user.id, current_hearts=5, max_hearts=5) response = self._get_hearts() self.assertEqual(response.data['currentHearts'], 5) self.assertIsNone(response.data['nextRefillAt'])