improve bazdid 3
This commit is contained in:
1 parent
f8d768a724
commit
f86d060e4d
6 files changed
+337
-121
No files matched your search
+140
-13
@@ -804,6 +804,100 @@ class VisitHoldTests(TestCase):
|
||||
def _ms(self, moment):
|
||||
return str(int(moment.timestamp() * 1000))
|
||||
|
||||
def _post_edit(self, customer, action, **payload):
|
||||
base = {'desc': 'تست', 'userID': self.user.id}
|
||||
base.update(payload)
|
||||
for key in [k for k, v in list(base.items()) if v is None]:
|
||||
base.pop(key)
|
||||
return self.client.post(
|
||||
reverse('admin_panel:customerEditAction',
|
||||
kwargs={'c_id': customer.pk, 'action_id': action.pk}),
|
||||
base,
|
||||
HTTP_REFERER='/panel/customer/%d/action' % customer.pk,
|
||||
)
|
||||
|
||||
# ---------- ویرایش: تبدیل بازدید به هماهنگی با تاریخ پیگیری ----------
|
||||
def test_editing_action_into_coordination_saves_hold(self):
|
||||
"""تبدیل یک اقدام «بازدید» موجود به «هماهنگی» باید تاریخ پیگیری را ذخیره کند."""
|
||||
customer = self._customer('تبدیل به هماهنگی')
|
||||
action = Action.objects.create(
|
||||
customer=customer, actionType='bazdid', status='waite',
|
||||
actionDateTime=timezone.now() + timedelta(days=5),
|
||||
desc='بازدید اولیه', forUser=self.user,
|
||||
)
|
||||
target = timezone.now() + timedelta(days=20)
|
||||
|
||||
response = self._post_edit(
|
||||
customer, action,
|
||||
actionType='hamahangi',
|
||||
dateTimeAnjam=self._ms(timezone.now()),
|
||||
visitHoldUntil=self._ms(target),
|
||||
is_done='on',
|
||||
FinishDateTime=self._ms(timezone.now()),
|
||||
result='هماهنگ شد',
|
||||
)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
customer.refresh_from_db()
|
||||
action.refresh_from_db()
|
||||
self.assertEqual(action.actionType, 'hamahangi')
|
||||
self.assertIsNotNone(customer.visit_hold_until, 'تاریخ پیگیری ذخیره نشد')
|
||||
self.assertEqual(customer.visit_hold_until.date(), target.date())
|
||||
|
||||
def test_edit_modal_prefills_saved_hold(self):
|
||||
"""هنگام بازکردن مجدد اقدام، فیلد باید مقدار ذخیرهشده را نشان دهد.
|
||||
|
||||
رگرسیون: مودال مقدار را از دیتابیس نمیخواند، پس همیشه خالی دیده میشد
|
||||
(کاربر فکر میکرد «ثبت نشده»).
|
||||
"""
|
||||
customer = self._customer('نمایش قرار در ویرایش')
|
||||
Action.objects.create(
|
||||
customer=customer, actionType='hamahangi', status='finish',
|
||||
actionDateTime=timezone.now() - timedelta(minutes=5),
|
||||
finishDateTime=timezone.now() - timedelta(minutes=5),
|
||||
desc='هماهنگی', forUser=self.user,
|
||||
)
|
||||
set_visit_hold(customer, timezone.now() + timedelta(days=18))
|
||||
|
||||
html = self.client.get(
|
||||
reverse('admin_panel:customerAction', kwargs={'c_id': customer.pk})
|
||||
).content.decode()
|
||||
# ردیفها مقدار ذخیرهشده را بهصورت ISO در خود دارند...
|
||||
self.assertIn('customer_hold=', html)
|
||||
self.assertIn('function seedHoldPicker', html)
|
||||
self.assertIn('seedHoldPicker(customerHold)', html)
|
||||
|
||||
def test_editing_old_visit_does_not_wipe_newer_hold(self):
|
||||
"""ویرایش یک اقدام قدیمی نباید قرار هماهنگیِ جدیدتر را پاک کند."""
|
||||
customer = self._customer('ویرایش قدیمی')
|
||||
old_visit = Action.objects.create(
|
||||
customer=customer, actionType='bazdid', status='finish',
|
||||
actionDateTime=timezone.now() - timedelta(days=400),
|
||||
finishDateTime=timezone.now() - timedelta(days=400),
|
||||
desc='بازدید قدیمی', forUser=self.user,
|
||||
)
|
||||
Action.objects.create(
|
||||
customer=customer, actionType='hamahangi', status='finish',
|
||||
actionDateTime=timezone.now() - timedelta(minutes=5),
|
||||
finishDateTime=timezone.now() - timedelta(minutes=5),
|
||||
desc='هماهنگی جدید', forUser=self.user,
|
||||
)
|
||||
set_visit_hold(customer, timezone.now() + timedelta(days=20))
|
||||
|
||||
# فقط توضیح اقدام قدیمی را عوض میکنیم
|
||||
self._post_edit(
|
||||
customer, old_visit,
|
||||
actionType='bazdid',
|
||||
dateTimeAnjam=self._ms(timezone.now() - timedelta(days=400)),
|
||||
is_done='on',
|
||||
FinishDateTime=self._ms(timezone.now() - timedelta(days=400)),
|
||||
desc='توضیح اصلاح شد',
|
||||
)
|
||||
customer.refresh_from_db()
|
||||
self.assertIsNotNone(customer.visit_hold_until,
|
||||
'ویرایش اقدام قدیمی قرار معتبر را پاک کرد')
|
||||
self.assertIn(customer.pk, self._ids('manual'))
|
||||
|
||||
# ---------- ریسک ۱: تاریخِ «امروز» تا پایان روز معتبر است ----------
|
||||
def test_hold_until_today_hides_customer_until_end_of_day(self):
|
||||
customer = self._customer('قرار امروز')
|
||||
@@ -1030,13 +1124,11 @@ class VisitHoldTests(TestCase):
|
||||
|
||||
counts = self._entezar().context['counts']
|
||||
self.assertEqual(counts['uncoordinated'], 1) # a
|
||||
# عددِ کارت باید با فهرستی که با کلیک باز میشود بخواند:
|
||||
# view=manual گروههای B و D را نشان میدهد.
|
||||
# هر کارت فقط منبع خودش را میشمارد؛ d هر دو منبع را دارد ⇒ در هر سه
|
||||
# کارت شمرده میشود (قرار دستی، بازدید، با قرار).
|
||||
self.assertEqual(counts['manual'], 2) # b + d
|
||||
self.assertEqual(counts['scheduled'], 2) # c + d
|
||||
self.assertEqual(counts['manual_only'], 1) # b
|
||||
self.assertEqual(counts['scheduled_only'], 1) # c
|
||||
self.assertEqual(counts['both'], 1) # d
|
||||
self.assertEqual(counts['coordination'], 0) # هیچکدام هماهنگیِ فعال ندارد
|
||||
self.assertEqual(counts['total'], 4)
|
||||
self.assertEqual(counts['coordinated'], 3)
|
||||
|
||||
@@ -1044,6 +1136,7 @@ class VisitHoldTests(TestCase):
|
||||
self.assertEqual(self._ids('all'), {a.pk, b.pk, c.pk, d.pk})
|
||||
self.assertEqual(self._ids('manual'), {b.pk, d.pk})
|
||||
self.assertEqual(self._ids('scheduled'), {c.pk, d.pk})
|
||||
self.assertEqual(self._ids('coordination'), set())
|
||||
self.assertEqual(self._ids('coordinated'), {b.pk, c.pk, d.pk})
|
||||
|
||||
def test_invalid_view_falls_back_to_default(self):
|
||||
@@ -1075,14 +1168,47 @@ class VisitHoldTests(TestCase):
|
||||
counts = self._entezar().context['counts']
|
||||
self.assertEqual(counts['manual'], len(self._ids('manual')))
|
||||
self.assertEqual(counts['scheduled'], len(self._ids('scheduled')))
|
||||
self.assertEqual(counts['coordination'], len(self._ids('coordination')))
|
||||
self.assertEqual(counts['coordinated'], len(self._ids('coordinated')))
|
||||
self.assertEqual(counts['uncoordinated'], len(self._ids('uncoordinated')))
|
||||
self.assertEqual(counts['total'], len(self._ids('all')))
|
||||
|
||||
# وقتی مشتریای هر دو نوع قرار را دارد، راهنمای بالای صفحه باید
|
||||
# توضیح بدهد که چرا جمع دو کارت با «با قرار» برابر نیست.
|
||||
self.assertGreaterEqual(counts['both'], 1)
|
||||
self.assertIn('پس در هر دو کارت شمرده میشوند', self._entezar().content.decode())
|
||||
def test_card_number_matches_list_for_every_new_view(self):
|
||||
"""هر سه منبع، فیلتر مستقل خودش را دارد و عدد کارت با فهرست میخواند."""
|
||||
# فقط هماهنگی (بدون بازدید) — موردِ باگ گزارششده
|
||||
coord = self._customer('فقط هماهنگی')
|
||||
Action.objects.create(customer=coord, actionType='hamahangi', status='finish',
|
||||
actionDateTime=timezone.now() + timedelta(days=8),
|
||||
finishDateTime=timezone.now() - timedelta(minutes=5))
|
||||
# فقط بازدید
|
||||
sched = self._customer('فقط بازدید')
|
||||
Action.objects.create(customer=sched, actionType='bazdid', status='waite',
|
||||
actionDateTime=timezone.now() + timedelta(days=5))
|
||||
# هر دو
|
||||
both = self._customer('بازدید و هماهنگی')
|
||||
Action.objects.create(customer=both, actionType='bazdid', status='waite',
|
||||
actionDateTime=timezone.now() + timedelta(days=6))
|
||||
Action.objects.create(customer=both, actionType='hamahangi', status='finish',
|
||||
actionDateTime=timezone.now() + timedelta(days=9),
|
||||
finishDateTime=timezone.now() - timedelta(minutes=5))
|
||||
|
||||
counts = self._entezar().context['counts']
|
||||
# «هماهنگی» هرگز در نمای «بازدید برنامهریزیشده» ظاهر نمیشود.
|
||||
self.assertNotIn(coord.pk, self._ids('scheduled'))
|
||||
self.assertIn(coord.pk, self._ids('coordination'))
|
||||
# و برعکس.
|
||||
self.assertNotIn(sched.pk, self._ids('coordination'))
|
||||
self.assertIn(sched.pk, self._ids('scheduled'))
|
||||
# مشتریِ هر دو منبع، در هر دو نما هست.
|
||||
self.assertIn(both.pk, self._ids('scheduled'))
|
||||
self.assertIn(both.pk, self._ids('coordination'))
|
||||
# اما در «با قرار» فقط یکبار شمرده میشود.
|
||||
self.assertIn(both.pk, self._ids('coordinated'))
|
||||
|
||||
for key in ('manual', 'scheduled', 'coordination', 'coordinated',
|
||||
'uncoordinated', 'total'):
|
||||
self.assertEqual(counts[key], len(self._ids(
|
||||
'all' if key == 'total' else key)), f'عدد کارت {key} با فهرست نمیخواند')
|
||||
|
||||
def test_stats_cards_have_minimal_descriptions(self):
|
||||
"""هر کارت آمار باید یک توضیح کوتاه داشته باشد تا معنیاش روشن باشد."""
|
||||
@@ -1090,12 +1216,13 @@ class VisitHoldTests(TestCase):
|
||||
# سرِ نوار آمار + توضیح «عقبافتاده»
|
||||
self.assertIn('ez-stats-title', html)
|
||||
self.assertIn('ez-stats-hint', html)
|
||||
# پنج توضیح، یکی برای هر کارت
|
||||
self.assertEqual(html.count('class="ez-desc"'), 5)
|
||||
# پنج توضیح برای کارتهای بدونقرار/باقرار/… و ششمی برای هماهنگی
|
||||
self.assertEqual(html.count('class="ez-desc"'), 6)
|
||||
for phrase in ('هنوز وقت بازدید تعیین نشده',
|
||||
'وقت بازدیدشان مشخص است',
|
||||
'تعویق دستی از فرم هماهنگی',
|
||||
'اقدام «بازدید» با تاریخ آینده'):
|
||||
'اقدام «بازدید» با تاریخ آینده',
|
||||
'پیگیری به آینده موکول شده است'):
|
||||
self.assertIn(phrase, html, f'توضیح «{phrase}» روی کارتها نیست')
|
||||
|
||||
# ---------- اسکنر پیامک هم قرار دستی را میبیند ----------
|
||||
@@ -1338,7 +1465,7 @@ class EntezarLayoutTests(TestCase):
|
||||
def test_column_widths_sum_to_one_hundred(self):
|
||||
widths = [float(w) for w in re.findall(
|
||||
r'<col style="width: (\d+(?:\.\d+)?)%">', self.html)]
|
||||
self.assertEqual(len(widths), 8, 'تعداد ستونها باید ۸ باشد')
|
||||
self.assertEqual(len(widths), 9, 'تعداد ستونها باید ۹ باشد')
|
||||
self.assertAlmostEqual(sum(widths), 100.0, places=1)
|
||||
|
||||
def test_row_number_is_not_a_column(self):
|
||||
|
||||
Reference in new issue
Block a user