Skip to content

Commit 550cbc2

Browse files
matteiusclaude
andcommitted
fix: approval inbox AJAX 500 on anonymous submissions
The inbox and completed-approvals DataTables endpoints, plus the inbox Excel export, accessed sub.submitter.get_full_name() directly, which raised AttributeError: 'NoneType' object has no attribute 'get_full_name' for submissions made through public/anonymous forms. Introduce a _submitter_label() helper that returns "Anonymous" when the submission has no submitter and use it in the three unsafe sites. Other callers across the package already had None guards. Regression test: TestApprovalInboxView.test_approval_inbox_ajax_handles_anonymous_submitter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent d6414e4 commit 550cbc2

2 files changed

Lines changed: 36 additions & 7 deletions

File tree

django_forms_workflows/views.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,7 +3679,7 @@ def bulk_export_submissions(request):
36793679
ws.cell(
36803680
row=row_idx,
36813681
column=2,
3682-
value=sub.submitter.get_full_name() or sub.submitter.username,
3682+
value=_submitter_label(sub),
36833683
)
36843684
ws.cell(row=row_idx, column=3, value=sub.get_status_display())
36853685
ws.cell(
@@ -3938,6 +3938,16 @@ def _cat_html(cat):
39383938
return f"{icon}{escape(cat.name)}"
39393939

39403940

3941+
def _submitter_label(submission):
3942+
"""Return a display name for a submission's submitter, or "Anonymous"
3943+
when the submission was made through a public/anonymous form.
3944+
Callers should escape() the result if rendering into HTML."""
3945+
user = submission.submitter
3946+
if user is None:
3947+
return "Anonymous"
3948+
return user.get_full_name() or user.username
3949+
3950+
39413951
# ---------------------------------------------------------------------------
39423952
# AJAX: completed_approvals
39433953
# ---------------------------------------------------------------------------
@@ -4066,9 +4076,7 @@ def completed_approvals_ajax(request):
40664076
),
40674077
"category": _cat_html(getattr(sub.form_definition, "category", None)),
40684078
"form": escape(sub.form_definition.name),
4069-
"submitter": escape(
4070-
sub.submitter.get_full_name() or sub.submitter.username
4071-
),
4079+
"submitter": escape(_submitter_label(sub)),
40724080
"status": _STATUS_BADGE.get(
40734081
sub.status,
40744082
f'<span class="badge bg-light text-dark">{escape(sub.status)}</span>',
@@ -4212,9 +4220,7 @@ def approval_inbox_ajax(request):
42124220
f'<i class="bi bi-eye"></i> View</a>'
42134221
),
42144222
"form": escape(sub.form_definition.name),
4215-
"submitter": escape(
4216-
sub.submitter.get_full_name() or sub.submitter.username
4217-
),
4223+
"submitter": escape(_submitter_label(sub)),
42184224
"step_num": escape(stage_name),
42194225
"assigned": escape(
42204226
task.assigned_group.name

tests/test_views.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,29 @@ def test_approval_inbox(self, auth_client, user, submission, approval_group):
141141
resp = auth_client.get(url)
142142
assert resp.status_code == 200
143143

144+
def test_approval_inbox_ajax_handles_anonymous_submitter(
145+
self, auth_client, user, form_with_fields, approval_group
146+
):
147+
user.groups.add(approval_group)
148+
anon_sub = FormSubmission.objects.create(
149+
form_definition=form_with_fields,
150+
submitter=None,
151+
form_data={"full_name": "Walk-in"},
152+
status="submitted",
153+
)
154+
ApprovalTask.objects.create(
155+
submission=anon_sub,
156+
assigned_group=approval_group,
157+
step_name="Review",
158+
status="pending",
159+
)
160+
url = reverse("forms_workflows:approval_inbox_ajax")
161+
resp = auth_client.post(url, {"draw": 1, "start": 0, "length": 10})
162+
assert resp.status_code == 200
163+
payload = resp.json()
164+
assert payload["recordsTotal"] >= 1
165+
assert any("Anonymous" in row["submitter"] for row in payload["data"])
166+
144167

145168
# ── withdraw_submission ──────────────────────────────────────────────────
146169

0 commit comments

Comments
 (0)