Skip to content

Commit c61ba22

Browse files
authored
View comments from project fix (#4960)
This was missed when support for multiple projects per submission was added.
1 parent ba461e2 commit c61ba22

2 files changed

Lines changed: 81 additions & 12 deletions

File tree

‎hypha/apply/funds/permissions.py‎

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,9 @@ def view_comments(role, user, submission) -> bool:
6060
if submission_view:
6161
return True
6262

63-
project = getattr(submission, "project", None)
64-
if project:
63+
# Users such as contracting staff and project form approvers reach a
64+
# submission's comments through its project rather than the submission.
65+
for project in submission.projects.all():
6566
can_access, _ = can_access_project(user, project)
6667
if can_access:
6768
return True
@@ -251,12 +252,10 @@ def can_view_submission_screening(user, submission):
251252
def can_invite_co_applicants(user, submission):
252253
if submission.is_archive:
253254
return False, _("Co-applicant can't be added to archived submission")
254-
project = getattr(submission, "project", None)
255-
if project:
256-
from hypha.apply.projects.models.project import COMPLETE
255+
from hypha.apply.projects.models.project import COMPLETE
257256

258-
if project.status == COMPLETE:
259-
return False, _("Co-applicants can't be invited to completed projects")
257+
if submission.projects.filter(status=COMPLETE).exists():
258+
return False, _("Co-applicants can't be invited to completed projects")
260259
if (
261260
submission.co_applicant_invites.count()
262261
>= settings.SUBMISSIONS_COAPPLICANT_INVITES_LIMIT
@@ -280,12 +279,10 @@ def can_view_co_applicants(user, submission):
280279
def can_update_co_applicant(user, invite):
281280
if invite.submission.is_archive:
282281
return False, _("Co-applicant can't be updated to archived submission")
283-
project = getattr(invite.submission, "project", None)
284-
if project:
285-
from hypha.apply.projects.models.project import COMPLETE
282+
from hypha.apply.projects.models.project import COMPLETE
286283

287-
if project.status == COMPLETE:
288-
return False, _("Co-applicants can't be updated to completed projects")
284+
if invite.submission.projects.filter(status=COMPLETE).exists():
285+
return False, _("Co-applicants can't be updated to completed projects")
289286
if invite.invited_by == user:
290287
return True, _("Same user who invited can delete the co-applicant")
291288
if invite.submission.user == user:

‎hypha/apply/funds/tests/test_permissions.py‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from hypha.apply.users.tests.factories import (
1616
AdminFactory,
1717
ApplicantFactory,
18+
ContractingFactory,
19+
FinanceFactory,
1820
ReviewerFactory,
1921
StaffFactory,
2022
UserFactory,
@@ -310,6 +312,23 @@ def test_limit_reached_blocks_invite(self):
310312
result, _ = can_invite_co_applicants(applicant, submission)
311313
self.assertFalse(result)
312314

315+
def test_complete_project_blocks_invite(self):
316+
"""The submission owner could otherwise invite, so this isolates status"""
317+
from hypha.apply.projects.models.project import COMPLETE
318+
from hypha.apply.projects.tests.factories import ProjectFactory
319+
320+
submission = ProjectFactory(status=COMPLETE).submission
321+
result, _ = can_invite_co_applicants(submission.user, submission)
322+
self.assertFalse(result)
323+
324+
def test_incomplete_project_does_not_block_invite(self):
325+
from hypha.apply.projects.models.project import INVOICING_AND_REPORTING
326+
from hypha.apply.projects.tests.factories import ProjectFactory
327+
328+
submission = ProjectFactory(status=INVOICING_AND_REPORTING).submission
329+
result, _ = can_invite_co_applicants(submission.user, submission)
330+
self.assertTrue(result)
331+
313332

314333
class TestGetArchiveGroups(TestCase):
315334
@override_settings(
@@ -457,6 +476,15 @@ def test_archived_submission_blocks_update(self):
457476
result, _ = can_update_co_applicant(self.inviter, invite)
458477
self.assertFalse(result)
459478

479+
def test_complete_project_blocks_update(self):
480+
from hypha.apply.projects.models.project import COMPLETE
481+
from hypha.apply.projects.tests.factories import ProjectFactory
482+
483+
project = ProjectFactory(status=COMPLETE, user=self.inviter)
484+
invite = self._make_invite(project.submission, invited_by=self.inviter)
485+
result, _ = can_update_co_applicant(self.inviter, invite)
486+
self.assertFalse(result)
487+
460488

461489
# ---------------------------------------------------------------------------
462490
# user_can_view_post_comment_form — co-applicant VIEW vs EDIT/COMMENT role
@@ -504,3 +532,47 @@ def test_staff_can_post_comment(self):
504532
self.assertTrue(
505533
user_can_view_post_comment_form(StaffFactory(), self.submission)
506534
)
535+
536+
537+
class TestViewComments(TestCase):
538+
"""`view_comments` reaches a submission's project via `submission.projects`"""
539+
540+
def setUp(self):
541+
from hypha.apply.projects.models.project import INVOICING_AND_REPORTING
542+
from hypha.apply.projects.tests.factories import ProjectFactory
543+
544+
self.vendor = ApplicantFactory()
545+
self.project = ProjectFactory(status=INVOICING_AND_REPORTING, user=self.vendor)
546+
self.submission = self.project.submission
547+
548+
def check(self, user):
549+
return has_object_permission("view_comments", user, self.submission)
550+
551+
def test_staff_can(self):
552+
self.assertTrue(self.check(StaffFactory()))
553+
554+
def test_admin_can(self):
555+
self.assertTrue(self.check(AdminFactory()))
556+
557+
def test_project_vendor_can(self):
558+
self.assertTrue(self.check(self.vendor))
559+
560+
def test_finance_and_contracting_can_via_the_project(self):
561+
"""These roles have no submission access, only project access"""
562+
for user in [FinanceFactory(), ContractingFactory()]:
563+
with self.subTest(user.roles):
564+
self.assertFalse(can_view_submission(user, self.submission)[0])
565+
self.assertTrue(self.check(user))
566+
567+
def test_unrelated_applicant_cannot(self):
568+
self.assertFalse(self.check(ApplicantFactory()))
569+
570+
def test_submission_without_a_project_falls_back_to_submission_access(self):
571+
submission = ApplicationSubmissionFactory()
572+
self.assertFalse(submission.projects.exists())
573+
self.assertTrue(
574+
has_object_permission("view_comments", StaffFactory(), submission)
575+
)
576+
self.assertFalse(
577+
has_object_permission("view_comments", ContractingFactory(), submission)
578+
)

0 commit comments

Comments
 (0)