mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-25 12:08:40 +02:00
355 lines
15 KiB
Python
355 lines
15 KiB
Python
from django.test import Client
|
|
from django.urls import reverse
|
|
from waffle.testutils import override_flag
|
|
|
|
from registrar.tests.common import (
|
|
MockDbForIndividualTests,
|
|
less_console_noise_decorator,
|
|
completed_domain_request,
|
|
)
|
|
from registrar.models import (
|
|
DomainRequest,
|
|
Portfolio,
|
|
UserPortfolioPermission,
|
|
PortfolioInvitation,
|
|
)
|
|
from registrar.models.utility.portfolio_helper import (
|
|
UserPortfolioRoleChoices,
|
|
UserPortfolioPermissionChoices,
|
|
)
|
|
from registrar.decorators import (
|
|
_domain_exists_under_portfolio,
|
|
_domain_request_exists_under_portfolio,
|
|
_member_exists_under_portfolio,
|
|
_member_invitation_exists_under_portfolio,
|
|
)
|
|
|
|
|
|
class TestPortfolioResourceAccess(MockDbForIndividualTests):
|
|
"""Test functions that verify resources belong to a portfolio.
|
|
More specifically, this function tests our helper utilities in decorators.py"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
|
|
# Create portfolios
|
|
self.portfolio = Portfolio.objects.create(creator=self.user, organization_name="Test Portfolio")
|
|
self.other_portfolio = Portfolio.objects.create(
|
|
creator=self.custom_staffuser, organization_name="Other Portfolio"
|
|
)
|
|
|
|
# Create domain requests
|
|
self.domain_request = completed_domain_request(name="eggnog.gov", user=self.user, portfolio=self.portfolio)
|
|
|
|
self.other_domain_request = completed_domain_request(
|
|
name="christmas.gov", user=self.tired_user, portfolio=self.other_portfolio
|
|
)
|
|
|
|
# Create domains
|
|
self.approved_domain_request_1 = completed_domain_request(
|
|
name="done_1.gov",
|
|
user=self.tired_user,
|
|
portfolio=self.portfolio,
|
|
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
|
|
)
|
|
self.approved_domain_request_2 = completed_domain_request(
|
|
name="done_2.gov",
|
|
user=self.tired_user,
|
|
portfolio=self.other_portfolio,
|
|
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
|
|
)
|
|
self.approved_domain_request_1.approve()
|
|
self.approved_domain_request_2.approve()
|
|
self.domain = self.approved_domain_request_1.approved_domain
|
|
self.other_domain = self.approved_domain_request_2.approved_domain
|
|
|
|
# Create portfolio permissions
|
|
self.user_permission = UserPortfolioPermission.objects.create(
|
|
user=self.user, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
|
)
|
|
|
|
self.other_user_permission = UserPortfolioPermission.objects.create(
|
|
user=self.tired_user, portfolio=self.other_portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
|
|
)
|
|
|
|
# Create portfolio invitations
|
|
self.portfolio_invitation = PortfolioInvitation.objects.create(
|
|
email="invited@example.com",
|
|
portfolio=self.portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
|
status=PortfolioInvitation.PortfolioInvitationStatus.INVITED,
|
|
)
|
|
|
|
self.other_portfolio_invitation = PortfolioInvitation.objects.create(
|
|
email="other-invited@example.com",
|
|
portfolio=self.other_portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
|
status=PortfolioInvitation.PortfolioInvitationStatus.INVITED,
|
|
)
|
|
|
|
# Domain request tests
|
|
@less_console_noise_decorator
|
|
def test_domain_request_exists_under_portfolio_when_pk_is_none(self):
|
|
"""Check behavior when the PK is None."""
|
|
self.assertTrue(_domain_request_exists_under_portfolio(self.portfolio, None))
|
|
|
|
@less_console_noise_decorator
|
|
def test_domain_request_exists_under_portfolio_when_exists(self):
|
|
"""Verify returns True when the domain request exists under the portfolio."""
|
|
self.assertTrue(_domain_request_exists_under_portfolio(self.portfolio, self.domain_request.id))
|
|
|
|
@less_console_noise_decorator
|
|
def test_domain_request_exists_under_portfolio_when_not_exists(self):
|
|
"""Verify returns False when the domain request does not exist under the portfolio."""
|
|
self.assertFalse(_domain_request_exists_under_portfolio(self.portfolio, self.other_domain_request.id))
|
|
|
|
# Domain tests
|
|
@less_console_noise_decorator
|
|
def test_domain_exists_under_portfolio_when_pk_is_none(self):
|
|
"""Check behavior when the PK is None."""
|
|
self.assertTrue(_domain_exists_under_portfolio(self.portfolio, None))
|
|
|
|
@less_console_noise_decorator
|
|
def test_domain_exists_under_portfolio_when_exists(self):
|
|
"""Verify returns True when the domain exists under the portfolio."""
|
|
self.assertTrue(_domain_exists_under_portfolio(self.portfolio, self.domain.id))
|
|
|
|
@less_console_noise_decorator
|
|
def test_domain_exists_under_portfolio_when_not_exists(self):
|
|
"""Verify returns False when the domain does not exist under the portfolio."""
|
|
self.assertFalse(_domain_exists_under_portfolio(self.portfolio, self.other_domain.id))
|
|
|
|
# Member tests
|
|
@less_console_noise_decorator
|
|
def test_member_exists_under_portfolio_when_pk_is_none(self):
|
|
"""Check behavior when the PK is None."""
|
|
self.assertTrue(_member_exists_under_portfolio(self.portfolio, None))
|
|
|
|
@less_console_noise_decorator
|
|
def test_member_exists_under_portfolio_when_exists(self):
|
|
"""Verify returns True when the member exists under the portfolio."""
|
|
self.assertTrue(_member_exists_under_portfolio(self.portfolio, self.user_permission.id))
|
|
|
|
@less_console_noise_decorator
|
|
def test_member_exists_under_portfolio_when_not_exists(self):
|
|
"""Verify returns False when the member does not exist under the portfolio."""
|
|
self.assertFalse(_member_exists_under_portfolio(self.portfolio, self.other_user_permission.id))
|
|
|
|
# Member invitation tests
|
|
@less_console_noise_decorator
|
|
def test_member_invitation_exists_under_portfolio_when_pk_is_none(self):
|
|
"""Check behavior when the PK is None."""
|
|
self.assertTrue(_member_invitation_exists_under_portfolio(self.portfolio, None))
|
|
|
|
@less_console_noise_decorator
|
|
def test_member_invitation_exists_under_portfolio_when_exists(self):
|
|
"""Verify returns True when the member invitation exists under the portfolio."""
|
|
self.assertTrue(_member_invitation_exists_under_portfolio(self.portfolio, self.portfolio_invitation.id))
|
|
|
|
@less_console_noise_decorator
|
|
def test_member_invitation_exists_under_portfolio_when_not_exists(self):
|
|
"""Verify returns False when the member invitation does not exist under the portfolio."""
|
|
self.assertFalse(_member_invitation_exists_under_portfolio(self.portfolio, self.other_portfolio_invitation.id))
|
|
|
|
|
|
class TestPortfolioDomainRequestViewAccess(MockDbForIndividualTests):
|
|
"""Tests for domain request views to ensure users can only access domain requests in their portfolio."""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.client = Client()
|
|
self.client.force_login(self.user)
|
|
|
|
# Create portfolios
|
|
self.portfolio = Portfolio.objects.create(creator=self.user, organization_name="Test Portfolio")
|
|
self.other_portfolio = Portfolio.objects.create(creator=self.tired_user, organization_name="Other Portfolio")
|
|
|
|
# Create domain requests
|
|
self.domain_request = completed_domain_request(
|
|
name="test-domain.gov",
|
|
portfolio=self.portfolio,
|
|
status=DomainRequest.DomainRequestStatus.STARTED,
|
|
user=self.user,
|
|
)
|
|
|
|
self.other_domain_request = completed_domain_request(
|
|
name="other-domain.gov",
|
|
portfolio=self.other_portfolio,
|
|
status=DomainRequest.DomainRequestStatus.STARTED,
|
|
user=self.tired_user,
|
|
)
|
|
|
|
# Give user permission to view all requests
|
|
self.user_permission = UserPortfolioPermission.objects.create(
|
|
user=self.user,
|
|
portfolio=self.portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER],
|
|
additional_permissions=[UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS],
|
|
)
|
|
|
|
# Setup session for portfolio views
|
|
session = self.client.session
|
|
session["portfolio"] = self.portfolio
|
|
session.save()
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_requests", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_request_view_same_portfolio(self):
|
|
"""Test that user can access domain requests in their portfolio."""
|
|
# With just the view all permission, access should be denied
|
|
response = self.client.get(reverse("edit-domain-request", kwargs={"domain_request_pk": self.domain_request.pk}))
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
# But with the edit permission, the user should be able to access this domain request
|
|
self.user_permission.additional_permissions = [
|
|
UserPortfolioPermissionChoices.VIEW_ALL_REQUESTS,
|
|
UserPortfolioPermissionChoices.EDIT_REQUESTS,
|
|
]
|
|
self.user_permission.save()
|
|
self.user_permission.refresh_from_db()
|
|
response = self.client.get(
|
|
reverse("edit-domain-request", kwargs={"domain_request_pk": self.domain_request.pk}), follow=True
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_requests", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_request_view_different_portfolio(self):
|
|
"""Test that user cannot access domain request not in their portfolio."""
|
|
response = self.client.get(
|
|
reverse("edit-domain-request", kwargs={"domain_request_pk": self.other_domain_request.pk})
|
|
)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_requests", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_request_viewonly_same_portfolio(self):
|
|
"""Test that user can access view-only domain request in their portfolio."""
|
|
response = self.client.get(
|
|
reverse("domain-request-status-viewonly", kwargs={"domain_request_pk": self.domain_request.pk})
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_requests", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_request_viewonly_different_portfolio(self):
|
|
"""Test that user cannot access view-only domain request not in their portfolio."""
|
|
response = self.client.get(
|
|
reverse("domain-request-status-viewonly", kwargs={"domain_request_pk": self.other_domain_request.pk})
|
|
)
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
|
|
class TestPortfolioDomainViewAccess(MockDbForIndividualTests):
|
|
"""Tests for domain views to ensure users can only access domains in their portfolio."""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.client = Client()
|
|
self.client.force_login(self.user)
|
|
|
|
# Create portfolios
|
|
self.portfolio = Portfolio.objects.create(creator=self.user, organization_name="Test Portfolio")
|
|
self.other_portfolio = Portfolio.objects.create(creator=self.tired_user, organization_name="Other Portfolio")
|
|
|
|
# Create domains through domain requests
|
|
self.domain_request = completed_domain_request(
|
|
name="test-domain.gov",
|
|
portfolio=self.portfolio,
|
|
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
|
|
user=self.user,
|
|
)
|
|
self.domain_request.approve()
|
|
self.domain = self.domain_request.approved_domain
|
|
|
|
self.other_domain_request = completed_domain_request(
|
|
name="other-domain.gov",
|
|
portfolio=self.other_portfolio,
|
|
status=DomainRequest.DomainRequestStatus.IN_REVIEW,
|
|
user=self.user,
|
|
)
|
|
self.other_domain_request.approve()
|
|
self.other_domain = self.other_domain_request.approved_domain
|
|
|
|
# Give user permission to view all domains
|
|
self.user_permission = UserPortfolioPermission.objects.create(
|
|
user=self.user,
|
|
portfolio=self.portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER],
|
|
additional_permissions=[UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS],
|
|
)
|
|
|
|
# Setup session for portfolio views
|
|
session = self.client.session
|
|
session["portfolio"] = self.portfolio
|
|
session.save()
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_view_same_portfolio(self):
|
|
"""Test that user can access domain in their portfolio."""
|
|
response = self.client.get(reverse("domain", kwargs={"domain_pk": self.domain.pk}))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@less_console_noise_decorator
|
|
def test_domain_view_different_portfolio(self):
|
|
"""Test that user cannot access domain not in their portfolio."""
|
|
response = self.client.get(reverse("domain", kwargs={"domain_pk": self.other_domain.pk}))
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
|
|
class TestPortfolioMemberViewAccess(MockDbForIndividualTests):
|
|
"""Tests for member views to ensure users can only access members in their portfolio."""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.client = Client()
|
|
self.client.force_login(self.user)
|
|
|
|
# Create portfolios
|
|
self.portfolio = Portfolio.objects.create(creator=self.user, organization_name="Test Portfolio")
|
|
self.other_portfolio = Portfolio.objects.create(creator=self.tired_user, organization_name="Other Portfolio")
|
|
|
|
# Create portfolio permissions
|
|
self.member_permission = UserPortfolioPermission.objects.create(
|
|
user=self.meoward_user, portfolio=self.portfolio, roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER]
|
|
)
|
|
|
|
self.other_member_permission = UserPortfolioPermission.objects.create(
|
|
user=self.lebowski_user,
|
|
portfolio=self.other_portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_MEMBER],
|
|
)
|
|
|
|
# Give user permission to view/edit members
|
|
self.user_permission = UserPortfolioPermission.objects.create(
|
|
user=self.user,
|
|
portfolio=self.portfolio,
|
|
roles=[UserPortfolioRoleChoices.ORGANIZATION_ADMIN],
|
|
)
|
|
|
|
# Setup session for portfolio views
|
|
session = self.client.session
|
|
session["portfolio"] = self.portfolio
|
|
session.save()
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_members", active=True)
|
|
@less_console_noise_decorator
|
|
def test_member_view_same_portfolio(self):
|
|
"""Test that user can access member in their portfolio."""
|
|
response = self.client.get(reverse("member", kwargs={"member_pk": self.member_permission.pk}))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
@override_flag("organization_feature", active=True)
|
|
@override_flag("organization_members", active=True)
|
|
@less_console_noise_decorator
|
|
def test_member_view_different_portfolio(self):
|
|
"""Test that user cannot access member not in their portfolio."""
|
|
response = self.client.get(reverse("member", kwargs={"member_pk": self.other_member_permission.pk}))
|
|
self.assertEqual(response.status_code, 403)
|