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:
@@ -285,9 +285,31 @@ def view_post(request, post_id):
|
||||
Brief.objects.filter(
|
||||
owner=request.user, post=our_post, is_unread=True,
|
||||
).update(is_unread=False)
|
||||
|
||||
# Header-prose branching: post.html shows different self/shared lines
|
||||
# depending on whether the viewer IS the owner. The invitee branch
|
||||
# ("shared with me, @viewer …" + "created by @owner …") only kicks
|
||||
# in when (a) the viewer is authenticated AND (b) the post has an
|
||||
# owner AND (c) the viewer is NOT that owner. Ownerless posts and
|
||||
# anonymous viewers fall through to the owner-style rendering (which
|
||||
# handles missing data gracefully via the at_handle/display_name
|
||||
# filter guards).
|
||||
is_real_invitee = (
|
||||
request.user.is_authenticated
|
||||
and our_post.owner is not None
|
||||
and request.user != our_post.owner
|
||||
)
|
||||
viewer_is_owner = not is_real_invitee
|
||||
if is_real_invitee:
|
||||
other_recipients = our_post.shared_with.exclude(pk=request.user.pk)
|
||||
else:
|
||||
other_recipients = our_post.shared_with.all()
|
||||
|
||||
return render(request, "apps/billboard/post.html", {
|
||||
"post": our_post,
|
||||
"form": form,
|
||||
"viewer_is_owner": viewer_is_owner,
|
||||
"other_recipients": other_recipients,
|
||||
"page_class": "page-billpost",
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user