From 5ebae382ed5737a66d681f46736d5c9acc1fd983 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:12:46 -0700 Subject: [PATCH 001/107] Update home.html --- src/registrar/templates/home.html | 41 ++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 15835920b..80b20c258 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -42,6 +42,7 @@ Expires Status Action +       @@ -80,6 +81,7 @@ {% endif %} + {% endfor %} @@ -104,6 +106,7 @@ Date submitted Status Action + Delete Action @@ -121,22 +124,54 @@ {{ application.get_status_display }} - {% if application.status == "started" or application.status == "action needed" or application.status == "withdrawn" %} + {% if application.status == "started" or application.status == "action needed" or application.status == "withdrawn" %} Edit {{ application.requested_domain.name|default:"New domain request" }} - {% else %} + {% else %} Manage {{application.requested_domain.name}} - {% endif %} + {% endif %} + + + + Delete + + + + Delete + + +
+
+ {% with heading="Are you sure you want to remove <"|add:permission.user.email|add:">?" %} + {% include 'includes/modal.html' with modal_heading=heading modal_description="<"|add:permission.user.email|add:"> will no longer be able to manage the domain "|add:domain.name|add:"." modal_button=modal_button|safe %} + {% endwith %} +
+
+ {% endfor %} From 403bfb6433eb15242b4f5cc3f1dbfc98dcd002e8 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:34:08 -0700 Subject: [PATCH 002/107] Delete functionality --- src/registrar/config/urls.py | 5 ++ src/registrar/templates/home.html | 50 +++++++++---------- src/registrar/views/application.py | 8 +++ src/registrar/views/index.py | 7 +++ .../views/utility/permission_views.py | 8 +++ 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 607bf5f61..bbe91f6fd 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -138,6 +138,11 @@ urlpatterns = [ views.DomainInvitationDeleteView.as_view(http_method_names=["post"]), name="invitation-delete", ), + path( + "application//delete", + views.DomainApplicationDeleteView.as_view(http_method_names=["post"]), + name="application-delete", + ), ] # we normally would guard these with `if settings.DEBUG` but tests run with diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 80b20c258..3a9a5a611 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -141,36 +141,32 @@ - - + + Delete - - - Delete - -
-
- {% with heading="Are you sure you want to remove <"|add:permission.user.email|add:">?" %} - {% include 'includes/modal.html' with modal_heading=heading modal_description="<"|add:permission.user.email|add:"> will no longer be able to manage the domain "|add:domain.name|add:"." modal_button=modal_button|safe %} - {% endwith %} -
-
+
+
+ {% with heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} + {% include 'includes/modal.html' with modal_heading=heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endwith %} +
+
{% endfor %} diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 41052e164..63adbf3d9 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -12,6 +12,7 @@ from registrar.forms import application_wizard as forms from registrar.models import DomainApplication from registrar.utility import StrEnum from registrar.views.utility import StepsHelper +from registrar.views.utility.permission_views import DomainApplicationPermissionDeleteView from .utility import ( DomainApplicationPermissionView, @@ -572,3 +573,10 @@ class ApplicationWithdrawn(DomainApplicationPermissionWithdrawView): application.withdraw() application.save() return HttpResponseRedirect(reverse("home")) + + +class DomainApplicationDeleteView(DomainApplicationPermissionDeleteView): + object: DomainApplication # workaround for type mismatch in DeleteView + + def get_success_url(self): + return reverse("home") \ No newline at end of file diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 9605c723d..a4a8e3d90 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -18,4 +18,11 @@ def index(request): domains = Domain.objects.filter(id__in=domain_ids) context["domains"] = domains + modal_button = ( + '' + ) + + context["modal_button"] = modal_button return render(request, "home.html", context) diff --git a/src/registrar/views/utility/permission_views.py b/src/registrar/views/utility/permission_views.py index 1798ec79d..cf6bd930d 100644 --- a/src/registrar/views/utility/permission_views.py +++ b/src/registrar/views/utility/permission_views.py @@ -122,3 +122,11 @@ class DomainInvitationPermissionDeleteView(DomainInvitationPermission, DeleteVie model = DomainInvitation object: DomainInvitation # workaround for type mismatch in DeleteView + + +class DomainApplicationPermissionDeleteView(DomainApplicationPermission, DeleteView, abc.ABC): + + """Abstract view for deleting a DomainApplication.""" + + model = DomainApplication + object: DomainApplication \ No newline at end of file From a251d1ca1ad2d4ec4fe9ba14f5a326728329f247 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:54:31 -0700 Subject: [PATCH 003/107] Conditional deletion --- src/registrar/templates/home.html | 53 +++++++++++++++--------------- src/registrar/tests/test_views.py | 5 +-- src/registrar/views/application.py | 14 ++++++++ 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 3a9a5a611..33708c8f6 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -81,7 +81,6 @@ {% endif %} - {% endfor %} @@ -141,32 +140,34 @@ - - - Delete - + {% if application.status == "started" or application.status == "withdrawn" %} + + + Delete + -
-
- {% with heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} - {% include 'includes/modal.html' with modal_heading=heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} - {% endwith %} -
-
+
+
+ {% with heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} + {% include 'includes/modal.html' with modal_heading=heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endwith %} +
+
+ {% endif %} {% endfor %} diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index 8f812b815..246222fe7 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -88,8 +88,9 @@ class LoggedInTests(TestWithUser): site = DraftDomain.objects.create(name="igorville.gov") application = DomainApplication.objects.create(creator=self.user, requested_domain=site) response = self.client.get("/") - # count = 2 because it is also in screenreader content - self.assertContains(response, "igorville.gov", count=2) + + # count = 6 because it is also in screenreader content, and in the delete modal + self.assertContains(response, "igorville.gov", count=6) # clean up application.delete() diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 63adbf3d9..5043ef245 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,4 +1,5 @@ import logging +from django.forms import ValidationError from django.http import Http404, HttpResponse, HttpResponseRedirect from django.shortcuts import redirect, render @@ -576,7 +577,20 @@ class ApplicationWithdrawn(DomainApplicationPermissionWithdrawView): class DomainApplicationDeleteView(DomainApplicationPermissionDeleteView): + """Delete view for home that allows the end user to delete DomainApplications""" object: DomainApplication # workaround for type mismatch in DeleteView + def has_permission(self): + """Custom override for has_permission to exclude all statuses, except WITHDRAWN and STARTED""" + has_perm = super().has_permission() + if not has_perm: + return False + + status = self.get_object().status + if status not in [DomainApplication.ApplicationStatus.WITHDRAWN, DomainApplication.ApplicationStatus.STARTED]: + return False + + return True + def get_success_url(self): return reverse("home") \ No newline at end of file From 2042fd1146223cb9cab91ea1dd01e90527d191b6 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:58:33 -0700 Subject: [PATCH 004/107] Increase padding --- src/registrar/templates/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 33708c8f6..b5bef3b71 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -9,7 +9,7 @@ {% if user.is_authenticated %} {# the entire logged in page goes here #} -
+

Manage your domains

From 0bbbc895b02f5abf7289ebbf9798768082c1487e Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:27:24 -0700 Subject: [PATCH 005/107] Fix styling --- src/registrar/assets/sass/_theme/_tables.scss | 4 ++++ src/registrar/templates/home.html | 13 ++++++++++-- src/registrar/views/index.py | 20 +++++++++++++------ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index 6dcc6f3bc..6a52a5d08 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -25,6 +25,10 @@ color: color('primary-darker'); padding-bottom: units(2px); } + + th.action-col-custom-width { + width: 27% !important; + } } .dotgov-table { diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index b5bef3b71..62bbc3ac6 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -41,8 +41,13 @@ Domain name Expires Status - Action -       + + Action + @@ -105,7 +110,9 @@ Date submitted Status Action + {% if has_deletable_applications %} Delete Action + {% endif %} @@ -139,6 +146,7 @@ {% endif %} + {% if has_deletable_applications %} {% if application.status == "started" or application.status == "withdrawn" %} {% endif %} + {% endif %} {% endfor %} diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index a4a8e3d90..5996c27f6 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -18,11 +18,19 @@ def index(request): domains = Domain.objects.filter(id__in=domain_ids) context["domains"] = domains - modal_button = ( - '' - ) - context["modal_button"] = modal_button + # Determine if the user will see applications that they can delete + valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] + has_deletable_applications = applications.filter(status__in=valid_statuses) + context["has_deletable_applications"] = has_deletable_applications + + if has_deletable_applications: + modal_button = ( + '' + ) + + + context["modal_button"] = modal_button return render(request, "home.html", context) From 90760e6d43d2d4c1e5af47f9811e0315da775a48 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:32:08 -0700 Subject: [PATCH 006/107] Add unit tests --- src/registrar/tests/test_views.py | 80 +++++++++++++++++++ src/registrar/views/application.py | 4 +- src/registrar/views/index.py | 1 - .../views/utility/permission_views.py | 2 +- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index 246222fe7..cfc03d70d 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -94,6 +94,86 @@ class LoggedInTests(TestWithUser): # clean up application.delete() + def test_home_deletes_withdrawn_domain_application(self): + """Tests if the user can delete a DomainApplication in the 'withdrawn' status""" + + site = DraftDomain.objects.create(name="igorville.gov") + application = DomainApplication.objects.create( + creator=self.user, requested_domain=site, status=DomainApplication.ApplicationStatus.WITHDRAWN + ) + + # Ensure that igorville.gov exists on the page + home_page = self.client.get("/") + self.assertContains(home_page, "igorville.gov") + + # Check if the delete button exists. We can do this by checking for its id and text content. + self.assertContains(home_page, "Delete") + self.assertContains(home_page, "button-toggle-delete-domain-alert-1") + + # Trigger the delete logic + response = self.client.post(reverse("application-delete", kwargs={"pk": application.pk}), follow=True) + + self.assertNotContains(response, "igorville.gov") + + # clean up + application.delete() + + def test_home_deletes_started_domain_application(self): + """Tests if the user can delete a DomainApplication in the 'started' status""" + + site = DraftDomain.objects.create(name="igorville.gov") + application = DomainApplication.objects.create( + creator=self.user, requested_domain=site, status=DomainApplication.ApplicationStatus.STARTED + ) + + # Ensure that igorville.gov exists on the page + home_page = self.client.get("/") + self.assertContains(home_page, "igorville.gov") + + # Check if the delete button exists. We can do this by checking for its id and text content. + self.assertContains(home_page, "Delete") + self.assertContains(home_page, "button-toggle-delete-domain-alert-1") + + # Trigger the delete logic + response = self.client.post(reverse("application-delete", kwargs={"pk": application.pk}), follow=True) + + self.assertNotContains(response, "igorville.gov") + + # clean up + application.delete() + + def test_home_doesnt_delete_other_domain_applications(self): + """Tests to ensure the user can't delete Applications not in the status of STARTED or WITHDRAWN""" + + # Given that we are including a subset of items that can be deleted while excluding the rest, + # subTest is appropriate here as otherwise we would need many duplicate tests for the same reason. + draft_domain = DraftDomain.objects.create(name="igorville.gov") + for status in DomainApplication.ApplicationStatus: + if status not in [ + DomainApplication.ApplicationStatus.STARTED, + DomainApplication.ApplicationStatus.WITHDRAWN, + ]: + with self.subTest(status=status): + application = DomainApplication.objects.create( + creator=self.user, requested_domain=draft_domain, status=status + ) + + # Trigger the delete logic + response = self.client.post( + reverse("application-delete", kwargs={"pk": application.pk}), follow=True + ) + + # Check for a 403 error - the end user should not be allowed to do this + self.assertEqual(response.status_code, 403) + + desired_application = DomainApplication.objects.filter(requested_domain=draft_domain) + + # Make sure the DomainApplication wasn't deleted + self.assertEqual(desired_application.count(), 1) + + # clean up + application.delete() + def test_home_lists_domains(self): response = self.client.get("/") domain, _ = Domain.objects.get_or_create(name="igorville.gov") diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 5043ef245..d50502db4 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,5 +1,4 @@ import logging -from django.forms import ValidationError from django.http import Http404, HttpResponse, HttpResponseRedirect from django.shortcuts import redirect, render @@ -578,6 +577,7 @@ class ApplicationWithdrawn(DomainApplicationPermissionWithdrawView): class DomainApplicationDeleteView(DomainApplicationPermissionDeleteView): """Delete view for home that allows the end user to delete DomainApplications""" + object: DomainApplication # workaround for type mismatch in DeleteView def has_permission(self): @@ -593,4 +593,4 @@ class DomainApplicationDeleteView(DomainApplicationPermissionDeleteView): return True def get_success_url(self): - return reverse("home") \ No newline at end of file + return reverse("home") diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 5996c27f6..43f251d47 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -31,6 +31,5 @@ def index(request): 'name="delete-application">Yes, delete request' ) - context["modal_button"] = modal_button return render(request, "home.html", context) diff --git a/src/registrar/views/utility/permission_views.py b/src/registrar/views/utility/permission_views.py index cf6bd930d..587eb0b5c 100644 --- a/src/registrar/views/utility/permission_views.py +++ b/src/registrar/views/utility/permission_views.py @@ -129,4 +129,4 @@ class DomainApplicationPermissionDeleteView(DomainApplicationPermission, DeleteV """Abstract view for deleting a DomainApplication.""" model = DomainApplication - object: DomainApplication \ No newline at end of file + object: DomainApplication From 693058c02a2d7a4430fd5c861319508735ad59b3 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:49:39 -0700 Subject: [PATCH 007/107] Add padding for mobile view --- src/registrar/assets/sass/_theme/_tables.scss | 7 +++++++ src/registrar/templates/home.html | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index 6a52a5d08..65fb8b487 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -29,6 +29,13 @@ th.action-col-custom-width { width: 27% !important; } + + // Fix margins in mobile view + @media screen { + td.tablet-margin-top-5 { + margin-top: 40px !important; + } + } } .dotgov-table { diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 62bbc3ac6..da9212bea 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -147,7 +147,7 @@ {% if has_deletable_applications %} - + {% if application.status == "started" or application.status == "withdrawn" %} Date: Fri, 5 Jan 2024 14:45:37 -0700 Subject: [PATCH 008/107] CSS changes --- src/registrar/assets/sass/_theme/_tables.scss | 2 +- .../assets/sass/_theme/_usa-modal.scss | 12 +++++++++ src/registrar/assets/sass/_theme/styles.scss | 1 + src/registrar/templates/home.html | 26 ++++++++++++++----- src/registrar/templates/includes/modal.html | 2 +- src/registrar/views/index.py | 3 ++- 6 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 src/registrar/assets/sass/_theme/_usa-modal.scss diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index 65fb8b487..f3adab18b 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -27,7 +27,7 @@ } th.action-col-custom-width { - width: 27% !important; + width: 23.25% !important; } // Fix margins in mobile view diff --git a/src/registrar/assets/sass/_theme/_usa-modal.scss b/src/registrar/assets/sass/_theme/_usa-modal.scss new file mode 100644 index 000000000..7106f1961 --- /dev/null +++ b/src/registrar/assets/sass/_theme/_usa-modal.scss @@ -0,0 +1,12 @@ +@use "uswds-core" as *; + +.usa-modal.wider-modal { + width: 40% !important; + max-width: 40% !important; +} + +.usa-modal { + .usa-modal__heading.blue-header{ + color: $dhs-blue; + } +} \ No newline at end of file diff --git a/src/registrar/assets/sass/_theme/styles.scss b/src/registrar/assets/sass/_theme/styles.scss index 8a2e1d2d3..499f9a806 100644 --- a/src/registrar/assets/sass/_theme/styles.scss +++ b/src/registrar/assets/sass/_theme/styles.scss @@ -17,6 +17,7 @@ @forward "tables"; @forward "sidenav"; @forward "register-form"; +@forward "usa-modal"; /*-------------------------------------------------- --- Admin ---------------------------------*/ diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index da9212bea..4e7e9729b 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -48,6 +48,9 @@ > Action + {% if has_deletable_applications %} + + {% endif %} @@ -86,6 +89,9 @@ {% endif %} + {% if has_deletable_applications %} + + {% endif %} {% endfor %} @@ -119,7 +125,13 @@ {% for application in domain_applications %} - {{ application.requested_domain.name|default:"New domain request" }} + {% if application.requested_domain and application.requested_domain.name %} + {{ application.requested_domain.name }} + {% elif forloop.counter != 1 %} + New domain request {{ forloop.counter }} + {% else %} + New domain request + {% endif %} {% if application.submission_date %} @@ -135,7 +147,7 @@ - Edit {{ application.requested_domain.name|default:"New domain request" }} + Edit {{ application.requested_domain.name|default:"New domain request"|add:forloop.counter|add:"" }} {% else %} @@ -163,16 +175,18 @@

- {% with heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} - {% include 'includes/modal.html' with modal_heading=heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} - {% endwith %} + {% if application.requested_domain %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% else %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete your domain request?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endif %}
{% endif %} diff --git a/src/registrar/templates/includes/modal.html b/src/registrar/templates/includes/modal.html index 1f9fbcfd4..a5ae4b1f2 100644 --- a/src/registrar/templates/includes/modal.html +++ b/src/registrar/templates/includes/modal.html @@ -2,7 +2,7 @@
-
diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 43f251d47..75a3944a6 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -21,7 +21,7 @@ def index(request): # Determine if the user will see applications that they can delete valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] - has_deletable_applications = applications.filter(status__in=valid_statuses) + has_deletable_applications = applications.filter(status__in=valid_statuses).exists() context["has_deletable_applications"] = has_deletable_applications if has_deletable_applications: @@ -32,4 +32,5 @@ def index(request): ) context["modal_button"] = modal_button + return render(request, "home.html", context) From d9151febcf7366855de4f30b01830794ec05aa7e Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:03:00 -0700 Subject: [PATCH 009/107] Update _usa-modal.scss --- src/registrar/assets/sass/_theme/_usa-modal.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/registrar/assets/sass/_theme/_usa-modal.scss b/src/registrar/assets/sass/_theme/_usa-modal.scss index 7106f1961..962394e42 100644 --- a/src/registrar/assets/sass/_theme/_usa-modal.scss +++ b/src/registrar/assets/sass/_theme/_usa-modal.scss @@ -1,3 +1,4 @@ +@use "cisa_colors" as *; @use "uswds-core" as *; .usa-modal.wider-modal { From dcc8f99553b087d98f9ceb335ee37e660f375380 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:37:48 -0700 Subject: [PATCH 010/107] Minor improvements --- src/registrar/assets/sass/_theme/_tables.scss | 4 ++-- src/registrar/templates/home.html | 4 ++-- src/registrar/tests/test_views.py | 4 ++-- src/registrar/views/application.py | 4 +++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index f3adab18b..bde74cf08 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -32,8 +32,8 @@ // Fix margins in mobile view @media screen { - td.tablet-margin-top-5 { - margin-top: 40px !important; + td.tablet-margin-top-2 { + margin-top: 16px !important; } } } diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 4e7e9729b..ba2a41aa3 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -147,7 +147,7 @@ - Edit {{ application.requested_domain.name|default:"New domain request"|add:forloop.counter|add:"" }} + Edit {{ application.requested_domain.name|default:"New domain request" }} {% else %} @@ -159,7 +159,7 @@ {% if has_deletable_applications %} - + {% if application.status == "started" or application.status == "withdrawn" %} Date: Fri, 5 Jan 2024 15:40:21 -0700 Subject: [PATCH 011/107] Fix wonky width --- src/registrar/assets/sass/_theme/_tables.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index bde74cf08..e30023d9b 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -27,7 +27,7 @@ } th.action-col-custom-width { - width: 23.25% !important; + width: 24.25% !important; } // Fix margins in mobile view From daec39a87a160720e785c3e6a8b84ed36584131a Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:44:15 -0700 Subject: [PATCH 012/107] Update test_views.py --- src/registrar/tests/test_views.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index 731b7224f..bd9ec3a4f 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -89,8 +89,9 @@ class LoggedInTests(TestWithUser): application = DomainApplication.objects.create(creator=self.user, requested_domain=site) response = self.client.get("/") - # count = 4 because it is also in screenreader content, and in the delete modal - self.assertContains(response, "igorville.gov", count=4) + # count = 5 because it is also in screenreader content, and in the delete modal + self.assertContains(response, "igorville.gov", count=5) + # clean up application.delete() From 0859311be2c8fbf7290b74d22849c85a5d1d9804 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Mon, 8 Jan 2024 07:43:53 -0700 Subject: [PATCH 013/107] Remove !important --- src/registrar/assets/sass/_theme/_tables.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index e30023d9b..a42eefd6c 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -27,13 +27,13 @@ } th.action-col-custom-width { - width: 24.25% !important; + width: 24.25%; } // Fix margins in mobile view @media screen { td.tablet-margin-top-2 { - margin-top: 16px !important; + margin-top: 16px; } } } From 62f460b165d37766edb10b3ed5864ac93baed92d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:22:03 -0700 Subject: [PATCH 014/107] Remove blue header --- src/registrar/assets/sass/_theme/_usa-modal.scss | 6 ------ src/registrar/templates/includes/modal.html | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_usa-modal.scss b/src/registrar/assets/sass/_theme/_usa-modal.scss index 962394e42..68a46a303 100644 --- a/src/registrar/assets/sass/_theme/_usa-modal.scss +++ b/src/registrar/assets/sass/_theme/_usa-modal.scss @@ -5,9 +5,3 @@ width: 40% !important; max-width: 40% !important; } - -.usa-modal { - .usa-modal__heading.blue-header{ - color: $dhs-blue; - } -} \ No newline at end of file diff --git a/src/registrar/templates/includes/modal.html b/src/registrar/templates/includes/modal.html index a5ae4b1f2..1f9fbcfd4 100644 --- a/src/registrar/templates/includes/modal.html +++ b/src/registrar/templates/includes/modal.html @@ -2,7 +2,7 @@
-
From 510b8e3f15f0eb5651527f2a4304c0a8f52811b1 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Mon, 8 Jan 2024 18:13:54 -0500 Subject: [PATCH 015/107] Handle the word 'optional' in nameservers labels on add and delete --- src/registrar/assets/js/get-gov.js | 39 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 177b771e4..9e3f699bf 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -260,10 +260,22 @@ function removeForm(e, formLabel, isNameserversForm, addButton, formIdentifier){ // h2 and legend for DS form, label for nameservers Array.from(form.querySelectorAll('h2, legend, label, p')).forEach((node) => { + + let innerSpan = node.querySelector('span') + if (innerSpan) { + innerSpan.textContent = innerSpan.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`); + } else { + node.textContent = node.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`); + node.textContent = node.textContent.replace(formExampleRegex, `ns${index + 1}`); + } // If the node is a nameserver label, one of the first 2 which was previously 3 and up (not required) // inject the USWDS required markup and make sure the INPUT is required if (isNameserversForm && index <= 1 && node.innerHTML.includes('server') && !node.innerHTML.includes('*')) { + + // Remove the word optional + innerSpan.textContent = innerSpan.textContent.replace(/\s*\(\s*optional\s*\)\s*/, ''); + // Create a new element const newElement = document.createElement('abbr'); newElement.textContent = '*'; @@ -286,13 +298,8 @@ function removeForm(e, formLabel, isNameserversForm, addButton, formIdentifier){ nextInputElement.required = true; } - let innerSpan = node.querySelector('span') - if (innerSpan) { - innerSpan.textContent = innerSpan.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`); - } else { - node.textContent = node.textContent.replace(formLabelRegex, `${formLabel} ${index + 1}`); - node.textContent = node.textContent.replace(formExampleRegex, `ns${index + 1}`); - } + + }); // Display the add more button if we have less than 13 forms @@ -469,7 +476,7 @@ function hideDeletedForms() { let formLabel = ''; let isNameserversForm = document.title.includes("DNS name servers |"); let isOtherContactsForm = document.title.includes("Other employees from your organization"); - // The Nameservers form st features 2 required and 11 optionals + // The Nameservers formset features 2 required and 11 optionals if (isNameserversForm) { cloneIndex = 2; formLabel = "Name server"; @@ -537,16 +544,24 @@ function hideDeletedForms() { formNum++; newForm.innerHTML = newForm.innerHTML.replace(formNumberRegex, `${formIdentifier}-${formNum-1}-`); - // For the other contacts form, we need to update the fieldset headers based on what's visible vs hidden, - // since the form on the backend employs Django's DELETE widget. For the other formsets, we delete the form - // in JS (completely remove from teh DOM) so we update the headers/labels based on total number of forms. if (isOtherContactsForm) { + // For the other contacts form, we need to update the fieldset headers based on what's visible vs hidden, + // since the form on the backend employs Django's DELETE widget. let totalShownForms = document.querySelectorAll(`.repeatable-form:not([style*="display: none"])`).length; newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${totalShownForms + 1}`); } else { - newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${formNum}`); + // Nameservers form is cloned from index 2 which has the word optional on init, does not have the word optional + // if indices 0 or 1 have been deleted + let containsOptional = newForm.innerHTML.includes('(optional)'); + if (isNameserversForm && !containsOptional) { + newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${formNum} (optional)`); + } else { + newForm.innerHTML = newForm.innerHTML.replace(formLabelRegex, `${formLabel} ${formNum}`); + } } newForm.innerHTML = newForm.innerHTML.replace(formExampleRegex, `ns${formNum}`); + newForm.innerHTML = newForm.innerHTML.replace(/\n/g, ''); // Remove newline characters + newForm.innerHTML = newForm.innerHTML.replace(/>\s*<'); // Remove spaces between tags container.insertBefore(newForm, addButton); newForm.style.display = 'block'; From dff0ef8f3fdb735dff533644eaf8625cbfb595a1 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 9 Jan 2024 07:57:13 -0700 Subject: [PATCH 016/107] Remove underline --- src/registrar/assets/sass/_theme/_base.scss | 4 ++++ src/registrar/templates/home.html | 21 ++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_base.scss b/src/registrar/assets/sass/_theme/_base.scss index 1d936a255..45f7a9383 100644 --- a/src/registrar/assets/sass/_theme/_base.scss +++ b/src/registrar/assets/sass/_theme/_base.scss @@ -125,3 +125,7 @@ abbr[title] { .flex-end { align-items: flex-end; } + +.remove-underline { + text-decoration: none !important; +} \ No newline at end of file diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index ba2a41aa3..30bfd1034 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -147,14 +147,21 @@ - Edit {{ application.requested_domain.name|default:"New domain request" }} - + {% if application.requested_domain and application.requested_domain.name %} + Edit {{ application.requested_domain.name }} + {% else %} + Edit New domain request {{ forloop.counter }} + {% endif %} {% else %} - Manage {{application.requested_domain.name}} + {% if application.requested_domain and application.requested_domain.name %} + Manage {{ application.requested_domain.name }} + {% else %} + Manage New domain request {{ forloop.counter }} + {% endif %} {% endif %} @@ -164,14 +171,18 @@ - Delete + {% if application.requested_domain and application.requested_domain.name %} + Delete {{ application.requested_domain.name }} + {% else %} + Delete New domain request {{ forloop.counter }} + {% endif %}
Date: Tue, 9 Jan 2024 08:42:37 -0700 Subject: [PATCH 017/107] Rewrite logic for "New domain request" --- src/registrar/templates/home.html | 26 ++++---------------------- src/registrar/views/index.py | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 30bfd1034..9ed1d924b 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -125,13 +125,7 @@ {% for application in domain_applications %} - {% if application.requested_domain and application.requested_domain.name %} - {{ application.requested_domain.name }} - {% elif forloop.counter != 1 %} - New domain request {{ forloop.counter }} - {% else %} - New domain request - {% endif %} + {{ application.requested_domain.name|default:"New domain request" }} {% if application.submission_date %} @@ -147,21 +141,13 @@ - {% if application.requested_domain and application.requested_domain.name %} - Edit {{ application.requested_domain.name }} - {% else %} - Edit New domain request {{ forloop.counter }} - {% endif %} + Edit {{ application.requested_domain.name|default:"New domain request" }} {% else %} - {% if application.requested_domain and application.requested_domain.name %} - Manage {{ application.requested_domain.name }} - {% else %} - Manage New domain request {{ forloop.counter }} - {% endif %} + Manage {{ application.requested_domain.name|default:"New domain request" }} {% endif %} @@ -178,11 +164,7 @@ - {% if application.requested_domain and application.requested_domain.name %} - Delete {{ application.requested_domain.name }} - {% else %} - Delete New domain request {{ forloop.counter }} - {% endif %} + Delete {{ application.requested_domain.name|default:"New domain request" }}
Date: Tue, 9 Jan 2024 08:44:33 -0700 Subject: [PATCH 018/107] Update index.py --- src/registrar/views/index.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 681f8e9c1..41cdd9cf2 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -12,8 +12,7 @@ def index(request): # domain_applications context will be used to populate # the active applications table applications = DomainApplication.objects.filter(creator=request.user).exclude(status="approved") - - sorted_applications = applications.filter("-requested_domain__name") + # Adds display logic for empty domain requests counter = 1 for application in applications: From fed4432207a994a3a6ba37d2a0479a7d00a1d6a5 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 9 Jan 2024 08:45:21 -0700 Subject: [PATCH 019/107] Linting --- src/registrar/views/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 41cdd9cf2..0e7528e08 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -19,7 +19,7 @@ def index(request): if not application.requested_domain or not application.requested_domain.name: application.requested_domain = DraftDomain(name=f"New domain request {counter}") counter += 1 - + # Pass the final context to the application context["domain_applications"] = applications From ba04cf7f878308c396640f64d50bc31fee3ee981 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 9 Jan 2024 09:11:40 -0700 Subject: [PATCH 020/107] Update test_views.py --- src/registrar/tests/test_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index bd9ec3a4f..11996097b 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -89,8 +89,8 @@ class LoggedInTests(TestWithUser): application = DomainApplication.objects.create(creator=self.user, requested_domain=site) response = self.client.get("/") - # count = 5 because it is also in screenreader content, and in the delete modal - self.assertContains(response, "igorville.gov", count=5) + # count = 6 because it is also in screenreader content, and in the delete modal + self.assertContains(response, "igorville.gov", count=6) # clean up application.delete() From 7c87718e2d21e310443d1482113e060d6d7f47b4 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:15:54 -0800 Subject: [PATCH 021/107] Save initial script --- src/epplibwrapper/tests/test_pool.py | 13 +++++ src/migrationdata/README.md | 8 --- .../update_security_email_disclose.py | 53 +++++++++++++++++++ src/registrar/models/domain.py | 2 +- 4 files changed, 67 insertions(+), 9 deletions(-) delete mode 100644 src/migrationdata/README.md create mode 100644 src/registrar/management/commands/update_security_email_disclose.py diff --git a/src/epplibwrapper/tests/test_pool.py b/src/epplibwrapper/tests/test_pool.py index 1c36d26da..916015980 100644 --- a/src/epplibwrapper/tests/test_pool.py +++ b/src/epplibwrapper/tests/test_pool.py @@ -246,3 +246,16 @@ class TestConnectionPool(TestCase): expected = "InfoDomain failed to execute due to a connection error." result = registry.send(commands.InfoDomain(name="test.gov"), cleaned=True) self.assertEqual(result, expected) + + @patch.object(EPPLibWrapper, "_test_registry_connection_success", patch_success) + def test_retries_on_transport_error(self): + """A .send is invoked on the pool, but transport error occurs and EPP + retries connection.""" + + with ExitStack() as stack: + stack.enter_context(patch.object(EPPConnectionPool, "_create_socket", self.fake_socket)) + stack.enter_context(patch.object(Socket, "connect", self.fake_client)) + + # Pool should be running + self.assertEqual(registry.pool_status.connection_success, True) + self.assertEqual(registry.pool_status.pool_running, True) diff --git a/src/migrationdata/README.md b/src/migrationdata/README.md deleted file mode 100644 index 81190ee3f..000000000 --- a/src/migrationdata/README.md +++ /dev/null @@ -1,8 +0,0 @@ -## Purpose -Use this folder for storing files for the migration process. Should otherwise be empty on local dev environments unless necessary. This folder must exist due to the nature of how data is stored on cloud.gov and the nature of the data we want to send. - -## How do I migrate registrar data? -This process is detailed in [data_migration.md](../../docs/operations/data_migration.md) - -## What kind of files can I store here? -The intent is for PII data or otherwise, but this can exist in any format. Do note that the data contained in this file will be temporary, so after the app is restaged it will lose it. This is ideal for migration files as they write to our DB, but not for something you need to permanently hold onto. \ No newline at end of file diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py new file mode 100644 index 000000000..13627e220 --- /dev/null +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -0,0 +1,53 @@ +""""Script description""" + +import logging + +from django.core.management import BaseCommand +from registrar.models import Domain + +logger = logging.getLogger(__name__) + +class Command(BaseCommand): + # TODO: write script description here + help = "Description" + + def __init__(self): + """Sets global variables for code tidyness""" + super().__init__() + # this array is used to store domains with errors, which are not + # successfully updated to disclose + domains_with_errors: List[str] = [] + + def handle(self, **options): + """ + Description for what update_security_email_disclose does + """ + logger.info("Updating security emails to public") + + domains = Domain.objects.filter() + + # Call security_contact on all domains to trigger saving contact information + for domain in domains: + contact = domain.security_contact + + domains_with_contact = Domain.objects.filter( + security_contact_registry_id=True + ) + logger.info("Found %d domains with security contact.", len(domains_with_contact)) + + # Update EPP contact for domains with a security contact + for domain in domains_with_contact: + try: + domain._update_epp_contact(contact=domain.security_contact_registry_id) + logger.info("Updated EPP contact for domain %d to disclose: %d", domain, domain.security_contact.disclose) + except Exception as err: + # error condition if domain not in database + self.domains_with_errors.append(copy.deepcopy(domain.domain_name)) + logger.error(f"error retrieving domain {domain.domain_name}: {err}") + + domains_disclosed = Domain.objects.filter( + security_contact_registry_id=True, + ) + logger.info("Updated %d domains to disclosed.", len(domains_disclosed)) + + diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 001937b89..b3791d4b9 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1400,7 +1400,7 @@ class Domain(TimeStampedModel, DomainHelper): is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} - disclose = is_security and contact.email != PublicContact.get_default_security().email + disclose = is_security # Will only disclose DF.EMAIL if its not the default return epp.Disclose( flag=disclose, From 683a2f46292d025cc2dd56c21972695bc4405854 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:13:48 -0800 Subject: [PATCH 022/107] Update initial disclose script --- .../update_security_email_disclose.py | 32 +++++++++++-------- src/registrar/models/domain.py | 2 ++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index 13627e220..9ba1c58b7 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -1,6 +1,7 @@ """"Script description""" import logging +import copy from django.core.management import BaseCommand from registrar.models import Domain @@ -14,16 +15,20 @@ class Command(BaseCommand): def __init__(self): """Sets global variables for code tidyness""" super().__init__() - # this array is used to store domains with errors, which are not - # successfully updated to disclose - domains_with_errors: List[str] = [] + # domains and transition domains that must be disclosed to true + self.domains_to_disclose: List[str] = [] + # domains with errors, which are not successfully updated to disclose + self.domains_with_errors: List[str] = [] + # domains that are successfully disclosed + self.disclosed_domain_contacts: List[str] = [] def handle(self, **options): """ Description for what update_security_email_disclose does """ logger.info("Updating security emails to public") - + + # Initializes domains that need to be disclosed domains = Domain.objects.filter() # Call security_contact on all domains to trigger saving contact information @@ -31,23 +36,24 @@ class Command(BaseCommand): contact = domain.security_contact domains_with_contact = Domain.objects.filter( - security_contact_registry_id=True + security_contact_registry_id__isnull=False ) logger.info("Found %d domains with security contact.", len(domains_with_contact)) # Update EPP contact for domains with a security contact for domain in domains_with_contact: try: - domain._update_epp_contact(contact=domain.security_contact_registry_id) - logger.info("Updated EPP contact for domain %d to disclose: %d", domain, domain.security_contact.disclose) + logger.info("Domain %s security contact: %s", domain, domain.security_contact) + domain._update_epp_contact(contact=domain.security_contact) + self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database - self.domains_with_errors.append(copy.deepcopy(domain.domain_name)) - logger.error(f"error retrieving domain {domain.domain_name}: {err}") + self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) + logger.error(f"error retrieving domain {domain.domain_info}: {err}") - domains_disclosed = Domain.objects.filter( - security_contact_registry_id=True, - ) - logger.info("Updated %d domains to disclosed.", len(domains_disclosed)) + # Update transition domains to disclose + + # Inform user how many contacts were disclosed + logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index b3791d4b9..bdca1d4ef 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1401,6 +1401,8 @@ class Domain(TimeStampedModel, DomainHelper): DF = epp.DiscloseField fields = {DF.EMAIL} disclose = is_security + # Delete after testing + logger.info("Updated domain contact to disclose: %s", disclose) # Will only disclose DF.EMAIL if its not the default return epp.Disclose( flag=disclose, From 0a13ff99766e3eca6705d1fc520314637e463823 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 10:38:17 -0800 Subject: [PATCH 023/107] Readd default email check for email disclose --- .../update_security_email_disclose.py | 24 ++++++++++--------- src/registrar/models/domain.py | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index 9ba1c58b7..ffefc815b 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -29,30 +29,32 @@ class Command(BaseCommand): logger.info("Updating security emails to public") # Initializes domains that need to be disclosed - domains = Domain.objects.filter() + statuses=["ready", "dns needed"] + domains = Domain.objects.filter( + state__in=statuses + ) # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact - domains_with_contact = Domain.objects.filter( - security_contact_registry_id__isnull=False - ) - logger.info("Found %d domains with security contact.", len(domains_with_contact)) + logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) # Update EPP contact for domains with a security contact - for domain in domains_with_contact: + for domain in domains: try: - logger.info("Domain %s security contact: %s", domain, domain.security_contact) - domain._update_epp_contact(contact=domain.security_contact) - self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) + logger.info("Domain %s security contact: %s", domain.domain_info, domain.security_contact.email) + if domain.security_contact.email != "registrar@dotgov.gov": + domain._update_epp_contact(contact=domain.security_contact) + self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) + else: + logger.info("Skipping disclose for %s security contact.", + domain.domain_info, domain.security_contact.email) except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") - # Update transition domains to disclose - # Inform user how many contacts were disclosed logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index bdca1d4ef..7f052a581 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1400,7 +1400,7 @@ class Domain(TimeStampedModel, DomainHelper): is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} - disclose = is_security + disclose = is_security and contact.email != PublicContact.get_default_security().email # Delete after testing logger.info("Updated domain contact to disclose: %s", disclose) # Will only disclose DF.EMAIL if its not the default From 74b115cd1868b702c0d46d5980cf79ce537ee2ab Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:33:01 -0700 Subject: [PATCH 024/107] CSS changes (PR suggestions) --- src/registrar/assets/sass/_theme/_base.scss | 4 ---- src/registrar/assets/sass/_theme/_tables.scss | 2 +- src/registrar/templates/home.html | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_base.scss b/src/registrar/assets/sass/_theme/_base.scss index 45f7a9383..1d936a255 100644 --- a/src/registrar/assets/sass/_theme/_base.scss +++ b/src/registrar/assets/sass/_theme/_base.scss @@ -125,7 +125,3 @@ abbr[title] { .flex-end { align-items: flex-end; } - -.remove-underline { - text-decoration: none !important; -} \ No newline at end of file diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index a42eefd6c..ec4ae3cd1 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -31,7 +31,7 @@ } // Fix margins in mobile view - @media screen { + @include at-media('tablet') { td.tablet-margin-top-2 { margin-top: 16px; } diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 9ed1d924b..d65ffa152 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -157,7 +157,7 @@ From f87be48c474dd2a2ceac103ae9eb78822bd6888c Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:35:59 -0800 Subject: [PATCH 025/107] Add logs for skipped disclose contacts --- .../commands/update_security_email_disclose.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/update_security_email_disclose.py index ffefc815b..7bf2c2533 100644 --- a/src/registrar/management/commands/update_security_email_disclose.py +++ b/src/registrar/management/commands/update_security_email_disclose.py @@ -21,6 +21,8 @@ class Command(BaseCommand): self.domains_with_errors: List[str] = [] # domains that are successfully disclosed self.disclosed_domain_contacts: List[str] = [] + # domains that skip disclose due to having contact registrar@dotgov.gov + self.skipped_domain_contacts: List[str] = [] def handle(self, **options): """ @@ -48,14 +50,17 @@ class Command(BaseCommand): domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) else: - logger.info("Skipping disclose for %s security contact.", + logger.info("Skipping disclose for %s security contact %s.", domain.domain_info, domain.security_contact.email) + self.skipped_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) logger.error(f"error retrieving domain {domain.domain_info}: {err}") - # Inform user how many contacts were disclosed + # Inform user how many contacts were disclosed and skipped logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) + logger.info("Skipped disclosing %d contacts with security email registrar@dotgov.gov.", + len(self.skipped_domain_contacts)) From 935172d5b27b69f7d9d75b84c69c920d65a20aa9 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:44:19 -0700 Subject: [PATCH 026/107] Update application.py --- src/registrar/views/application.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 5a13b8a46..f4e76b6ee 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -154,6 +154,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): def storage(self): # marking session as modified on every access # so that updates to nested keys are always saved + # TEST PUSHWILL DELETE self.request.session.modified = True return self.request.session.setdefault(self.prefix, {}) From 3c4ec9ab1ff58b209aa00e0b1bffcbf44a0407e7 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Wed, 10 Jan 2024 18:39:01 -0500 Subject: [PATCH 027/107] CSS cleanup --- src/registrar/assets/sass/_theme/_tables.scss | 25 +++++++++++-------- .../assets/sass/_theme/_usa-modal.scss | 7 ------ src/registrar/assets/sass/_theme/styles.scss | 1 - src/registrar/templates/home.html | 20 ++++++++------- 4 files changed, 26 insertions(+), 27 deletions(-) delete mode 100644 src/registrar/assets/sass/_theme/_usa-modal.scss diff --git a/src/registrar/assets/sass/_theme/_tables.scss b/src/registrar/assets/sass/_theme/_tables.scss index ec4ae3cd1..84c4791e5 100644 --- a/src/registrar/assets/sass/_theme/_tables.scss +++ b/src/registrar/assets/sass/_theme/_tables.scss @@ -26,16 +26,21 @@ padding-bottom: units(2px); } - th.action-col-custom-width { - width: 24.25%; - } - - // Fix margins in mobile view - @include at-media('tablet') { - td.tablet-margin-top-2 { - margin-top: 16px; - } - } + // Ticket #1510 + // @include at-media('desktop') { + // th:first-child { + // width: 220px; + // } + // th:nth-child(2) { + // width: 175px; + // } + // th:nth-child(3) { + // width: 130px; + // } + // th:nth-child(5) { + // width: 130px; + // } + // } } .dotgov-table { diff --git a/src/registrar/assets/sass/_theme/_usa-modal.scss b/src/registrar/assets/sass/_theme/_usa-modal.scss deleted file mode 100644 index 68a46a303..000000000 --- a/src/registrar/assets/sass/_theme/_usa-modal.scss +++ /dev/null @@ -1,7 +0,0 @@ -@use "cisa_colors" as *; -@use "uswds-core" as *; - -.usa-modal.wider-modal { - width: 40% !important; - max-width: 40% !important; -} diff --git a/src/registrar/assets/sass/_theme/styles.scss b/src/registrar/assets/sass/_theme/styles.scss index 499f9a806..8a2e1d2d3 100644 --- a/src/registrar/assets/sass/_theme/styles.scss +++ b/src/registrar/assets/sass/_theme/styles.scss @@ -17,7 +17,6 @@ @forward "tables"; @forward "sidenav"; @forward "register-form"; -@forward "usa-modal"; /*-------------------------------------------------- --- Admin ---------------------------------*/ diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index d65ffa152..9067c7927 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -9,7 +9,7 @@ {% if user.is_authenticated %} {# the entire logged in page goes here #} -
+

Manage your domains

@@ -31,7 +31,7 @@ {% endif %}

-
+

Domains

{% if domains %} @@ -44,13 +44,14 @@ + {% comment %} + #1510 {% if has_deletable_applications %} - {% endif %} + {% endif %} {% endcomment %} @@ -105,7 +106,7 @@ {% endif %} -
+

Domain requests

{% if domain_applications %}
Action
@@ -137,7 +138,7 @@ {% if has_deletable_applications %} - - {% if has_deletable_applications %} - - {% endif %} {% endfor %} From 3ed410aaa8c44185bd708a0fd4ebd4d4fd1ce35a Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:46:35 -0700 Subject: [PATCH 029/107] Revert "Update home.html" This reverts commit e490c5de1d70e32cbd4e7e21b5eb9856b32eafe8. --- src/registrar/templates/home.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 30580389a..9067c7927 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -90,6 +90,9 @@ {% endif %} + {% if has_deletable_applications %} + + {% endif %} {% endfor %} From dfec1d24821d884229d6e76f08957840d67a42ad Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:47:40 -0700 Subject: [PATCH 030/107] Update home.html --- src/registrar/templates/home.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 9067c7927..30580389a 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -90,9 +90,6 @@ {% endif %} - {% if has_deletable_applications %} - - {% endif %} {% endfor %} From e3bb4afbb12d5c92213e091b143f83d1b9490604 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:12:08 -0800 Subject: [PATCH 031/107] Add test for disclose_security_emails making EPP calls --- ...isclose.py => disclose_security_emails.py} | 0 src/registrar/tests/test_models_domain.py | 30 +++++++++++++++++++ 2 files changed, 30 insertions(+) rename src/registrar/management/commands/{update_security_email_disclose.py => disclose_security_emails.py} (100%) diff --git a/src/registrar/management/commands/update_security_email_disclose.py b/src/registrar/management/commands/disclose_security_emails.py similarity index 100% rename from src/registrar/management/commands/update_security_email_disclose.py rename to src/registrar/management/commands/disclose_security_emails.py diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 9026832cd..6b3a7ba05 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -5,6 +5,7 @@ This file tests the various ways in which the registrar interacts with the regis """ from django.test import TestCase from django.db.utils import IntegrityError +from django.core.management import call_command from unittest.mock import MagicMock, patch, call import datetime from registrar.models import Domain, Host, HostIP @@ -548,6 +549,19 @@ class TestRegistrantContacts(MockEppLib): self.domain_contact._invalidate_cache() PublicContact.objects.all().delete() Domain.objects.all().delete() + + def run_disclose_security_emails(self): + """ + This method executes the disclose_security_emails command. + + The 'call_command' function from Django's management framework is then used to + execute the disclose_security_emails command. + """ + with patch( + "registrar.management.commands.utility.terminal_helper.TerminalHelper.query_yes_no_exit", # noqa + return_value=True, + ): + call_command("extend_expiration_dates") def test_no_security_email(self): """ @@ -963,6 +977,22 @@ class TestRegistrantContacts(MockEppLib): self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) # Confirm that we are getting the desired email self.assertEqual(domain.security_contact.email, expectedSecContact.email) + + def test_disclose_security_emails(self): + """ + Tests that command disclose_security_emails runs successfully with + appropriate logs. + """ + domain, _ = Domain.objects.get_or_create(name="igorville.gov") + expectedSecContact = PublicContact.get_default_security() + expectedSecContact.domain = domain + expectedSecContact.email = "123@mail.gov" + domain.security_contact = expectedSecContact + self.run_disclose_security_emails() + + # running disclose_security_emails makes EPP calls + expectedUpdateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) + self.mockedSendFunction.assert_any_call(expectedUpdateCommand, cleaned=True) @skip("not implemented yet") def test_update_is_unsuccessful(self): From 273d457ac611eb58910c813605a449cac2e0fecc Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:12:55 -0800 Subject: [PATCH 032/107] Reword test description --- src/registrar/tests/test_models_domain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 6b3a7ba05..9c0a73a0a 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -981,7 +981,7 @@ class TestRegistrantContacts(MockEppLib): def test_disclose_security_emails(self): """ Tests that command disclose_security_emails runs successfully with - appropriate logs. + appropriate EPP calll to UpdateContact. """ domain, _ = Domain.objects.get_or_create(name="igorville.gov") expectedSecContact = PublicContact.get_default_security() From 4ddf96aed4a684aa0fb997994461368d764e6c4d Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:15:40 -0800 Subject: [PATCH 033/107] Add description to disclose_security_emails script --- .../management/commands/disclose_security_emails.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 7bf2c2533..ff26e4882 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -1,4 +1,8 @@ -""""Script description""" +"""" +Converts all ready and DNS needed domains with a non-default public contact +to disclose their public contact. Created for Issue#1535 to resolve + disclose issue of domains with missing security emails. +""" import logging import copy @@ -9,8 +13,7 @@ from registrar.models import Domain logger = logging.getLogger(__name__) class Command(BaseCommand): - # TODO: write script description here - help = "Description" + help = "Disclose all nondefault domain security emails." def __init__(self): """Sets global variables for code tidyness""" @@ -26,7 +29,8 @@ class Command(BaseCommand): def handle(self, **options): """ - Description for what update_security_email_disclose does + Converts all ready and DNS needed domains with a non-default public contact + to disclose their public contact. """ logger.info("Updating security emails to public") From d34b49c685ce63b625c8525d40f65393299db032 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:34:30 -0800 Subject: [PATCH 034/107] Fix lint errors --- .../commands/disclose_security_emails.py | 40 +++++++++++-------- src/registrar/tests/test_models_domain.py | 4 +- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index ff26e4882..a7ea0d2dd 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -12,6 +12,7 @@ from registrar.models import Domain logger = logging.getLogger(__name__) + class Command(BaseCommand): help = "Disclose all nondefault domain security emails." @@ -19,13 +20,13 @@ class Command(BaseCommand): """Sets global variables for code tidyness""" super().__init__() # domains and transition domains that must be disclosed to true - self.domains_to_disclose: List[str] = [] + self.contacts_saved: list[str] = [] # domains with errors, which are not successfully updated to disclose - self.domains_with_errors: List[str] = [] + self.domains_with_errors: list[str] = [] # domains that are successfully disclosed - self.disclosed_domain_contacts: List[str] = [] + self.disclosed_domain_contacts: list[str] = [] # domains that skip disclose due to having contact registrar@dotgov.gov - self.skipped_domain_contacts: List[str] = [] + self.skipped_domain_contacts: list[str] = [] def handle(self, **options): """ @@ -33,18 +34,20 @@ class Command(BaseCommand): to disclose their public contact. """ logger.info("Updating security emails to public") - + # Initializes domains that need to be disclosed - statuses=["ready", "dns needed"] - domains = Domain.objects.filter( - state__in=statuses - ) - + + statuses = ["ready", "dns needed"] + domains = Domain.objects.filter(state__in=statuses) + + logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) + # Call security_contact on all domains to trigger saving contact information for domain in domains: contact = domain.security_contact + self.contacts_saved.append(copy.deepcopy(contact)) - logger.info("Found %d domains with status Ready or DNS Needed.", len(domains)) + logger.info("Found %d security contacts.", len(self.contacts_saved)) # Update EPP contact for domains with a security contact for domain in domains: @@ -54,8 +57,11 @@ class Command(BaseCommand): domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts.append(copy.deepcopy(domain.security_contact)) else: - logger.info("Skipping disclose for %s security contact %s.", - domain.domain_info, domain.security_contact.email) + logger.info( + "Skipping disclose for %s security contact %s.", + domain.domain_info, + domain.security_contact.email, + ) self.skipped_domain_contacts.append(copy.deepcopy(domain.security_contact)) except Exception as err: # error condition if domain not in database @@ -64,7 +70,7 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed and skipped logger.info("Updated %d contacts to disclosed.", len(self.disclosed_domain_contacts)) - logger.info("Skipped disclosing %d contacts with security email registrar@dotgov.gov.", - len(self.skipped_domain_contacts)) - - + logger.info( + "Skipped disclosing %d contacts with security email registrar@dotgov.gov.", + len(self.skipped_domain_contacts), + ) diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index 9c0a73a0a..81b63e3f6 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -549,7 +549,7 @@ class TestRegistrantContacts(MockEppLib): self.domain_contact._invalidate_cache() PublicContact.objects.all().delete() Domain.objects.all().delete() - + def run_disclose_security_emails(self): """ This method executes the disclose_security_emails command. @@ -977,7 +977,7 @@ class TestRegistrantContacts(MockEppLib): self.mockedSendFunction.assert_any_call(expectedCreateCommand, cleaned=True) # Confirm that we are getting the desired email self.assertEqual(domain.security_contact.email, expectedSecContact.email) - + def test_disclose_security_emails(self): """ Tests that command disclose_security_emails runs successfully with From fa4789d6458bd343edb03558e3402cf5bc0af957 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 11 Jan 2024 08:23:44 -0700 Subject: [PATCH 035/107] Add role="button" --- src/registrar/templates/home.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 30580389a..8f7eee0b7 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -71,7 +71,7 @@ {% endif %} @@ -164,7 +170,7 @@ - Delete {{ application.requested_domain.name|default:"New domain request" }} + Delete {{ application.requested_domain.name|default:"New domain request ("|add:application.created_at|add:")" }}
- {% if application.requested_domain %} - {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} - {% else %} - {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete your domain request?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} - {% endif %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %}
{% endif %} diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index c76d285a7..80ff1eff1 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -143,93 +143,13 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): except DomainApplication.DoesNotExist: logger.debug("Application id %s did not have a DomainApplication" % id) - draft_domain = self._create_default_draft_domain() - - # Check added for linting purposes - if self.request.user and isinstance(self.request.user, User): - self._application = DomainApplication.objects.create( - creator=self.request.user, - requested_domain=draft_domain, - ) - else: - # TODO - Need some sort of front end display for this - raise ValueError("Invalid type for user") + self._application = DomainApplication.objects.create( + creator=self.request.user + ) self.storage["application_id"] = self._application.id return self._application - def _create_default_draft_domain(self): - "Set a default draft name for if the user exits without completing" - default_draft_text = "New domain request" - - # Does the user have any incomplete drafts? - existing_applications = DomainApplication.objects.filter( - Q(requested_domain=None) | Q(requested_domain__is_incomplete=True), - creator=self.request.user, - ) - - name_field = "requested_domain__name" - - incomplete_drafts = ( - existing_applications.exclude(requested_domain=None) - .filter(requested_domain__name__icontains=default_draft_text) - .order_by(name_field) - ) - - incomplete_draft_names = incomplete_drafts.values_list(name_field, flat=True) - - proposed_draft_number = incomplete_drafts.count() + 1 - draft_number = 1 - for application in existing_applications: - if application.requested_domain is not None and application.requested_domain.name is not None: - name = application.requested_domain.name - - # If we already have a list of draft numbers, base the - # subsequent number off of the last numbered field. - # This is to avoid a scenario in which drafts 1, 2, 3 and exist - # and 2 is deleted - meaning we would get two duplicate "3"s if we added another - if name in incomplete_draft_names: - # Get the last numbered draft - last_draft = incomplete_drafts.last() - last_draft_number = last_draft.requested_domain.draft_number - - smallest_number = self._find_smallest_missing_number(incomplete_drafts) - smallest_name = f"New domain request {smallest_number}" - if smallest_name not in incomplete_draft_names: - draft_number = smallest_number - elif proposed_draft_number == last_draft_number: - # If the draft number we are trying to create matches the last draft number, - # simply add one to that number - draft_number = last_draft_number + 1 - - draft_domain = DraftDomain( - # Save a blank string rather then None due to DB requirements - name="", - draft_number=draft_number, - is_incomplete=True, - ) - # Generate a default name based off of a draft_number - draft_domain.name = draft_domain.get_default_request_name() - draft_domain.save() - - return draft_domain - - def _find_smallest_missing_number(self, incomplete_drafts): - draft_numbers = [] - for draft in incomplete_drafts: - number = draft.requested_domain.draft_number - if number is not None: - draft_numbers.append(number) - - draft_numbers = sorted(draft_numbers) - smallest_missing = 1 - for number in draft_numbers: - if number == smallest_missing: - smallest_missing += 1 - elif number > smallest_missing: - break - return smallest_missing - @property def storage(self): # marking session as modified on every access @@ -409,7 +329,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): # Build the submit button that we'll pass to the modal. modal_button = '" # Concatenate the modal header that we'll pass to the modal. - if self.application.requested_domain and not self.application.requested_domain.is_incomplete: + if self.application.requested_domain: modal_heading = "You are about to submit a domain request for " + str(self.application.requested_domain) else: modal_heading = "You are about to submit an incomplete request" @@ -556,14 +476,6 @@ class DotgovDomain(ApplicationWizard): context["federal_type"] = self.application.federal_type return context - def post(self, request, *args, **kwargs): - """Override for the post method to mark the DraftDomain as complete""" - # Set the DraftDomain to "complete" - print(f"what is the request at this time? {request}") - self.application.requested_domain.is_incomplete = False - response = super().post(request, *args, **kwargs) - return response - class Purpose(ApplicationWizard): template_name = "application_purpose.html" diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index f9a658942..3c0f7c723 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -1,6 +1,8 @@ +from django.utils import timezone from django.shortcuts import render from registrar.models import DomainApplication, Domain, UserDomainRole +from registrar.models.draft_domain import DraftDomain def index(request): @@ -12,6 +14,22 @@ def index(request): # the active applications table applications = DomainApplication.objects.filter(creator=request.user).exclude(status="approved") + + valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] + + # Create a placeholder DraftDomain for each incomplete draft + deletable_applications = applications.filter(status__in=valid_statuses, requested_domain=None) + for application in applications: + if application in deletable_applications: + created_at = application.created_at.strftime("%b. %d, %Y, %I:%M %p UTC") + _name = f"New domain request ({created_at})" + default_draft_domain = DraftDomain( + name=_name, + is_complete=False + ) + + application.requested_domain = default_draft_domain + # Pass the final context to the application context["domain_applications"] = applications @@ -22,17 +40,16 @@ def index(request): context["domains"] = domains # Determine if the user will see applications that they can delete - valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] - has_deletable_applications = applications.filter(status__in=valid_statuses).exists() + has_deletable_applications = deletable_applications.exists() context["has_deletable_applications"] = has_deletable_applications - if has_deletable_applications: + + # Add the delete modal button to the context modal_button = ( '' ) - context["modal_button"] = modal_button return render(request, "home.html", context) From f623d00fc229d102df05a682dc3207f77238ca22 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:16:48 -0700 Subject: [PATCH 051/107] Index.py refactor --- src/registrar/views/index.py | 66 ++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 3c0f7c723..0a682b855 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -9,41 +9,21 @@ def index(request): """This page is available to anyone without logging in.""" context = {} if request.user.is_authenticated: - # Let's exclude the approved applications since our - # domain_applications context will be used to populate - # the active applications table - applications = DomainApplication.objects.filter(creator=request.user).exclude(status="approved") - - valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] - - # Create a placeholder DraftDomain for each incomplete draft - deletable_applications = applications.filter(status__in=valid_statuses, requested_domain=None) - for application in applications: - if application in deletable_applications: - created_at = application.created_at.strftime("%b. %d, %Y, %I:%M %p UTC") - _name = f"New domain request ({created_at})" - default_draft_domain = DraftDomain( - name=_name, - is_complete=False - ) - - application.requested_domain = default_draft_domain - - # Pass the final context to the application + # Get all domain applications the user has access to + applications, deletable_applications = _get_applications(request) context["domain_applications"] = applications - user_domain_roles = UserDomainRole.objects.filter(user=request.user) - domain_ids = user_domain_roles.values_list("domain_id", flat=True) - domains = Domain.objects.filter(id__in=domain_ids) - + # Get all domains the user has access to + domains = _get_domains(request) context["domains"] = domains # Determine if the user will see applications that they can delete has_deletable_applications = deletable_applications.exists() context["has_deletable_applications"] = has_deletable_applications - if has_deletable_applications: + # If they can delete applications, add the delete button to the context + if has_deletable_applications: # Add the delete modal button to the context modal_button = ( '
{{ application.get_status_display }} {% if application.status == "started" or application.status == "action needed" or application.status == "withdrawn" %} - + @@ -152,12 +153,13 @@ + {% if application.status == "started" or application.status == "withdrawn" %} @@ -168,7 +170,7 @@
Date: Wed, 10 Jan 2024 16:44:18 -0700 Subject: [PATCH 028/107] Update home.html --- src/registrar/templates/home.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index d65ffa152..e62a25de2 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -89,9 +89,6 @@ {% endif %}
- + {{ application.requested_domain.name|default:"New domain request" }} {% else %} - + From 10b589a1ecc09c98e3a54551bd096668bc7cde63 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:21:08 -0700 Subject: [PATCH 036/107] Use DB for draft domain naming in progress --- ...in_is_incomplete_alter_draftdomain_name.py | 22 +++++ src/registrar/models/draft_domain.py | 6 +- src/registrar/views/application.py | 90 ++++++++++++++++++- src/registrar/views/index.py | 8 +- 4 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py diff --git a/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py b/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py new file mode 100644 index 000000000..fcb462e22 --- /dev/null +++ b/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.7 on 2024-01-11 19:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("registrar", "0062_alter_host_name"), + ] + + operations = [ + migrations.AddField( + model_name="draftdomain", + name="is_incomplete", + field=models.BooleanField(default=False, help_text="Determines if this Draft is complete or not"), + ), + migrations.AlterField( + model_name="draftdomain", + name="name", + field=models.CharField(help_text="Fully qualified domain name", max_length=253), + ), + ] diff --git a/src/registrar/models/draft_domain.py b/src/registrar/models/draft_domain.py index fc70a18f3..4d79494f5 100644 --- a/src/registrar/models/draft_domain.py +++ b/src/registrar/models/draft_domain.py @@ -17,6 +17,10 @@ class DraftDomain(TimeStampedModel, DomainHelper): name = models.CharField( max_length=253, blank=False, - default=None, # prevent saving without a value help_text="Fully qualified domain name", ) + + is_incomplete = models.BooleanField( + default=False, + help_text="Determines if this Draft is complete or not" + ) \ No newline at end of file diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 9b60c49ab..deda6d0d2 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,5 +1,7 @@ import logging +import re +from django.db.models import Q from django.http import Http404, HttpResponse, HttpResponseRedirect from django.shortcuts import redirect, render from django.urls import resolve, reverse @@ -10,6 +12,7 @@ from django.contrib import messages from registrar.forms import application_wizard as forms from registrar.models import DomainApplication +from registrar.models.draft_domain import DraftDomain from registrar.utility import StrEnum from registrar.views.utility import StepsHelper from registrar.views.utility.permission_views import DomainApplicationPermissionDeleteView @@ -139,14 +142,97 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): return self._application except DomainApplication.DoesNotExist: logger.debug("Application id %s did not have a DomainApplication" % id) - + + # TODO - revert back to using draft_name + draft_domain = self._create_default_draft_domain() self._application = DomainApplication.objects.create( - creator=self.request.user, # type: ignore + creator=self.request.user, + requested_domain=draft_domain, ) self.storage["application_id"] = self._application.id return self._application + def _create_default_draft_domain(self): + "Set a default draft name for if the user exits without completing" + default_draft_text = "New domain request" + + # Does the user have any incomplete drafts? + existing_applications = DomainApplication.objects.filter( + Q(requested_domain=None) | Q(requested_domain__is_incomplete=True), + creator=self.request.user, + ) + + name_field = "requested_domain__name" + + incomplete_drafts = existing_applications.exclude(requested_domain=None).filter( + requested_domain__name__icontains=default_draft_text + ).order_by(name_field) + + incomplete_draft_names = incomplete_drafts.values_list(name_field, flat=True) + + proposed_draft_number = incomplete_drafts.count() + 1 + draft_name = f"New domain request {proposed_draft_number}" + for application in existing_applications: + if application.requested_domain is not None and application.requested_domain.name is not None: + name = application.requested_domain.name + + # If we already have a list of draft numbers, base the + # subsequent number off of the last numbered field. + # This is to avoid a scenario in which drafts 1, 2, 3 and exist + # and 2 is deleted - meaning we would get two duplicate "3"s if we added another + if name in incomplete_draft_names: + # Get the last numbered draft + last_draft = incomplete_draft_names.last() + last_draft_number = self._parse_first_number_from_string(last_draft) + + smallest_number = self._find_smallest_missing_number(incomplete_draft_names) + smallest_name = f"New domain request {smallest_number}" + if smallest_name not in incomplete_draft_names: + draft_name = smallest_name + elif proposed_draft_number == last_draft_number: + # If the draft number we are trying to create matches the last draft number, + # simply add one to that number + draft_name = f"New domain request {last_draft_number + 1}" + + # Handle edge case if the user has an obscene number of domain drafts + if len(draft_name) > 253: + draft_name = default_draft_text + + draft_domain = DraftDomain( + name=draft_name, + is_incomplete=True, + ) + draft_domain.save() + + return draft_domain + + def _find_smallest_missing_number(self, incomplete_drafts): + draft_numbers = [] + for draft in incomplete_drafts: + # Parse the number out of the text + number = self._parse_first_number_from_string(draft) + if number is not None: + draft_numbers.append(number) + + draft_numbers = sorted(draft_numbers) + smallest_missing = 1 + for number in draft_numbers: + if number == smallest_missing: + smallest_missing += 1 + elif number > smallest_missing: + break + return smallest_missing + + def _parse_first_number_from_string(self, string_to_parse: str) -> int | None: + """Given a `string_to_parse`, try to find any number in it and return that. + Returns None if no match is found""" + + # Parse the number out of the text + match = re.search("\d+", string_to_parse) + + number = int(match.group()) if match else None + return number @property def storage(self): # marking session as modified on every access diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 0e7528e08..44345e72f 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -12,13 +12,11 @@ def index(request): # domain_applications context will be used to populate # the active applications table applications = DomainApplication.objects.filter(creator=request.user).exclude(status="approved") - + # Adds display logic for empty domain requests - counter = 1 for application in applications: - if not application.requested_domain or not application.requested_domain.name: - application.requested_domain = DraftDomain(name=f"New domain request {counter}") - counter += 1 + if not application.requested_domain.name: + application.requested_domain.name = application.requested_domain.draft_name # Pass the final context to the application context["domain_applications"] = applications From 4d8cb4534553e3b0ca7e2a44862aa6d02be2d58d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:24:14 -0700 Subject: [PATCH 037/107] Persist information correctly --- src/registrar/forms/application_wizard.py | 5 ++- ...draft_number_draftdomain_is_incomplete.py} | 14 ++++---- src/registrar/models/domain_application.py | 5 +++ src/registrar/models/draft_domain.py | 13 ++++++- src/registrar/views/application.py | 34 +++++++------------ 5 files changed, 42 insertions(+), 29 deletions(-) rename src/registrar/migrations/{0063_draftdomain_is_incomplete_alter_draftdomain_name.py => 0063_draftdomain_draft_number_draftdomain_is_incomplete.py} (63%) diff --git a/src/registrar/forms/application_wizard.py b/src/registrar/forms/application_wizard.py index 2d151a08e..d731c3965 100644 --- a/src/registrar/forms/application_wizard.py +++ b/src/registrar/forms/application_wizard.py @@ -511,7 +511,10 @@ class DotGovDomainForm(RegistrarForm): values = {} requested_domain = getattr(obj, "requested_domain", None) if requested_domain is not None: - values["requested_domain"] = Domain.sld(requested_domain.name) + is_incomplete = requested_domain.is_incomplete + # Only display a preexisting name if the application was completed + domain_name = requested_domain.name if not is_incomplete else "" + values["requested_domain"] = Domain.sld(domain_name) return values def clean_requested_domain(self): diff --git a/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py b/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py similarity index 63% rename from src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py rename to src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py index fcb462e22..1ea545c70 100644 --- a/src/registrar/migrations/0063_draftdomain_is_incomplete_alter_draftdomain_name.py +++ b/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.7 on 2024-01-11 19:40 +# Generated by Django 4.2.7 on 2024-01-12 16:17 from django.db import migrations, models @@ -9,14 +9,16 @@ class Migration(migrations.Migration): ] operations = [ + migrations.AddField( + model_name="draftdomain", + name="draft_number", + field=models.IntegerField( + help_text="The draft number in the event a user doesn't save at this stage", null=True + ), + ), migrations.AddField( model_name="draftdomain", name="is_incomplete", field=models.BooleanField(default=False, help_text="Determines if this Draft is complete or not"), ), - migrations.AlterField( - model_name="draftdomain", - name="name", - field=models.CharField(help_text="Fully qualified domain name", max_length=253), - ), ] diff --git a/src/registrar/models/domain_application.py b/src/registrar/models/domain_application.py index 196449bfa..d93c429f9 100644 --- a/src/registrar/models/domain_application.py +++ b/src/registrar/models/domain_application.py @@ -631,6 +631,11 @@ class DomainApplication(TimeStampedModel): # Update submission_date to today self.submission_date = timezone.now().date() + + # Mark the draft domain as complete + if self.requested_domain.is_incomplete: + self.requested_domain.is_incomplete = False + self.save() self._send_status_update_email( diff --git a/src/registrar/models/draft_domain.py b/src/registrar/models/draft_domain.py index 4d79494f5..8a2ced775 100644 --- a/src/registrar/models/draft_domain.py +++ b/src/registrar/models/draft_domain.py @@ -17,10 +17,21 @@ class DraftDomain(TimeStampedModel, DomainHelper): name = models.CharField( max_length=253, blank=False, + default=None, # prevent saving without a value help_text="Fully qualified domain name", ) + draft_number = models.IntegerField( + null=True, + help_text="The draft number in the event a user doesn't save at this stage", + ) + is_incomplete = models.BooleanField( default=False, help_text="Determines if this Draft is complete or not" - ) \ No newline at end of file + ) + + def get_default_request_name(self): + """Returns the draft name that would be used for applications if no name exists""" + return f"New domain request {self.draft_number}" + \ No newline at end of file diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index deda6d0d2..b03de7774 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,5 +1,6 @@ import logging import re +from typing import List from django.db.models import Q from django.http import Http404, HttpResponse, HttpResponseRedirect @@ -172,7 +173,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): incomplete_draft_names = incomplete_drafts.values_list(name_field, flat=True) proposed_draft_number = incomplete_drafts.count() + 1 - draft_name = f"New domain request {proposed_draft_number}" + draft_number = 1 for application in existing_applications: if application.requested_domain is not None and application.requested_domain.name is not None: name = application.requested_domain.name @@ -183,26 +184,26 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): # and 2 is deleted - meaning we would get two duplicate "3"s if we added another if name in incomplete_draft_names: # Get the last numbered draft - last_draft = incomplete_draft_names.last() - last_draft_number = self._parse_first_number_from_string(last_draft) + last_draft = incomplete_drafts.last() + last_draft_number = last_draft.draft_number - smallest_number = self._find_smallest_missing_number(incomplete_draft_names) + smallest_number = self._find_smallest_missing_number(incomplete_drafts) smallest_name = f"New domain request {smallest_number}" if smallest_name not in incomplete_draft_names: - draft_name = smallest_name + draft_number = smallest_number elif proposed_draft_number == last_draft_number: # If the draft number we are trying to create matches the last draft number, # simply add one to that number - draft_name = f"New domain request {last_draft_number + 1}" - - # Handle edge case if the user has an obscene number of domain drafts - if len(draft_name) > 253: - draft_name = default_draft_text + draft_number = last_draft_number + 1 draft_domain = DraftDomain( - name=draft_name, + # Save a blank string rather then None due to DB requirements + name="", + draft_number=draft_number, is_incomplete=True, ) + # Generate a default name based off of a draft_number + draft_domain.name = draft_domain.get_default_request_name() draft_domain.save() return draft_domain @@ -211,7 +212,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): draft_numbers = [] for draft in incomplete_drafts: # Parse the number out of the text - number = self._parse_first_number_from_string(draft) + number = draft.draft_number if number is not None: draft_numbers.append(number) @@ -224,15 +225,6 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): break return smallest_missing - def _parse_first_number_from_string(self, string_to_parse: str) -> int | None: - """Given a `string_to_parse`, try to find any number in it and return that. - Returns None if no match is found""" - - # Parse the number out of the text - match = re.search("\d+", string_to_parse) - - number = int(match.group()) if match else None - return number @property def storage(self): # marking session as modified on every access From 6f09c4b6533c5d5e87446adab1e21ab7300a6f62 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:42:20 -0700 Subject: [PATCH 038/107] Remove merge weirdnesss --- src/registrar/tests/test_views.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index d99d311d0..56f3cb5a5 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -178,18 +178,6 @@ class LoggedInTests(TestWithUser): # clean up application.delete() - def test_home_lists_domains(self): - response = self.client.get("/") - domain, _ = Domain.objects.get_or_create(name="igorville.gov") - self.assertNotContains(response, "igorville.gov") - role, _ = UserDomainRole.objects.get_or_create(user=self.user, domain=domain, role=UserDomainRole.Roles.MANAGER) - response = self.client.get("/") - # count = 2 because it is also in screenreader content - self.assertContains(response, "igorville.gov", count=2) - self.assertContains(response, "Expired") - # clean up - role.delete() - def test_application_form_view(self): response = self.client.get("/register/", follow=True) self.assertContains( From 5c5fcfcf866a469bed6485c033f0939d187c9d8e Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:49:36 -0700 Subject: [PATCH 039/107] Update application.py --- src/registrar/views/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index b03de7774..fac722275 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -185,7 +185,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): if name in incomplete_draft_names: # Get the last numbered draft last_draft = incomplete_drafts.last() - last_draft_number = last_draft.draft_number + last_draft_number = last_draft.requested_domain.draft_number smallest_number = self._find_smallest_missing_number(incomplete_drafts) smallest_name = f"New domain request {smallest_number}" From f5fb4b24b88fe0e173d72e84746e2c6718c85993 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 09:57:45 -0700 Subject: [PATCH 040/107] Update application.py --- src/registrar/views/application.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index fac722275..c2fe823aa 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -211,8 +211,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): def _find_smallest_missing_number(self, incomplete_drafts): draft_numbers = [] for draft in incomplete_drafts: - # Parse the number out of the text - number = draft.draft_number + number = draft.requested_domain.draft_number if number is not None: draft_numbers.append(number) From cde4ab2fef12f447d7101f78fecc7cd1e2d764e0 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 10:39:01 -0700 Subject: [PATCH 041/107] Remove old check --- src/registrar/views/index.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 44345e72f..bcff0affd 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -12,11 +12,6 @@ def index(request): # domain_applications context will be used to populate # the active applications table applications = DomainApplication.objects.filter(creator=request.user).exclude(status="approved") - - # Adds display logic for empty domain requests - for application in applications: - if not application.requested_domain.name: - application.requested_domain.name = application.requested_domain.draft_name # Pass the final context to the application context["domain_applications"] = applications From 8b2a0c928d05cc8831f157b1c1870a3e30d52480 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:18:49 -0700 Subject: [PATCH 042/107] Set is_incomplete flag on post --- src/registrar/views/application.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index adde07e96..9aed1fa4d 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -549,6 +549,14 @@ class DotgovDomain(ApplicationWizard): context["organization_type"] = self.application.organization_type context["federal_type"] = self.application.federal_type return context + + def post(self, request, *args, **kwargs): + """Override for the post method to mark the DraftDomain as complete""" + response = super().post(request, *args, **kwargs) + # Set the DraftDomain to "complete" + self.application.requested_domain.is_incomplete = False + self.application.save() + return response class Purpose(ApplicationWizard): From 93107877f32276b6a49629e55d1e9497ff84908c Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 11:42:00 -0700 Subject: [PATCH 043/107] Remove bad role --- src/registrar/templates/home.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index b496aa265..54daa4aa4 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -72,7 +72,7 @@ {% endif %} - + {% if application.status == "started" or application.status == "action needed" or application.status == "withdrawn" %} - + Edit {{ application.requested_domain.name|default:"New domain request" }} {% else %} - + From c9495667440da0397e065b35359c34aca87b8862 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Jan 2024 12:06:44 -0700 Subject: [PATCH 044/107] Fix post bug --- src/registrar/views/application.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 9aed1fa4d..482bc2f10 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -552,10 +552,10 @@ class DotgovDomain(ApplicationWizard): def post(self, request, *args, **kwargs): """Override for the post method to mark the DraftDomain as complete""" - response = super().post(request, *args, **kwargs) # Set the DraftDomain to "complete" + print(f"what is the request at this time? {request}") self.application.requested_domain.is_incomplete = False - self.application.save() + response = super().post(request, *args, **kwargs) return response From 0b503442a8388cf6494520a03063234d28024312 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Jan 2024 15:50:04 -0500 Subject: [PATCH 045/107] Change header to Current websites --- src/registrar/templates/application_status.html | 2 +- .../templates/emails/includes/application_summary.txt | 2 +- src/registrar/tests/test_emails.py | 6 +++--- src/registrar/views/application.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/registrar/templates/application_status.html b/src/registrar/templates/application_status.html index fbabf39a7..590d00b28 100644 --- a/src/registrar/templates/application_status.html +++ b/src/registrar/templates/application_status.html @@ -90,7 +90,7 @@ {% endif %} {% if domainapplication.current_websites.all %} - {% include "includes/summary_item.html" with title='Current website for your organization' value=domainapplication.current_websites.all list='true' heading_level=heading_level %} + {% include "includes/summary_item.html" with title='Current websites' value=domainapplication.current_websites.all list='true' heading_level=heading_level %} {% endif %} {% if domainapplication.requested_domain %} diff --git a/src/registrar/templates/emails/includes/application_summary.txt b/src/registrar/templates/emails/includes/application_summary.txt index c628e1074..ee2564613 100644 --- a/src/registrar/templates/emails/includes/application_summary.txt +++ b/src/registrar/templates/emails/includes/application_summary.txt @@ -17,7 +17,7 @@ About your organization: Authorizing official: {% spaceless %}{% include "emails/includes/contact.txt" with contact=application.authorizing_official %}{% endspaceless %} {% if application.current_websites.exists %}{# if block makes a newline #} -Current website for your organization: {% for site in application.current_websites.all %} +Current websites: {% for site in application.current_websites.all %} {% spaceless %}{{ site.website }}{% endspaceless %} {% endfor %}{% endif %} .gov domain: diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index 61c950255..bc0513a07 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -47,7 +47,7 @@ class TestEmails(TestCase): # check for optional things self.assertIn("Other employees from your organization:", body) self.assertIn("Testy2 Tester2", body) - self.assertIn("Current website for your organization:", body) + self.assertIn("Current websites:", body) self.assertIn("city.com", body) self.assertIn("About your organization:", body) self.assertIn("Anything else", body) @@ -61,7 +61,7 @@ class TestEmails(TestCase): application.submit() _, kwargs = self.mock_client.send_email.call_args body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] - self.assertNotIn("Current website for your organization:", body) + self.assertNotIn("Current websites:", body) # spacing should be right between adjacent elements self.assertRegex(body, r"5555\n\n.gov domain:") @@ -74,7 +74,7 @@ class TestEmails(TestCase): application.submit() _, kwargs = self.mock_client.send_email.call_args body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] - self.assertIn("Current website for your organization:", body) + self.assertIn("Current websites:", body) # spacing should be right between adjacent elements self.assertRegex(body, r"5555\n\nCurrent website for") self.assertRegex(body, r"city.com\n\n.gov domain:") diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 486964e66..3eabe574f 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -83,7 +83,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): Step.ORGANIZATION_CONTACT: _("Organization name and mailing address"), Step.ABOUT_YOUR_ORGANIZATION: _("About your organization"), Step.AUTHORIZING_OFFICIAL: _("Authorizing official"), - Step.CURRENT_SITES: _("Current website for your organization"), + Step.CURRENT_SITES: _("Current websites"), Step.DOTGOV_DOMAIN: _(".gov domain"), Step.PURPOSE: _("Purpose of your domain"), Step.YOUR_CONTACT: _("Your contact information"), From 9300b06d4c56a19176bb1bf62e56afa88647eef5 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Jan 2024 15:55:56 -0500 Subject: [PATCH 046/107] Fixed test test_submission_confirmation_current_website_spacing --- src/registrar/tests/test_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index bc0513a07..3f5b7fc18 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -76,7 +76,7 @@ class TestEmails(TestCase): body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] self.assertIn("Current websites:", body) # spacing should be right between adjacent elements - self.assertRegex(body, r"5555\n\nCurrent website for") + self.assertRegex(body, r"5555\n\nCurrent websites for") self.assertRegex(body, r"city.com\n\n.gov domain:") @boto3_mocking.patching From 938e501a6cafa1d706dbbf4399d87898bda2e0e7 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Fri, 12 Jan 2024 15:56:16 -0500 Subject: [PATCH 047/107] Fixed test test_submission_confirmation_current_website_spacing --- src/registrar/tests/test_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index 3f5b7fc18..fcdd46577 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -76,7 +76,7 @@ class TestEmails(TestCase): body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] self.assertIn("Current websites:", body) # spacing should be right between adjacent elements - self.assertRegex(body, r"5555\n\nCurrent websites for") + self.assertRegex(body, r"5555\n\nCurrent websites") self.assertRegex(body, r"city.com\n\n.gov domain:") @boto3_mocking.patching From a3f78e2ac7250de3dac401aadb90a3a93ab9575d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 16 Jan 2024 08:52:03 -0700 Subject: [PATCH 048/107] Linting and fix unit test --- src/registrar/models/draft_domain.py | 6 +----- src/registrar/views/application.py | 20 ++++++++++---------- src/registrar/views/index.py | 1 - 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/registrar/models/draft_domain.py b/src/registrar/models/draft_domain.py index 8a2ced775..5fe00257e 100644 --- a/src/registrar/models/draft_domain.py +++ b/src/registrar/models/draft_domain.py @@ -26,12 +26,8 @@ class DraftDomain(TimeStampedModel, DomainHelper): help_text="The draft number in the event a user doesn't save at this stage", ) - is_incomplete = models.BooleanField( - default=False, - help_text="Determines if this Draft is complete or not" - ) + is_incomplete = models.BooleanField(default=False, help_text="Determines if this Draft is complete or not") def get_default_request_name(self): """Returns the draft name that would be used for applications if no name exists""" return f"New domain request {self.draft_number}" - \ No newline at end of file diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index 482bc2f10..bef707cb6 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -1,6 +1,4 @@ import logging -import re -from typing import List from django.db.models import Q from django.http import Http404, HttpResponse, HttpResponseRedirect @@ -143,7 +141,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): return self._application except DomainApplication.DoesNotExist: logger.debug("Application id %s did not have a DomainApplication" % id) - + # TODO - revert back to using draft_name draft_domain = self._create_default_draft_domain() self._application = DomainApplication.objects.create( @@ -166,9 +164,11 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): name_field = "requested_domain__name" - incomplete_drafts = existing_applications.exclude(requested_domain=None).filter( - requested_domain__name__icontains=default_draft_text - ).order_by(name_field) + incomplete_drafts = ( + existing_applications.exclude(requested_domain=None) + .filter(requested_domain__name__icontains=default_draft_text) + .order_by(name_field) + ) incomplete_draft_names = incomplete_drafts.values_list(name_field, flat=True) @@ -178,9 +178,9 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): if application.requested_domain is not None and application.requested_domain.name is not None: name = application.requested_domain.name - # If we already have a list of draft numbers, base the + # If we already have a list of draft numbers, base the # subsequent number off of the last numbered field. - # This is to avoid a scenario in which drafts 1, 2, 3 and exist + # This is to avoid a scenario in which drafts 1, 2, 3 and exist # and 2 is deleted - meaning we would get two duplicate "3"s if we added another if name in incomplete_draft_names: # Get the last numbered draft @@ -403,7 +403,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): # Build the submit button that we'll pass to the modal. modal_button = '" # Concatenate the modal header that we'll pass to the modal. - if self.application.requested_domain: + if self.application.requested_domain and not self.application.requested_domain.is_incomplete: modal_heading = "You are about to submit a domain request for " + str(self.application.requested_domain) else: modal_heading = "You are about to submit an incomplete request" @@ -549,7 +549,7 @@ class DotgovDomain(ApplicationWizard): context["organization_type"] = self.application.organization_type context["federal_type"] = self.application.federal_type return context - + def post(self, request, *args, **kwargs): """Override for the post method to mark the DraftDomain as complete""" # Set the DraftDomain to "complete" diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index bcff0affd..f9a658942 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -1,7 +1,6 @@ from django.shortcuts import render from registrar.models import DomainApplication, Domain, UserDomainRole -from registrar.models.draft_domain import DraftDomain def index(request): From 9899b5ae3e24fe9343d83329312ac5eba60975b3 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 16 Jan 2024 09:31:22 -0700 Subject: [PATCH 049/107] Update application.py --- src/registrar/views/application.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py index bef707cb6..c76d285a7 100644 --- a/src/registrar/views/application.py +++ b/src/registrar/views/application.py @@ -12,6 +12,7 @@ from django.contrib import messages from registrar.forms import application_wizard as forms from registrar.models import DomainApplication from registrar.models.draft_domain import DraftDomain +from registrar.models.user import User from registrar.utility import StrEnum from registrar.views.utility import StepsHelper from registrar.views.utility.permission_views import DomainApplicationPermissionDeleteView @@ -142,12 +143,17 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView): except DomainApplication.DoesNotExist: logger.debug("Application id %s did not have a DomainApplication" % id) - # TODO - revert back to using draft_name draft_domain = self._create_default_draft_domain() - self._application = DomainApplication.objects.create( - creator=self.request.user, - requested_domain=draft_domain, - ) + + # Check added for linting purposes + if self.request.user and isinstance(self.request.user, User): + self._application = DomainApplication.objects.create( + creator=self.request.user, + requested_domain=draft_domain, + ) + else: + # TODO - Need some sort of front end display for this + raise ValueError("Invalid type for user") self.storage["application_id"] = self._application.id return self._application From 9fe1bbaac5c08701f6f59b35a95fb05b489c8a8d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:01:56 -0700 Subject: [PATCH 050/107] Remove numbering --- src/registrar/forms/application_wizard.py | 4 +- ..._draft_number_draftdomain_is_incomplete.py | 24 ----- .../0063_draftdomain_is_complete.py | 17 ++++ src/registrar/models/domain_application.py | 4 - src/registrar/models/draft_domain.py | 12 +-- src/registrar/templates/home.html | 20 ++-- src/registrar/views/application.py | 96 +------------------ src/registrar/views/index.py | 25 ++++- 8 files changed, 57 insertions(+), 145 deletions(-) delete mode 100644 src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py create mode 100644 src/registrar/migrations/0063_draftdomain_is_complete.py diff --git a/src/registrar/forms/application_wizard.py b/src/registrar/forms/application_wizard.py index d731c3965..157d4b234 100644 --- a/src/registrar/forms/application_wizard.py +++ b/src/registrar/forms/application_wizard.py @@ -511,9 +511,7 @@ class DotGovDomainForm(RegistrarForm): values = {} requested_domain = getattr(obj, "requested_domain", None) if requested_domain is not None: - is_incomplete = requested_domain.is_incomplete - # Only display a preexisting name if the application was completed - domain_name = requested_domain.name if not is_incomplete else "" + domain_name = requested_domain.name values["requested_domain"] = Domain.sld(domain_name) return values diff --git a/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py b/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py deleted file mode 100644 index 1ea545c70..000000000 --- a/src/registrar/migrations/0063_draftdomain_draft_number_draftdomain_is_incomplete.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 4.2.7 on 2024-01-12 16:17 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("registrar", "0062_alter_host_name"), - ] - - operations = [ - migrations.AddField( - model_name="draftdomain", - name="draft_number", - field=models.IntegerField( - help_text="The draft number in the event a user doesn't save at this stage", null=True - ), - ), - migrations.AddField( - model_name="draftdomain", - name="is_incomplete", - field=models.BooleanField(default=False, help_text="Determines if this Draft is complete or not"), - ), - ] diff --git a/src/registrar/migrations/0063_draftdomain_is_complete.py b/src/registrar/migrations/0063_draftdomain_is_complete.py new file mode 100644 index 000000000..d17e59400 --- /dev/null +++ b/src/registrar/migrations/0063_draftdomain_is_complete.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.7 on 2024-01-16 20:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("registrar", "0062_alter_host_name"), + ] + + operations = [ + migrations.AddField( + model_name="draftdomain", + name="is_complete", + field=models.BooleanField(default=True, help_text="Determines if this Draft is complete or not"), + ), + ] diff --git a/src/registrar/models/domain_application.py b/src/registrar/models/domain_application.py index d93c429f9..51c322283 100644 --- a/src/registrar/models/domain_application.py +++ b/src/registrar/models/domain_application.py @@ -632,10 +632,6 @@ class DomainApplication(TimeStampedModel): # Update submission_date to today self.submission_date = timezone.now().date() - # Mark the draft domain as complete - if self.requested_domain.is_incomplete: - self.requested_domain.is_incomplete = False - self.save() self._send_status_update_email( diff --git a/src/registrar/models/draft_domain.py b/src/registrar/models/draft_domain.py index 5fe00257e..a750771b5 100644 --- a/src/registrar/models/draft_domain.py +++ b/src/registrar/models/draft_domain.py @@ -21,13 +21,7 @@ class DraftDomain(TimeStampedModel, DomainHelper): help_text="Fully qualified domain name", ) - draft_number = models.IntegerField( - null=True, - help_text="The draft number in the event a user doesn't save at this stage", + is_complete = models.BooleanField( + default=True, + help_text="Determines if this Draft is complete or not" ) - - is_incomplete = models.BooleanField(default=False, help_text="Determines if this Draft is complete or not") - - def get_default_request_name(self): - """Returns the draft name that would be used for applications if no name exists""" - return f"New domain request {self.draft_number}" diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 54daa4aa4..1ab4a135e 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -124,7 +124,13 @@ {% for application in domain_applications %}
- {{ application.requested_domain.name|default:"New domain request" }} + {% if application.requested_domain is None or not application.requested_domain.is_complete %} + New domain request +
+ ({{ application.created_at }}) + {% else %} + {{ application.requested_domain.name }} + {% endif %}
{% if application.submission_date %} @@ -140,13 +146,13 @@ - Edit {{ application.requested_domain.name|default:"New domain request" }} + Edit {{ application.requested_domain.name|default:"New domain request ("|add:application.created_at|add:")" }} {% else %} - Manage {{ application.requested_domain.name|default:"New domain request" }} + Manage {{ application.requested_domain.name|default:"New domain request ("|add:application.created_at|add:")" }} {% endif %}
- {% if application.requested_domain is None or not application.requested_domain.is_complete %} + {% if application.requested_domain is None %} New domain request
({{ application.created_at }}) @@ -181,7 +181,26 @@ data-force-action >
- {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% if application.requested_domain is None %} + {% with prefix="Are you sure you want to delete New domain request " %} + {% if application.created_at %} + {% with formatted_date=application.created_at|date:"DATETIME_FORMAT" %} + {% with modal_heading=prefix|add:formatted_date %} + {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endwith %} + {% endwith %} + {% else %} + {# Handle the case when application.created_at is not available or empty #} + {% with modal_heading=prefix %} + {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endwith %} + {% endif %} + {% endwith %} + {% else %} + {% with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} + {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% endwith %} + {% endif %}
{% endif %} diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index f9dcaa253..b98154a23 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -48,13 +48,7 @@ def _get_applications(request): # Create a placeholder DraftDomain for each incomplete draft valid_statuses = [DomainApplication.ApplicationStatus.STARTED, DomainApplication.ApplicationStatus.WITHDRAWN] deletable_applications = applications.filter(status__in=valid_statuses) - for application in applications: - if application in deletable_applications and application.requested_domain is None: - created_at = application.created_at.strftime("%b. %d, %Y, %I:%M %p UTC") - _name = f"New domain request ({created_at})" - default_draft_domain = DraftDomain(name=_name, is_complete=False) - - application.requested_domain = default_draft_domain + return (applications, deletable_applications) From dc032e522234da7ff06bded2dbd381565a1bbaa1 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:52:27 -0700 Subject: [PATCH 063/107] Update home.html --- src/registrar/templates/home.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 5bda944c4..ea70fdbfc 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -182,10 +182,10 @@ >
{% if application.requested_domain is None %} - {% with prefix="Are you sure you want to delete New domain request " %} + {% with prefix="Are you sure you want to delete New domain request (" %} {% if application.created_at %} {% with formatted_date=application.created_at|date:"DATETIME_FORMAT" %} - {% with modal_heading=prefix|add:formatted_date %} + {% with modal_heading=prefix|add:formatted_date|add:")?" %} {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} {% endwith %} {% endwith %} From 25a3ed44f7954e24ab7c37c093f661ea8adf23b4 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:56:27 -0700 Subject: [PATCH 064/107] Linting and tests --- src/registrar/templates/home.html | 2 +- src/registrar/tests/test_views.py | 2 +- src/registrar/views/index.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index ea70fdbfc..cccc20f28 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -174,7 +174,7 @@
Date: Wed, 17 Jan 2024 14:59:10 -0700 Subject: [PATCH 065/107] Update index.py --- src/registrar/views/index.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 048bd24b5..a4a1f64d0 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -1,7 +1,6 @@ from django.shortcuts import render from registrar.models import DomainApplication, Domain, UserDomainRole -from registrar.models.draft_domain import DraftDomain def index(request): From 267ba5130867228e609b43204db8adc57f6abc97 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:00:42 -0800 Subject: [PATCH 066/107] Fix linting --- .../commands/disclose_security_emails.py | 8 +++---- src/registrar/tests/test_models_domain.py | 23 +++++++++++++++---- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 3e0c06bbc..4e40dda20 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -52,19 +52,19 @@ class Command(BaseCommand): # Update EPP contact for domains with a security contact for domain in domains: try: - logger.info(f"Domain {domain.domain_info} security contact: {domain.security_contact.email}") + logger.info(f"Domain {domain.name} security contact: {domain.security_contact.email}") if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) self.disclosed_domain_contacts_count += 1 else: logger.info( - f"Skipping disclose for {domain.domain_info} security contact {domain.security_contact.email}." + f"Skipping disclose for {domain.name} security contact {domain.security_contact.email}." ) self.skipped_domain_contacts_count += 1 except Exception as err: # error condition if domain not in database - self.domains_with_errors.append(copy.deepcopy(domain.domain_info)) - logger.error(f"error retrieving domain {domain.domain_info} contact {domain.security_contact}: {err}") + self.domains_with_errors.append(copy.deepcopy(domain.name)) + logger.error(f"error retrieving domain {domain.name} contact {domain.security_contact}: {err}") # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") diff --git a/src/registrar/tests/test_models_domain.py b/src/registrar/tests/test_models_domain.py index af9c7b053..02346b907 100644 --- a/src/registrar/tests/test_models_domain.py +++ b/src/registrar/tests/test_models_domain.py @@ -983,16 +983,31 @@ class TestRegistrantContacts(MockEppLib): Tests that command disclose_security_emails runs successfully with appropriate EPP calll to UpdateContact. """ - domain, _ = Domain.objects.get_or_create(name="igorville.gov") + domain, _ = Domain.objects.get_or_create(name="testdisclose.gov", state=Domain.State.READY) expectedSecContact = PublicContact.get_default_security() expectedSecContact.domain = domain expectedSecContact.email = "123@mail.gov" + # set domain security email to 123@mail.gov instead of default email domain.security_contact = expectedSecContact self.run_disclose_security_emails() - # running disclose_security_emails makes EPP calls - expectedUpdateCommand = self._convertPublicContactToEpp(expectedSecContact, disclose_email=True) - self.mockedSendFunction.assert_any_call(expectedUpdateCommand, cleaned=True) + # running disclose_security_emails sends EPP call UpdateContact with disclose + self.mockedSendFunction.assert_has_calls( + [ + call( + commands.UpdateContact( + id=domain.security_contact.registry_id, + postal_info=domain._make_epp_contact_postal_info(contact=domain.security_contact), + email=domain.security_contact.email, + voice=domain.security_contact.voice, + fax=domain.security_contact.fax, + auth_info=common.ContactAuthInfo(pw="2fooBAR123fooBaz"), + disclose=domain._disclose_fields(contact=domain.security_contact), + ), + cleaned=True, + ) + ] + ) @skip("not implemented yet") def test_update_is_unsuccessful(self): From 08c6803cf03d1891769c51cd7aca608cdd215e28 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:10:11 -0800 Subject: [PATCH 067/107] Fix whitespace issue in logs --- src/registrar/management/commands/disclose_security_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 4e40dda20..56f77dc13 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -69,7 +69,7 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security \ + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email registrar@dotgov.gov." ) logger.info( From 595c2f8d80836d6459f24708975e405e78bda9c9 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:27:19 -0800 Subject: [PATCH 068/107] Fix whitespace issue in logs --- src/registrar/management/commands/disclose_security_emails.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 56f77dc13..1fdd297a9 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -69,8 +69,8 @@ class Command(BaseCommand): # Inform user how many contacts were disclosed, skipped, and errored logger.info(f"Updated {self.disclosed_domain_contacts_count} contacts to disclosed.") logger.info( - f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security - email registrar@dotgov.gov." + f"Skipped disclosing {self.skipped_domain_contacts_count} contacts with security email " + f"registrar@dotgov.gov." ) logger.info( f"Error disclosing the following {len(self.domains_with_errors)} contacts: {self.domains_with_errors}" From 71f6c8e3ae74decfdde6a8b337952f6bb1cfc255 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:31:57 -0800 Subject: [PATCH 069/107] Fix typo in comment in domain --- 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 4d455d320..1a581a4ec 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1396,7 +1396,7 @@ class Domain(TimeStampedModel, DomainHelper): def _disclose_fields(self, contact: PublicContact): """creates a disclose object that can be added to a contact Create using .disclose= on the command before sending. - if item is security email then make sure email is visable""" + if item is security email then make sure email is visible""" is_security = contact.contact_type == contact.ContactTypeChoices.SECURITY DF = epp.DiscloseField fields = {DF.EMAIL} From 3ed806c1a1ecaaec1712c0ef0dadcc0c265feebd Mon Sep 17 00:00:00 2001 From: Alysia Broddrick Date: Wed, 17 Jan 2024 21:30:23 -0400 Subject: [PATCH 070/107] removed the hover effect and disable of the start button --- src/registrar/templates/home.html | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 138f83e04..92ca03343 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -13,22 +13,10 @@

Manage your domains

- {% if IS_PRODUCTION %} - - Start a new domain request - - {% else %} Start a new domain request - {% endif %}

From b140d631f57363ae2e216b20e3dfe36d599f09a7 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Thu, 18 Jan 2024 11:42:17 -0500 Subject: [PATCH 071/107] update all references to beta.get.gov to get.gov in all settings files; update application_org_contact to use _public_site_url rather than hardcoded value --- ops/manifests/manifest-ab.yaml | 2 +- ops/manifests/manifest-backup.yaml | 2 +- ops/manifests/manifest-bl.yaml | 2 +- ops/manifests/manifest-development.yaml | 2 +- ops/manifests/manifest-dk.yaml | 2 +- ops/manifests/manifest-es.yaml | 2 +- ops/manifests/manifest-gd.yaml | 2 +- ops/manifests/manifest-ko.yaml | 2 +- ops/manifests/manifest-ky.yaml | 2 +- ops/manifests/manifest-nl.yaml | 2 +- ops/manifests/manifest-rb.yaml | 2 +- ops/manifests/manifest-rh.yaml | 2 +- ops/manifests/manifest-rjm.yaml | 2 +- ops/manifests/manifest-stable.yaml | 2 +- ops/manifests/manifest-staging.yaml | 2 +- ops/manifests/manifest-za.yaml | 2 +- ops/scripts/manifest-sandbox-template-migrate.yaml | 2 +- ops/scripts/manifest-sandbox-template.yaml | 2 +- src/docker-compose.yml | 2 +- src/registrar/config/settings.py | 2 +- src/registrar/templates/application_org_contact.html | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ops/manifests/manifest-ab.yaml b/ops/manifests/manifest-ab.yaml index 38109bdcb..3ca800392 100644 --- a/ops/manifests/manifest-ab.yaml +++ b/ops/manifests/manifest-ab.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-backup.yaml b/ops/manifests/manifest-backup.yaml index c4615d1d5..ab9e36d68 100644 --- a/ops/manifests/manifest-backup.yaml +++ b/ops/manifests/manifest-backup.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-bl.yaml b/ops/manifests/manifest-bl.yaml index 59529278b..ea0617427 100644 --- a/ops/manifests/manifest-bl.yaml +++ b/ops/manifests/manifest-bl.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-development.yaml b/ops/manifests/manifest-development.yaml index 0a1f30ffa..08244cf08 100644 --- a/ops/manifests/manifest-development.yaml +++ b/ops/manifests/manifest-development.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-dk.yaml b/ops/manifests/manifest-dk.yaml index 256beeda2..071efb416 100644 --- a/ops/manifests/manifest-dk.yaml +++ b/ops/manifests/manifest-dk.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-es.yaml b/ops/manifests/manifest-es.yaml index 47c78ce1b..7fd19b7a0 100644 --- a/ops/manifests/manifest-es.yaml +++ b/ops/manifests/manifest-es.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-gd.yaml b/ops/manifests/manifest-gd.yaml index 0c4b2535f..89a7c2169 100644 --- a/ops/manifests/manifest-gd.yaml +++ b/ops/manifests/manifest-gd.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-ko.yaml b/ops/manifests/manifest-ko.yaml index cc6a09337..a69493f9b 100644 --- a/ops/manifests/manifest-ko.yaml +++ b/ops/manifests/manifest-ko.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-ky.yaml b/ops/manifests/manifest-ky.yaml index 31d67cfb3..f416d7385 100644 --- a/ops/manifests/manifest-ky.yaml +++ b/ops/manifests/manifest-ky.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-nl.yaml b/ops/manifests/manifest-nl.yaml index ca6fb4693..d74174e7d 100644 --- a/ops/manifests/manifest-nl.yaml +++ b/ops/manifests/manifest-nl.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-rb.yaml b/ops/manifests/manifest-rb.yaml index 62f243513..570b49dde 100644 --- a/ops/manifests/manifest-rb.yaml +++ b/ops/manifests/manifest-rb.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-rh.yaml b/ops/manifests/manifest-rh.yaml index 4985f3261..f44894ce8 100644 --- a/ops/manifests/manifest-rh.yaml +++ b/ops/manifests/manifest-rh.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-rjm.yaml b/ops/manifests/manifest-rjm.yaml index 7d72e7835..048b44e95 100644 --- a/ops/manifests/manifest-rjm.yaml +++ b/ops/manifests/manifest-rjm.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-stable.yaml b/ops/manifests/manifest-stable.yaml index d8502c625..a70035445 100644 --- a/ops/manifests/manifest-stable.yaml +++ b/ops/manifests/manifest-stable.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Which OIDC provider to use OIDC_ACTIVE_PROVIDER: login.gov production # Flag to disable/enable features in prod environments diff --git a/ops/manifests/manifest-staging.yaml b/ops/manifests/manifest-staging.yaml index b616973ac..38099cf17 100644 --- a/ops/manifests/manifest-staging.yaml +++ b/ops/manifests/manifest-staging.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/manifests/manifest-za.yaml b/ops/manifests/manifest-za.yaml index 1b84a74a1..271f49da9 100644 --- a/ops/manifests/manifest-za.yaml +++ b/ops/manifests/manifest-za.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/ops/scripts/manifest-sandbox-template-migrate.yaml b/ops/scripts/manifest-sandbox-template-migrate.yaml index dfebed766..9054e9494 100644 --- a/ops/scripts/manifest-sandbox-template-migrate.yaml +++ b/ops/scripts/manifest-sandbox-template-migrate.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # use a non-default route to avoid conflicts routes: - route: getgov-ENVIRONMENT-migrate.app.cloud.gov diff --git a/ops/scripts/manifest-sandbox-template.yaml b/ops/scripts/manifest-sandbox-template.yaml index 8cdb8d71b..f0aee9664 100644 --- a/ops/scripts/manifest-sandbox-template.yaml +++ b/ops/scripts/manifest-sandbox-template.yaml @@ -22,7 +22,7 @@ applications: # Tell Django how much stuff to log DJANGO_LOG_LEVEL: INFO # default public site location - GETGOV_PUBLIC_SITE_URL: https://beta.get.gov + GETGOV_PUBLIC_SITE_URL: https://get.gov # Flag to disable/enable features in prod environments IS_PRODUCTION: False routes: diff --git a/src/docker-compose.yml b/src/docker-compose.yml index c9b78fd8e..ba6530674 100644 --- a/src/docker-compose.yml +++ b/src/docker-compose.yml @@ -32,7 +32,7 @@ services: # Is this a production environment - IS_PRODUCTION # Public site URL link - - GETGOV_PUBLIC_SITE_URL=https://beta.get.gov + - GETGOV_PUBLIC_SITE_URL=https://get.gov # Set a username for accessing the registry - REGISTRY_CL_ID=nothing # Set a password for accessing the registry diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py index 2de7e6eb2..efa512f22 100644 --- a/src/registrar/config/settings.py +++ b/src/registrar/config/settings.py @@ -335,7 +335,7 @@ CSP_INCLUDE_NONCE_IN = ["script-src-elem"] # Cross-Origin Resource Sharing (CORS) configuration # Sets clients that allow access control to manage.get.gov # TODO: remove :8080 to see if we can have all localhost access -CORS_ALLOWED_ORIGINS = ["http://localhost:8080", "https://beta.get.gov"] +CORS_ALLOWED_ORIGINS = ["http://localhost:8080", "https://beta.get.gov", "https://get.gov"] CORS_ALLOWED_ORIGIN_REGEXES = [r"https://[\w-]+\.sites\.pages\.cloud\.gov"] # Content-Length header is set by django.middleware.common.CommonMiddleware diff --git a/src/registrar/templates/application_org_contact.html b/src/registrar/templates/application_org_contact.html index 01b55d03d..8ddd2e6fd 100644 --- a/src/registrar/templates/application_org_contact.html +++ b/src/registrar/templates/application_org_contact.html @@ -2,7 +2,7 @@ {% load field_helpers %} {% block form_instructions %} -

If your domain request is approved, the name of your organization and your city/state will be listed in .gov’s public data.

+

If your domain request is approved, the name of your organization and your city/state will be listed in .gov’s public data.

What is the name and mailing address of the organization you represent?

From c60c4126f622bd80103694b400c8c539d5f1acbb Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 18 Jan 2024 09:50:14 -0700 Subject: [PATCH 072/107] Change count on test --- src/registrar/tests/test_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index f878eee80..abb5f0eb1 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -96,7 +96,7 @@ class LoggedInTests(TestWithUser): response = self.client.get("/") # count = 5 because of screenreader content - self.assertContains(response, "igorville.gov", count=4) + self.assertContains(response, "igorville.gov", count=5) # clean up application.delete() From 2afd48a4a105fd70e6b32b8a635dcb9802f1e4f6 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Thu, 18 Jan 2024 12:12:49 -0500 Subject: [PATCH 073/107] fixed application_org_contact --- src/registrar/templates/application_org_contact.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/application_org_contact.html b/src/registrar/templates/application_org_contact.html index 8ddd2e6fd..e8e8f50bf 100644 --- a/src/registrar/templates/application_org_contact.html +++ b/src/registrar/templates/application_org_contact.html @@ -1,5 +1,5 @@ {% extends 'application_form.html' %} -{% load field_helpers %} +{% load field_helpers url_helpers %} {% block form_instructions %}

If your domain request is approved, the name of your organization and your city/state will be listed in .gov’s public data.

From c297ec125d942f041f017e5f651e32de148281eb Mon Sep 17 00:00:00 2001 From: rachidatecs <107004823+rachidatecs@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:15:35 -0500 Subject: [PATCH 074/107] Update src/registrar/tests/test_emails.py Co-authored-by: zandercymatics <141044360+zandercymatics@users.noreply.github.com> --- src/registrar/tests/test_emails.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/tests/test_emails.py b/src/registrar/tests/test_emails.py index fcdd46577..a4f32bfcf 100644 --- a/src/registrar/tests/test_emails.py +++ b/src/registrar/tests/test_emails.py @@ -76,7 +76,7 @@ class TestEmails(TestCase): body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"] self.assertIn("Current websites:", body) # spacing should be right between adjacent elements - self.assertRegex(body, r"5555\n\nCurrent websites") + self.assertRegex(body, r"5555\n\nCurrent websites:") self.assertRegex(body, r"city.com\n\n.gov domain:") @boto3_mocking.patching From 573d6d05651e0d995a8d41efac4d869c053cbcf9 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Thu, 18 Jan 2024 12:31:09 -0500 Subject: [PATCH 075/107] merged main and fixed hardcoded urls from another test --- src/registrar/tests/test_forms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/registrar/tests/test_forms.py b/src/registrar/tests/test_forms.py index 7968c54e0..9d553acc5 100644 --- a/src/registrar/tests/test_forms.py +++ b/src/registrar/tests/test_forms.py @@ -101,7 +101,7 @@ class TestFormValidation(MockEppLib): ( "whitehouse.gov", "That domain isn’t available. Read more about " + "href='https://get.gov/domains/choosing' target='_blank'>Read more about " "choosing your .gov domain.", ), ] @@ -151,7 +151,7 @@ class TestFormValidation(MockEppLib): ( "whitehouse.gov", "That domain isn’t available. Read more about " + "href='https://get.gov/domains/choosing' target='_blank'>Read more about " "choosing your .gov domain.", ), ] From 3c99c0339387d79703f14572f2033ebe7c1f5ced Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:21:49 -0700 Subject: [PATCH 076/107] Update home.html --- src/registrar/templates/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 138f83e04..f0db2d02b 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -58,7 +58,7 @@ {% elif domain.state == domain.State.UNKNOWN or domain.state == domain.State.DNS_NEEDED %} DNS needed {% else %} - {{ domain.state|title }} + {{ domain.state|capfirst }} {% endif %}
From 7194b2748f440e9450ac47da75497c566c910537 Mon Sep 17 00:00:00 2001 From: Erin <121973038+erinysong@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:02:36 -0800 Subject: [PATCH 077/107] Merge iterations of domains in disclose_emails script --- .../management/commands/disclose_security_emails.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/registrar/management/commands/disclose_security_emails.py b/src/registrar/management/commands/disclose_security_emails.py index 1fdd297a9..f44f9bf85 100644 --- a/src/registrar/management/commands/disclose_security_emails.py +++ b/src/registrar/management/commands/disclose_security_emails.py @@ -19,8 +19,6 @@ class Command(BaseCommand): def __init__(self): """Sets global variables for code tidyness""" super().__init__() - # domains and transition domains that must be disclosed to true - self.contacts_saved_count = 0 # domains with errors, which are not successfully updated to disclose self.domains_with_errors: list[str] = [] # domains that are successfully disclosed @@ -42,16 +40,10 @@ class Command(BaseCommand): logger.info(f"Found {len(domains)} domains with status Ready or DNS Needed.") - # Call security_contact on all domains to trigger saving contact information - for domain in domains: - contact = domain.security_contact # noqa on these items as we only want to call security_contact - self.contacts_saved_count += 1 - - logger.info(f"Found {self.contacts_saved_count} security contacts.") - # Update EPP contact for domains with a security contact for domain in domains: try: + contact = domain.security_contact # noqa on these items as we only want to call security_contact logger.info(f"Domain {domain.name} security contact: {domain.security_contact.email}") if domain.security_contact.email != "registrar@dotgov.gov": domain._update_epp_contact(contact=domain.security_contact) From 94d7c351563ae0bc5c9161edb66399e7b31df843 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 18 Jan 2024 12:29:02 -0700 Subject: [PATCH 078/107] PR suggestions --- src/registrar/templates/home.html | 21 +++++++++------------ src/registrar/templates/includes/modal.html | 4 ++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index cccc20f28..b0d510819 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -127,7 +127,7 @@ {% if application.requested_domain is None %} New domain request
- ({{ application.created_at }}) + ({{ application.created_at }}) {% else %} {{ application.requested_domain.name }} {% endif %} @@ -174,31 +174,28 @@
{% if application.requested_domain is None %} - {% with prefix="Are you sure you want to delete New domain request (" %} + {% with prefix="New domain request (" %} {% if application.created_at %} {% with formatted_date=application.created_at|date:"DATETIME_FORMAT" %} - {% with modal_heading=prefix|add:formatted_date|add:")?" %} - {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% with modal_content=prefix|add:formatted_date|add:")" %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete" heading_value="New domain request?"" modal_description="This will remove "|add:modal_content|add:" from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} {% endwith %} {% endwith %} {% else %} - {# Handle the case when application.created_at is not available or empty #} - {% with modal_heading=prefix %} - {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} - {% endwith %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete New domain request?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} {% endif %} {% endwith %} {% else %} - {% with modal_heading="Are you sure you want to delete "|add:application.requested_domain.name|add:"?" %} - {% include 'includes/modal.html' with modal_heading=modal_heading modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} + {% with modal_heading_value=application.requested_domain.name|add:"?" %} + {% include 'includes/modal.html' with modal_heading="Are you sure you want to delete" heading_value=modal_heading_value modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %} {% endwith %} {% endif %} diff --git a/src/registrar/templates/includes/modal.html b/src/registrar/templates/includes/modal.html index 1f9fbcfd4..45a6fa3b5 100644 --- a/src/registrar/templates/includes/modal.html +++ b/src/registrar/templates/includes/modal.html @@ -4,6 +4,10 @@