unit tests

This commit is contained in:
Rachid Mrad 2024-07-17 21:04:59 -04:00
parent 72ee81a43c
commit ea6ccae948
No known key found for this signature in database
7 changed files with 309 additions and 43 deletions

View file

@ -296,6 +296,8 @@ function openInNewTab(el, removeAttribute = false){
// "to" select list
checkToListThenInitWidget('id_groups_to', 0);
checkToListThenInitWidget('id_user_permissions_to', 0);
checkToListThenInitWidget('id_portfolio_roles_to', 0);
checkToListThenInitWidget('id_portfolio_additional_permissions_to', 0);
})();
// Function to check for the existence of the "to" select list element in the DOM, and if and when found,

View file

@ -34,22 +34,6 @@
pointer-events: none;
}
}
// Ticket #1510
// @include at-media('desktop') {
// th:first-child {
// width: 220px;
// }
// th:nth-child(2) {
// width: 175px;
// }
// th:nth-child(3) {
// width: 130px;
// }
// th:nth-child(5) {
// width: 130px;
// }
// }
}
.dotgov-table {

View file

@ -138,7 +138,7 @@ class User(AbstractUser):
null=True,
blank=True,
related_name="user",
on_delete=models.PROTECT,
on_delete=models.SET_NULL,
)
portfolio_roles = ArrayField(
@ -250,35 +250,35 @@ class User(AbstractUser):
def has_contact_info(self):
return bool(self.title or self.email or self.phone)
def has_role(self, role):
"""Do not rely on roles when testing for perms in views"""
return role in self.portfolio_roles if self.portfolio_roles else False
def has_portfolio_permission(self, portfolio_permission):
"""The views should only call this guy when testing for perms and not rely on roles"""
print(f"IN has_portfolio_permission")
# EDIT_DOMAINS === user is a manager on a domain (has UserDomainRole)
# NOTE: Should we check whether the domain is in the portfolio?
if portfolio_permission == self.UserPortfolioPermissionChoices.EDIT_DOMAINS and self.domains.exists():
return True
if not self.portfolio:
return False
portfolio_permissions = self.get_portfolio_permissions()
portfolio_permissions = self._get_portfolio_permissions()
return portfolio_permission in portfolio_permissions
def get_portfolio_permissions(self):
def _get_portfolio_permissions(self):
"""
Retrieve the permissions for the user's portfolio roles.
"""
portfolio_permissions = set() # Use a set to avoid duplicate permissions
for role in self.portfolio_roles:
if role in self.PORTFOLIO_ROLE_PERMISSIONS:
portfolio_permissions.update(self.PORTFOLIO_ROLE_PERMISSIONS[role])
portfolio_permissions.update(self.portfolio_additional_permissions)
if self.portfolio_roles:
for role in self.portfolio_roles:
if role in self.PORTFOLIO_ROLE_PERMISSIONS:
portfolio_permissions.update(self.PORTFOLIO_ROLE_PERMISSIONS[role])
if self.portfolio_additional_permissions:
portfolio_permissions.update(self.portfolio_additional_permissions)
return list(portfolio_permissions) # Convert back to list if necessary
@classmethod

View file

@ -3710,6 +3710,22 @@ class TestMyUserAdmin(MockDb):
expected_href = reverse("admin:registrar_domain_change", args=[domain_deleted.pk])
self.assertNotContains(response, expected_href)
def test_analyst_can_see_selects_for_portfolio_role_and_permissions_in_user_form(self):
"""Can only test for the presence of a base element. The multiselects and the h2->h3 conversion are all
dynamically generated."""
p = "userpass"
self.client.login(username="staffuser", password=p)
response = self.client.get(
"/admin/registrar/user/{}/change/".format(self.meoward_user.id),
follow=True,
)
self.assertEqual(response.status_code, 200)
self.assertContains(response,"Portfolio roles:")
self.assertContains(response,"Portfolio additional permissions:")
class AuditedAdminTest(TestCase):
def setUp(self):

View file

@ -19,6 +19,7 @@ from registrar.models import (
)
import boto3_mocking
from registrar.models.portfolio import Portfolio
from registrar.models.transition_domain import TransitionDomain
from registrar.models.verified_by_staff import VerifiedByStaff # type: ignore
from registrar.utility.constants import BranchChoices
@ -1214,6 +1215,66 @@ class TestUser(TestCase):
self.user.phone = None
self.assertFalse(self.user.has_contact_info())
def test_has_portfolio_permission(self):
"""
0. Returns False when user does not have a permission
1. Returns False when a user does not have a portfolio
2. Returns True when user has direct permission
3. Returns True when user has permission through a role
4. Returns True EDIT_DOMAINS when user does not have the perm but has UserDomainRole
Note: This tests _get_portfolio_permissions as a side effect
"""
portfolio, _ = Portfolio.objects.get_or_create(creator=self.user, organization_name="Hotel California")
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_DOMAINS]
self.user.save()
self.user.refresh_from_db()
user_can_view_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_DOMAINS)
user_can_view_requests = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)
user_can_edit_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
self.assertFalse(user_can_view_domains)
self.assertFalse(user_can_view_requests)
self.assertFalse(user_can_edit_domains)
self.user.portfolio=portfolio
self.user.save()
self.user.refresh_from_db()
user_can_view_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_DOMAINS)
user_can_view_requests = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)
user_can_edit_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
self.assertTrue(user_can_view_domains)
self.assertFalse(user_can_view_requests)
self.assertFalse(user_can_edit_domains)
self.user.portfolio_roles = [User.UserPortfolioRoleChoices.ORGANIZATION_ADMIN]
self.user.save()
self.user.refresh_from_db()
user_can_view_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_DOMAINS)
user_can_view_requests = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)
user_can_edit_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
self.assertTrue(user_can_view_domains)
self.assertTrue(user_can_view_requests)
self.assertFalse(user_can_edit_domains)
UserDomainRole.objects.all().get_or_create(user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER)
user_can_view_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_DOMAINS)
user_can_view_requests = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.VIEW_REQUESTS)
user_can_edit_domains = self.user.has_portfolio_permission(User.UserPortfolioPermissionChoices.EDIT_DOMAINS)
self.assertTrue(user_can_view_domains)
self.assertTrue(user_can_view_requests)
self.assertTrue(user_can_edit_domains)
Portfolio.objects.all().delete()
class TestContact(TestCase):
def setUp(self):

View file

@ -958,22 +958,22 @@ class PortfoliosTests(TestWithUser, WebTest):
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@less_console_noise_decorator
def test_middleware_redirects_to_portfolio_homepage(self):
"""Tests that a user is redirected to the portfolio homepage when organization_feature is on and
a portfolio belongs to the user, test for the special h1s which only exist in that version
of the homepage"""
self.app.set_user(self.user.username)
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home")).follow()
self._set_session_cookie()
# @less_console_noise_decorator
# def test_middleware_redirects_to_portfolio_homepage(self):
# """Tests that a user is redirected to the portfolio homepage when organization_feature is on and
# a portfolio belongs to the user, test for the special h1s which only exist in that version
# of the homepage"""
# self.app.set_user(self.user.username)
# with override_flag("organization_feature", active=True):
# # This will redirect the user to the portfolio page.
# # Follow implicity checks if our redirect is working.
# portfolio_page = self.app.get(reverse("home")).follow()
# self._set_session_cookie()
# Assert that we're on the right page
self.assertContains(portfolio_page, self.portfolio.organization_name)
# # Assert that we're on the right page
# self.assertContains(portfolio_page, self.portfolio.organization_name)
self.assertContains(portfolio_page, '<h1 id="domains-header">Domains</h1>')
# self.assertContains(portfolio_page, '<h1 id="domains-header">Domains</h1>')
@less_console_noise_decorator
def test_no_redirect_when_org_flag_false(self):

View file

@ -0,0 +1,203 @@
from unittest import skip
from unittest.mock import MagicMock, ANY, patch
from django.conf import settings
from django.urls import reverse
from django.contrib.auth import get_user_model
from api.tests.common import less_console_noise_decorator
from registrar.models.portfolio import Portfolio
from .common import MockEppLib, MockSESClient, create_user # type: ignore
from django_webtest import WebTest # type: ignore
import boto3_mocking # type: ignore
from registrar.utility.errors import (
NameserverError,
NameserverErrorCodes,
SecurityEmailError,
SecurityEmailErrorCodes,
GenericError,
GenericErrorCodes,
DsDataError,
DsDataErrorCodes,
)
from registrar.models import (
DomainRequest,
Domain,
DomainInformation,
DomainInvitation,
Contact,
PublicContact,
Host,
HostIP,
UserDomainRole,
User,
FederalAgency,
)
from datetime import date, datetime, timedelta
from django.utils import timezone
from .common import less_console_noise
from .test_views import TestWithUser
from waffle.testutils import override_flag
import logging
logger = logging.getLogger(__name__)
class TestPortfolioViews(TestWithUser, WebTest):
def setUp(self):
super().setUp()
self.domain, _ = Domain.objects.get_or_create(name="igorville.gov")
self.portfolio, _ = Portfolio.objects.get_or_create(creator=self.user, organization_name="Hotel California")
self.role, _ = UserDomainRole.objects.get_or_create(
user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER
)
@less_console_noise_decorator
def test_middleware_does_not_redirect_if_no_permission(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home"))
# Assert that we're on the right page
self.assertNotContains(portfolio_page, self.portfolio.organization_name)
@less_console_noise_decorator
def test_middleware_does_not_redirect_if_no_portfolio(self):
""" """
self.app.set_user(self.user.username)
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO]
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home"))
# Assert that we're on the right page
self.assertNotContains(portfolio_page, self.portfolio.organization_name)
@less_console_noise_decorator
def test_middleware_redirects_to_portfolio_organization_page(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO]
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home")).follow()
# Assert that we're on the right page
self.assertContains(portfolio_page, self.portfolio.organization_name)
self.assertContains(portfolio_page, '<h1>Organization</h1>')
@less_console_noise_decorator
def test_middleware_redirects_to_portfolio_domains_page(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO, User.UserPortfolioPermissionChoices.VIEW_DOMAINS]
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home")).follow()
# Assert that we're on the right page
self.assertContains(portfolio_page, self.portfolio.organization_name)
self.assertNotContains(portfolio_page, '<h1>Organization</h1>')
self.assertContains(portfolio_page, '<h1 id="domains-header">Domains</h1>')
@less_console_noise_decorator
def test_portfolio_domains_page_403_when_user_not_have_permission(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
response = self.app.get(reverse("portfolio-domains", kwargs={"portfolio_id": self.portfolio.pk}), status=403)
# Assert the response is a 403
# Assert the response is a 403 Forbidden
self.assertEqual(response.status_code, 403)
@less_console_noise_decorator
def test_portfolio_domain_requests_page_403_when_user_not_have_permission(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
response = self.app.get(reverse("portfolio-domain-requests", kwargs={"portfolio_id": self.portfolio.pk}), status=403)
# Assert the response is a 403
# Assert the response is a 403 Forbidden
self.assertEqual(response.status_code, 403)
@less_console_noise_decorator
def test_portfolio_organization_page_403_when_user_not_have_permission(self):
""""""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
response = self.app.get(reverse("portfolio-organization", kwargs={"portfolio_id": self.portfolio.pk}), status=403)
# Assert the response is a 403
# Assert the response is a 403 Forbidden
self.assertEqual(response.status_code, 403)
@less_console_noise_decorator
def test_navigation_links_hidden_when_user_not_have_permission(self):
"""This test is AMAZING"""
self.app.set_user(self.user.username)
self.user.portfolio=self.portfolio
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO, User.UserPortfolioPermissionChoices.VIEW_DOMAINS, User.UserPortfolioPermissionChoices.VIEW_REQUESTS]
self.user.save()
self.user.refresh_from_db()
with override_flag("organization_feature", active=True):
# This will redirect the user to the portfolio page.
# Follow implicity checks if our redirect is working.
portfolio_page = self.app.get(reverse("home")).follow()
# Assert that we're on the right page
self.assertContains(portfolio_page, self.portfolio.organization_name)
self.assertNotContains(portfolio_page, '<h1>Organization</h1>')
self.assertContains(portfolio_page, '<h1 id="domains-header">Domains</h1>')
self.assertContains(portfolio_page, reverse("portfolio-domains", kwargs={"portfolio_id": self.portfolio.pk}))
self.assertContains(portfolio_page, reverse("portfolio-domain-requests", kwargs={"portfolio_id": self.portfolio.pk}))
self.user.portfolio_additional_permissions = [User.UserPortfolioPermissionChoices.VIEW_PORTFOLIO]
self.user.save()
self.user.refresh_from_db()
portfolio_page = self.app.get(reverse("home")).follow()
self.assertContains(portfolio_page, self.portfolio.organization_name)
self.assertContains(portfolio_page, '<h1>Organization</h1>')
self.assertNotContains(portfolio_page, '<h1 id="domains-header">Domains</h1>')
self.assertNotContains(portfolio_page, reverse("portfolio-domains", kwargs={"portfolio_id": self.portfolio.pk}))
self.assertNotContains(portfolio_page, reverse("portfolio-domain-requests", kwargs={"portfolio_id": self.portfolio.pk}))
def tearDown(self):
Portfolio.objects.all().delete()
UserDomainRole.objects.all().delete()
DomainRequest.objects.all().delete()
DomainInformation.objects.all().delete()
Domain.objects.all().delete()
super().tearDown()