diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html
index 414b28a22..0b6f47481 100644
--- a/src/registrar/templates/domain_detail.html
+++ b/src/registrar/templates/domain_detail.html
@@ -64,11 +64,19 @@
diff --git a/src/registrar/templates/includes/domain_sidenav_item.html b/src/registrar/templates/includes/domain_sidenav_item.html
new file mode 100644
index 000000000..206e49c05
--- /dev/null
+++ b/src/registrar/templates/includes/domain_sidenav_item.html
@@ -0,0 +1,10 @@
+
+ {% if url_name %}
+ {% url url_name pk=domain.id as url %}
+ {% endif %}
+
+ {{ item_text }}
+
+
diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py
index 00fcc8fe0..31ca776e2 100644
--- a/src/registrar/tests/test_views_domain.py
+++ b/src/registrar/tests/test_views_domain.py
@@ -4,10 +4,9 @@
from django.conf import settings
from django.urls import reverse
from django.contrib.auth import get_user_model
-
+from waffle.testutils import override_flag
from api.tests.common import less_console_noise_decorator
-from registrar.models.portfolio import Portfolio
-from registrar.models.utility.portfolio_helper import UserPortfolioRoleChoices
+from registrar.models.utility.portfolio_helper import UserPortfolioPermissionChoices, UserPortfolioRoleChoices
from .common import MockEppLib, MockSESClient, create_user # type: ignore
from django_webtest import WebTest # type: ignore
import boto3_mocking # type: ignore
@@ -35,6 +34,8 @@
UserDomainRole,
User,
FederalAgency,
+ Portfolio,
+ Suborganization,
)
from datetime import date, datetime, timedelta
from django.utils import timezone
@@ -140,6 +141,7 @@ def tearDown(self):
Host.objects.all().delete()
Domain.objects.all().delete()
UserDomainRole.objects.all().delete()
+ Suborganization.objects.all().delete()
Portfolio.objects.all().delete()
except ValueError: # pass if already deleted
pass
@@ -1126,7 +1128,7 @@ class TestDomainSeniorOfficial(TestDomainOverview):
def test_domain_senior_official(self):
"""Can load domain's senior official page."""
page = self.client.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
- self.assertContains(page, "Senior official", count=13)
+ self.assertContains(page, "Senior official", count=14)
@less_console_noise_decorator
def test_domain_senior_official_content(self):
@@ -1346,7 +1348,7 @@ def test_domain_org_name_address(self):
"""Can load domain's org name and mailing address page."""
page = self.client.get(reverse("domain-org-name-address", kwargs={"pk": self.domain.id}))
# once on the sidebar, once in the page title, once as H1
- self.assertContains(page, "Organization name and mailing address", count=3)
+ self.assertContains(page, "Organization name and mailing address", count=4)
@less_console_noise_decorator
def test_domain_org_name_address_content(self):
@@ -1521,6 +1523,52 @@ def test_federal_agency_submit_blocked(self):
self.assertNotEqual(self.domain_information.federal_agency, new_value)
+class TestDomainSuborganization(TestDomainOverview):
+ """Tests the Suborganization page for portfolio users"""
+
+ @less_console_noise_decorator
+ @override_flag("organization_feature", active=True)
+ def test_has_suborganization_field_on_overview_with_flag(self):
+ """Ensures that the suborganization field is visible
+ and displays correctly on the domain overview page"""
+
+ # Create a portfolio
+ portfolio = Portfolio.objects.create(creator=self.user, organization_name="Ice Cream")
+ suborg = Suborganization.objects.create(portfolio=portfolio, name="Vanilla")
+
+ # Add the portfolio to the domain_information object
+ self.domain_information.portfolio = portfolio
+
+ # Add a organization_name to test if the old value still displays
+ self.domain_information.organization_name = "Broccoli"
+ self.domain_information.save()
+ self.domain_information.refresh_from_db()
+
+ # Add portfolio perms to the user object
+ self.user.portfolio = portfolio
+ self.user.portfolio_additional_permissions = [UserPortfolioPermissionChoices.VIEW_PORTFOLIO]
+ self.user.save()
+ self.user.refresh_from_db()
+
+ # Navigate to the domain overview page
+ page = self.app.get(reverse("domain", kwargs={"pk": self.domain.id}))
+
+ # Test for the title change
+ self.assertContains(page, "Suborganization")
+ self.assertNotContains(page, "Organization name")
+
+ # Test for the good value
+ self.assertContains(page, "Ice Cream")
+
+ # Test for the bad value
+ self.assertNotContains(page, "Broccoli")
+
+ # Cleanup
+ self.domain_information.delete()
+ suborg.delete()
+ portfolio.delete()
+
+
class TestDomainContactInformation(TestDomainOverview):
@less_console_noise_decorator
def test_domain_your_contact_information(self):
diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py
index da34ce646..8e17c7b59 100644
--- a/src/registrar/views/domain.py
+++ b/src/registrar/views/domain.py
@@ -23,8 +23,8 @@
DomainInvitation,
User,
UserDomainRole,
+ PublicContact,
)
-from registrar.models.public_contact import PublicContact
from registrar.utility.enums import DefaultEmail
from registrar.utility.errors import (
GenericError,
@@ -231,6 +231,16 @@ def form_valid(self, form):
# superclass has the redirect
return super().form_valid(form)
+ def has_permission(self):
+ """Override for the has_permission class to exclude portfolio users"""
+
+ # Org users shouldn't have access to this page
+ is_org_user = self.request.user.is_org_user(self.request)
+ if self.request.user.portfolio and is_org_user:
+ return False
+ else:
+ return super().has_permission()
+
class DomainSeniorOfficialView(DomainFormBaseView):
"""Domain senior official editing view."""
@@ -248,7 +258,6 @@ def get_form_kwargs(self, *args, **kwargs):
domain_info = self.get_domain_info_from_domain()
invalid_fields = [DomainRequest.OrganizationChoices.FEDERAL, DomainRequest.OrganizationChoices.TRIBAL]
is_federal_or_tribal = domain_info and (domain_info.generic_org_type in invalid_fields)
-
form_kwargs["disable_fields"] = is_federal_or_tribal
return form_kwargs
@@ -276,6 +285,16 @@ def form_valid(self, form):
# superclass has the redirect
return super().form_valid(form)
+ def has_permission(self):
+ """Override for the has_permission class to exclude portfolio users"""
+
+ # Org users shouldn't have access to this page
+ is_org_user = self.request.user.is_org_user(self.request)
+ if self.request.user.portfolio and is_org_user:
+ return False
+ else:
+ return super().has_permission()
+
class DomainDNSView(DomainBaseView):
"""DNS Information View."""