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 @@

DNS name servers

{% endif %} {% endif %} - {% url 'domain-org-name-address' pk=domain.id as url %} - {% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url editable=is_editable %} + {% if portfolio %} + {% comment %} TODO - uncomment in #2352 and add to edit_link + {% url 'domain-suborganization' pk=domain.id as url %} + {% endcomment %} + {% include "includes/summary_item.html" with title='Suborganization' value=domain.domain_info.sub_organization edit_link="#" editable=is_editable %} + {% else %} + {% url 'domain-org-name-address' pk=domain.id as url %} + {% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url editable=is_editable %} + + {% url 'domain-senior-official' pk=domain.id as url %} + {% include "includes/summary_item.html" with title='Senior official' value=domain.domain_info.senior_official contact='true' edit_link=url editable=is_editable %} + {% endif %} - {% url 'domain-senior-official' pk=domain.id as url %} - {% include "includes/summary_item.html" with title='Senior official' value=domain.domain_info.senior_official contact='true' edit_link=url editable=is_editable %} {# Conditionally display profile #} {% if not has_profile_feature_flag %} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 603822d0d..d1a4ef9e6 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -3,16 +3,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."""