give topic cards a colour before anyone picks one

رنگ و آیکونِ مبحث تازه اضافه شده بودند و هنوز هیچ‌کس پرشان نکرده، یعنی
کارت‌ها تا وقتی کسی از پنلِ ادمین وقت بگذارد بی‌رنگ می‌ماندند.

حالا وقتی فیلد خالی است، مقدارِ پیش‌فرض از پالت و آیکون‌های خودِ اپ می‌آید
(همان رنگ‌های طرح و همان آیکون‌هایی که از lucide وارد می‌شوند)، تا بومی به
نظر برسد نه وصله.

چرخشی بر اساسِ جایگاهِ مبحث در پایه است، نه تصادفی: رنگی که بینِ دو بارگذاری
عوض شود بدتر از بی‌رنگ بودن است، و دو مبحثِ کنارِ هم نباید یک‌رنگ دربیایند.
مقدارِ صریحِ ادمین همیشه برنده است.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 02:10:50 +03:30
parent 10ad1e232c
commit 2218f82938
2 changed files with 76 additions and 15 deletions

View File

@@ -150,3 +150,53 @@ class HomeGradeParamTests(TestCase):
def test_an_unknown_grade_is_a_clean_404_not_a_silent_fallback(self):
self.assertEqual(self.client.get('/api/home?gradeId=999999', **self.auth).status_code, 404)
class NodeVisualDefaultsTests(TestCase):
"""
تا وقتی کسی از پنلِ ادمین رنگ نگذاشته، کارتِ مبحث نباید بی‌رنگ بماند.
پیش‌فرض باید *پایدار* باشد نه تصادفی: رنگی که بینِ دو بارگذاری عوض شود،
بدتر از بی‌رنگ بودن است.
"""
def setUp(self):
cache.clear()
self.grade = Grade.objects.create(title='پایه نهم', icon='', color='')
unit = Unit.objects.create(grade=self.grade, title='فصل ۱', order=1)
self.nodes = [
Node.objects.create(unit=unit, title=f'مبحث {i}', order=i)
for i in range(1, 4)
]
for node in self.nodes:
Lesson.objects.create(node=node, title='نوع', intro_text='x')
user = User.objects.create(phone='09120000003', grade_id=self.grade.id)
from accounts.authentication import issue_access_token
self.auth = {'HTTP_AUTHORIZATION': f'Bearer {issue_access_token(user.id)}'}
def _nodes(self):
return self.client.get('/api/home', **self.auth).json()['units'][0]['nodes']
def test_a_node_without_a_colour_still_gets_one(self):
for node in self._nodes():
self.assertTrue(node['color'].startswith('#'), node)
self.assertTrue(node['icon'])
def test_neighbouring_nodes_do_not_share_a_colour(self):
colors = [n['color'] for n in self._nodes()]
self.assertEqual(len(set(colors)), len(colors))
def test_the_same_node_keeps_the_same_colour_between_requests(self):
first = [n['color'] for n in self._nodes()]
cache.clear()
self.assertEqual(first, [n['color'] for n in self._nodes()])
def test_an_explicit_colour_from_the_admin_wins(self):
self.nodes[0].color = '#123456'
self.nodes[0].icon = 'Trophy'
self.nodes[0].save()
cache.clear()
first = self._nodes()[0]
self.assertEqual(first['color'], '#123456')
self.assertEqual(first['icon'], 'Trophy')