post.html header prose branches on viewer-vs-owner: invitees see "shared with me, @viewer the {title}" + "created by @owner the {title}" instead of the owner-centric "just me / shared between" lines; owner view unchanged — TDD
- billboard.views.view_post adds viewer_is_owner + other_recipients context vars. is_real_invitee = (auth AND post has owner AND viewer != owner). Anon viewers + ownerless-post legacy path fall through to owner-style rendering (which renders empty gracefully via the at_handle / display_name AnonymousUser guards).
- other_recipients = post.shared_with.exclude(viewer) when invitee; .all() otherwise.
- post.html .post-header branches:
• viewer_is_owner: existing prose ("just me, @owner …" / "shared between {recipients} & me, @owner …").
• sole invitee: "shared with me, @viewer the {viewer.title}" + "created by @owner the {owner.title}".
• multi invitee: "shared with {other_recipients}" + "& me, @viewer the {viewer.title}" + "created by @owner the {owner.title}".
- lyric_extras at_handle + display_name: guard against AnonymousUser (no .email attribute) — return "" rather than crash. Preserves the Percival ch. 18 anon-views-ownerless-post path.
- 12 new ITs in test_post_invitee_view (context vars: viewer_is_owner, other_recipients exclude/include; template prose: sole + multi invitee phrasing, owner unchanged).
- 878 IT regression + 8 post-html FT regression green (1 Marionette flake on multi-run that passes in isolation).
Code architected by Disco DeDisco <discodedisco@outlook.com>
Git commit message Co-Authored-By:
Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,7 +43,11 @@ def relative_ts(dt):
|
||||
|
||||
@register.filter
|
||||
def display_name(user):
|
||||
if user is None:
|
||||
# `getattr` guards: AnonymousUser has no `.email` attribute and is not
|
||||
# None, so `if user is None` doesn't catch it. Render anonymous viewers
|
||||
# as empty rather than crashing — the legacy ownerless-post path
|
||||
# (Percival ch. 18) shows post detail to anon visitors.
|
||||
if user is None or not getattr(user, "is_authenticated", False):
|
||||
return ""
|
||||
if user.username:
|
||||
return user.username
|
||||
@@ -55,8 +59,9 @@ def at_handle(user):
|
||||
"""`@username` when the user has set one; falls back to the truncated
|
||||
email otherwise (no `@` prefix on bare emails since the address itself
|
||||
already carries the `@`). Used in post.html to colour usernames in the
|
||||
--quaUser palette key while leaving emails as-is."""
|
||||
if user is None:
|
||||
--quaUser palette key while leaving emails as-is. Anonymous viewers
|
||||
render as empty (legacy ownerless-post path)."""
|
||||
if user is None or not getattr(user, "is_authenticated", False):
|
||||
return ""
|
||||
if user.username:
|
||||
return f"@{user.username}"
|
||||
|
||||
Reference in New Issue
Block a user