""" تاریخِ تولدِ شمسی در پروفایل (۲۰۲۶-۱۰-۰۱). اپ روز/ماه/سالِ شمسی می‌فرستد؛ سرور میلادی ذخیره می‌کند و birthYear را از آن می‌سازد. راه‌های شکستن: تاریخِ ناموجود (۳۰ اسفندِ غیرکبیسه)، ارقامِ فارسی، سنِ خارج از بازه، و جدا افتادنِ سال از تاریخ. """ from datetime import date from django.core.cache import cache from django.test import SimpleTestCase, TestCase from rest_framework.test import APIClient from accounts import jalali from accounts.authentication import issue_access_token from accounts.models import Profile, User class JalaliConversionTests(SimpleTestCase): KNOWN = [ ((1405, 1, 1), date(2026, 3, 21)), ((1403, 12, 30), date(2025, 3, 20)), # اسفندِ کبیسه ((1404, 12, 29), date(2026, 3, 20)), # آخرین روزِ سالِ غیرکبیسه ((1385, 4, 12), date(2006, 7, 3)), ((1367, 10, 11), date(1989, 1, 1)), ] def test_known_dates_both_ways(self): for jalali_date, gregorian in self.KNOWN: self.assertEqual(jalali.to_gregorian(*jalali_date), gregorian) self.assertEqual(jalali.from_gregorian(gregorian), jalali_date) def test_thirtieth_of_esfand_exists_only_in_leap_years(self): self.assertTrue(jalali.is_leap(1403)) self.assertFalse(jalali.is_leap(1404)) with self.assertRaises(ValueError): jalali.to_gregorian(1404, 12, 30) def test_every_day_of_a_century_round_trips(self): start = date(1940, 1, 1).toordinal() for offset in range(0, 36600, 7): day = date.fromordinal(start + offset) self.assertEqual(jalali.to_gregorian(*jalali.from_gregorian(day)), day) def test_persian_digits_and_slashes_are_accepted(self): self.assertEqual(jalali.parse('۱۳۸۵/۰۴/۱۲'), date(2006, 7, 3)) class ProfileBirthDateApiTests(TestCase): def setUp(self): cache.clear() self.user = User.objects.create(device_id='birth-date-device', is_guest=True) self.client = APIClient() self.client.credentials(HTTP_AUTHORIZATION=f'Bearer {issue_access_token(self.user.id)}') def patch(self, body): return self.client.patch('/api/user/profile', body, format='json') def test_date_is_stored_and_returned_in_jalali_with_its_year(self): response = self.patch({'birthDate': '1385-04-12'}) self.assertEqual(response.status_code, 200, response.content) self.assertEqual(response.json()['birthDate'], '1385-04-12') self.assertEqual(response.json()['birthYear'], 1385) self.assertEqual(Profile.objects.get(user=self.user).birth_date, date(2006, 7, 3)) self.assertEqual(self.client.get('/api/user/profile').json()['birthDate'], '1385-04-12') def test_adults_are_accepted(self): self.assertEqual(self.patch({'birthDate': '1360-01-15'}).status_code, 200) def test_impossible_dates_are_rejected(self): for bad in ('1404-12-30', '1385-13-01', '1385-07-31', '1385-4', 'دیروز'): self.assertEqual(self.patch({'birthDate': bad}).status_code, 400, bad) def test_future_and_too_young_or_old_are_rejected(self): for bad in ('1410-01-01', '1403-01-01', '1300-01-01'): self.assertEqual(self.patch({'birthDate': bad}).status_code, 400, bad) def test_date_and_year_together_are_ambiguous(self): self.assertEqual(self.patch({'birthDate': '1385-04-12', 'birthYear': 1390}).status_code, 400) def test_a_different_year_alone_clears_the_old_date(self): self.patch({'birthDate': '1385-04-12'}) data = self.patch({'birthYear': 1388}).json() self.assertEqual((data['birthYear'], data['birthDate']), (1388, None)) def test_null_clears_the_date(self): self.patch({'birthDate': '1385-04-12'}) data = self.patch({'birthDate': None}).json() self.assertEqual((data['birthYear'], data['birthDate']), (None, None)) def test_parent_phone_is_gone(self): self.assertNotIn('parentPhone', self.client.get('/api/user/profile').json())