Skip to content

Commit 99ded5b

Browse files
committed
Make results viewable by users if allowed by creator
1 parent ec54c55 commit 99ded5b

5 files changed

Lines changed: 56 additions & 3 deletions

File tree

src/experimental/doodle/browser/doodle_answer.pt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
</p>
2626
</div>
2727
<div class="doodle-header-actions"
28-
tal:condition="view/is_creator"
28+
tal:condition="view/can_view_results"
2929
>
3030
<a class="btn btn-secondary btn-sm"
3131
tal:attributes="

src/experimental/doodle/browser/views.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from experimental.doodle.utils import format_date
88
from experimental.doodle.utils import format_date_long
99
from experimental.doodle.utils import get_member_info
10+
from experimental.doodle.utils import is_doodle_manager
1011
from experimental.doodle.utils import parse_iso_dates
1112
from experimental.doodle.utils import require_authenticated
1213
from Products.Five import BrowserView
@@ -32,7 +33,8 @@ def update(self):
3233
self.selected = (
3334
set(self.existing.get("selected_dates", [])) if self.existing else set()
3435
)
35-
self.is_creator = can_view_results(self.context)
36+
self.is_creator = is_doodle_manager(self.context)
37+
self.can_view_results = can_view_results(self.context)
3638
self.results_url = f"{self.context.absolute_url()}/@@results"
3739

3840
if self.request.method != "POST":
@@ -73,7 +75,7 @@ def format_date_long(self, value):
7375

7476

7577
class ResultsView(BrowserView):
76-
"""Creator-only summary of all answers."""
78+
"""Summary of all answers for users allowed to view results."""
7779

7880
index = ViewPageTemplateFile("doodle_results.pt")
7981

src/experimental/doodle/content/interfaces.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,13 @@ class IDoodle(model.Schema):
1919
required=True,
2020
min_length=1,
2121
)
22+
23+
allow_members_view_results = schema.Bool(
24+
title=_("Allow participants to view results"),
25+
description=_(
26+
"When enabled, any logged-in member who can view this doodle "
27+
"may also open the results page."
28+
),
29+
required=False,
30+
default=False,
31+
)

src/experimental/doodle/utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ def can_view_results(context):
2929
if member.has_role("Manager"):
3030
return True
3131
creator = getattr(context, "Creator", lambda: None)()
32+
if creator == member.getId():
33+
return True
34+
if getattr(context, "allow_members_view_results", False):
35+
return True
36+
return False
37+
38+
39+
def is_doodle_manager(context):
40+
"""True if the current user may manage doodle settings (creator UI)."""
41+
if api.user.is_anonymous():
42+
return False
43+
member = api.user.get_current()
44+
if member is None:
45+
return False
46+
if member.has_role("Manager"):
47+
return True
48+
creator = getattr(context, "Creator", lambda: None)()
3249
return creator == member.getId()
3350

3451

tests/test_doodle.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,27 @@ def test_non_creator_cannot_view_results(self, portal, http_request):
115115
view = ResultsView(obj, request)
116116
with pytest.raises(Unauthorized):
117117
view.update()
118+
119+
def test_member_can_view_results_when_allowed(self, portal, http_request):
120+
obj = _create_doodle(portal)
121+
obj.allow_members_view_results = True
122+
upsert_answer(obj, "member", "Member", [date(2026, 5, 20)])
123+
login(portal, TEST_USER_NAME)
124+
request = _prepare_request(http_request)
125+
126+
html = ResultsView(obj, request)()
127+
128+
assert "Who can make it" in html
129+
assert "Member" in html
130+
131+
def test_member_sees_results_link_when_allowed(self, portal, http_request):
132+
obj = _create_doodle(portal)
133+
obj.allow_members_view_results = True
134+
login(portal, TEST_USER_NAME)
135+
request = _prepare_request(http_request)
136+
request.method = "GET"
137+
138+
html = AnswerView(obj, request)()
139+
140+
assert "View results" in html
141+
assert "Share this link" not in html

0 commit comments

Comments
 (0)