From d84a7890224ca1ec52c2e5097e8c0c1104589cdd Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Thu, 26 Dec 2024 17:10:37 -0800 Subject: [PATCH 01/41] Renewal form --- src/registrar/config/urls.py | 5 ++ src/registrar/fixtures/fixtures_domains.py | 2 +- src/registrar/models/domain.py | 5 ++ src/registrar/templates/domain_base.html | 9 +- src/registrar/templates/domain_detail.html | 4 +- src/registrar/templates/domain_sidebar.html | 10 ++- src/registrar/templatetags/custom_filters.py | 1 + src/registrar/views/__init__.py | 1 + src/registrar/views/domain.py | 92 ++++++++++++++++++-- 9 files changed, 117 insertions(+), 12 deletions(-) diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 66708c571..2bf7b9e5f 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -345,6 +345,11 @@ views.DomainSecurityEmailView.as_view(), name="domain-security-email", ), + path( + "domain//renewal", + views.DomainRenewalView.as_view(), + name="domain-renewal", + ), path( "domain//users/add", views.DomainAddUserView.as_view(), diff --git a/src/registrar/fixtures/fixtures_domains.py b/src/registrar/fixtures/fixtures_domains.py index 4606024d0..4d4115180 100644 --- a/src/registrar/fixtures/fixtures_domains.py +++ b/src/registrar/fixtures/fixtures_domains.py @@ -44,7 +44,7 @@ def load(cls): cls._approve_domain_requests(users) @staticmethod - def _generate_fake_expiration_date(days_in_future=365): + def _generate_fake_expiration_date(days_in_future=40): """Generates a fake expiration date between 1 and 365 days in the future.""" current_date = timezone.now().date() # nosec return current_date + timedelta(days=random.randint(1, days_in_future)) # nosec diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 6eb2fac07..3fa6a61b2 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1167,6 +1167,11 @@ def is_expiring(self): threshold_date = now + timedelta(days=60) return now < self.expiration_date <= threshold_date + ###dummy method for testing for domain renewal form fail or success banner + + def update_expiration(self, success=True): + return success + def state_display(self, request=None): """Return the display status of the domain.""" if self.is_expired() and (self.state != self.State.UNKNOWN): diff --git a/src/registrar/templates/domain_base.html b/src/registrar/templates/domain_base.html index 9f7e8d2e6..de8e88791 100644 --- a/src/registrar/templates/domain_base.html +++ b/src/registrar/templates/domain_base.html @@ -1,5 +1,7 @@ {% extends "base.html" %} {% load static %} +{% load static url_helpers %} + {% block title %}{{ domain.name }} | {% endblock %} @@ -53,8 +55,11 @@

Attention!

{% endif %} {% block domain_content %} - + {% if request.path|endswith:"renewal"%} +

Renew {{domain.name}}

+ {%else%}

Domain Overview

+ {% endif%} {% endblock %} {# domain_content #} {% endif %} @@ -62,4 +67,4 @@

Domain Overview

-{% endblock %} {# content #} +{% endblock %} {# content #} \ No newline at end of file diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index a5b8e52cb..b168f7e82 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -50,7 +50,9 @@

{{ domain.name }}

{% if domain.get_state_help_text %}
{% if has_domain_renewal_flag and domain.is_expiring and is_domain_manager %} - This domain will expire soon. Renew to maintain access. + This domain will expire soon. + {% url 'domain-renewal' pk=domain.id as url %} + Renew to maintain access. {% elif has_domain_renewal_flag and domain.is_expiring and is_portfolio_user %} This domain will expire soon. Contact one of the listed domain managers to renew the domain. {% else %} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 289f544ce..dc97f5ca1 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -79,8 +79,14 @@ {% with url_name="domain-users" %} {% include "includes/domain_sidenav_item.html" with item_text="Domain managers" %} {% endwith %} - + + {% if has_domain_renewal_flag and is_domain_manager and domain.is_expiring %} + {% with url_name="domain-renewal" %} + {% include "includes/domain_sidenav_item.html" with item_text="Renewal form" %} + {% endwith %} + {% endif %} + {% endif %} -
+ \ No newline at end of file diff --git a/src/registrar/templatetags/custom_filters.py b/src/registrar/templatetags/custom_filters.py index 6140130c8..6f3894ea5 100644 --- a/src/registrar/templatetags/custom_filters.py +++ b/src/registrar/templatetags/custom_filters.py @@ -200,6 +200,7 @@ def is_domain_subpage(path): "domain-users-add", "domain-request-delete", "domain-user-delete", + "domain-renewal", "invitation-cancel", ] return get_url_name(path) in url_names diff --git a/src/registrar/views/__init__.py b/src/registrar/views/__init__.py index a80b16b1a..4e3faced1 100644 --- a/src/registrar/views/__init__.py +++ b/src/registrar/views/__init__.py @@ -14,6 +14,7 @@ DomainInvitationCancelView, DomainDeleteUserView, PrototypeDomainDNSRecordView, + DomainRenewalView, ) from .user_profile import UserProfileView, FinishProfileSetupView from .health import * diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index cb3da1f83..99a173517 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -12,7 +12,7 @@ from django.contrib.messages.views import SuccessMessageMixin from django.db import IntegrityError from django.http import HttpResponseRedirect -from django.shortcuts import redirect +from django.shortcuts import redirect, render from django.urls import reverse from django.views.generic.edit import FormMixin from django.conf import settings @@ -307,6 +307,90 @@ def _get_domain(self, request): self._update_session_with_domain() +class DomainRenewalView(DomainBaseView): + """Domain detail overview page.""" + + template_name = "domain_renewal.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + default_emails = [DefaultEmail.PUBLIC_CONTACT_DEFAULT.value, DefaultEmail.LEGACY_DEFAULT.value] + context["hidden_security_emails"] = default_emails + + security_email = self.object.get_security_email() + user = self.request.user + if security_email is None or security_email in default_emails: + context["security_email"] = None + context["user"] = user + return context + + def can_access_domain_via_portfolio(self, pk): + """Most views should not allow permission to portfolio users. + If particular views allow permissions, they will need to override + this function.""" + portfolio = self.request.session.get("portfolio") + if self.request.user.has_any_domains_portfolio_permission(portfolio): + if Domain.objects.filter(id=pk).exists(): + domain = Domain.objects.get(id=pk) + if domain.domain_info.portfolio == portfolio: + return True + return False + + def in_editable_state(self, pk): + """Override in_editable_state from DomainPermission + Allow detail page to be viewable""" + + requested_domain = None + if Domain.objects.filter(id=pk).exists(): + requested_domain = Domain.objects.get(id=pk) + + # return true if the domain exists, this will allow the detail page to load + if requested_domain: + return True + return False + + def _get_domain(self, request): + """ + override get_domain for this view so that domain overview + always resets the cache for the domain object + """ + self.session = request.session + self.object = self.get_object() + self._update_session_with_domain() + + def post(self, request, pk): + domain = Domain.objects.filter(id=pk).first() + + # Check if the checkbox is checked + is_policy_acknowledged = request.POST.get("is_policy_acknowledged", None) + if is_policy_acknowledged != "on": + print("!!! Checkbox is NOT acknowledged") + messages.error( + request, "Check the box if you read and agree to the requirements for operating a .gov domain." + ) + return render( + request, + "domain_renewal.html", + { + "domain": domain, + "form": request.POST, + }, + ) + + print("*** Checkbox is acknowledged") + if "submit_button" in request.POST: + print("*** Submit button clicked") + updated_expiration = domain.update_expiration(success=True) + print("*** Updated expiration result:", updated_expiration) + + if updated_expiration is True: + messages.success(request, "This domain has been renewed for one year") + else: + messages.error(request, "This domain has not been renewed") + return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) + + class DomainOrgNameAddressView(DomainFormBaseView): """Organization view""" @@ -807,11 +891,7 @@ def get_context_data(self, **kwargs): has_dnssec_records = self.object.dnssecdata is not None # Create HTML for the modal button - modal_button = ( - '' - ) + modal_button = '' context["modal_button"] = modal_button context["has_dnssec_records"] = has_dnssec_records From b5658a357b6aa9b49c7c37393ae1f8893dbebbeb Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Thu, 26 Dec 2024 17:15:07 -0800 Subject: [PATCH 02/41] Fix linter --- src/registrar/models/domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 3fa6a61b2..715f1b9da 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1167,7 +1167,7 @@ def is_expiring(self): threshold_date = now + timedelta(days=60) return now < self.expiration_date <= threshold_date - ###dummy method for testing for domain renewal form fail or success banner + # Dummy method for testing for domain renewal form fail or success banner def update_expiration(self, success=True): return success From 8b9eb93b682a3f8b714c42558b90db6b94bc7c57 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Mon, 30 Dec 2024 11:07:33 -0500 Subject: [PATCH 03/41] added back domain renewal form --- src/registrar/templates/domain_renewal.html | 127 ++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/registrar/templates/domain_renewal.html diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html new file mode 100644 index 000000000..c179941d6 --- /dev/null +++ b/src/registrar/templates/domain_renewal.html @@ -0,0 +1,127 @@ +{% extends "domain_base.html" %} +{% load static url_helpers %} +{% load custom_filters %} + +{% block domain_content %} + {% block breadcrumb %} + {% if portfolio %} + + + {% endif %} + {% endblock breadcrumb %} + + {{ block.super }} +
+

Confirm the following information for accuracy

+

Review these details below. We + require that you maintain accurate information for the domain. + The details you provide will only be used to support eh administration of .gov and won't be made public. +

+

If you would like to retire your domain instead, please + contact us.

+

Required fields are marked with an asterisk (*). +

+
+ + {% url 'user-profile' as url %} + {% include "includes/summary_item.html" with title='Your Contact Information' value=user edit_link=url editable=is_editable contact='true' %} + + + + {% if analyst_action != 'edit' or analyst_action_location != domain.pk %} + {% if is_portfolio_user and not is_domain_manager %} +
+
+

+ You don't have access to manage {{domain.name}}. If you need to make updates, contact one of the listed domain managers. +

+
+
+ {% endif %} + {% endif %} + + {% url 'domain-security-email' pk=domain.id as url %} + {% if security_email is not None and security_email not in hidden_security_emails%} + {% include "includes/summary_item.html" with title='Security email' value=security_email edit_link=url editable=is_editable %} + {% else %} + {% include "includes/summary_item.html" with title='Security email' value='None provided' edit_link=url editable=is_editable %} + {% endif %} + {% url 'domain-users' pk=domain.id as url %} + {% if portfolio %} + {% include "includes/summary_item.html" with title='Domain managers' domain_permissions=True value=domain edit_link=url editable=is_editable %} + {% else %} + {% include "includes/summary_item.html" with title='Domain managers' list=True users=True value=domain.permissions.all edit_link=url editable=is_editable %} + {% endif %} + + +
+ +
+ +

+ Acknowledgement of .gov domain requirements +

+
+ + {% if messages %} +
    + {% for message in messages %} +

    {{ message }}

    + {% endfor %} + + {% endif %} + + +
    + {% csrf_token %} +
    +
    + + + + + +{% endblock %} {# domain_content #} \ No newline at end of file From 19e5700a4db2dd3d46ab4490ec37911c0c678f14 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Mon, 30 Dec 2024 09:05:40 -0800 Subject: [PATCH 04/41] Add in the domain renewal template oops --- src/registrar/templates/domain_renewal.html | 127 ++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/registrar/templates/domain_renewal.html diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html new file mode 100644 index 000000000..eda7a8bdd --- /dev/null +++ b/src/registrar/templates/domain_renewal.html @@ -0,0 +1,127 @@ +{% extends "domain_base.html" %} +{% load static url_helpers %} +{% load custom_filters %} + +{% block domain_content %} + {% block breadcrumb %} + {% if portfolio %} + + + {% endif %} + {% endblock breadcrumb %} + + {{ block.super }} +
    +

    Confirm the following information for accuracy

    +

    Review these details below. We + require that you maintain accurate information for the domain. + The details you provide will only be used to support eh administration of .gov and won't be made public. +

    +

    If you would like to retire your domain instead, please + contact us.

    +

    Required fields are marked with an asterisk (*). +

    +
    + + {% url 'user-profile' as url %} + {% include "includes/summary_item.html" with title='Your Contact Information' value=user edit_link=url editable=is_editable contact='true' %} + + + + {% if analyst_action != 'edit' or analyst_action_location != domain.pk %} + {% if is_portfolio_user and not is_domain_manager %} +
    +
    +

    + You don't have access to manage {{domain.name}}. If you need to make updates, contact one of the listed domain managers. +

    +
    +
    + {% endif %} + {% endif %} + + {% url 'domain-security-email' pk=domain.id as url %} + {% if security_email is not None and security_email not in hidden_security_emails%} + {% include "includes/summary_item.html" with title='Security email' value=security_email edit_link=url editable=is_editable %} + {% else %} + {% include "includes/summary_item.html" with title='Security email' value='None provided' edit_link=url editable=is_editable %} + {% endif %} + {% url 'domain-users' pk=domain.id as url %} + {% if portfolio %} + {% include "includes/summary_item.html" with title='Domain managers' domain_permissions=True value=domain edit_link=url editable=is_editable %} + {% else %} + {% include "includes/summary_item.html" with title='Domain managers' list=True users=True value=domain.permissions.all edit_link=url editable=is_editable %} + {% endif %} + + +
    + +
    + +

    + Acknowledgement of .gov domain requirements +

    +
    + + {% if messages %} +
      + {% for message in messages %} +

      {{ message }}

      + {% endfor %} + + {% endif %} + + +
      + {% csrf_token %} +
      +
      + + + + + +{% endblock %} {# domain_content #} \ No newline at end of file From e23d81f7e7d4096e76450b0cca84908846484872 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Mon, 30 Dec 2024 12:44:52 -0500 Subject: [PATCH 05/41] added renew method --- src/registrar/models/domain.py | 6 +++++- src/registrar/views/domain.py | 11 ++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 715f1b9da..e170c8668 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -322,28 +322,32 @@ def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR): """ # If no date is specified, grab the registry_expiration_date + print("checking if there is a date") try: exp_date = self.registry_expiration_date except KeyError: # if no expiration date from registry, set it to today logger.warning("current expiration date not set; setting to today") exp_date = date.today() - + print("we got the date", exp_date) # create RenewDomain request request = commands.RenewDomain(name=self.name, cur_exp_date=exp_date, period=epp.Period(length, unit)) try: # update expiration date in registry, and set the updated # expiration date in the registrar, and in the cache + print("we are in the second try") self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date self.expiration_date = self._cache["ex_date"] self.save() except RegistryError as err: # if registry error occurs, log the error, and raise it as well + print("registry error") logger.error(f"registry error renewing domain: {err}") raise (err) except Exception as e: # exception raised during the save to registrar + print("this is the last error") logger.error(f"error updating expiration date in registrar: {e}") raise (e) diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 99a173517..1c1996c65 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -381,12 +381,13 @@ def post(self, request, pk): print("*** Checkbox is acknowledged") if "submit_button" in request.POST: print("*** Submit button clicked") - updated_expiration = domain.update_expiration(success=True) - print("*** Updated expiration result:", updated_expiration) - - if updated_expiration is True: + # updated_expiration = domain.update_expiration(success=True) + # print("*** Updated expiration result:", updated_expiration) + try: + domain.renew_domain() messages.success(request, "This domain has been renewed for one year") - else: + except Exception as e: + print(f'An error occured: {e}') messages.error(request, "This domain has not been renewed") return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) From a128086d6f5e2cf51dda942dfc92c7dceb92a45d Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 31 Dec 2024 10:13:53 -0800 Subject: [PATCH 06/41] Update print statements and exp timing --- src/registrar/models/domain.py | 16 +++++++++------- src/registrar/views/domain.py | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index e170c8668..b7145ec0c 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -322,32 +322,34 @@ def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR): """ # If no date is specified, grab the registry_expiration_date - print("checking if there is a date") + print("*** Checking if there is a date") try: exp_date = self.registry_expiration_date except KeyError: # if no expiration date from registry, set it to today - logger.warning("current expiration date not set; setting to today") - exp_date = date.today() - print("we got the date", exp_date) + logger.warning("*** Current expiration date not set; setting to 35 days ") + # exp_date = date.today() + exp_date = date.today() - timedelta(days=35) + print(exp_date) + print("*** The exp_date is", exp_date) # create RenewDomain request request = commands.RenewDomain(name=self.name, cur_exp_date=exp_date, period=epp.Period(length, unit)) try: # update expiration date in registry, and set the updated # expiration date in the registrar, and in the cache - print("we are in the second try") + print("** In renew_domain in 2nd try statement") self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date self.expiration_date = self._cache["ex_date"] self.save() except RegistryError as err: # if registry error occurs, log the error, and raise it as well - print("registry error") + print("*** Registry error") logger.error(f"registry error renewing domain: {err}") raise (err) except Exception as e: # exception raised during the save to registrar - print("this is the last error") + print("*** In renew_domain, in the last Exception statement") logger.error(f"error updating expiration date in registrar: {e}") raise (e) diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 1c1996c65..dd8e9928b 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -384,11 +384,12 @@ def post(self, request, pk): # updated_expiration = domain.update_expiration(success=True) # print("*** Updated expiration result:", updated_expiration) try: + print("*** Did we get into the try statement") domain.renew_domain() messages.success(request, "This domain has been renewed for one year") except Exception as e: - print(f'An error occured: {e}') - messages.error(request, "This domain has not been renewed") + print(f"An error occured: {e}") + messages.error(request, "*** This domain has not been renewed") return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) From c145ecbfa29d925af2806343eb8d8534677d8ac5 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Tue, 31 Dec 2024 13:55:18 -0500 Subject: [PATCH 07/41] put back the fixtures command --- src/registrar/fixtures/fixtures_domains.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/fixtures/fixtures_domains.py b/src/registrar/fixtures/fixtures_domains.py index 4d4115180..4606024d0 100644 --- a/src/registrar/fixtures/fixtures_domains.py +++ b/src/registrar/fixtures/fixtures_domains.py @@ -44,7 +44,7 @@ def load(cls): cls._approve_domain_requests(users) @staticmethod - def _generate_fake_expiration_date(days_in_future=40): + def _generate_fake_expiration_date(days_in_future=365): """Generates a fake expiration date between 1 and 365 days in the future.""" current_date = timezone.now().date() # nosec return current_date + timedelta(days=random.randint(1, days_in_future)) # nosec From e5f9696bac942a946c92430ff36dc6eba489b608 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Fri, 3 Jan 2025 10:43:35 -0500 Subject: [PATCH 08/41] added tests --- src/registrar/tests/test_views_domain.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index ba237e1e7..767445810 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -529,6 +529,21 @@ def test_expiring_domain_on_detail_page_in_org_model_as_a_domain_manager(self): ) self.assertContains(detail_page, "Renew to maintain access") + @override_flag("domain_renewal", active=True) + def test_domain_renewal_sidebar_and_form(self): + self.client.force_login(self.user) + with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( + Domain, "is_expired", self.custom_is_expired + ): + detail_page = self.client.get( + reverse("domain", kwargs={"pk": self.expiringdomain.id}), + ) + self.assertContains(detail_page, "Renewal form") + response = self.client.get(reverse("domain-renewal",kwargs={"pk": self.expiringdomain.id})) + self.assertEqual(response.status_code, 200) + self.assertContains(response, f"Renew {self.expiringdomain.name}") + + class TestDomainManagers(TestDomainOverview): @classmethod From 4feb29b269a39417e35fae2589b7026fbee757c3 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 3 Jan 2025 10:47:42 -0800 Subject: [PATCH 09/41] Add in tests for making edit is clickable and goes to right route --- src/registrar/tests/test_views_domain.py | 57 +++++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 767445810..281b7291e 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -539,10 +539,63 @@ def test_domain_renewal_sidebar_and_form(self): reverse("domain", kwargs={"pk": self.expiringdomain.id}), ) self.assertContains(detail_page, "Renewal form") - response = self.client.get(reverse("domain-renewal",kwargs={"pk": self.expiringdomain.id})) + response = self.client.get(reverse("domain-renewal", kwargs={"pk": self.expiringdomain.id})) self.assertEqual(response.status_code, 200) self.assertContains(response, f"Renew {self.expiringdomain.name}") - + + @override_flag("domain_renewal", active=True) + def test_domain_renewal_form_your_contact_info_edit(self): + with less_console_noise(): + # Start on the Renewal page for the domain + renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) + + # Verify we see "Your Contact Information" on the renewal form + self.assertContains(renewal_page, "Your Contact Information") + + # Verify that the "Edit" button for Your Contact is there and links to correct URL + edit_button_url = reverse("user-profile") + self.assertContains(renewal_page, f'href="{edit_button_url}"') + + # Simulate clicking on edit button + edit_page = renewal_page.click(href=edit_button_url, index=1) + self.assertEqual(edit_page.status_code, 200) + self.assertContains(edit_page, "Review the details below and update any required information") + + @override_flag("domain_renewal", active=True) + def test_domain_renewal_form_security_contact_edit(self): + with less_console_noise(): + # Start on the Renewal page for the domain + renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) + + # Verify we see "Security email" on the renewal form + self.assertContains(renewal_page, "Security email") + + # Verify that the "Edit" button for Security email is there and links to correct URL + edit_button_url = reverse("domain-security-email", kwargs={"pk": self.domain_with_ip.id}) + self.assertContains(renewal_page, f'href="{edit_button_url}"') + + # Simulate clicking on edit button + edit_page = renewal_page.click(href=edit_button_url, index=1) + self.assertEqual(edit_page.status_code, 200) + self.assertContains(edit_page, "A security contact should be capable of evaluating") + + @override_flag("domain_renewal", active=True) + def test_domain_renewal_form_domain_manager_edit(self): + with less_console_noise(): + # Start on the Renewal page for the domain + renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) + + # Verify we see "Domain managers" on the renewal form + self.assertContains(renewal_page, "Domain managers") + + # Verify that the "Edit" button for Domain managers is there and links to correct URL + edit_button_url = reverse("domain-users", kwargs={"pk": self.domain_with_ip.id}) + self.assertContains(renewal_page, f'href="{edit_button_url}"') + + # Simulate clicking on edit button + edit_page = renewal_page.click(href=edit_button_url, index=1) + self.assertEqual(edit_page.status_code, 200) + self.assertContains(edit_page, "Domain managers can update all information related to a domain") class TestDomainManagers(TestDomainOverview): From 3f3ba22a119db0568861440f88dc0632d2ae4bfd Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 3 Jan 2025 11:28:48 -0800 Subject: [PATCH 10/41] Update text to click on link --- src/registrar/tests/test_views_domain.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 281b7291e..02d7aa9ac 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -535,11 +535,24 @@ def test_domain_renewal_sidebar_and_form(self): with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( Domain, "is_expired", self.custom_is_expired ): + # Grab the detail page detail_page = self.client.get( reverse("domain", kwargs={"pk": self.expiringdomain.id}), ) + + # Make sure we see the link as a domain manager + self.assertContains(detail_page, "Renew to maintain access") + + # Make sure we can see Renewal form on the sidebar since it's expiring self.assertContains(detail_page, "Renewal form") - response = self.client.get(reverse("domain-renewal", kwargs={"pk": self.expiringdomain.id})) + + # Grab link to the renewal page + renewal_form_url = reverse("domain-renewal", kwargs={"pk": self.expiringdomain.id}) + self.assertContains(detail_page, f'href="{renewal_form_url}"') + + # Simulate clicking the link + response = self.client.get(renewal_form_url) + self.assertEqual(response.status_code, 200) self.assertContains(response, f"Renew {self.expiringdomain.name}") From dca70f4195237db300508421ecc59b0a43bab908 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Sat, 4 Jan 2025 14:17:55 -0800 Subject: [PATCH 11/41] Unit test for submit and recieving error message --- src/registrar/tests/test_views_domain.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 02d7aa9ac..50b8f31f6 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -9,6 +9,7 @@ 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 +from django.contrib.messages import get_messages import boto3_mocking # type: ignore from registrar.utility.errors import ( @@ -610,6 +611,25 @@ def test_domain_renewal_form_domain_manager_edit(self): self.assertEqual(edit_page.status_code, 200) self.assertContains(edit_page, "Domain managers can update all information related to a domain") + @override_flag("domain_renewal", active=True) + def test_ack_checkbox_not_checked(self): + + # Grab the renewal URL + renewal_url = reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id}) + + # Test clicking the checkbox + response = self.client.post(renewal_url, data={"submit_button": "next"}) + + # Verify the error message is displayed + # Retrieves messages obj (used in the post call) + messages = list(get_messages(response.wsgi_request)) + # Check we only get 1 error message + self.assertEqual(len(messages), 1) + # Check that the 1 error msg also is the right text + self.assertEqual( + str(messages[0]), + "Check the box if you read and agree to the requirements for operating a .gov domain.", + ) class TestDomainManagers(TestDomainOverview): @classmethod From bad8a8c98a75c1df161321c6a49d4b087d19e291 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Sat, 4 Jan 2025 14:48:21 -0800 Subject: [PATCH 12/41] Fix padding on form and addin subtext for security email --- src/registrar/templates/domain_renewal.html | 7 ++++--- src/registrar/templates/includes/summary_item.html | 8 +++++--- src/registrar/tests/test_views_domain.py | 1 + 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index eda7a8bdd..4bf69dbca 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -26,6 +26,7 @@ {{ block.super }}

      Confirm the following information for accuracy

      +

      HELLO

      Review these details below. We require that you maintain accurate information for the domain. The details you provide will only be used to support eh administration of .gov and won't be made public. @@ -55,9 +56,9 @@

      Confirm the following i {% url 'domain-security-email' pk=domain.id as url %} {% if security_email is not None and security_email not in hidden_security_emails%} - {% include "includes/summary_item.html" with title='Security email' value=security_email edit_link=url editable=is_editable %} + {% include "includes/summary_item.html" with title='Security email' value=security_email custom_text_for_value_none='We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain.' edit_link=url editable=is_editable %} {% else %} - {% include "includes/summary_item.html" with title='Security email' value='None provided' edit_link=url editable=is_editable %} + {% include "includes/summary_item.html" with title='Security email' value='None provided' custom_text_for_value_none='We strongly recommend that you provide a security email. This email will allow the public to report observed or suspected security issues on your domain.' edit_link=url editable=is_editable %} {% endif %} {% url 'domain-users' pk=domain.id as url %} {% if portfolio %} @@ -67,7 +68,7 @@

      Confirm the following i {% endif %} -
      +
      diff --git a/src/registrar/templates/includes/summary_item.html b/src/registrar/templates/includes/summary_item.html index 15cc0f67f..facc8956a 100644 --- a/src/registrar/templates/includes/summary_item.html +++ b/src/registrar/templates/includes/summary_item.html @@ -128,11 +128,13 @@

      Invited domain managers

      {% endif %} {% else %}

      + {% if custom_text_for_value_none %} +

      {{ custom_text_for_value_none }}

      + {% endif %} {% if value %} {{ value }} - {% elif custom_text_for_value_none %} - {{ custom_text_for_value_none }} - {% else %} + {% endif %} + {% if not value and not custom_text_for_value_none %} None {% endif %}

      diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 50b8f31f6..fa4351de1 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -631,6 +631,7 @@ def test_ack_checkbox_not_checked(self): "Check the box if you read and agree to the requirements for operating a .gov domain.", ) + class TestDomainManagers(TestDomainOverview): @classmethod def setUpClass(cls): From a3c50043c5a1d6fdc7154ad2944926d39181d9ac Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Sat, 4 Jan 2025 14:55:40 -0800 Subject: [PATCH 13/41] Removing print statements --- src/registrar/models/domain.py | 16 ++-------------- src/registrar/templates/domain_renewal.html | 1 - src/registrar/views/domain.py | 7 ------- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index b7145ec0c..59e04e7c3 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -322,34 +322,27 @@ def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR): """ # If no date is specified, grab the registry_expiration_date - print("*** Checking if there is a date") try: exp_date = self.registry_expiration_date except KeyError: # if no expiration date from registry, set it to today - logger.warning("*** Current expiration date not set; setting to 35 days ") - # exp_date = date.today() - exp_date = date.today() - timedelta(days=35) - print(exp_date) - print("*** The exp_date is", exp_date) + logger.warning("current expiration date not set; setting to today") + exp_date = date.today() # create RenewDomain request request = commands.RenewDomain(name=self.name, cur_exp_date=exp_date, period=epp.Period(length, unit)) try: # update expiration date in registry, and set the updated # expiration date in the registrar, and in the cache - print("** In renew_domain in 2nd try statement") self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date self.expiration_date = self._cache["ex_date"] self.save() except RegistryError as err: # if registry error occurs, log the error, and raise it as well - print("*** Registry error") logger.error(f"registry error renewing domain: {err}") raise (err) except Exception as e: # exception raised during the save to registrar - print("*** In renew_domain, in the last Exception statement") logger.error(f"error updating expiration date in registrar: {e}") raise (e) @@ -1173,11 +1166,6 @@ def is_expiring(self): threshold_date = now + timedelta(days=60) return now < self.expiration_date <= threshold_date - # Dummy method for testing for domain renewal form fail or success banner - - def update_expiration(self, success=True): - return success - def state_display(self, request=None): """Return the display status of the domain.""" if self.is_expired() and (self.state != self.State.UNKNOWN): diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index 4bf69dbca..07aeecd1a 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -26,7 +26,6 @@ {{ block.super }}

      Confirm the following information for accuracy

      -

      HELLO

      Review these details below. We require that you maintain accurate information for the domain. The details you provide will only be used to support eh administration of .gov and won't be made public. diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 44ac9e9d6..ab68addb7 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -365,7 +365,6 @@ def post(self, request, pk): # Check if the checkbox is checked is_policy_acknowledged = request.POST.get("is_policy_acknowledged", None) if is_policy_acknowledged != "on": - print("!!! Checkbox is NOT acknowledged") messages.error( request, "Check the box if you read and agree to the requirements for operating a .gov domain." ) @@ -378,17 +377,11 @@ def post(self, request, pk): }, ) - print("*** Checkbox is acknowledged") if "submit_button" in request.POST: - print("*** Submit button clicked") - # updated_expiration = domain.update_expiration(success=True) - # print("*** Updated expiration result:", updated_expiration) try: - print("*** Did we get into the try statement") domain.renew_domain() messages.success(request, "This domain has been renewed for one year") except Exception as e: - print(f"An error occured: {e}") messages.error(request, "*** This domain has not been renewed") return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) From 3dc445d17da90c09251faa03adaaa05960f84edc Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Mon, 6 Jan 2025 14:32:16 -0800 Subject: [PATCH 14/41] Update test and add in documentation --- docs/developer/registry-access.md | 47 ++++++++++++++++++++++++ src/registrar/tests/test_views_domain.py | 5 ++- src/registrar/views/domain.py | 4 +- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index c7737d5bc..c52810c35 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -103,3 +103,50 @@ response = registry._client.transport.receive() ``` This is helpful for debugging situations where epplib is not correctly or fully parsing the XML returned from the registry. + +### Adding in a expiring soon domain +The below scenario is if you are NOT in org model mode (`organization_feature` waffle flag is off). + +1. Go to the `staging` sandbox and to `/admin` +2. Go to Domains and find a domain that is actually expired by sorting the Expiration Date column +3. Click into the domain to check the expiration date +4. Click into Manage Domain to double check the expiration date as well +5. Now hold onto that domain name, and save it for the command below + +6. In a terminal, run these commands: +``` +cf ssh getgov- +/tmp/lifecycle/shell +./manage.py shell +from registrar.models import Domain, DomainInvitation +from registrar.models import User +user = User.objects.filter(first_name="") +domain = Domain.objects.get_or_create(name="") +``` + +7. Go back to `/admin` and create Domain Information for that domain you just added in via the terminal +8. Go to Domain to find it +9. Click Manage Domain +10. Add yourself as domain manager +11. Go to the Registrar page and you should now see the expiring domain + +If you want to be in the org model mode, turn the `organization_feature` waffle flag on, and add that domain via Django Admin to a portfolio to be able to view it. + + + + + + + + + + + + + + + + + + + diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index fa4351de1..e6e42d563 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -576,7 +576,7 @@ def test_domain_renewal_form_your_contact_info_edit(self): self.assertContains(edit_page, "Review the details below and update any required information") @override_flag("domain_renewal", active=True) - def test_domain_renewal_form_security_contact_edit(self): + def test_domain_renewal_form_security_email_edit(self): with less_console_noise(): # Start on the Renewal page for the domain renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) @@ -584,6 +584,9 @@ def test_domain_renewal_form_security_contact_edit(self): # Verify we see "Security email" on the renewal form self.assertContains(renewal_page, "Security email") + # Verify we see "strong recommend" blurb + self.assertContains(renewal_page, "We strongly recommend that you provide a security email.") + # Verify that the "Edit" button for Security email is there and links to correct URL edit_button_url = reverse("domain-security-email", kwargs={"pk": self.domain_with_ip.id}) self.assertContains(renewal_page, f'href="{edit_button_url}"') diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index ab68addb7..7ce0d7e1a 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -380,9 +380,9 @@ def post(self, request, pk): if "submit_button" in request.POST: try: domain.renew_domain() - messages.success(request, "This domain has been renewed for one year") + messages.success(request, "This domain has been renewed for one year.") except Exception as e: - messages.error(request, "*** This domain has not been renewed") + messages.error(request, "This domain has not been renewed for one year, error was %s" % e) return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) From 5f9a398bb77fd5217c4f0c019a8c4420fd8327e2 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Tue, 7 Jan 2025 09:43:48 -0500 Subject: [PATCH 15/41] some test --- src/registrar/tests/test_views_domain.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 02d7aa9ac..4eed20d56 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -530,7 +530,7 @@ def test_expiring_domain_on_detail_page_in_org_model_as_a_domain_manager(self): self.assertContains(detail_page, "Renew to maintain access") @override_flag("domain_renewal", active=True) - def test_domain_renewal_sidebar_and_form(self): + def test_domain_renewal_form_and_sidebar(self): self.client.force_login(self.user) with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( Domain, "is_expired", self.custom_is_expired @@ -608,8 +608,7 @@ def test_domain_renewal_form_domain_manager_edit(self): # Simulate clicking on edit button edit_page = renewal_page.click(href=edit_button_url, index=1) self.assertEqual(edit_page.status_code, 200) - self.assertContains(edit_page, "Domain managers can update all information related to a domain") - + self.assertContains(edit_page, "Domain managers can update all information related to a domain" class TestDomainManagers(TestDomainOverview): @classmethod From a8808e5356ccb5c5cf54b7f9f85616de6323a9ba Mon Sep 17 00:00:00 2001 From: asaki222 Date: Tue, 7 Jan 2025 16:11:33 -0500 Subject: [PATCH 16/41] ran app black --- src/registrar/tests/test_views_domain.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 25f79d7e0..ee8adf903 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -464,7 +464,7 @@ def custom_is_expired(self): def custom_is_expiring(self): return True - + def custom_renew_domain(self): self.domain_with_ip.expiration_date = self.todays_expiration_date() self.domain_with_ip.save() @@ -644,7 +644,7 @@ def test_ack_checkbox_not_checked(self): str(messages[0]), "Check the box if you read and agree to the requirements for operating a .gov domain.", ) - + @override_flag("domain_renewal", active=True) def test_ack_checkbox_checked(self): @@ -652,19 +652,18 @@ def test_ack_checkbox_checked(self): with patch.object(Domain, "renew_domain", self.custom_renew_domain): renewal_url = reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id}) - # Click the check, and submit + # Click the check, and submit response = self.client.post(renewal_url, data={"is_policy_acknowledged": "on", "submit_button": "next"}) - #Check that it redirects after a successfully submits - self.assertRedirects(response, reverse("domain", kwargs={"pk":self.domain_with_ip.id})) + # Check that it redirects after a successfully submits + self.assertRedirects(response, reverse("domain", kwargs={"pk": self.domain_with_ip.id})) - #Check for the updated expiration + # Check for the updated expiration formatted_new_expiration_date = self.todays_expiration_date().strftime("%b. %-d, %Y") - redirect_response = self.client.get(reverse("domain", kwargs={"pk":self.domain_with_ip.id}), follow=True) + redirect_response = self.client.get(reverse("domain", kwargs={"pk": self.domain_with_ip.id}), follow=True) self.assertContains(redirect_response, formatted_new_expiration_date) - class TestDomainManagers(TestDomainOverview): @classmethod def setUpClass(cls): From b077f814094a98353b7e925a2b34d0ffd8c97376 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 7 Jan 2025 17:24:13 -0800 Subject: [PATCH 17/41] Address feedback - use form pattern and update error messaging --- docs/developer/registry-access.md | 21 +---- src/registrar/forms/__init__.py | 1 + src/registrar/forms/domain.py | 12 +++ src/registrar/models/domain.py | 5 +- src/registrar/templates/domain_renewal.html | 94 ++++++++++----------- src/registrar/tests/test_views_domain.py | 6 +- src/registrar/views/domain.py | 50 +++++------ 7 files changed, 93 insertions(+), 96 deletions(-) diff --git a/docs/developer/registry-access.md b/docs/developer/registry-access.md index c52810c35..50caa4823 100644 --- a/docs/developer/registry-access.md +++ b/docs/developer/registry-access.md @@ -130,23 +130,4 @@ domain = Domain.objects.get_or_create(name="") 10. Add yourself as domain manager 11. Go to the Registrar page and you should now see the expiring domain -If you want to be in the org model mode, turn the `organization_feature` waffle flag on, and add that domain via Django Admin to a portfolio to be able to view it. - - - - - - - - - - - - - - - - - - - +If you want to be in the org model mode, turn the `organization_feature` waffle flag on, and add that domain via Django Admin to a portfolio to be able to view it. \ No newline at end of file diff --git a/src/registrar/forms/__init__.py b/src/registrar/forms/__init__.py index 121e2b3f7..13725f109 100644 --- a/src/registrar/forms/__init__.py +++ b/src/registrar/forms/__init__.py @@ -10,6 +10,7 @@ DomainDsdataFormset, DomainDsdataForm, DomainSuborganizationForm, + DomainRenewalForm, ) from .portfolio import ( PortfolioOrgAddressForm, diff --git a/src/registrar/forms/domain.py b/src/registrar/forms/domain.py index b43d91a58..699efe63b 100644 --- a/src/registrar/forms/domain.py +++ b/src/registrar/forms/domain.py @@ -661,3 +661,15 @@ def clean(self): extra=0, can_delete=True, ) + + +class DomainRenewalForm(forms.Form): + """Form making sure domain renewal ack is checked""" + + is_policy_acknowledged = forms.BooleanField( + required=True, + label="I have read and agree to the requirements for operating a .gov domain.", + error_messages={ + "required": "Check the box if you read and agree to the requirements for operating a .gov domain." + }, + ) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 59e04e7c3..217b88202 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -337,13 +337,14 @@ def renew_domain(self, length: int = 1, unit: epp.Unit = epp.Unit.YEAR): self._cache["ex_date"] = registry.send(request, cleaned=True).res_data[0].ex_date self.expiration_date = self._cache["ex_date"] self.save() + except RegistryError as err: # if registry error occurs, log the error, and raise it as well - logger.error(f"registry error renewing domain: {err}") + logger.error(f"Registry error renewing domain '{self.name}': {err}") raise (err) except Exception as e: # exception raised during the save to registrar - logger.error(f"error updating expiration date in registrar: {e}") + logger.error(f"Error updating expiration date for domain '{self.name}' in registrar: {e}") raise (e) @Cache diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index 07aeecd1a..bf529a04d 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -4,6 +4,18 @@ {% block domain_content %} {% block breadcrumb %} + + + {% if form.is_policy_acknowledged.errors %} +

      +
      + {% for error in form.is_policy_acknowledged.errors %} +

      {{ error }}

      + {% endfor %} +
      +
      + {% endif %} + {% if portfolio %}
      +
      {% url 'user-profile' as url %} {% include "includes/summary_item.html" with title='Your Contact Information' value=user edit_link=url editable=is_editable contact='true' %} @@ -66,62 +78,50 @@

      Confirm the following i {% include "includes/summary_item.html" with title='Domain managers' list=True users=True value=domain.permissions.all edit_link=url editable=is_editable %} {% endif %} - +
      -

      - Acknowledgement of .gov domain requirements -

      + Acknowledgement of .gov domain requirements

      - - {% if messages %} -
        - {% for message in messages %} -

        {{ message }}

        - {% endfor %} - - {% endif %} - - -
        - {% csrf_token %} -
        +
        + + + + +

        {% endblock %} {# domain_content #} \ No newline at end of file diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index ee8adf903..0a4096fbf 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -454,7 +454,7 @@ def setUp(self): self.user.save() - def todays_expiration_date(self): + def expiration_date_one_year_out(self): todays_date = datetime.today() new_expiration_date = todays_date.replace(year=todays_date.year + 1) return new_expiration_date @@ -466,7 +466,7 @@ def custom_is_expiring(self): return True def custom_renew_domain(self): - self.domain_with_ip.expiration_date = self.todays_expiration_date() + self.domain_with_ip.expiration_date = self.expiration_date_one_year_out() self.domain_with_ip.save() @override_flag("domain_renewal", active=True) @@ -659,7 +659,7 @@ def test_ack_checkbox_checked(self): self.assertRedirects(response, reverse("domain", kwargs={"pk": self.domain_with_ip.id})) # Check for the updated expiration - formatted_new_expiration_date = self.todays_expiration_date().strftime("%b. %-d, %Y") + formatted_new_expiration_date = self.expiration_date_one_year_out().strftime("%b. %-d, %Y") redirect_response = self.client.get(reverse("domain", kwargs={"pk": self.domain_with_ip.id}), follow=True) self.assertContains(redirect_response, formatted_new_expiration_date) diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index b849459f2..593fc9093 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -12,11 +12,11 @@ from django.contrib.messages.views import SuccessMessageMixin from django.db import IntegrityError from django.http import HttpResponseRedirect -from django.shortcuts import redirect, render +from django.shortcuts import redirect, render, get_object_or_404 from django.urls import reverse from django.views.generic.edit import FormMixin from django.conf import settings -from registrar.forms.domain import DomainSuborganizationForm +from registrar.forms.domain import DomainSuborganizationForm, DomainRenewalForm from registrar.models import ( Domain, DomainRequest, @@ -364,30 +364,32 @@ def _get_domain(self, request): self._update_session_with_domain() def post(self, request, pk): - domain = Domain.objects.filter(id=pk).first() + domain = get_object_or_404(Domain, id=pk) - # Check if the checkbox is checked - is_policy_acknowledged = request.POST.get("is_policy_acknowledged", None) - if is_policy_acknowledged != "on": - messages.error( - request, "Check the box if you read and agree to the requirements for operating a .gov domain." - ) - return render( - request, - "domain_renewal.html", - { - "domain": domain, - "form": request.POST, - }, - ) + form = DomainRenewalForm(request.POST) - if "submit_button" in request.POST: - try: - domain.renew_domain() - messages.success(request, "This domain has been renewed for one year.") - except Exception as e: - messages.error(request, "This domain has not been renewed for one year, error was %s" % e) - return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) + if form.is_valid(): + # check for key in the post request data + if "submit_button" in request.POST: + try: + domain.renew_domain() + messages.success(request, "This domain has been renewed for one year.") + except Exception as e: + messages.error( + request, + "This domain has not been renewed for one year, please email help@get.gov if this problem persists.", + ) + return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) + + # if not valid, render the template with error messages + return render( + request, + "domain_renewal.html", + { + "domain": domain, + "form": form, + }, + ) class DomainOrgNameAddressView(DomainFormBaseView): From e196e02d9284c55057ec1dc6ce4736c6b0f3e0ba Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 7 Jan 2025 17:28:35 -0800 Subject: [PATCH 18/41] Address linter errors --- src/registrar/views/domain.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 593fc9093..4b26caa5f 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -374,10 +374,11 @@ def post(self, request, pk): try: domain.renew_domain() messages.success(request, "This domain has been renewed for one year.") - except Exception as e: + except Exception: messages.error( request, - "This domain has not been renewed for one year, please email help@get.gov if this problem persists.", + "This domain has not been renewed for one year, " + "please email help@get.gov if this problem persists.", ) return HttpResponseRedirect(reverse("domain", kwargs={"pk": pk})) From aad1ee976b5735633d93caa1a1b9724a46206206 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 7 Jan 2025 17:40:37 -0800 Subject: [PATCH 19/41] Fix checkbox unchecked test --- src/registrar/tests/test_views_domain.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 0a4096fbf..ef4d415df 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -631,19 +631,11 @@ def test_ack_checkbox_not_checked(self): # Grab the renewal URL renewal_url = reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id}) - # Test clicking the checkbox + # Test that the checkbox is not checked response = self.client.post(renewal_url, data={"submit_button": "next"}) - # Verify the error message is displayed - # Retrieves messages obj (used in the post call) - messages = list(get_messages(response.wsgi_request)) - # Check we only get 1 error message - self.assertEqual(len(messages), 1) - # Check that the 1 error msg also is the right text - self.assertEqual( - str(messages[0]), - "Check the box if you read and agree to the requirements for operating a .gov domain.", - ) + error_message = "Check the box if you read and agree to the requirements for operating a .gov domain." + self.assertContains(response, error_message) @override_flag("domain_renewal", active=True) def test_ack_checkbox_checked(self): From 33e36590a4e0ff9b21836d22848618bc456b0533 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Tue, 7 Jan 2025 17:43:54 -0800 Subject: [PATCH 20/41] Remove unused import for linter --- src/registrar/tests/test_views_domain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index ef4d415df..79240286a 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -11,7 +11,6 @@ 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 -from django.contrib.messages import get_messages import boto3_mocking # type: ignore from registrar.utility.errors import ( From 628c4c0d0e4015a248bcc2ee33d583bbf5bcdb69 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Wed, 8 Jan 2025 13:56:48 -0500 Subject: [PATCH 21/41] expired domain renewal form --- src/registrar/templates/domain_detail.html | 6 ++++++ src/registrar/templates/domain_sidebar.html | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/registrar/templates/domain_detail.html b/src/registrar/templates/domain_detail.html index b168f7e82..becf46d5b 100644 --- a/src/registrar/templates/domain_detail.html +++ b/src/registrar/templates/domain_detail.html @@ -50,11 +50,17 @@

        {{ domain.name }}

        {% if domain.get_state_help_text %}
        {% if has_domain_renewal_flag and domain.is_expiring and is_domain_manager %} + This domain has expired, but it is still online. + {% url 'domain-renewal' pk=domain.id as url %} + Renew to maintain access. + {% elif has_domain_renewal_flag and domain.is_expired and is_domain_manager %} This domain will expire soon. {% url 'domain-renewal' pk=domain.id as url %} Renew to maintain access. {% elif has_domain_renewal_flag and domain.is_expiring and is_portfolio_user %} This domain will expire soon. Contact one of the listed domain managers to renew the domain. + {% elif has_domain_renewal_flag and domain.is_expired and is_portfolio_user %} + This domain has expired, but it is still online. Contact one of the listed domain managers to renew the domain. {% else %} {{ domain.get_state_help_text }} {% endif %} diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index 9d71ebf63..c9feb7200 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -80,7 +80,7 @@ {% include "includes/domain_sidenav_item.html" with item_text="Domain managers" %} {% endwith %} - {% if has_domain_renewal_flag and is_domain_manager and domain.is_expiring %} + {% if has_domain_renewal_flag and is_domain_manager and (domain.is_expiring or domain.is_expired) %} {% with url_name="domain-renewal" %} {% include "includes/domain_sidenav_item.html" with item_text="Renewal form" %} {% endwith %} From e8fede74ac05885d3b83d90b5cff372f870a5c89 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Wed, 8 Jan 2025 15:25:06 -0500 Subject: [PATCH 22/41] updated code to fix parsing error --- src/registrar/templates/domain_sidebar.html | 10 +-- src/registrar/tests/test_views_domain.py | 77 +++++++++++++++------ 2 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/registrar/templates/domain_sidebar.html b/src/registrar/templates/domain_sidebar.html index c9feb7200..336a9fe7c 100644 --- a/src/registrar/templates/domain_sidebar.html +++ b/src/registrar/templates/domain_sidebar.html @@ -80,10 +80,12 @@ {% include "includes/domain_sidenav_item.html" with item_text="Domain managers" %} {% endwith %} - {% if has_domain_renewal_flag and is_domain_manager and (domain.is_expiring or domain.is_expired) %} - {% with url_name="domain-renewal" %} - {% include "includes/domain_sidenav_item.html" with item_text="Renewal form" %} - {% endwith %} + {% if has_domain_renewal_flag and is_domain_manager%} + {% if domain.is_expiring or domain.is_expired %} + {% with url_name="domain-renewal" %} + {% include "includes/domain_sidenav_item.html" with item_text="Renewal form" %} + {% endwith %} + {% endif %} {% endif %} {% endif %} diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index ee8adf903..406e96ed4 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -440,15 +440,15 @@ def setUp(self): username="usertest", ) - self.expiringdomain, _ = Domain.objects.get_or_create( - name="expiringdomain.gov", + self.domaintorenew, _ = Domain.objects.get_or_create( + name="domainrenewal.gov", ) UserDomainRole.objects.get_or_create( - user=self.user, domain=self.expiringdomain, role=UserDomainRole.Roles.MANAGER + user=self.user, domain=self.domaintorenew, role=UserDomainRole.Roles.MANAGER ) - DomainInformation.objects.get_or_create(creator=self.user, domain=self.expiringdomain) + DomainInformation.objects.get_or_create(creator=self.user, domain=self.domaintorenew) self.portfolio, _ = Portfolio.objects.get_or_create(organization_name="Test org", creator=self.user) @@ -459,9 +459,12 @@ def todays_expiration_date(self): new_expiration_date = todays_date.replace(year=todays_date.year + 1) return new_expiration_date - def custom_is_expired(self): + def custom_is_expired_false(self): return False + def custom_is_expired_true(self): + return True + def custom_is_expiring(self): return True @@ -473,11 +476,11 @@ def custom_renew_domain(self): def test_expiring_domain_on_detail_page_as_domain_manager(self): self.client.force_login(self.user) with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( - Domain, "is_expired", self.custom_is_expired + Domain, "is_expired", self.custom_is_expired_false ): - self.assertEquals(self.expiringdomain.state, Domain.State.UNKNOWN) + self.assertEquals(self.domaintorenew.state, Domain.State.UNKNOWN) detail_page = self.client.get( - reverse("domain", kwargs={"pk": self.expiringdomain.id}), + reverse("domain", kwargs={"pk": self.domaintorenew.id}), ) self.assertContains(detail_page, "Expiring soon") @@ -508,17 +511,17 @@ def test_expiring_domain_on_detail_page_in_org_model_as_a_non_domain_manager(sel UserPortfolioPermissionChoices.VIEW_ALL_DOMAINS, ], ) - expiringdomain2, _ = Domain.objects.get_or_create(name="bogusdomain2.gov") + domaintorenew2, _ = Domain.objects.get_or_create(name="bogusdomain2.gov") DomainInformation.objects.get_or_create( - creator=non_dom_manage_user, domain=expiringdomain2, portfolio=self.portfolio + creator=non_dom_manage_user, domain=domaintorenew2, portfolio=self.portfolio ) non_dom_manage_user.refresh_from_db() self.client.force_login(non_dom_manage_user) with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( - Domain, "is_expired", self.custom_is_expired + Domain, "is_expired", self.custom_is_expired_false ): detail_page = self.client.get( - reverse("domain", kwargs={"pk": expiringdomain2.id}), + reverse("domain", kwargs={"pk": domaintorenew2.id}), ) self.assertContains(detail_page, "Contact one of the listed domain managers to renew the domain.") @@ -527,29 +530,29 @@ def test_expiring_domain_on_detail_page_in_org_model_as_a_non_domain_manager(sel def test_expiring_domain_on_detail_page_in_org_model_as_a_domain_manager(self): portfolio, _ = Portfolio.objects.get_or_create(organization_name="Test org2", creator=self.user) - expiringdomain3, _ = Domain.objects.get_or_create(name="bogusdomain3.gov") + domaintorenew3, _ = Domain.objects.get_or_create(name="bogusdomain3.gov") - UserDomainRole.objects.get_or_create(user=self.user, domain=expiringdomain3, role=UserDomainRole.Roles.MANAGER) - DomainInformation.objects.get_or_create(creator=self.user, domain=expiringdomain3, portfolio=portfolio) + UserDomainRole.objects.get_or_create(user=self.user, domain=domaintorenew3, role=UserDomainRole.Roles.MANAGER) + DomainInformation.objects.get_or_create(creator=self.user, domain=domaintorenew3, portfolio=portfolio) self.user.refresh_from_db() self.client.force_login(self.user) with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( - Domain, "is_expired", self.custom_is_expired + Domain, "is_expired", self.custom_is_expired_false ): detail_page = self.client.get( - reverse("domain", kwargs={"pk": expiringdomain3.id}), + reverse("domain", kwargs={"pk": domaintorenew3.id}), ) self.assertContains(detail_page, "Renew to maintain access") @override_flag("domain_renewal", active=True) - def test_domain_renewal_form_and_sidebar(self): + def test_domain_renewal_form_and_sidebar_expiring(self): self.client.force_login(self.user) with patch.object(Domain, "is_expiring", self.custom_is_expiring), patch.object( - Domain, "is_expired", self.custom_is_expired + Domain, "is_expiring", self.custom_is_expiring ): # Grab the detail page detail_page = self.client.get( - reverse("domain", kwargs={"pk": self.expiringdomain.id}), + reverse("domain", kwargs={"pk": self.domaintorenew.id}), ) # Make sure we see the link as a domain manager @@ -559,14 +562,44 @@ def test_domain_renewal_form_and_sidebar(self): self.assertContains(detail_page, "Renewal form") # Grab link to the renewal page - renewal_form_url = reverse("domain-renewal", kwargs={"pk": self.expiringdomain.id}) + renewal_form_url = reverse("domain-renewal", kwargs={"pk": self.domaintorenew.id}) + self.assertContains(detail_page, f'href="{renewal_form_url}"') + + # Simulate clicking the link + response = self.client.get(renewal_form_url) + + self.assertEqual(response.status_code, 200) + self.assertContains(response, f"Renew {self.domaintorenew.name}") + + @override_flag("domain_renewal", active=True) + def test_domain_renewal_form_and_sidebar_expired(self): + + self.client.force_login(self.user) + + with patch.object(Domain, "is_expired", self.custom_is_expired_true), patch.object( + Domain, "is_expired", self.custom_is_expired_true + ): + # Grab the detail page + detail_page = self.client.get( + reverse("domain", kwargs={"pk": self.domaintorenew.id}), + ) + + print("puglesss", self.domaintorenew.is_expired) + # Make sure we see the link as a domain manager + self.assertContains(detail_page, "Renew to maintain access") + + # Make sure we can see Renewal form on the sidebar since it's expired + self.assertContains(detail_page, "Renewal form") + + # Grab link to the renewal page + renewal_form_url = reverse("domain-renewal", kwargs={"pk": self.domaintorenew.id}) self.assertContains(detail_page, f'href="{renewal_form_url}"') # Simulate clicking the link response = self.client.get(renewal_form_url) self.assertEqual(response.status_code, 200) - self.assertContains(response, f"Renew {self.expiringdomain.name}") + self.assertContains(response, f"Renew {self.domaintorenew.name}") @override_flag("domain_renewal", active=True) def test_domain_renewal_form_your_contact_info_edit(self): From c7af6645d4a8ffac6a3b33b307f97ed6871aded2 Mon Sep 17 00:00:00 2001 From: asaki222 Date: Wed, 8 Jan 2025 15:31:59 -0500 Subject: [PATCH 23/41] ran app black . --- src/registrar/tests/test_views_domain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 406e96ed4..575dc0faf 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -464,7 +464,7 @@ def custom_is_expired_false(self): def custom_is_expired_true(self): return True - + def custom_is_expiring(self): return True @@ -570,12 +570,12 @@ def test_domain_renewal_form_and_sidebar_expiring(self): self.assertEqual(response.status_code, 200) self.assertContains(response, f"Renew {self.domaintorenew.name}") - + @override_flag("domain_renewal", active=True) def test_domain_renewal_form_and_sidebar_expired(self): - + self.client.force_login(self.user) - + with patch.object(Domain, "is_expired", self.custom_is_expired_true), patch.object( Domain, "is_expired", self.custom_is_expired_true ): From acd20e89141f7a581fdb62281fc3d5c082d3b780 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Wed, 8 Jan 2025 21:16:01 -0800 Subject: [PATCH 24/41] Fix uncheck error --- src/registrar/templates/domain_renewal.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index bf529a04d..7867bfce8 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -103,7 +103,9 @@

        Confirm the following i class="usa-checkbox__input" id="renewal-checkbox" type="checkbox" - name="{{ form.is_policy_acknowledged.name }}"> + name="{{ form.is_policy_acknowledged.name }}" + {% if form.is_policy_acknowledged.value %}checked{% endif %} + >

        {% url 'user-profile' as url %} - {% include "includes/summary_item.html" with title='Your Contact Information' value=user edit_link=url editable=is_editable contact='true' %} + {% include "includes/summary_item.html" with title='Your Contact Information' value=request.user edit_link=url editable=is_editable contact='true' %} diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index 4b26caa5f..629d1bf03 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -311,24 +311,11 @@ def _get_domain(self, request): self._update_session_with_domain() -class DomainRenewalView(DomainBaseView): +class DomainRenewalView(DomainView): """Domain detail overview page.""" template_name = "domain_renewal.html" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - - default_emails = [DefaultEmail.PUBLIC_CONTACT_DEFAULT.value, DefaultEmail.LEGACY_DEFAULT.value] - context["hidden_security_emails"] = default_emails - - security_email = self.object.get_security_email() - user = self.request.user - if security_email is None or security_email in default_emails: - context["security_email"] = None - context["user"] = user - return context - def can_access_domain_via_portfolio(self, pk): """Most views should not allow permission to portfolio users. If particular views allow permissions, they will need to override @@ -341,28 +328,6 @@ def can_access_domain_via_portfolio(self, pk): return True return False - def in_editable_state(self, pk): - """Override in_editable_state from DomainPermission - Allow detail page to be viewable""" - - requested_domain = None - if Domain.objects.filter(id=pk).exists(): - requested_domain = Domain.objects.get(id=pk) - - # return true if the domain exists, this will allow the detail page to load - if requested_domain: - return True - return False - - def _get_domain(self, request): - """ - override get_domain for this view so that domain overview - always resets the cache for the domain object - """ - self.session = request.session - self.object = self.get_object() - self._update_session_with_domain() - def post(self, request, pk): domain = get_object_or_404(Domain, id=pk) From 6b2123d0f3dd7733b9a90b6192912023e480f4de Mon Sep 17 00:00:00 2001 From: asaki222 Date: Fri, 10 Jan 2025 11:44:04 -0500 Subject: [PATCH 32/41] reformatted and updated test --- src/registrar/tests/test_views_domain.py | 2 +- src/registrar/views/domain.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index d92da17dd..56bfe7306 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -607,7 +607,7 @@ def test_domain_renewal_form_your_contact_info_edit(self): renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) # Verify we see "Your contact information" on the renewal form - self.assertContains(renewal_page, "Your contact information") + self.assertContains(renewal_page, "Your Contact Information") # Verify that the "Edit" button for Your contact is there and links to correct URL edit_button_url = reverse("user-profile") diff --git a/src/registrar/views/domain.py b/src/registrar/views/domain.py index bee59e4a9..629d1bf03 100644 --- a/src/registrar/views/domain.py +++ b/src/registrar/views/domain.py @@ -315,7 +315,7 @@ class DomainRenewalView(DomainView): """Domain detail overview page.""" template_name = "domain_renewal.html" - + def can_access_domain_via_portfolio(self, pk): """Most views should not allow permission to portfolio users. If particular views allow permissions, they will need to override From 6e1b352d4f4a2f11b1fd1f6cbc6b4e394a0121b4 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 10 Jan 2025 09:36:57 -0800 Subject: [PATCH 33/41] Fix your contact info title --- src/registrar/templates/domain_renewal.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index 0e72568cc..f81389efb 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -49,7 +49,7 @@

        Confirm the following i {% url 'user-profile' as url %} - {% include "includes/summary_item.html" with title='Your Contact Information' value=request.user edit_link=url editable=is_editable contact='true' %} + {% include "includes/summary_item.html" with title='Your contact information' value=request.user edit_link=url editable=is_editable contact='true' %} {% if analyst_action != 'edit' or analyst_action_location != domain.pk %} {% if is_portfolio_user and not is_domain_manager %} From 25ba5b2a5172c4f7e4cd79eac25663ec0a80b4a6 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 10 Jan 2025 09:56:58 -0800 Subject: [PATCH 34/41] Fix test capitalization --- src/registrar/tests/test_views_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 56bfe7306..d92da17dd 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -607,7 +607,7 @@ def test_domain_renewal_form_your_contact_info_edit(self): renewal_page = self.app.get(reverse("domain-renewal", kwargs={"pk": self.domain_with_ip.id})) # Verify we see "Your contact information" on the renewal form - self.assertContains(renewal_page, "Your Contact Information") + self.assertContains(renewal_page, "Your contact information") # Verify that the "Edit" button for Your contact is there and links to correct URL edit_button_url = reverse("user-profile") From 19114c7e7214474e2afcb49a57140846e40640c6 Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Fri, 10 Jan 2025 11:02:31 -0800 Subject: [PATCH 35/41] Fix checkbox issue --- src/registrar/templates/domain_renewal.html | 7 +++---- src/registrar/views/domain.py | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/registrar/templates/domain_renewal.html b/src/registrar/templates/domain_renewal.html index f81389efb..02c9666e3 100644 --- a/src/registrar/templates/domain_renewal.html +++ b/src/registrar/templates/domain_renewal.html @@ -94,14 +94,13 @@

        Confirm the following i
        {% csrf_token %}
        - {% if form.is_policy_acknowledged.errors %} -

        {{ form.is_policy_acknowledged.errors|join:" " }}

        - {% endif %} +
        - +