From 880408285a54cdcb0a92e84f03bfbdd01bb462ea Mon Sep 17 00:00:00 2001 From: Disco DeDisco Date: Tue, 12 May 2026 15:13:49 -0400 Subject: [PATCH] =?UTF-8?q?post.html=20line=20timestamps=20mirror=20scroll?= =?UTF-8?q?'s=20relative=5Fts=20buckets:=20swap=20`date:'g:i=20A'`=20for?= =?UTF-8?q?=20the=20existing=20`lyric=5Fextras.relative=5Fts`=20filter=20s?= =?UTF-8?q?o=20same-day=20Lines=20render=20as=20`11:46=20p.m.`,=20then=20c?= =?UTF-8?q?ollapse=20to=20weekday=20(`Sat`)=20past=2024h,=20`07=20Mar`=20p?= =?UTF-8?q?ast=20a=20week,=20`07=20Mar=202025`=20past=20a=20year=20?= =?UTF-8?q?=E2=80=94=20DRYs=20onto=20the=20single=20filter=20scroll=20alre?= =?UTF-8?q?ady=20uses=20(no=20duplicated=20bucketing=20logic);=20same-day?= =?UTF-8?q?=20rendering=20shifts=20from=20`11:46=20PM`=20to=20`11:46=20p.m?= =?UTF-8?q?.`=20as=20a=20side=20effect=20of=20reusing=20the=20lowercase=20?= =?UTF-8?q?`g:i=20a`=20format=20`relative=5Fts`=20already=20standardised?= =?UTF-8?q?=20on=20=E2=80=94=20TDD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code architected by Disco DeDisco Git commit message Co-Authored-By: Claude Opus 4.7 (1M context) --- .../billboard/tests/integrated/test_views.py | 48 +++++++++++++++++++ src/templates/apps/billboard/post.html | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/apps/billboard/tests/integrated/test_views.py b/src/apps/billboard/tests/integrated/test_views.py index b5ed60e..0d2938d 100644 --- a/src/apps/billboard/tests/integrated/test_views.py +++ b/src/apps/billboard/tests/integrated/test_views.py @@ -433,3 +433,51 @@ class SaveScrollPositionTest(TestCase): {"position": 100}, ) self.assertEqual(response.status_code, 302) + + +class PostLineRelativeTimestampTest(TestCase): + """post.html mirrors scroll.html's bucketed `relative_ts` time rendering: + same-day Lines show a time; older ones collapse to weekday / month-day / + month-day-year. Bypasses `auto_now_add` with a queryset .update() so the + test can backdate Lines.""" + + def setUp(self): + self.owner = User.objects.create(email="owner@post-ts.io", username="owner") + self.client.force_login(self.owner) + from apps.billboard.models import Line, Post + self.Line = Line + self.post = Post.objects.create(owner=self.owner, title="Stamp") + + def _backdate(self, line, **delta): + from apps.billboard.models import Line + Line.objects.filter(pk=line.pk).update( + created_at=timezone.now() - timezone.timedelta(**delta) + ) + + def test_recent_line_renders_clock_time(self): + self.Line.objects.create(post=self.post, text="now", author=self.owner) + response = self.client.get(reverse("billboard:view_post", args=[self.post.id])) + self.assertRegex( + response.content.decode(), + r'class="post-line-time"[^>]*>\s*\d+:\d{2}\s*[ap]\.m\.\s*<', + ) + + def test_two_day_old_line_renders_weekday(self): + line = self.Line.objects.create(post=self.post, text="old", author=self.owner) + self._backdate(line, days=2) + response = self.client.get(reverse("billboard:view_post", args=[self.post.id])) + import re + m = re.search( + r'class="post-line-time"[^>]*>\s*(\w+)\s*<', response.content.decode() + ) + self.assertIsNotNone(m, "no .post-line-time cell rendered") + self.assertIn(m.group(1), {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}) + + def test_thirty_day_old_line_renders_day_month(self): + line = self.Line.objects.create(post=self.post, text="oldr", author=self.owner) + self._backdate(line, days=30) + response = self.client.get(reverse("billboard:view_post", args=[self.post.id])) + self.assertRegex( + response.content.decode(), + r'class="post-line-time"[^>]*>\s*\d{2}\s\w{3}\s*<', + ) diff --git a/src/templates/apps/billboard/post.html b/src/templates/apps/billboard/post.html index abccf5f..0c42722 100644 --- a/src/templates/apps/billboard/post.html +++ b/src/templates/apps/billboard/post.html @@ -42,7 +42,7 @@
  • {{ line.author|at_handle }} {# adman-authored Lines (note unlock + share invite system prose) carry an `` anchor that needs to render as HTML. User-typed Lines stay escaped. #}{% if line.author.username == 'adman' %}{{ line.text|safe }}{% else %}{{ line.text }}{% endif %} - +
  • {% endfor %}