mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-23 19:20:47 +02:00
3684: Organization overview page [ES] (#3788)
* Add organization overview page * Add tests * Change margin between overview headings
This commit is contained in:
parent
85171ee572
commit
9d6d51e771
17 changed files with 342 additions and 116 deletions
|
@ -27,6 +27,9 @@
|
|||
"http://localhost:8080/request/requesting_entity/",
|
||||
"http://localhost:8080/user-profile/",
|
||||
"http://localhost:8080/members/",
|
||||
"http://localhost:8080/members/new-member"
|
||||
"http://localhost:8080/members/new-member",
|
||||
"http://localhost:8080/organization",
|
||||
"http://localhost:8080/organization/organization-info",
|
||||
"http://localhost:8080/organization/senior-official"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -164,9 +164,14 @@ urlpatterns = [
|
|||
name="organization",
|
||||
),
|
||||
path(
|
||||
"senior-official/",
|
||||
"organization/organization-info",
|
||||
views.PortfolioOrganizationInfoView.as_view(),
|
||||
name="organization-info",
|
||||
),
|
||||
path(
|
||||
"organization/senior-official",
|
||||
views.PortfolioSeniorOfficialView.as_view(),
|
||||
name="senior-official",
|
||||
name="organization-senior-official",
|
||||
),
|
||||
path(
|
||||
"admin/analytics/export_data_type/",
|
||||
|
|
|
@ -63,7 +63,8 @@ URL_PERMISSIONS = {
|
|||
"domain-requests": [HAS_PORTFOLIO_DOMAIN_REQUESTS_ANY_PERM],
|
||||
"no-portfolio-requests": [IS_PORTFOLIO_MEMBER],
|
||||
"organization": [IS_PORTFOLIO_MEMBER],
|
||||
"senior-official": [IS_PORTFOLIO_MEMBER],
|
||||
"organization-info": [IS_PORTFOLIO_MEMBER],
|
||||
"organization-senior-official": [IS_PORTFOLIO_MEMBER],
|
||||
# Domain requests
|
||||
"domain-request-status": [HAS_PORTFOLIO_DOMAIN_REQUESTS_EDIT, IS_DOMAIN_REQUEST_CREATOR],
|
||||
"domain-request-status-viewonly": [HAS_PORTFOLIO_DOMAIN_REQUESTS_VIEW_ALL],
|
||||
|
|
|
@ -21,8 +21,7 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="tablet:grid-col">
|
||||
<main id="main-content" class="grid-container">
|
||||
<div class="tablet:grid-col" id="main-content">
|
||||
{% if not domain.domain_info %}
|
||||
<div class="usa-alert usa-alert--error margin-bottom-2">
|
||||
<div class="usa-alert__body">
|
||||
|
@ -63,7 +62,6 @@
|
|||
|
||||
{% endblock %} {# domain_content #}
|
||||
{% endif %}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
{% endblock breadcrumb %}
|
||||
|
||||
{{ block.super }}
|
||||
<div class="margin-top-4 tablet:grid-col-10">
|
||||
<h2 class="string-wrap">{{ domain.name }}</h2>
|
||||
<div class="margin-top-2 tablet:grid-col-10">
|
||||
<h2 class="string-wrap margin-top-2">{{ domain.name }}</h2>
|
||||
<div
|
||||
class="usa-summary-box padding-y-2 margin-bottom-1"
|
||||
role="region"
|
||||
|
@ -108,7 +108,7 @@
|
|||
{% else %}
|
||||
{% include "includes/summary_item.html" with title='DNSSEC' value='Not enabled' edit_link=url editable=is_editable %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if portfolio %}
|
||||
{% if has_any_domains_portfolio_permission and has_edit_portfolio_permission %}
|
||||
{% url 'domain-suborganization' domain_pk=domain.id as url %}
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
<div class="tablet:grid-col-3 grid-col--sidenav">
|
||||
{% include 'domain_request_sidebar.html' %}
|
||||
</div>
|
||||
<div class="tablet:grid-col">
|
||||
<main id="main-content" class="grid-container register-form-step">
|
||||
<div class="tablet:grid-col register-form-step" id="main-content">
|
||||
<input type="hidden" class="display-none" id="wizard-domain-request-id" value="{{domain_request_id}}"/>
|
||||
{% if steps.current == steps.first %}
|
||||
{% if portfolio %}
|
||||
|
@ -142,8 +141,6 @@
|
|||
</form>
|
||||
|
||||
{% block after_form_content %}{% endblock %}
|
||||
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
{{ contact.get_formatted_name }}<br />
|
||||
{% if contact.title %}{{ contact.title }}<br />{% endif %}
|
||||
{% if contact.email %}{{ contact.email }}<br />{% endif %}
|
||||
{% if contact.phone %}{{ contact.phone.as_national }}{% endif %}
|
||||
{% if not portfolio and contact.phone %}{{ contact.phone.as_national }}{% endif %}
|
||||
</address>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<address>
|
||||
{% if organization.federal_agency %}
|
||||
{{ organization.federal_agency }}<br />
|
||||
{% if not portfolio and organization.federal_agency %}
|
||||
{{ organization.federal_agency }}<br />
|
||||
{% endif %}
|
||||
{% if organization.organization_name %}
|
||||
{{ organization.organization_name }}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
{% load static url_helpers %}
|
||||
|
||||
<section class="summary-item margin-top-3">
|
||||
{% if portfolio_first_section %} <section class="summary-item margin-top-2">
|
||||
{% else %} <section class="summary-item margin-top-3">
|
||||
{% endif %}
|
||||
<hr class="" aria-hidden="true" />
|
||||
<div class="display-flex flex-justify">
|
||||
<div>
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
<main class="grid-container grid-container--widescreen">
|
||||
{% if user.is_authenticated %}
|
||||
{# the entire logged in page goes here #}
|
||||
|
||||
{# portfolio organization page layout #}
|
||||
{% block portfolio_organization_content %}{% endblock %}
|
||||
|
||||
<div class="grid-row {% if not is_widescreen_centered %}max-width--grid-container{% endif %}">
|
||||
<div class="desktop:grid-col-10{% if not is_widescreen_centered %} tablet:grid-col-11{% else %} tablet:grid-col-12 desktop:grid-offset-1{% endif %}">
|
||||
|
||||
{% block portfolio_content %}{% endblock %}
|
||||
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
{% extends 'portfolio_base.html' %}
|
||||
{% load static field_helpers%}
|
||||
|
||||
{% block title %}Organization name and mailing address | {{ portfolio.name }}{% endblock %}
|
||||
{% block title %}Organization overview | {{ portfolio }}{% endblock %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% block portfolio_content %}
|
||||
<div class="grid-row grid-gap">
|
||||
<div class="tablet:grid-col-3">
|
||||
{% block portfolio_organization_content %}
|
||||
<div class="grid-row grid-gap max-width--grid-container">
|
||||
<div class="tablet:grid-col-3 grid-col--sidenav">
|
||||
<p class="font-body-md margin-top-0 margin-bottom-2
|
||||
text-primary-darker text-semibold"
|
||||
>
|
||||
|
@ -17,63 +15,18 @@
|
|||
{% include 'portfolio_organization_sidebar.html' %}
|
||||
</div>
|
||||
|
||||
<div class="tablet:grid-col-9" id="main-content">
|
||||
<!-- Form messages -->
|
||||
{% include "includes/form_errors.html" with form=form %}
|
||||
{% block messages %}
|
||||
{% include "includes/form_messages.html" %}
|
||||
{% endblock messages%}
|
||||
|
||||
<h1>Organization</h1>
|
||||
|
||||
<p>The name of your organization will be publicly listed as the domain registrant.</p>
|
||||
|
||||
{% if has_edit_portfolio_permission %}
|
||||
<p>
|
||||
Your organization name can’t be updated here.
|
||||
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
|
||||
</p>
|
||||
|
||||
{% include "includes/required_fields.html" %}
|
||||
<form class="usa-form usa-form--large desktop:margin-top-4" method="post" novalidate>
|
||||
{% csrf_token %}
|
||||
<h4 class="margin-bottom-05">Organization name</h4>
|
||||
<p class="margin-top-0">
|
||||
{{ portfolio.federal_agency }}
|
||||
</p>
|
||||
{% input_with_errors form.address_line1 %}
|
||||
{% input_with_errors form.address_line2 %}
|
||||
{% input_with_errors form.city %}
|
||||
{% input_with_errors form.state_territory %}
|
||||
{% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
|
||||
{% input_with_errors form.zipcode %}
|
||||
{% endwith %}
|
||||
<button type="submit" class="usa-button">
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<h4 class="margin-bottom-05">Organization name</h4>
|
||||
<p class="margin-top-0">
|
||||
{{ portfolio.federal_agency }}
|
||||
</p>
|
||||
{% if form.address_line1.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.address_line1 %}
|
||||
{% endif %}
|
||||
{% if form.address_line2.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.address_line2 %}
|
||||
{% endif %}
|
||||
{% if form.city.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.city %}
|
||||
{% endif %}
|
||||
{% if form.state_territory.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.state_territory %}
|
||||
{% endif %}
|
||||
{% if form.zipcode.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.zipcode %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="tablet:grid-col" id="main-content">
|
||||
<h1>Organization overview</h1>
|
||||
<div class="margin-top-2 tablet:grid-col-10">
|
||||
<h2 class="string-wrap margin-top-2">{{ portfolio }}</h2>
|
||||
{% url 'organization-info' as url %}
|
||||
{% include "includes/summary_item.html" with title='Organization' value=portfolio address='true' edit_link=url editable=has_edit_portfolio_permission view_button='true' portfolio_first_section='true'%}
|
||||
|
||||
{% url 'organization-senior-official' as url %}
|
||||
{% include "includes/summary_item.html" with title='Senior official' value=portfolio.senior_official contact='true' edit_link=url view_button='true' %}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
92
src/registrar/templates/portfolio_organization_info.html
Normal file
92
src/registrar/templates/portfolio_organization_info.html
Normal file
|
@ -0,0 +1,92 @@
|
|||
{% extends 'portfolio_base.html' %}
|
||||
{% load static field_helpers%}
|
||||
|
||||
{% block title %}Organization name and mailing address | {{ portfolio }}{% endblock %}
|
||||
|
||||
{% load static %}
|
||||
|
||||
{% block portfolio_organization_content %}
|
||||
<div class="grid-row grid-gap max-width--grid-container">
|
||||
<div class="tablet:grid-col-3 grid-col--sidenav">
|
||||
<p class="font-body-md margin-top-0 margin-bottom-2
|
||||
text-primary-darker text-semibold"
|
||||
>
|
||||
<span class="usa-sr-only"> Portfolio name:</span> {{ portfolio }}
|
||||
</p>
|
||||
|
||||
{% include 'portfolio_organization_sidebar.html' %}
|
||||
</div>
|
||||
|
||||
<div class="tablet:grid-col" id="main-content">
|
||||
{% block breadcrumb %}
|
||||
<!-- Navigation breadcrumbs -->
|
||||
<nav class="usa-breadcrumb padding-top-0" aria-label="Portfolio organization breadcrumb">
|
||||
<ol class="usa-breadcrumb__list">
|
||||
<li class="usa-breadcrumb__list-item">
|
||||
<a href="{% url 'organization' %}" class="usa-breadcrumb__link"><span>{{ portfolio }}</span></a>
|
||||
</li>
|
||||
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
|
||||
<span>Organization</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
{% endblock breadcrumb %}
|
||||
<!-- Form messages -->
|
||||
{% include "includes/form_errors.html" with form=form %}
|
||||
{% block messages %}
|
||||
{% include "includes/form_messages.html" %}
|
||||
{% endblock messages%}
|
||||
|
||||
<h1>Organization</h1>
|
||||
<div class="margin-top-2 tablet:grid-col-10">
|
||||
<p>The name of your organization will be publicly listed as the domain registrant.</p>
|
||||
|
||||
{% if has_edit_portfolio_permission %}
|
||||
<p>
|
||||
Your organization name can’t be updated here.
|
||||
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
|
||||
</p>
|
||||
|
||||
{% include "includes/required_fields.html" %}
|
||||
<form class="usa-form usa-form--large desktop:margin-top-4" method="post" novalidate>
|
||||
{% csrf_token %}
|
||||
<h4 class="margin-bottom-05">Organization name</h4>
|
||||
<p class="margin-top-0">
|
||||
{{ portfolio.federal_agency }}
|
||||
</p>
|
||||
{% input_with_errors form.address_line1 %}
|
||||
{% input_with_errors form.address_line2 %}
|
||||
{% input_with_errors form.city %}
|
||||
{% input_with_errors form.state_territory %}
|
||||
{% with add_class="usa-input--small" sublabel_text="Enter a 5-digit or 9-digit zip code, like 12345 or 12345-6789." %}
|
||||
{% input_with_errors form.zipcode %}
|
||||
{% endwith %}
|
||||
<button type="submit" class="usa-button">
|
||||
Save
|
||||
</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<h4 class="margin-bottom-05">Organization name</h4>
|
||||
<p class="margin-top-0">
|
||||
{{ portfolio.federal_agency }}
|
||||
</p>
|
||||
{% if form.address_line1.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.address_line1 %}
|
||||
{% endif %}
|
||||
{% if form.address_line2.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.address_line2 %}
|
||||
{% endif %}
|
||||
{% if form.city.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.city %}
|
||||
{% endif %}
|
||||
{% if form.state_territory.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.state_territory %}
|
||||
{% endif %}
|
||||
{% if form.zipcode.value is not None %}
|
||||
{% include "includes/input_read_only.html" with field=form.zipcode %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -5,6 +5,15 @@
|
|||
<ul class="usa-sidenav">
|
||||
<li class="usa-sidenav__item">
|
||||
{% url 'organization' as url %}
|
||||
<a href="{{ url }}"
|
||||
{% if request.path == url %}class="usa-current"{% endif %}
|
||||
>
|
||||
Organization overview
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li class="usa-sidenav__item">
|
||||
{% url 'organization-info' as url %}
|
||||
<a href="{{ url }}"
|
||||
{% if request.path == url %}class="usa-current"{% endif %}
|
||||
>
|
||||
|
@ -13,7 +22,7 @@
|
|||
</li>
|
||||
|
||||
<li class="usa-sidenav__item">
|
||||
{% url 'senior-official' as url %}
|
||||
{% url 'organization-senior-official' as url %}
|
||||
<a href="{{ url }}"
|
||||
{% if request.path == url %}class="usa-current"{% endif %}
|
||||
>
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
{% load static %}
|
||||
|
||||
{% block portfolio_content %}
|
||||
{% block portfolio_organization_content %}
|
||||
|
||||
<div class="grid-row grid-gap">
|
||||
<div class="tablet:grid-col-3">
|
||||
<div class="grid-row grid-gap max-width--grid-container">
|
||||
<div class="tablet:grid-col-3 grid-col--sidenav">
|
||||
<p class="font-body-md margin-top-0 margin-bottom-2
|
||||
text-primary-darker text-semibold"
|
||||
>
|
||||
|
@ -19,6 +19,20 @@
|
|||
</div>
|
||||
|
||||
<div class="tablet:grid-col-9" id="main-content">
|
||||
{% block breadcrumb %}
|
||||
<!-- Navigation breadcrumbs -->
|
||||
<nav class="usa-breadcrumb padding-top-0" aria-label="Portfolio organization breadcrumb">
|
||||
<ol class="usa-breadcrumb__list">
|
||||
<li class="usa-breadcrumb__list-item">
|
||||
<a href="{% url 'organization' %}" class="usa-breadcrumb__link"><span>{{ portfolio }}</span></a>
|
||||
</li>
|
||||
<li class="usa-breadcrumb__list-item usa-current" aria-current="page">
|
||||
<span>Senior official</span>
|
||||
</li>
|
||||
</ol>
|
||||
</nav>
|
||||
{% endblock breadcrumb %}
|
||||
|
||||
{% include "includes/senior_official.html" with can_edit=False %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -241,7 +241,8 @@ def is_portfolio_subpage(path):
|
|||
# Since our pages aren't unified under a common path, we need this approach for now.
|
||||
url_names = [
|
||||
"organization",
|
||||
"senior-official",
|
||||
"organization-info",
|
||||
"organization-senior-official",
|
||||
]
|
||||
return get_url_name(path) in url_names
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ class TestPortfolio(WebTest):
|
|||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO],
|
||||
)
|
||||
|
||||
so_portfolio_page = self.app.get(reverse("senior-official"))
|
||||
so_portfolio_page = self.app.get(reverse("organization-senior-official"))
|
||||
# Assert that we're on the right page
|
||||
self.assertContains(so_portfolio_page, "Senior official")
|
||||
self.assertContains(so_portfolio_page, "Saturn Enceladus")
|
||||
|
@ -196,29 +196,119 @@ class TestPortfolio(WebTest):
|
|||
self.assertEqual(response.status_code, 403)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_page_read_only(self):
|
||||
"""Test that user with a portfolio can access the portfolio organization page, read only"""
|
||||
def test_portfolio_organization_page_includes_org_info_and_senior_official(self):
|
||||
"""Test that portfolio user on the organization overview page includes sections on the organization's
|
||||
info and senior official"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
],
|
||||
)
|
||||
so = SeniorOfficial.objects.create(
|
||||
first_name="Saturn", last_name="Enceladus", title="Planet/Moon", email="spacedivision@igorville.com"
|
||||
)
|
||||
|
||||
self.portfolio.senior_official = so
|
||||
self.portfolio.organization_name = "Hotel California"
|
||||
self.portfolio.city = "Los Angeles"
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
# User can access organization info form via organization overview page
|
||||
response = self.app.get(reverse("organization"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# Organization overview page includes organization name
|
||||
self.assertContains(response, "<h1>Organization overview</h1>")
|
||||
self.assertContains(response, "Hotel California</h2>")
|
||||
# Organization overview page includes organization info and senior official details
|
||||
self.assertContains(response, "Los Angeles")
|
||||
self.assertContains(response, "spacedivision@igorville.com")
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_page_directs_to_org_detail_forms(self):
|
||||
"""Test that portfolio user on the organization overview page can click on the overview
|
||||
sections to their respective forms"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
],
|
||||
)
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
# User can access organization info form via organization overview page
|
||||
response = self.app.get(reverse("organization"))
|
||||
# The overview page includes button to edit organization
|
||||
org_info_url = reverse("organization-info")
|
||||
org_senior_official_url = reverse("organization-senior-official")
|
||||
self.assertContains(response, f'href="{org_info_url}"')
|
||||
self.assertContains(response, f'href="{org_senior_official_url}"')
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_page_section_viewonly_icon(self):
|
||||
"""Test organization page setion displays viewonly icon for portfolio nonadmin member"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO],
|
||||
)
|
||||
self.portfolio.city = "Los Angeles"
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
response = self.app.get(reverse("organization"))
|
||||
# Assert the response is a 200
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# The label for Federal agency will always be a h4
|
||||
self.assertContains(response, '<h4 class="margin-bottom-05">Organization name</h4>')
|
||||
# The read only label for city will be a h4
|
||||
self.assertContains(response, '<h4 class="margin-bottom-05">City</h4>')
|
||||
self.assertNotContains(response, 'for="id_city"')
|
||||
self.assertContains(response, '<p class="margin-top-0">Los Angeles</p>')
|
||||
# User can access view-only form via organization overview page
|
||||
org_overview_response = self.app.get(reverse("organization"))
|
||||
# Viewonly icons for org info and senior official (which is always viewonly)
|
||||
# visibility is html id of view only icon
|
||||
self.assertContains(org_overview_response, "visibility", count=2)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_page_edit_access(self):
|
||||
def test_portfolio_organization_page_section_edit_icon(self):
|
||||
"""Test organization page setion displays viewonly icon for portfolio nonadmin member"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[UserPortfolioPermissionChoices.VIEW_PORTFOLIO],
|
||||
)
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
# User can access view-only form via organization overview page
|
||||
org_overview_response = self.app.get(reverse("organization"))
|
||||
# Viewonly icons for org info and senior official (which is always viewonly)
|
||||
# visibility is html id of view only icon
|
||||
self.assertContains(org_overview_response, "visibility", count=2)
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_info_page_read_only(self):
|
||||
"""Test that user with a portfolio can access the portfolio organization page, read only"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
],
|
||||
)
|
||||
self.portfolio.save()
|
||||
with override_flag("organization_feature", active=True):
|
||||
# User can access view-only form via organization overview page
|
||||
org_overview_response = self.app.get(reverse("organization"))
|
||||
# Edit icons for org info (senior official is always viewonly)
|
||||
self.assertContains(org_overview_response, "Edit")
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_info_page_edit_access(self):
|
||||
"""Test that user with a portfolio can access the portfolio organization page, read only"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
|
@ -231,8 +321,10 @@ class TestPortfolio(WebTest):
|
|||
)
|
||||
self.portfolio.city = "Los Angeles"
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
response = self.app.get(reverse("organization"))
|
||||
# User can access editable form via organization info page
|
||||
response = self.app.get(reverse("organization-info"))
|
||||
# Assert the response is a 200
|
||||
self.assertEqual(response.status_code, 200)
|
||||
# The label for Federal agency will always be a h4
|
||||
|
@ -242,6 +334,33 @@ class TestPortfolio(WebTest):
|
|||
self.assertNotContains(response, '<p class="margin-top-0">Los Angeles</p>')
|
||||
self.assertContains(response, 'for="id_city"')
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_portfolio_organization_detail_pages_include_breadcrumb(self):
|
||||
"""Test that breadcrumb menus display on portfolio detail pages"""
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user,
|
||||
portfolio=self.portfolio,
|
||||
additional_permissions=[
|
||||
UserPortfolioPermissionChoices.VIEW_PORTFOLIO,
|
||||
UserPortfolioPermissionChoices.EDIT_PORTFOLIO,
|
||||
],
|
||||
)
|
||||
self.portfolio.organization_name = "Hotel California"
|
||||
self.portfolio.save()
|
||||
|
||||
with override_flag("organization_feature", active=True):
|
||||
# Breadcrumb appears on organization info page
|
||||
org_info_response = self.app.get(reverse("organization-info"))
|
||||
self._assert_has_organization_breadcrumb(org_info_response)
|
||||
so_response = self.app.get(reverse("organization-senior-official"))
|
||||
self._assert_has_organization_breadcrumb(so_response)
|
||||
|
||||
def _assert_has_organization_breadcrumb(self, response):
|
||||
self.assertContains(response, '<ol class="usa-breadcrumb__list">')
|
||||
self.assertContains(response, "Hotel California")
|
||||
self.assertContains(response, 'href="/organization/"')
|
||||
|
||||
@less_console_noise_decorator
|
||||
@override_flag("organization_requests", active=True)
|
||||
def test_accessible_pages_when_user_does_not_have_permission(self):
|
||||
|
@ -285,7 +404,7 @@ class TestPortfolio(WebTest):
|
|||
# The organization page should still be accessible
|
||||
org_page = self.app.get(reverse("organization"))
|
||||
self.assertContains(org_page, self.portfolio.organization_name)
|
||||
self.assertContains(org_page, "<h1>Organization</h1>")
|
||||
self.assertContains(org_page, "<h1>Organization overview</h1>")
|
||||
|
||||
# Both domain pages should not be accessible
|
||||
domain_page = self.app.get(reverse("domains"), expect_errors=True)
|
||||
|
@ -332,7 +451,7 @@ class TestPortfolio(WebTest):
|
|||
# The organization page should still be accessible
|
||||
org_page = self.app.get(reverse("organization"))
|
||||
self.assertContains(org_page, self.portfolio.organization_name)
|
||||
self.assertContains(org_page, "<h1>Organization</h1>")
|
||||
self.assertContains(org_page, "<h1>Organization overview</h1>")
|
||||
|
||||
# Both domain pages should not be accessible
|
||||
domain_page = self.app.get(reverse("domains"), expect_errors=True)
|
||||
|
@ -352,12 +471,12 @@ class TestPortfolio(WebTest):
|
|||
portfolio_permission, _ = UserPortfolioPermission.objects.get_or_create(
|
||||
user=self.user, portfolio=self.portfolio, additional_permissions=portfolio_additional_permissions
|
||||
)
|
||||
page = self.app.get(reverse("organization"))
|
||||
page = self.app.get(reverse("organization-info"))
|
||||
self.assertContains(page, "The name of your organization will be publicly listed as the domain registrant.")
|
||||
|
||||
@less_console_noise_decorator
|
||||
def test_domain_org_name_address_content(self):
|
||||
"""Org name and address information appears on the page."""
|
||||
def test_portfolio_org_info_includes_name_and_address(self):
|
||||
"""Org name and address appears on the org info page."""
|
||||
with override_flag("organization_feature", active=True):
|
||||
self.app.set_user(self.user.username)
|
||||
portfolio_additional_permissions = [
|
||||
|
@ -370,9 +489,9 @@ class TestPortfolio(WebTest):
|
|||
|
||||
self.portfolio.organization_name = "Hotel California"
|
||||
self.portfolio.save()
|
||||
page = self.app.get(reverse("organization"))
|
||||
# Once in the sidenav, once in the main nav
|
||||
self.assertContains(page, "Hotel California", count=2)
|
||||
page = self.app.get(reverse("organization-info"))
|
||||
# Org name in Sidenav, main nav, webpage title, and breadcrumb
|
||||
self.assertContains(page, "Hotel California", count=4)
|
||||
self.assertContains(page, "Non-Federal Agency")
|
||||
|
||||
@less_console_noise_decorator
|
||||
|
@ -390,7 +509,7 @@ class TestPortfolio(WebTest):
|
|||
|
||||
self.portfolio.address_line1 = "1600 Penn Ave"
|
||||
self.portfolio.save()
|
||||
portfolio_org_name_page = self.app.get(reverse("organization"))
|
||||
portfolio_org_name_page = self.app.get(reverse("organization-info"))
|
||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||
|
||||
portfolio_org_name_page.form["address_line1"] = "6 Downing st"
|
||||
|
@ -419,7 +538,7 @@ class TestPortfolio(WebTest):
|
|||
|
||||
self.portfolio.address_line1 = "1600 Penn Ave"
|
||||
self.portfolio.save()
|
||||
portfolio_org_name_page = self.app.get(reverse("organization"))
|
||||
portfolio_org_name_page = self.app.get(reverse("organization-info"))
|
||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||
|
||||
# Form validates and redirects with all required fields
|
||||
|
@ -458,7 +577,7 @@ class TestPortfolio(WebTest):
|
|||
|
||||
self.portfolio.address_line1 = "1600 Penn Ave"
|
||||
self.portfolio.save()
|
||||
portfolio_org_name_page = self.app.get(reverse("organization"))
|
||||
portfolio_org_name_page = self.app.get(reverse("organization-info"))
|
||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||
portfolio_org_name_page.form["address_line1"] = "6 Downing st"
|
||||
portfolio_org_name_page.form["city"] = "London"
|
||||
|
|
|
@ -890,13 +890,43 @@ class PortfolioNoDomainRequestsView(View):
|
|||
|
||||
|
||||
@grant_access(IS_PORTFOLIO_MEMBER)
|
||||
class PortfolioOrganizationView(DetailView, FormMixin):
|
||||
class PortfolioOrganizationView(DetailView):
|
||||
"""
|
||||
View to handle displaying and updating overview of portfolio's information.
|
||||
"""
|
||||
|
||||
model = Portfolio
|
||||
template_name = "portfolio_organization.html"
|
||||
context_object_name = "portfolio"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
"""Add additional context data to the template."""
|
||||
context = super().get_context_data(**kwargs)
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
context["has_edit_portfolio_permission"] = self.request.user.has_edit_portfolio_permission(portfolio)
|
||||
return context
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
"""Get the portfolio object based on the session."""
|
||||
portfolio = self.request.session.get("portfolio")
|
||||
if portfolio is None:
|
||||
raise Http404("No organization found for this user")
|
||||
return portfolio
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
context = self.get_context_data(object=self.object)
|
||||
return self.render_to_response(context)
|
||||
|
||||
|
||||
@grant_access(IS_PORTFOLIO_MEMBER)
|
||||
class PortfolioOrganizationInfoView(DetailView, FormMixin):
|
||||
"""
|
||||
View to handle displaying and updating the portfolio's organization details.
|
||||
"""
|
||||
|
||||
model = Portfolio
|
||||
template_name = "portfolio_organization.html"
|
||||
template_name = "portfolio_organization_info.html"
|
||||
form_class = portfolioForms.PortfolioOrgAddressForm
|
||||
context_object_name = "portfolio"
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue