From d57155acc5c5a797c69856aad4af82b00cff21ce Mon Sep 17 00:00:00 2001 From: CocoByte Date: Tue, 14 May 2024 13:07:55 -0600 Subject: [PATCH 01/58] Added domain request pre-amble for user contact info (uses waffle flag for profile feature) --- .../templates/domain_request_intro.html | 6 ++++ .../templates/domain_request_review.html | 2 +- .../includes/profile_information.html | 36 +++++++++++++++++++ src/registrar/views/domain_request.py | 6 ++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/registrar/templates/includes/profile_information.html diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index 72abe6a27..c8bfc47ac 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -15,6 +15,12 @@

If you have all the information you need, completing your domain request might take around 15 minutes.

+ {% if has_profile_feature_flag %} +

How we'll reach you

+

While reviewing your domain request, we may need to reach out with questions. We'll also email you when we complete our review If the contact information below is not correct, visit your profile to make updates.

+ {% include "includes/profile_information.html" with user=user%} + {% endif %} + {% block form_buttons %}
diff --git a/src/registrar/templates/domain_request_review.html b/src/registrar/templates/domain_request_review.html index 5f359e95f..d24e6f8fa 100644 --- a/src/registrar/templates/domain_request_review.html +++ b/src/registrar/templates/domain_request_review.html @@ -1,4 +1,4 @@ -{% extends 'domain_request_form.html' %} +{% extends '(request):.html' %} {% load static url_helpers %} {% load custom_filters %} diff --git a/src/registrar/templates/includes/profile_information.html b/src/registrar/templates/includes/profile_information.html new file mode 100644 index 000000000..edd6ea645 --- /dev/null +++ b/src/registrar/templates/includes/profile_information.html @@ -0,0 +1,36 @@ +{% load static field_helpers %} + +{% block domain_content %} + + +
+
+

+ Your contact information +

+
+
    +
  • Full name: {{ user.contact.first_name }} {{ user.contact.last_name }}
  • +
  • Organization email: {{ user.contact.email }}
  • +
  • Title or role in your organization: {{ user.contact.title }}
  • +
  • Phone: {{ user.contact.phone }}
  • +
+
+
+
+ +{% endblock %} diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index f93976138..f6101873e 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -16,6 +16,8 @@ from registrar.utility import StrEnum from registrar.views.utility import StepsHelper from registrar.views.utility.permission_views import DomainRequestPermissionDeleteView +from waffle.decorators import flag_is_active + from .utility import ( DomainRequestPermissionView, DomainRequestPermissionWithdrawView, @@ -227,6 +229,10 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): # know which view is first in the list of steps. if self.__class__ == DomainRequestWizard: if request.path_info == self.NEW_URL_NAME: + user = self.request.user + context = self.get_context_data() + context["user"] = user + context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature") return render(request, "domain_request_intro.html") else: return self.goto(self.steps.first) From fa2d6a1387c12c9ee8bc08ec3b180b689453503d Mon Sep 17 00:00:00 2001 From: CocoByte Date: Wed, 15 May 2024 15:53:54 -0600 Subject: [PATCH 02/58] Fixed profile flag --- src/registrar/templates/domain_request_intro.html | 8 ++++---- src/registrar/views/domain_request.py | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/registrar/templates/domain_request_intro.html b/src/registrar/templates/domain_request_intro.html index c8bfc47ac..2db0177fb 100644 --- a/src/registrar/templates/domain_request_intro.html +++ b/src/registrar/templates/domain_request_intro.html @@ -15,10 +15,10 @@

If you have all the information you need, completing your domain request might take around 15 minutes.

- {% if has_profile_feature_flag %} -

How we'll reach you

-

While reviewing your domain request, we may need to reach out with questions. We'll also email you when we complete our review If the contact information below is not correct, visit your profile to make updates.

- {% include "includes/profile_information.html" with user=user%} + {% if has_profile_feature_flag == true %} +

How we'll reach you

+

While reviewing your domain request, we may need to reach out with questions. We'll also email you when we complete our review If the contact information below is not correct, visit your profile to make updates.

+ {% include "includes/profile_information.html" with user=user%} {% endif %} diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index f6101873e..e141af502 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -229,10 +229,10 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): # know which view is first in the list of steps. if self.__class__ == DomainRequestWizard: if request.path_info == self.NEW_URL_NAME: - user = self.request.user context = self.get_context_data() - context["user"] = user - context["has_profile_feature_flag"] = flag_is_active(request, "profile_feature") + has_prof = flag_is_active(self.request, "profile_feature") + context["has_profile_feature_flag"] = has_prof + logger.debug("PROFILE FLAG is %s" % has_prof) return render(request, "domain_request_intro.html") else: return self.goto(self.steps.first) @@ -390,7 +390,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): else: modal_heading = "You are about to submit an incomplete request" - return { + context = { "form_titles": self.TITLES, "steps": self.steps, # Add information about which steps should be unlocked @@ -398,7 +398,11 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): "is_federal": self.domain_request.is_federal(), "modal_button": modal_button, "modal_heading": modal_heading, + #Use the profile waffle feature flag to toggle profile features throughout domain requests + "has_profile_feature_flag": flag_is_active(self.request, "profile_feature"), + "user": self.request.user } + return context def get_step_list(self) -> list: """Dynamically generated list of steps in the form wizard.""" From affd7d88acfd9429e641416c9f375460ad7373bf Mon Sep 17 00:00:00 2001 From: CocoByte Date: Wed, 15 May 2024 15:58:03 -0600 Subject: [PATCH 03/58] linted --- src/registrar/views/domain_request.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/registrar/views/domain_request.py b/src/registrar/views/domain_request.py index e141af502..21675c2fe 100644 --- a/src/registrar/views/domain_request.py +++ b/src/registrar/views/domain_request.py @@ -230,9 +230,6 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): if self.__class__ == DomainRequestWizard: if request.path_info == self.NEW_URL_NAME: context = self.get_context_data() - has_prof = flag_is_active(self.request, "profile_feature") - context["has_profile_feature_flag"] = has_prof - logger.debug("PROFILE FLAG is %s" % has_prof) return render(request, "domain_request_intro.html") else: return self.goto(self.steps.first) @@ -390,6 +387,9 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): else: modal_heading = "You are about to submit an incomplete request" + has_profile_flag = flag_is_active(self.request, "profile_feature") + logger.debug("PROFILE FLAG is %s" % has_profile_flag) + context = { "form_titles": self.TITLES, "steps": self.steps, @@ -398,9 +398,9 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView): "is_federal": self.domain_request.is_federal(), "modal_button": modal_button, "modal_heading": modal_heading, - #Use the profile waffle feature flag to toggle profile features throughout domain requests - "has_profile_feature_flag": flag_is_active(self.request, "profile_feature"), - "user": self.request.user + # Use the profile waffle feature flag to toggle profile features throughout domain requests + "has_profile_feature_flag": has_profile_flag, + "user": self.request.user, } return context From ce70e8e3e800984a884d9c06297c73244bb92144 Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Tue, 21 May 2024 11:00:47 -0400 Subject: [PATCH 04/58] wip --- src/registrar/assets/js/get-gov.js | 124 ++++++++++++++++++++++++++++ src/registrar/config/urls.py | 2 + src/registrar/models/domain.py | 9 ++ src/registrar/templates/home.html | 63 +++----------- src/registrar/views/domains_json.py | 38 +++++++++ src/registrar/views/index.py | 25 +++++- 6 files changed, 205 insertions(+), 56 deletions(-) create mode 100644 src/registrar/views/domains_json.py diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index e7260ee21..16c04dd4d 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -834,3 +834,127 @@ function hideDeletedForms() { (function cisaRepresentativesFormListener() { HookupYesNoListener("additional_details-has_cisa_representative",'cisa-representative', null) })(); + + +document.addEventListener('DOMContentLoaded', function() { + let currentPage = 1; + let currentSortBy = 'id'; + let currentOrder = 'asc'; + + function loadPage(page, sortBy = currentSortBy, order = currentOrder) { + fetch(`/get-domains-json/?page=${page}&sort_by=${sortBy}&order=${order}`) + .then(response => response.json()) + .then(data => { + if (data.error) { + alert(data.error); + return; + } + + const domainList = document.querySelector('.dotgov-table__registered-domains tbody'); + domainList.innerHTML = ''; + + data.domains.forEach(domain => { + const expirationDate = domain.expiration_date ? new Date(domain.expiration_date) : null; + const expirationDateSortValue = expirationDate ? expirationDate.getTime() : ''; + + const row = document.createElement('tr'); + row.innerHTML = ` + + ${domain.name} + + + ${expirationDate ? expirationDate.toLocaleDateString() : ''} + + + ${domain.status_text} + + + + + + + + ${domain.state === 'deleted' || domain.state === 'on hold' ? 'View' : 'Manage'} ${domain.name} + + + `; + domainList.appendChild(row); + }); + + updatePagination(data.page, data.num_pages, data.has_previous, data.has_next); + currentPage = page; + currentSortBy = sortBy; + currentOrder = order; + }); + } + + function updatePagination(currentPage, numPages, hasPrevious, hasNext) { + const paginationContainer = document.querySelector('.usa-pagination__list'); + paginationContainer.innerHTML = ''; + + if (hasPrevious) { + const prevPageItem = document.createElement('li'); + prevPageItem.className = 'usa-pagination__item usa-pagination__arrow'; + prevPageItem.innerHTML = ` + + + Previous + + `; + prevPageItem.querySelector('a').addEventListener('click', () => loadPage(currentPage - 1)); + paginationContainer.appendChild(prevPageItem); + } + + for (let i = 1; i <= numPages; i++) { + const pageItem = document.createElement('li'); + pageItem.className = 'usa-pagination__item usa-pagination__page-no'; + pageItem.innerHTML = ` + ${i} + `; + if (i === currentPage) { + pageItem.querySelector('a').classList.add('usa-current'); + pageItem.querySelector('a').setAttribute('aria-current', 'page'); + } + pageItem.querySelector('a').addEventListener('click', () => loadPage(i)); + paginationContainer.appendChild(pageItem); + } + + if (hasNext) { + const nextPageItem = document.createElement('li'); + nextPageItem.className = 'usa-pagination__item usa-pagination__arrow'; + nextPageItem.innerHTML = ` + + Next + + + `; + nextPageItem.querySelector('a').addEventListener('click', () => loadPage(currentPage + 1)); + paginationContainer.appendChild(nextPageItem); + } + } + + // Add event listeners to table headers for sorting + document.querySelectorAll('.dotgov-table th[data-sortable]').forEach(header => { + header.addEventListener('click', function() { + const sortBy = this.getAttribute('data-sortable'); + const order = currentOrder === 'asc' ? 'desc' : 'asc'; + loadPage(1, sortBy, order); + }); +}); + + // Load the first page initially + loadPage(1); +}); \ No newline at end of file diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 720034150..4d3a25652 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -21,6 +21,7 @@ from registrar.views.admin_views import ( ) from registrar.views.domain_request import Step +from registrar.views.domains_json import get_domains_json from registrar.views.utility import always_404 from api.views import available, get_current_federal, get_current_full @@ -193,6 +194,7 @@ urlpatterns = [ views.DomainDeleteUserView.as_view(http_method_names=["post"]), name="domain-user-delete", ), + path('get-domains-json/', get_domains_json, name='get_domains_json'), ] # Djangooidc strips out context data from that context, so we define a custom error diff --git a/src/registrar/models/domain.py b/src/registrar/models/domain.py index 4c9028bb4..080acdb9b 100644 --- a/src/registrar/models/domain.py +++ b/src/registrar/models/domain.py @@ -1024,6 +1024,15 @@ class Domain(TimeStampedModel, DomainHelper): verbose_name="domain state", ) + @property + def status_text(self): + if self.is_expired and self.state != Domain.State.UNKNOWN: + return "Expired" + elif self.state == Domain.State.UNKNOWN or self.state == Domain.State.DNS_NEEDED: + return "DNS needed" + else: + return self.get_state_display() # Assuming get_state_display returns the capitalized state name + expiration_date = DateField( null=True, help_text=("Date the domain expires in the registry"), diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 6cc17817a..ed76bd898 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -25,14 +25,14 @@

Domains

- {% if domains %} + {% if page_obj %} - - - + + + - {% for domain in domains %} - - - - - - - {% endfor %} +
Your registered domains
Domain nameExpiresStatusDomain nameExpiresStatus
- {{ domain.name }} - {{ domain.expiration_date|date }} - {# UNKNOWN domains would not have an expiration date and thus would show 'Expired' #} - {% if domain.is_expired and domain.state != domain.State.UNKNOWN %} - Expired - {% elif domain.state == domain.State.UNKNOWN or domain.state == domain.State.DNS_NEEDED %} - DNS needed - {% else %} - {{ domain.state|capfirst }} - {% endif %} - - - - - - - View {{ domain.name }} - {% else %} - - - Manage {{ domain.name }} - {% endif %} - -
+ +

Domain requests

{% if domain_requests %} diff --git a/src/registrar/views/domains_json.py b/src/registrar/views/domains_json.py new file mode 100644 index 000000000..5d102f593 --- /dev/null +++ b/src/registrar/views/domains_json.py @@ -0,0 +1,38 @@ +from django.http import JsonResponse +from django.core.paginator import Paginator +from registrar.models import UserDomainRole, Domain + +def get_domains_json(request): + """Given the current request, + get all domains that are associated with the UserDomainRole object""" + + if not request.user.is_authenticated: + return JsonResponse({'error': 'User not authenticated'}, status=401) + + user_domain_roles = UserDomainRole.objects.filter(user=request.user) + domain_ids = user_domain_roles.values_list("domain_id", flat=True) + + objects = Domain.objects.filter(id__in=domain_ids) + + # Handle sorting + sort_by = request.GET.get('sort_by', 'id') # Default to 'id' + order = request.GET.get('order', 'asc') # Default to 'asc' + + if order == 'desc': + sort_by = f'-{sort_by}' + + objects = objects.order_by(sort_by) + + paginator = Paginator(objects, 2) + page_number = request.GET.get('page') + page_obj = paginator.get_page(page_number) + + domains = list(page_obj.object_list.values()) # Convert QuerySet to list of dicts + + return JsonResponse({ + 'domains': domains, + 'page': page_obj.number, + 'num_pages': paginator.num_pages, + 'has_previous': page_obj.has_previous(), + 'has_next': page_obj.has_next(), + }) \ No newline at end of file diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index 651507c44..dbf21468d 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -1,5 +1,5 @@ from django.shortcuts import render - +from django.core.paginator import Paginator from registrar.models import DomainRequest, Domain, UserDomainRole from waffle.decorators import flag_is_active @@ -7,6 +7,18 @@ from waffle.decorators import flag_is_active def index(request): """This page is available to anyone without logging in.""" context = {} + + + paginator = _get_domains(request) + page_number = request.GET.get('page') + page_obj = paginator.get_page(page_number) + + context = { + 'page_obj': page_obj, + } + + + if request.user.is_authenticated: # Get all domain requests the user has access to domain_requests, deletable_domain_requests = _get_domain_requests(request) @@ -14,8 +26,8 @@ def index(request): context["domain_requests"] = domain_requests # Get all domains the user has access to - domains = _get_domains(request) - context["domains"] = domains + # domains = _get_domains(request) + # context["domains"] = domains # Determine if the user will see domain requests that they can delete has_deletable_domain_requests = deletable_domain_requests.exists() @@ -62,4 +74,9 @@ def _get_domains(request): get all domains that are associated with the UserDomainRole object""" user_domain_roles = UserDomainRole.objects.filter(user=request.user) domain_ids = user_domain_roles.values_list("domain_id", flat=True) - return Domain.objects.filter(id__in=domain_ids) + + objects = Domain.objects.filter(id__in=domain_ids).order_by('id') + p = Paginator(objects, 2) + print(p.count) + print(p.num_pages) + return p From f44d8896cbe9340f454dedf462f5fe8177c269c6 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Tue, 21 May 2024 12:11:53 -0400 Subject: [PATCH 05/58] wip --- src/registrar/assets/js/get-gov.js | 2 +- src/registrar/models/domain.py | 17 +++++++++-------- src/registrar/templates/home.html | 2 +- src/registrar/views/domains_json.py | 26 +++++++++++++++++++++----- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 16c04dd4d..ffa28ce34 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -866,7 +866,7 @@ document.addEventListener('DOMContentLoaded', function() { ${expirationDate ? expirationDate.toLocaleDateString() : ''} - ${domain.status_text} + ${domain.state_display} Domain name Expires - Status + Status Date: Tue, 21 May 2024 13:00:22 -0400 Subject: [PATCH 06/58] wip requests --- src/registrar/assets/js/get-gov.js | 140 +++++++++++++++++++- src/registrar/config/urls.py | 2 + src/registrar/templates/home.html | 115 ++-------------- src/registrar/views/domain_requests_json.py | 37 ++++++ src/registrar/views/domains_json.py | 4 +- 5 files changed, 186 insertions(+), 112 deletions(-) create mode 100644 src/registrar/views/domain_requests_json.py diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index ffa28ce34..2679a2116 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -894,11 +894,12 @@ document.addEventListener('DOMContentLoaded', function() { currentPage = page; currentSortBy = sortBy; currentOrder = order; - }); + }) + .catch(error => console.error('Error fetching domains:', error)); } function updatePagination(currentPage, numPages, hasPrevious, hasNext) { - const paginationContainer = document.querySelector('.usa-pagination__list'); + const paginationContainer = document.querySelector('#domains-pagination .usa-pagination__list'); paginationContainer.innerHTML = ''; if (hasPrevious) { @@ -957,4 +958,137 @@ document.addEventListener('DOMContentLoaded', function() { // Load the first page initially loadPage(1); -}); \ No newline at end of file +}); + +document.addEventListener('DOMContentLoaded', function() { + let currentPage = 1; + let currentSortBy = 'id'; + let currentOrder = 'asc'; + + function loadDomainRequestsPage(page, sortBy = currentSortBy, order = currentOrder) { + fetch(`/get-domain-requests-json/?page=${page}&sort_by=${sortBy}&order=${order}`) + .then(response => response.json()) + .then(data => { + if (data.error) { + alert(data.error); + return; + } + + const tbody = document.querySelector('.dotgov-table__domain-requests tbody'); + tbody.innerHTML = ''; + + data.domain_requests.forEach(request => { + const domainName = request.requested_domain ? request.requested_domain.name : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`; + const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : 'Not submitted'; + const actionUrl = (request.status === 'Started' || request.status === 'Withdrawn') ? `/edit-domain-request/${request.id}` : `/domain-request-status/${request.id}`; + const actionLabel = (request.status === 'Started' || request.status === 'Withdrawn') ? 'Edit' : 'Manage'; + const deleteButton = request.is_deletable ? ` + + Delete + ` : ''; + + const row = document.createElement('tr'); + row.innerHTML = ` + + ${domainName} + + + ${submissionDate} + + + ${request.state_display} + + + + + + + + ${actionLabel} ${request.requested_domain ? request.requested_domain.name : 'New domain request'} + + + ${deleteButton} + `; + tbody.appendChild(row); + }); + + updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next); + currentPage = page; + currentSortBy = sortBy; + currentOrder = order; + }) + .catch(error => console.error('Error fetching domain requests:', error)); + } + + function updateDomainRequestsPagination(currentPage, numPages, hasPrevious, hasNext) { + const paginationContainer = document.querySelector('#domain-requests-pagination .usa-pagination__list'); + paginationContainer.innerHTML = ''; + + if (hasPrevious) { + const prevPageItem = document.createElement('li'); + prevPageItem.className = 'usa-pagination__item usa-pagination__arrow'; + prevPageItem.innerHTML = ` + + + Previous + + `; + prevPageItem.querySelector('a').addEventListener('click', () => loadDomainRequestsPage(currentPage - 1)); + paginationContainer.appendChild(prevPageItem); + } + + for (let i = 1; i <= numPages; i++) { + const pageItem = document.createElement('li'); + pageItem.className = 'usa-pagination__item usa-pagination__page-no'; + pageItem.innerHTML = ` + ${i} + `; + if (i === currentPage) { + pageItem.querySelector('a').classList.add('usa-current'); + pageItem.querySelector('a').setAttribute('aria-current', 'page'); + } + pageItem.querySelector('a').addEventListener('click', () => loadDomainRequestsPage(i)); + paginationContainer.appendChild(pageItem); + } + + if (hasNext) { + const nextPageItem = document.createElement('li'); + nextPageItem.className = 'usa-pagination__item usa-pagination__arrow'; + nextPageItem.innerHTML = ` + + Next + + + `; + nextPageItem.querySelector('a').addEventListener('click', () => loadDomainRequestsPage(currentPage + 1)); + paginationContainer.appendChild(nextPageItem); + } + } + + // Add event listeners to table headers for sorting + document.querySelectorAll('.dotgov-table__domain-requests th[data-sortable]').forEach(header => { + header.addEventListener('click', function() { + const sortBy = this.getAttribute('data-sortable'); + const order = currentOrder === 'asc' ? 'desc' : 'asc'; + loadDomainRequestsPage(1, sortBy, order); + }); + }); + + // Load the first page initially + loadDomainRequestsPage(1); +}); diff --git a/src/registrar/config/urls.py b/src/registrar/config/urls.py index 4d3a25652..ba11c7863 100644 --- a/src/registrar/config/urls.py +++ b/src/registrar/config/urls.py @@ -21,6 +21,7 @@ from registrar.views.admin_views import ( ) from registrar.views.domain_request import Step +from registrar.views.domain_requests_json import get_domain_requests_json from registrar.views.domains_json import get_domains_json from registrar.views.utility import always_404 from api.views import available, get_current_federal, get_current_full @@ -195,6 +196,7 @@ urlpatterns = [ name="domain-user-delete", ), path('get-domains-json/', get_domains_json, name='get_domains_json'), + path('get-domain-requests-json/', get_domain_requests_json, name='get_domain_requests_json'), ] # Djangooidc strips out context data from that context, so we define a custom error diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 77934c9e4..3e51551d7 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -62,7 +62,7 @@ {% endif %}
-
{# Note: Reimplement this after MVP #} diff --git a/src/registrar/views/index.py b/src/registrar/views/index.py index dbf21468d..6d8cf2ddc 100644 --- a/src/registrar/views/index.py +++ b/src/registrar/views/index.py @@ -1,6 +1,5 @@ from django.shortcuts import render -from django.core.paginator import Paginator -from registrar.models import DomainRequest, Domain, UserDomainRole +from registrar.models import DomainRequest from waffle.decorators import flag_is_active @@ -8,26 +7,12 @@ def index(request): """This page is available to anyone without logging in.""" context = {} - - paginator = _get_domains(request) - page_number = request.GET.get('page') - page_obj = paginator.get_page(page_number) - - context = { - 'page_obj': page_obj, - } - - - if request.user.is_authenticated: # Get all domain requests the user has access to domain_requests, deletable_domain_requests = _get_domain_requests(request) context["domain_requests"] = domain_requests - # Get all domains the user has access to - # domains = _get_domains(request) - # context["domains"] = domains # Determine if the user will see domain requests that they can delete has_deletable_domain_requests = deletable_domain_requests.exists() @@ -68,15 +53,3 @@ def _get_domain_requests(request): return (domain_requests, deletable_domain_requests) - -def _get_domains(request): - """Given the current request, - get all domains that are associated with the UserDomainRole object""" - user_domain_roles = UserDomainRole.objects.filter(user=request.user) - domain_ids = user_domain_roles.values_list("domain_id", flat=True) - - objects = Domain.objects.filter(id__in=domain_ids).order_by('id') - p = Paginator(objects, 2) - print(p.count) - print(p.num_pages) - return p From 2d26ae222c09837053c1a1d75d4365d3fb85df3d Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 22 May 2024 13:11:00 -0400 Subject: [PATCH 09/58] wip --- src/registrar/assets/js/get-gov.js | 48 +++++++++++++++++++------ src/registrar/assets/js/uswds-edited.js | 34 ++---------------- src/registrar/templates/base.html | 2 +- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 2141c2769..f22379a20 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -836,6 +836,29 @@ function hideDeletedForms() { })(); +function initializeTooltips() { + function checkTooltip() { + //console.log('Checking for tooltip...'); + if (window.tooltip && typeof window.tooltip.init === 'function') { + console.log('Tooltip is available, initializing...'); + window.tooltip.init(); + } else { + console.log('Tooltip not available, retrying...'); + // Retry after a short delay + setTimeout(checkTooltip, 100); + } + } + checkTooltip(); +} + +function initializeModals() { + window.modal.on(); +} + +function unloadModals() { + window.modal.off(); +} + document.addEventListener('DOMContentLoaded', function() { let currentPage = 1; let currentSortBy = 'id'; @@ -885,13 +908,13 @@ document.addEventListener('DOMContentLoaded', function() { aria-label="Status Information" role="tooltip" > - + ${domain.state === 'deleted' || domain.state === 'on hold' ? 'View' : 'Manage'} ${domain.name} @@ -899,6 +922,7 @@ document.addEventListener('DOMContentLoaded', function() { `; domainList.appendChild(row); }); + initializeTooltips(); updatePagination(data.page, data.num_pages, data.has_previous, data.has_next); currentPage = page; @@ -908,6 +932,7 @@ document.addEventListener('DOMContentLoaded', function() { .catch(error => console.error('Error fetching domains:', error)); } + function updatePagination(currentPage, numPages, hasPrevious, hasNext) { const paginationContainer = document.querySelector('#domains-pagination .usa-pagination__list'); paginationContainer.innerHTML = ''; @@ -918,7 +943,7 @@ document.addEventListener('DOMContentLoaded', function() { prevPageItem.innerHTML = ` Previous @@ -948,7 +973,7 @@ document.addEventListener('DOMContentLoaded', function() { Next `; @@ -997,8 +1022,9 @@ document.addEventListener('DOMContentLoaded', function() { const tbody = document.querySelector('.dotgov-table__domain-requests tbody'); tbody.innerHTML = ''; + unloadModals(); data.domain_requests.forEach(request => { - const domainName = request.requested_domain ? request.requested_domain.name : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`; + const domainName = request.requested_domain ? request.requested_domain : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`; const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : 'Not submitted'; const actionUrl = (request.status === 'Started' || request.status === 'Withdrawn') ? `/domain-request/${request.id}/edit` : `/domain-request/${request.id}`; const actionLabel = (request.status === 'Started' || request.status === 'Withdrawn') ? 'Edit' : 'Manage'; @@ -1012,7 +1038,7 @@ document.addEventListener('DOMContentLoaded', function() { data-open-modal > Delete ${domainName} ` : ''; @@ -1034,13 +1060,13 @@ document.addEventListener('DOMContentLoaded', function() { aria-label="Status Information" role="tooltip" > - + ${actionLabel} ${request.requested_domain ? request.requested_domain.name : 'New domain request'} @@ -1049,6 +1075,8 @@ document.addEventListener('DOMContentLoaded', function() { `; tbody.appendChild(row); }); + initializeTooltips(); + initializeModals(); updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next); currentPage = page; @@ -1073,7 +1101,7 @@ document.addEventListener('DOMContentLoaded', function() { prevPageItem.innerHTML = ` Previous @@ -1103,7 +1131,7 @@ document.addEventListener('DOMContentLoaded', function() { Next `; diff --git a/src/registrar/assets/js/uswds-edited.js b/src/registrar/assets/js/uswds-edited.js index 60f286bb5..ac3e7d8d4 100644 --- a/src/registrar/assets/js/uswds-edited.js +++ b/src/registrar/assets/js/uswds-edited.js @@ -5336,36 +5336,6 @@ modal = { item.addEventListener("click", toggleModal); }); }); - - // Check for the presence of the testerPixel element - const intervalId = setInterval(() => { - console.log('testing'); - const testerPixel = document.querySelector('.testerPixel'); - if (testerPixel) { - clearInterval(intervalId); - console.log('found it'); - - - document.querySelectorAll('.late-loading-modal-trigger').forEach(item => { - // Turn anchor links into buttons because of - // VoiceOver on Safari - if (item.nodeName === "A") { - item.setAttribute("role", "button"); - item.addEventListener("click", e => e.preventDefault()); - } - - // Can uncomment when aria-haspopup="dialog" is supported - // https://a11ysupport.io/tech/aria/aria-haspopup_attribute - // Most screen readers support aria-haspopup, but might announce - // as opening a menu if "dialog" is not supported. - // item.setAttribute("aria-haspopup", "dialog"); - - item.addEventListener("click", toggleModal); - }); - - - } - }, 100); // Check every 100ms }, teardown(root) { selectOrMatches(MODAL, root).forEach(modalWindow => { @@ -5384,6 +5354,7 @@ modal = { } }; module.exports = modal; +window.modal = modal; },{"../../uswds-core/src/js/config":35,"../../uswds-core/src/js/utils/focus-trap":47,"../../uswds-core/src/js/utils/scrollbar-width":51,"../../uswds-core/src/js/utils/select-or-matches":52}],29:[function(require,module,exports){ "use strict"; @@ -5854,7 +5825,7 @@ const { prefix: PREFIX } = require("../../uswds-core/src/js/config"); const isElementInViewport = require("../../uswds-core/src/js/utils/is-in-viewport"); -const TOOLTIP = `.${PREFIX}-tooltip`; +const TOOLTIP = `svg.${PREFIX}-tooltip`; const TOOLTIP_TRIGGER = `.${PREFIX}-tooltip__trigger`; const TOOLTIP_TRIGGER_CLASS = `${PREFIX}-tooltip__trigger`; const TOOLTIP_CLASS = `${PREFIX}-tooltip`; @@ -6188,6 +6159,7 @@ const tooltip = behavior({ hide: hideToolTip }); module.exports = tooltip; +window.tooltip = tooltip; },{"../../uswds-core/src/js/config":35,"../../uswds-core/src/js/utils/behavior":45,"../../uswds-core/src/js/utils/is-in-viewport":48,"../../uswds-core/src/js/utils/select-or-matches":52}],34:[function(require,module,exports){ "use strict"; diff --git a/src/registrar/templates/base.html b/src/registrar/templates/base.html index f28d28de1..5eb69438e 100644 --- a/src/registrar/templates/base.html +++ b/src/registrar/templates/base.html @@ -45,6 +45,7 @@ {% block css %} + {% endblock %} @@ -67,7 +68,6 @@ - Skip to main content {% if not IS_PRODUCTION %} From f2b7176a4a24099bbdd87244e6f9daca771554ba Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 22 May 2024 14:17:10 -0400 Subject: [PATCH 10/58] wip --- src/registrar/assets/js/get-gov.js | 16 ------------ src/registrar/assets/js/uswds-edited.js | 2 +- src/registrar/templates/home.html | 29 +++------------------ src/registrar/views/domain_requests_json.py | 6 +++++ src/registrar/views/domains_json.py | 2 +- 5 files changed, 11 insertions(+), 44 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index f22379a20..f6d634492 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -1052,16 +1052,6 @@ document.addEventListener('DOMContentLoaded', function() { ${request.status} - - - @@ -1075,18 +1065,12 @@ document.addEventListener('DOMContentLoaded', function() { `; tbody.appendChild(row); }); - initializeTooltips(); initializeModals(); updateDomainRequestsPagination(data.page, data.num_pages, data.has_previous, data.has_next); currentPage = page; currentSortBy = sortBy; currentOrder = order; - - // Add the testerPixel element to the DOM - const testerPixel = document.createElement('span'); - testerPixel.classList.add('display-none', 'testerPixel'); - document.body.appendChild(testerPixel); }) .catch(error => console.error('Error fetching domain requests:', error)); } diff --git a/src/registrar/assets/js/uswds-edited.js b/src/registrar/assets/js/uswds-edited.js index ac3e7d8d4..ba3df092d 100644 --- a/src/registrar/assets/js/uswds-edited.js +++ b/src/registrar/assets/js/uswds-edited.js @@ -5825,7 +5825,7 @@ const { prefix: PREFIX } = require("../../uswds-core/src/js/config"); const isElementInViewport = require("../../uswds-core/src/js/utils/is-in-viewport"); -const TOOLTIP = `svg.${PREFIX}-tooltip`; +const TOOLTIP = `.${PREFIX}-tooltip`; const TOOLTIP_TRIGGER = `.${PREFIX}-tooltip__trigger`; const TOOLTIP_TRIGGER_CLASS = `${PREFIX}-tooltip__trigger`; const TOOLTIP_CLASS = `${PREFIX}-tooltip`; diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 3cbc66f8a..cd4d1ed83 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -76,9 +76,9 @@ Your domain requests - Domain name - Date submitted - Status + Domain name + Date submitted + Status Action Delete Action @@ -91,29 +91,6 @@ {% for domain_request in domain_requests %} {% if has_deletable_domain_requests %} {% if domain_request.status == "started" or domain_request.status == "withdrawn" %} -
Date: Wed, 22 May 2024 14:55:51 -0400 Subject: [PATCH 11/58] toggle pagination, template tweaks --- src/registrar/assets/js/get-gov.js | 8 ++++++-- src/registrar/views/domain_requests_json.py | 2 +- src/registrar/views/domains_json.py | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index f6d634492..484e435d3 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -937,6 +937,8 @@ document.addEventListener('DOMContentLoaded', function() { const paginationContainer = document.querySelector('#domains-pagination .usa-pagination__list'); paginationContainer.innerHTML = ''; + paginationContainer.classList.toggle('display-none', numPages <= 1); + if (hasPrevious) { const prevPageItem = document.createElement('li'); prevPageItem.className = 'usa-pagination__item usa-pagination__arrow'; @@ -1024,8 +1026,8 @@ document.addEventListener('DOMContentLoaded', function() { unloadModals(); data.domain_requests.forEach(request => { - const domainName = request.requested_domain ? request.requested_domain : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`; - const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : 'Not submitted'; + const domainName = request.requested_domain ? request.requested_domain : `New domain request (${new Date(request.created_at).toLocaleString()} UTC)`; + const submissionDate = request.submission_date ? new Date(request.submission_date).toLocaleDateString() : `Not submitted`; const actionUrl = (request.status === 'Started' || request.status === 'Withdrawn') ? `/domain-request/${request.id}/edit` : `/domain-request/${request.id}`; const actionLabel = (request.status === 'Started' || request.status === 'Withdrawn') ? 'Edit' : 'Manage'; const deleteButton = request.is_deletable ? ` @@ -1079,6 +1081,8 @@ document.addEventListener('DOMContentLoaded', function() { const paginationContainer = document.querySelector('#domain-requests-pagination .usa-pagination__list'); paginationContainer.innerHTML = ''; + paginationContainer.classList.toggle('display-none', numPages <= 1); + if (hasPrevious) { const prevPageItem = document.createElement('li'); prevPageItem.className = 'usa-pagination__item usa-pagination__arrow'; diff --git a/src/registrar/views/domain_requests_json.py b/src/registrar/views/domain_requests_json.py index e54fffcf8..a212e519e 100644 --- a/src/registrar/views/domain_requests_json.py +++ b/src/registrar/views/domain_requests_json.py @@ -19,7 +19,7 @@ def get_domain_requests_json(request): sort_by = f'-{sort_by}' domain_requests = domain_requests.order_by(sort_by) page_number = request.GET.get('page', 1) - paginator = Paginator(domain_requests, 2) # Adjust the number of items per page as needed + paginator = Paginator(domain_requests, 10) # Adjust the number of items per page as needed page_obj = paginator.get_page(page_number) domain_requests_data = [ diff --git a/src/registrar/views/domains_json.py b/src/registrar/views/domains_json.py index c49338693..4b5011034 100644 --- a/src/registrar/views/domains_json.py +++ b/src/registrar/views/domains_json.py @@ -27,7 +27,7 @@ def get_domains_json(request): sort_by = f'-{sort_by}' objects = objects.order_by(sort_by) - paginator = Paginator(objects, 1) + paginator = Paginator(objects, 10) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) From dfea3860e8e1e9ec799a1cd475854e4d6df64af7 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 22 May 2024 14:57:37 -0400 Subject: [PATCH 12/58] wip --- src/registrar/assets/js/get-gov.js | 16 +++++++++++----- src/registrar/templates/home.html | 2 +- src/registrar/views/domains_json.py | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index f6d634492..5fd4a0957 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -925,9 +925,9 @@ document.addEventListener('DOMContentLoaded', function() { initializeTooltips(); updatePagination(data.page, data.num_pages, data.has_previous, data.has_next); - currentPage = page; - currentSortBy = sortBy; - currentOrder = order; + currentPage = page; + currentSortBy = sortBy; + currentOrder = order; }) .catch(error => console.error('Error fetching domains:', error)); } @@ -986,7 +986,10 @@ document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.dotgov-table th[data-sortable]').forEach(header => { header.addEventListener('click', function() { const sortBy = this.getAttribute('data-sortable'); - const order = currentOrder === 'asc' ? 'desc' : 'asc'; + let order = 'asc'; + if (sortBy === currentSortBy) { + order = currentOrder === 'asc' ? 'desc' : 'asc'; + } loadPage(1, sortBy, order); }); }); @@ -1128,7 +1131,10 @@ document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.dotgov-table__domain-requests th[data-sortable]').forEach(header => { header.addEventListener('click', function() { const sortBy = this.getAttribute('data-sortable'); - const order = currentOrder === 'asc' ? 'desc' : 'asc'; + let order = 'asc'; + if (sortBy === currentSortBy) { + order = currentOrder === 'asc' ? 'desc' : 'asc'; + } loadDomainRequestsPage(1, sortBy, order); }); }); diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index cd4d1ed83..0f101717d 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -76,7 +76,7 @@ Your domain requests - Domain name + Domain name Date submitted Status Action diff --git a/src/registrar/views/domains_json.py b/src/registrar/views/domains_json.py index c49338693..c65fedd52 100644 --- a/src/registrar/views/domains_json.py +++ b/src/registrar/views/domains_json.py @@ -27,7 +27,7 @@ def get_domains_json(request): sort_by = f'-{sort_by}' objects = objects.order_by(sort_by) - paginator = Paginator(objects, 1) + paginator = Paginator(objects, 3) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) From 7b92943be28bec47f90882189180026341765709 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 22 May 2024 15:14:11 -0400 Subject: [PATCH 13/58] fixed sort --- src/registrar/assets/js/get-gov.js | 2 +- src/registrar/templates/home.html | 2 +- src/registrar/views/domain_requests_json.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/registrar/assets/js/get-gov.js b/src/registrar/assets/js/get-gov.js index 6b323bcba..e664ed7b5 100644 --- a/src/registrar/assets/js/get-gov.js +++ b/src/registrar/assets/js/get-gov.js @@ -985,7 +985,7 @@ document.addEventListener('DOMContentLoaded', function() { } // Add event listeners to table headers for sorting - document.querySelectorAll('.dotgov-table th[data-sortable]').forEach(header => { + document.querySelectorAll('.dotgov-table__registered-domains th[data-sortable]').forEach(header => { header.addEventListener('click', function() { const sortBy = this.getAttribute('data-sortable'); let order = 'asc'; diff --git a/src/registrar/templates/home.html b/src/registrar/templates/home.html index 0f101717d..e588608c0 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -76,7 +76,7 @@ Your domain requests - Domain name + Domain name Date submitted Status Action diff --git a/src/registrar/views/domain_requests_json.py b/src/registrar/views/domain_requests_json.py index a212e519e..654749694 100644 --- a/src/registrar/views/domain_requests_json.py +++ b/src/registrar/views/domain_requests_json.py @@ -19,7 +19,7 @@ def get_domain_requests_json(request): sort_by = f'-{sort_by}' domain_requests = domain_requests.order_by(sort_by) page_number = request.GET.get('page', 1) - paginator = Paginator(domain_requests, 10) # Adjust the number of items per page as needed + paginator = Paginator(domain_requests, 4) # Adjust the number of items per page as needed page_obj = paginator.get_page(page_number) domain_requests_data = [ From fc2a00c76120fc622d6f75b22bfb19336eadb95e Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Wed, 22 May 2024 16:35:07 -0400 Subject: [PATCH 14/58] Fix failing tests --- src/registrar/tests/test_views.py | 67 ++++++----------------- src/registrar/tests/test_views_domain.py | 38 +------------ src/registrar/tests/test_views_request.py | 56 +++++-------------- 3 files changed, 30 insertions(+), 131 deletions(-) diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py index 217e24b9a..a9afedb22 100644 --- a/src/registrar/tests/test_views.py +++ b/src/registrar/tests/test_views.py @@ -157,30 +157,15 @@ class HomeTests(TestWithUser): self.assertContains(response, "You don't have any registered domains.") self.assertContains(response, "Why don't I see my domain when I sign in to the registrar?") - def test_home_lists_domain_requests(self): - response = self.client.get("/") - self.assertNotContains(response, "igorville.gov") - site = DraftDomain.objects.create(name="igorville.gov") - domain_request = DomainRequest.objects.create(creator=self.user, requested_domain=site) - response = self.client.get("/") - - # count = 7 because of screenreader content - self.assertContains(response, "igorville.gov", count=7) - - # clean up - domain_request.delete() - def test_state_help_text(self): """Tests if each domain state has help text""" # Get the expected text content of each state deleted_text = "This domain has been removed and " "is no longer registered to your organization." - dns_needed_text = "Before this domain can be used, " "you’ll need to add name server addresses." + dns_needed_text = "Before this domain can be used, " ready_text = "This domain has name servers and is ready for use." on_hold_text = ( "This domain is administratively paused, " - "so it can’t be edited and won’t resolve in DNS. " - "Contact help@get.gov for details." ) deleted_text = "This domain has been removed and " "is no longer registered to your organization." # Generate a mapping of domain names, the state, and expected messages for the subtest @@ -202,12 +187,12 @@ class HomeTests(TestWithUser): user=self.user, domain=test_domain, role=UserDomainRole.Roles.MANAGER ) - # Grab the home page - response = self.client.get("/") + # Grab the response + response = self.client.get("/get-domains-json/") # Make sure the user can actually see the domain. # We expect two instances because of SR content. - self.assertContains(response, domain_name, count=2) + self.assertContains(response, domain_name, count=1) # Check that we have the right text content. self.assertContains(response, expected_message, count=1) @@ -218,19 +203,19 @@ class HomeTests(TestWithUser): def test_state_help_text_expired(self): """Tests if each domain state has help text when expired""" - expired_text = "This domain has expired, but it is still online. " "To renew this domain, contact help@get.gov." + expired_text = "This domain has expired, but it is still online. " test_domain, _ = Domain.objects.get_or_create(name="expired.gov", state=Domain.State.READY) test_domain.expiration_date = date(2011, 10, 10) test_domain.save() UserDomainRole.objects.get_or_create(user=self.user, domain=test_domain, role=UserDomainRole.Roles.MANAGER) - # Grab the home page - response = self.client.get("/") + # Grab the response + response = self.client.get("/get-domains-json/") # Make sure the user can actually see the domain. # We expect two instances because of SR content. - self.assertContains(response, "expired.gov", count=2) + self.assertContains(response, "expired.gov", count=1) # Check that we have the right text content. self.assertContains(response, expired_text, count=1) @@ -239,19 +224,17 @@ class HomeTests(TestWithUser): """Tests if each domain state has help text when expiration date is None""" # == Test a expiration of None for state ready. This should be expired. == # - expired_text = "This domain has expired, but it is still online. " "To renew this domain, contact help@get.gov." + expired_text = "This domain has expired, but it is still online. " test_domain, _ = Domain.objects.get_or_create(name="imexpired.gov", state=Domain.State.READY) test_domain.expiration_date = None test_domain.save() UserDomainRole.objects.get_or_create(user=self.user, domain=test_domain, role=UserDomainRole.Roles.MANAGER) - # Grab the home page - response = self.client.get("/") + # Grab the response + response = self.client.get("/get-domains-json/") - # Make sure the user can actually see the domain. - # We expect two instances because of SR content. - self.assertContains(response, "imexpired.gov", count=2) + self.assertContains(response, "imexpired.gov", count=1) # Make sure the expiration date is None self.assertEqual(test_domain.expiration_date, None) @@ -260,19 +243,17 @@ class HomeTests(TestWithUser): self.assertContains(response, expired_text, count=1) # == Test a expiration of None for state unknown. This should not display expired text. == # - unknown_text = "Before this domain can be used, " "you’ll need to add name server addresses." + unknown_text = "Before this domain can be used, " test_domain_2, _ = Domain.objects.get_or_create(name="notexpired.gov", state=Domain.State.UNKNOWN) test_domain_2.expiration_date = None test_domain_2.save() UserDomainRole.objects.get_or_create(user=self.user, domain=test_domain_2, role=UserDomainRole.Roles.MANAGER) - # Grab the home page - response = self.client.get("/") + # Grab the response + response = self.client.get("/get-domains-json/") - # Make sure the user can actually see the domain. - # We expect two instances because of SR content. - self.assertContains(response, "notexpired.gov", count=2) + self.assertContains(response, "notexpired.gov", count=1) # Make sure the expiration date is None self.assertEqual(test_domain_2.expiration_date, None) @@ -288,14 +269,6 @@ class HomeTests(TestWithUser): creator=self.user, requested_domain=site, status=DomainRequest.DomainRequestStatus.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("domain-request-delete", kwargs={"pk": domain_request.pk}), follow=True) @@ -312,14 +285,6 @@ class HomeTests(TestWithUser): creator=self.user, requested_domain=site, status=DomainRequest.DomainRequestStatus.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("domain-request-delete", kwargs={"pk": domain_request.pk}), follow=True) diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py index 1d9fbb2a8..d042ee371 100644 --- a/src/registrar/tests/test_views_domain.py +++ b/src/registrar/tests/test_views_domain.py @@ -222,27 +222,6 @@ class TestDomainDetail(TestDomainOverview): self.assertContains(detail_page, "igorville.gov") self.assertContains(detail_page, "Status") - def test_unknown_domain_does_not_show_as_expired_on_homepage(self): - """An UNKNOWN domain does not show as expired on the homepage. - It shows as 'DNS needed'""" - # At the time of this test's writing, there are 6 UNKNOWN domains inherited - # from constructors. Let's reset. - with less_console_noise(): - Domain.objects.all().delete() - UserDomainRole.objects.all().delete() - self.domain, _ = Domain.objects.get_or_create(name="igorville.gov") - home_page = self.app.get("/") - self.assertNotContains(home_page, "igorville.gov") - self.role, _ = UserDomainRole.objects.get_or_create( - user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER - ) - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") - igorville = Domain.objects.get(name="igorville.gov") - self.assertEquals(igorville.state, Domain.State.UNKNOWN) - self.assertNotContains(home_page, "Expired") - self.assertContains(home_page, "DNS needed") - def test_unknown_domain_does_not_show_as_expired_on_detail_page(self): """An UNKNOWN domain should not exist on the detail_page anymore. It shows as 'DNS needed'""" @@ -258,11 +237,9 @@ class TestDomainDetail(TestDomainOverview): user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER ) - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") igorville = Domain.objects.get(name="igorville.gov") self.assertEquals(igorville.state, Domain.State.UNKNOWN) - detail_page = home_page.click("Manage", index=0) + detail_page = self.app.get(f'/domain/{igorville.id}') self.assertContains(detail_page, "Expired") self.assertNotContains(detail_page, "DNS needed") @@ -274,26 +251,18 @@ class TestDomainDetail(TestDomainOverview): with less_console_noise(): self.user.status = User.RESTRICTED self.user.save() - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") response = self.client.get(reverse("domain", kwargs={"pk": self.domain.id})) self.assertEqual(response.status_code, 403) def test_domain_detail_allowed_for_on_hold(self): """Test that the domain overview page displays for on hold domain""" with less_console_noise(): - home_page = self.app.get("/") - self.assertContains(home_page, "on-hold.gov") - # View domain overview page detail_page = self.client.get(reverse("domain", kwargs={"pk": self.domain_on_hold.id})) self.assertNotContains(detail_page, "Edit") def test_domain_detail_see_just_nameserver(self): with less_console_noise(): - home_page = self.app.get("/") - self.assertContains(home_page, "justnameserver.com") - # View nameserver on Domain Overview page detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_just_nameserver.id})) @@ -303,9 +272,6 @@ class TestDomainDetail(TestDomainOverview): def test_domain_detail_see_nameserver_and_ip(self): with less_console_noise(): - home_page = self.app.get("/") - self.assertContains(home_page, "nameserverwithip.gov") - # View nameserver on Domain Overview page detail_page = self.app.get(reverse("domain", kwargs={"pk": self.domain_with_ip.id})) @@ -1644,8 +1610,6 @@ class TestDomainSecurityEmail(TestDomainOverview): management pages share the same permissions class""" self.user.status = User.RESTRICTED self.user.save() - home_page = self.app.get("/") - self.assertContains(home_page, "igorville.gov") with less_console_noise(): response = self.client.get(reverse("domain", kwargs={"pk": self.domain.id})) self.assertEqual(response.status_code, 403) diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py index 2b577b41a..87fee4b61 100644 --- a/src/registrar/tests/test_views_request.py +++ b/src/registrar/tests/test_views_request.py @@ -47,11 +47,8 @@ class DomainRequestTests(TestWithUser, WebTest): def test_domain_request_form_intro_is_skipped_when_edit_access(self): """Tests that user is NOT presented with intro acknowledgement page when accessed through 'edit'""" - completed_domain_request(status=DomainRequest.DomainRequestStatus.STARTED, user=self.user) - home_page = self.app.get("/") - self.assertContains(home_page, "city.gov") - # click the "Edit" link - detail_page = home_page.click("Edit", index=0) + domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.STARTED, user=self.user) + detail_page = self.app.get(f'/domain-request/{domain_request.id}/edit/') # Check that the response is a redirect self.assertEqual(detail_page.status_code, 302) # You can access the 'Location' header to get the redirect URL @@ -2402,10 +2399,7 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest): domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.SUBMITTED, user=self.user) domain_request.save() - home_page = self.app.get("/") - self.assertContains(home_page, "city.gov") - # click the "Manage" link - detail_page = home_page.click("Manage", index=0) + detail_page = self.app.get(f'/domain-request/{domain_request.id}') self.assertContains(detail_page, "city.gov") self.assertContains(detail_page, "city1.gov") self.assertContains(detail_page, "Chief Tester") @@ -2422,10 +2416,7 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest): domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.SUBMITTED, user=self.user) domain_request.save() - home_page = self.app.get("/") - self.assertContains(home_page, "city.gov") - # click the "Manage" link - detail_page = home_page.click("Manage", index=0) + detail_page = self.app.get(f'/domain-request/{domain_request.id}') self.assertContains(detail_page, "city.gov") self.assertContains(detail_page, "Chief Tester") self.assertContains(detail_page, "testy@town.com") @@ -2437,10 +2428,7 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest): domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.SUBMITTED, user=self.user) domain_request.save() - home_page = self.app.get("/") - self.assertContains(home_page, "city.gov") - # click the "Manage" link - detail_page = home_page.click("Manage", index=0) + detail_page = self.app.get(f'/domain-request/{domain_request.id}') self.assertContains(detail_page, "city.gov") self.assertContains(detail_page, "city1.gov") self.assertContains(detail_page, "Chief Tester") @@ -2462,8 +2450,8 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest): target_status_code=200, fetch_redirect_response=True, ) - home_page = self.app.get("/") - self.assertContains(home_page, "Withdrawn") + response = self.client.get('/get-domain-requests-json/') + self.assertContains(response, "Withdrawn") def test_domain_request_withdraw_no_permissions(self): """Can't withdraw domain requests as a restricted user.""" @@ -2472,10 +2460,7 @@ class DomainRequestTestDifferentStatuses(TestWithUser, WebTest): domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.SUBMITTED, user=self.user) domain_request.save() - home_page = self.app.get("/") - self.assertContains(home_page, "city.gov") - # click the "Manage" link - detail_page = home_page.click("Manage", index=0) + detail_page = self.app.get(f'/domain-request/{domain_request.id}') self.assertContains(detail_page, "city.gov") self.assertContains(detail_page, "city1.gov") self.assertContains(detail_page, "Chief Tester") @@ -2545,23 +2530,16 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest): def test_unlocked_steps_full_domain_request(self): """Test when all fields in the domain request are filled.""" - completed_domain_request(status=DomainRequest.DomainRequestStatus.STARTED, user=self.user) - # Make a request to the home page - home_page = self.app.get("/") - # django-webtest does not handle cookie-based sessions well because it keeps + domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.STARTED, user=self.user) + + response = self.app.get(f'/domain-request/{domain_request.id}/edit/') + # django-webtest does not handle cookie-based sessions well because it keeps # resetting the session key on each new request, thus destroying the concept # of a "session". We are going to do it manually, saving the session ID here # and then setting the cookie on each request. session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - # Assert that the response contains "city.gov" - self.assertContains(home_page, "city.gov") - - # Click the "Edit" link - response = home_page.click("Edit", index=0) - self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - # Check if the response is a redirect if response.status_code == 302: # Follow the redirect manually @@ -2612,8 +2590,7 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest): ) domain_request.other_contacts.set([contact_2]) - # Make a request to the home page - home_page = self.app.get("/") + response = self.app.get(f'/domain-request/{domain_request.id}/edit/') # django-webtest does not handle cookie-based sessions well because it keeps # resetting the session key on each new request, thus destroying the concept # of a "session". We are going to do it manually, saving the session ID here @@ -2621,13 +2598,6 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest): session_id = self.app.cookies[settings.SESSION_COOKIE_NAME] self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - # Assert that the response contains "city.gov" - self.assertContains(home_page, "igorville.gov") - - # Click the "Edit" link - response = home_page.click("Edit", index=0) - self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id) - # Check if the response is a redirect if response.status_code == 302: # Follow the redirect manually From 5f064c09d2779db39dc10314b8aadbf7039e94de Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Wed, 22 May 2024 16:49:07 -0400 Subject: [PATCH 15/58] Fix nav alignment --- 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 e588608c0..5d09d408b 100644 --- a/src/registrar/templates/home.html +++ b/src/registrar/templates/home.html @@ -63,7 +63,7 @@
-
-