From cf946004c0d11c1637fad2d68f5a042f734b5eda Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 3 Apr 2024 06:49:29 -0400 Subject: [PATCH 01/43] added user request details below creator in django admin --- src/registrar/models/user.py | 18 ++++++++++++++++++ .../admin/includes/detail_table_fieldset.html | 4 ++++ .../admin/includes/user_detail_list.html | 12 ++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/registrar/templates/django/admin/includes/user_detail_list.html diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index bf904a044..5085c0b94 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -67,6 +67,24 @@ class User(AbstractUser): def is_restricted(self): return self.status == self.RESTRICTED + def get_approved_domains_count(self): + """Return count of approved domains""" + allowed_states = ['unknown', 'dns needed', 'ready', 'on hold'] + approved_domains_count = self.domains.filter(state__in=allowed_states).count() + return approved_domains_count + + def get_active_requests_count(self): + """Return count of active requests""" + allowed_states = ['submitted', 'in review', 'action needed'] + active_requests_count = self.domain_requests_created.filter(status__in=allowed_states).count() + return active_requests_count + + def get_rejected_requests_count(self): + """Return count of rejected or ineligible requests""" + allowed_states = ['rejected', 'ineligible'] + rejected_requests_count = self.domain_requests_created.filter(status__in=allowed_states).count() + return rejected_requests_count + @classmethod def needs_identity_verification(cls, email, uuid): """A method used by our oidc classes to test whether a user needs email/uuid verification diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index 47145faf2..2c3b76253 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -65,6 +65,10 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html) {% include "django/admin/includes/contact_detail_list.html" with user=original.creator no_title_top_padding=field.is_readonly %} +
+ + {% include "django/admin/includes/user_detail_list.html" with user=original.creator no_title_top_padding=field.is_readonly %} +
{% elif field.field.name == "submitter" %}
diff --git a/src/registrar/templates/django/admin/includes/user_detail_list.html b/src/registrar/templates/django/admin/includes/user_detail_list.html new file mode 100644 index 000000000..9daa8a0ee --- /dev/null +++ b/src/registrar/templates/django/admin/includes/user_detail_list.html @@ -0,0 +1,12 @@ +{% load i18n static %} + +
+ + {# Approved domains #} + Approved domains: {{ user.get_approved_domains_count }}
+ {# Active requests #} + Active requests: {{ user.get_active_requests_count }}
+ {# Rejected or ineligible requests #} + Rejected or ineligible: {{ user.get_rejected_requests_count }}
+ +
From 36a86533de363e08b7f4e621e43807fdbf125424 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:18:42 -0600 Subject: [PATCH 02/43] Remove website and draftdomain --- src/registrar/models/user_group.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/registrar/models/user_group.py b/src/registrar/models/user_group.py index e8636a462..604004b19 100644 --- a/src/registrar/models/user_group.py +++ b/src/registrar/models/user_group.py @@ -36,11 +36,6 @@ class UserGroup(Group): "model": "domain", "permissions": ["view_domain"], }, - { - "app_label": "registrar", - "model": "draftdomain", - "permissions": ["change_draftdomain"], - }, { "app_label": "registrar", "model": "user", @@ -51,11 +46,6 @@ class UserGroup(Group): "model": "domaininvitation", "permissions": ["add_domaininvitation", "view_domaininvitation"], }, - { - "app_label": "registrar", - "model": "website", - "permissions": ["change_website"], - }, { "app_label": "registrar", "model": "userdomainrole", From a66e873edfcb9f4d011c4cf8a4a6c5834872dd3a Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:24:58 -0600 Subject: [PATCH 03/43] Fixtures --- .../migrations/0081_create_groups_v10.py | 2 +- .../migrations/0082_create_groups_v11.py | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/registrar/migrations/0082_create_groups_v11.py diff --git a/src/registrar/migrations/0081_create_groups_v10.py b/src/registrar/migrations/0081_create_groups_v10.py index d65b6dbd2..5d8e3dbda 100644 --- a/src/registrar/migrations/0081_create_groups_v10.py +++ b/src/registrar/migrations/0081_create_groups_v10.py @@ -25,7 +25,7 @@ def create_groups(apps, schema_editor) -> Any: class Migration(migrations.Migration): dependencies = [ - ("registrar", "0080_create_groups_v09"), + ("registrar", "0080_create_groups_v10"), ] operations = [ diff --git a/src/registrar/migrations/0082_create_groups_v11.py b/src/registrar/migrations/0082_create_groups_v11.py new file mode 100644 index 000000000..73f54fb2f --- /dev/null +++ b/src/registrar/migrations/0082_create_groups_v11.py @@ -0,0 +1,37 @@ +# This migration creates the create_full_access_group and create_cisa_analyst_group groups +# It is dependent on 0079 (which populates federal agencies) +# If permissions on the groups need changing, edit CISA_ANALYST_GROUP_PERMISSIONS +# in the user_group model then: +# [NOT RECOMMENDED] +# step 1: docker-compose exec app ./manage.py migrate --fake registrar 0035_contenttypes_permissions +# step 2: docker-compose exec app ./manage.py migrate registrar 0036_create_groups +# step 3: fake run the latest migration in the migrations list +# [RECOMMENDED] +# Alternatively: +# step 1: duplicate the migration that loads data +# step 2: docker-compose exec app ./manage.py migrate + +from django.db import migrations +from registrar.models import UserGroup +from typing import Any + + +# For linting: RunPython expects a function reference, +# so let's give it one +def create_groups(apps, schema_editor) -> Any: + UserGroup.create_cisa_analyst_group(apps, schema_editor) + UserGroup.create_full_access_group(apps, schema_editor) + + +class Migration(migrations.Migration): + dependencies = [ + ("registrar", "0081_create_groups_v09"), + ] + + operations = [ + migrations.RunPython( + create_groups, + reverse_code=migrations.RunPython.noop, + atomic=True, + ), + ] From c1ed009a055a3e5a3cc048be5bc25564a0e8dd34 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 10:57:05 -0600 Subject: [PATCH 04/43] Add migrations and selective model view --- src/registrar/admin.py | 40 ++++++++++++++++++- .../migrations/0081_create_groups_v10.py | 2 +- .../migrations/0082_create_groups_v11.py | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index e0c98b7c2..7ae7c1e27 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -765,6 +765,41 @@ class WebsiteAdmin(ListHeaderAdmin): "website", ] search_help_text = "Search by website." + + def get_model_perms(self, request): + """ + Return empty perms dict thus hiding the model from admin index. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return {} + return super().get_model_perms(request) + + def has_change_permission(self, request, obj=None): + """ + Allow analysts to access the change form directly via URL. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return True + return super().has_change_permission(request, obj) + + def response_change(self, request, obj): + """ + Override to redirect admins back to the same page after saving. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + + # Don't redirect to the website page on save if the user is an analyst. + # Rather, just redirect back to the same change page. + if analyst_perm and not superuser_perm: + opts = obj._meta + pk_value = obj._get_pk_val() + return HttpResponseRedirect(reverse('admin:%s_%s_change' % (opts.app_label, opts.model_name), args=(pk_value,))) + return super().response_change(request, obj) class UserDomainRoleAdmin(ListHeaderAdmin): @@ -1439,7 +1474,10 @@ class DomainInformationInline(admin.StackedInline): def has_change_permission(self, request, obj=None): """Custom has_change_permission override so that we can specify that analysts can edit this through this inline, but not through the model normally""" - if request.user.has_perm("registrar.analyst_access_permission"): + + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: return True return super().has_change_permission(request, obj) diff --git a/src/registrar/migrations/0081_create_groups_v10.py b/src/registrar/migrations/0081_create_groups_v10.py index 5d8e3dbda..d65b6dbd2 100644 --- a/src/registrar/migrations/0081_create_groups_v10.py +++ b/src/registrar/migrations/0081_create_groups_v10.py @@ -25,7 +25,7 @@ def create_groups(apps, schema_editor) -> Any: class Migration(migrations.Migration): dependencies = [ - ("registrar", "0080_create_groups_v10"), + ("registrar", "0080_create_groups_v09"), ] operations = [ diff --git a/src/registrar/migrations/0082_create_groups_v11.py b/src/registrar/migrations/0082_create_groups_v11.py index 73f54fb2f..8bd0102cd 100644 --- a/src/registrar/migrations/0082_create_groups_v11.py +++ b/src/registrar/migrations/0082_create_groups_v11.py @@ -25,7 +25,7 @@ def create_groups(apps, schema_editor) -> Any: class Migration(migrations.Migration): dependencies = [ - ("registrar", "0081_create_groups_v09"), + ("registrar", "0081_create_groups_v10"), ] operations = [ From 269bb0cab3803cff73361a777d559dd39b203ab6 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:19:40 -0600 Subject: [PATCH 05/43] Unit tests --- src/registrar/admin.py | 6 ++- src/registrar/tests/test_admin.py | 78 +++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 7ae7c1e27..73b3e7e2a 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -765,7 +765,7 @@ class WebsiteAdmin(ListHeaderAdmin): "website", ] search_help_text = "Search by website." - + def get_model_perms(self, request): """ Return empty perms dict thus hiding the model from admin index. @@ -798,7 +798,9 @@ class WebsiteAdmin(ListHeaderAdmin): if analyst_perm and not superuser_perm: opts = obj._meta pk_value = obj._get_pk_val() - return HttpResponseRedirect(reverse('admin:%s_%s_change' % (opts.app_label, opts.model_name), args=(pk_value,))) + return HttpResponseRedirect( + reverse("admin:%s_%s_change" % (opts.app_label, opts.model_name), args=(pk_value,)) + ) return super().response_change(request, obj) diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 368f30721..81bf2736b 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -701,6 +701,84 @@ class TestDomainRequestAdmin(MockEppLib): ) self.mock_client = MockSESClient() + @less_console_noise_decorator + def test_analyst_can_see_alternative_domain(self): + """Tests if an analyst can still see the alternative domain field""" + + # Create fake creator + _creator = User.objects.create( + username="MrMeoward", + first_name="Meoward", + last_name="Jones", + ) + + # Create a fake domain request + _domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator) + + fake_website = Website.objects.create(website="thisisatest.gov") + _domain_request.alternative_domains.add(fake_website) + _domain_request.save() + + p = "userpass" + self.client.login(username="staffuser", password=p) + response = self.client.get( + "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk), + follow=True, + ) + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, _domain_request.requested_domain.name) + + # Test if the page has the alternative domain + self.assertContains(response, "thisisatest.gov") + + # Check that the page contains the url we expect + expected_href = reverse("admin:registrar_website_change", args=[fake_website.id]) + self.assertContains(response, expected_href) + + # Navigate to the website to ensure that we can still edit it + response = self.client.get( + "/admin/registrar/website/{}/change/".format(fake_website.pk), + follow=True, + ) + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, "thisisatest.gov") + + @less_console_noise_decorator + def test_analyst_can_see_current_websites(self): + """Tests if an analyst can still see current website field""" + + # Create fake creator + _creator = User.objects.create( + username="MrMeoward", + first_name="Meoward", + last_name="Jones", + ) + + # Create a fake domain request + _domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator) + + fake_website = Website.objects.create(website="thisisatest.gov") + _domain_request.current_websites.add(fake_website) + _domain_request.save() + + p = "userpass" + self.client.login(username="staffuser", password=p) + response = self.client.get( + "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk), + follow=True, + ) + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, _domain_request.requested_domain.name) + + # Test if the page has the current website + self.assertContains(response, "thisisatest.gov") + def test_domain_sortable(self): """Tests if the DomainRequest sorts by domain correctly""" with less_console_noise(): From 02257c4f7846499b51b58010e4e54265d4811ca5 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:33:49 -0600 Subject: [PATCH 06/43] fix unit test --- src/registrar/tests/test_migrations.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/registrar/tests/test_migrations.py b/src/registrar/tests/test_migrations.py index add65105a..6d8ff7151 100644 --- a/src/registrar/tests/test_migrations.py +++ b/src/registrar/tests/test_migrations.py @@ -37,7 +37,6 @@ class TestGroups(TestCase): "add_domaininvitation", "view_domaininvitation", "change_domainrequest", - "change_draftdomain", "add_federalagency", "change_federalagency", "delete_federalagency", @@ -48,7 +47,6 @@ class TestGroups(TestCase): "add_verifiedbystaff", "change_verifiedbystaff", "delete_verifiedbystaff", - "change_website", ] # Get the codenames of actual permissions associated with the group From 2f7ca1de6541496abc79b766ee58e0f7abaeef5d Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:40:06 -0600 Subject: [PATCH 07/43] Update src/registrar/admin.py --- src/registrar/admin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 73b3e7e2a..9514c569d 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -788,7 +788,7 @@ class WebsiteAdmin(ListHeaderAdmin): def response_change(self, request, obj): """ - Override to redirect admins back to the same page after saving. + Override to redirect users back to the same page after saving. """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") From 7303f8055f879f5fa546d78e6be0ce19f820c587 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 3 Apr 2024 13:19:04 -0600 Subject: [PATCH 08/43] DraftDomain --- src/registrar/admin.py | 37 ++++++++++++++++++++ src/registrar/tests/test_admin.py | 57 +++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 9514c569d..e4990ed60 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1909,6 +1909,43 @@ class DraftDomainAdmin(ListHeaderAdmin): # in autocomplete_fields for user ordering = ["name"] + def get_model_perms(self, request): + """ + Return empty perms dict thus hiding the model from admin index. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return {} + return super().get_model_perms(request) + + def has_change_permission(self, request, obj=None): + """ + Allow analysts to access the change form directly via URL. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + if analyst_perm and not superuser_perm: + return True + return super().has_change_permission(request, obj) + + def response_change(self, request, obj): + """ + Override to redirect users back to the same page after saving. + """ + superuser_perm = request.user.has_perm("registrar.full_access_permission") + analyst_perm = request.user.has_perm("registrar.analyst_access_permission") + + # Don't redirect to the website page on save if the user is an analyst. + # Rather, just redirect back to the same change page. + if analyst_perm and not superuser_perm: + opts = obj._meta + pk_value = obj._get_pk_val() + return HttpResponseRedirect( + reverse("admin:%s_%s_change" % (opts.app_label, opts.model_name), args=(pk_value,)) + ) + return super().response_change(request, obj) + class VerifiedByStaffAdmin(ListHeaderAdmin): list_display = ("email", "requestor", "truncated_notes", "created_at") diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 81bf2736b..74f4ba60e 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -19,7 +19,16 @@ from registrar.admin import ( UserDomainRoleAdmin, VerifiedByStaffAdmin, ) -from registrar.models import Domain, DomainRequest, DomainInformation, User, DomainInvitation, Contact, Website +from registrar.models import ( + Domain, + DomainRequest, + DomainInformation, + User, + DomainInvitation, + Contact, + Website, + DraftDomain, +) from registrar.models.user_domain_role import UserDomainRole from registrar.models.verified_by_staff import VerifiedByStaff from .common import ( @@ -702,8 +711,8 @@ class TestDomainRequestAdmin(MockEppLib): self.mock_client = MockSESClient() @less_console_noise_decorator - def test_analyst_can_see_alternative_domain(self): - """Tests if an analyst can still see the alternative domain field""" + def test_analyst_can_see_and_edit_alternative_domain(self): + """Tests if an analyst can still see and edit the alternative domain field""" # Create fake creator _creator = User.objects.create( @@ -747,6 +756,48 @@ class TestDomainRequestAdmin(MockEppLib): self.assertEqual(response.status_code, 200) self.assertContains(response, "thisisatest.gov") + @less_console_noise_decorator + def test_analyst_can_see_and_edit_requested_domain(self): + """Tests if an analyst can still see and edit the requested domain field""" + + # Create fake creator + _creator = User.objects.create( + username="MrMeoward", + first_name="Meoward", + last_name="Jones", + ) + + # Create a fake domain request + _domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW, user=_creator) + + p = "userpass" + self.client.login(username="staffuser", password=p) + response = self.client.get( + "/admin/registrar/domainrequest/{}/change/".format(_domain_request.pk), + follow=True, + ) + + # Filter to get the latest from the DB (rather than direct assignment) + requested_domain = DraftDomain.objects.filter(name=_domain_request.requested_domain.name).get() + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, requested_domain.name) + + # Check that the page contains the url we expect + expected_href = reverse("admin:registrar_draftdomain_change", args=[requested_domain.id]) + self.assertContains(response, expected_href) + + # Navigate to the website to ensure that we can still edit it + response = self.client.get( + "/admin/registrar/draftdomain/{}/change/".format(requested_domain.pk), + follow=True, + ) + + # Make sure the page loaded, and that we're on the right page + self.assertEqual(response.status_code, 200) + self.assertContains(response, "city.gov") + @less_console_noise_decorator def test_analyst_can_see_current_websites(self): """Tests if an analyst can still see current website field""" From 784fcbc26a8a146efa7aa7a0802d4ac1eb178b5e Mon Sep 17 00:00:00 2001 From: Rebecca Hsieh Date: Thu, 4 Apr 2024 15:35:15 -0700 Subject: [PATCH 09/43] Update expiration date code and unit test --- src/registrar/admin.py | 8 ++------ src/registrar/tests/test_admin.py | 12 +++--------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index e0c98b7c2..37535f1a2 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -1600,12 +1600,8 @@ class DomainAdmin(ListHeaderAdmin): # No expiration date was found. Return none. extra_context["extended_expiration_date"] = None return super().changeform_view(request, object_id, form_url, extra_context) - - if curr_exp_date < date.today(): - extra_context["extended_expiration_date"] = date.today() + relativedelta(years=years_to_extend_by) - else: - new_date = domain.registry_expiration_date + relativedelta(years=years_to_extend_by) - extra_context["extended_expiration_date"] = new_date + new_date = curr_exp_date + relativedelta(years=years_to_extend_by) + extra_context["extended_expiration_date"] = new_date else: extra_context["extended_expiration_date"] = None diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 368f30721..4cb66c534 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -74,11 +74,10 @@ class TestDomainAdmin(MockEppLib, WebTest): ) super().setUp() - @skip("TODO for another ticket. This test case is grabbing old db data.") @patch("registrar.admin.DomainAdmin._get_current_date", return_value=date(2024, 1, 1)) def test_extend_expiration_date_button(self, mock_date_today): """ - Tests if extend_expiration_date button extends correctly + Tests if extend_expiration_date modal gives an accurate date """ # Create a ready domain with a preset expiration date @@ -105,17 +104,11 @@ class TestDomainAdmin(MockEppLib, WebTest): # Follow the response response = response.follow() - # refresh_from_db() does not work for objects with protected=True. - # https://github.com/viewflow/django-fsm/issues/89 - new_domain = Domain.objects.get(id=domain.id) - - # Check that the current expiration date is what we expect - self.assertEqual(new_domain.expiration_date, date(2025, 5, 25)) - # Assert that everything on the page looks correct self.assertEqual(response.status_code, 200) self.assertContains(response, domain.name) self.assertContains(response, "Extend expiration date") + self.assertContains(response, "New expiration date: May 25, 2025") # Ensure the message we recieve is in line with what we expect expected_message = "Successfully extended the expiration date." @@ -127,6 +120,7 @@ class TestDomainAdmin(MockEppLib, WebTest): extra_tags="", fail_silently=False, ) + mock_add_message.assert_has_calls([expected_call], 1) @less_console_noise_decorator From 8bea5fd0c474933596f687c1df7469c2a794d187 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Fri, 5 Apr 2024 14:31:16 -0400 Subject: [PATCH 10/43] wip --- src/registrar/models/user.py | 10 ++++--- .../admin/includes/user_detail_list.html | 28 +++++++++++++------ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 5085c0b94..e2b3840a6 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -80,10 +80,12 @@ class User(AbstractUser): return active_requests_count def get_rejected_requests_count(self): - """Return count of rejected or ineligible requests""" - allowed_states = ['rejected', 'ineligible'] - rejected_requests_count = self.domain_requests_created.filter(status__in=allowed_states).count() - return rejected_requests_count + """Return count of rejected requests""" + return self.domain_requests_created.filter(status='rejected').count() + + def get_ineligible_requests_count(self): + """Return count of ineligible requests""" + return self.domain_requests_created.filter(status='ineligible').count() @classmethod def needs_identity_verification(cls, email, uuid): diff --git a/src/registrar/templates/django/admin/includes/user_detail_list.html b/src/registrar/templates/django/admin/includes/user_detail_list.html index 9daa8a0ee..522dfe3c4 100644 --- a/src/registrar/templates/django/admin/includes/user_detail_list.html +++ b/src/registrar/templates/django/admin/includes/user_detail_list.html @@ -1,12 +1,22 @@ {% load i18n static %} -
+{% with approved_domains_count=user.get_approved_domains_count %} + {% with active_requests_count=user.get_active_requests_count %} + {% with rejected_requests_count=user.get_rejected_requests_count %} + {% with ineligible_requests_count=user.get_ineligible_requests_count %} +
    - {# Approved domains #} - Approved domains: {{ user.get_approved_domains_count }}
    - {# Active requests #} - Active requests: {{ user.get_active_requests_count }}
    - {# Rejected or ineligible requests #} - Rejected or ineligible: {{ user.get_rejected_requests_count }}
    - -
+ {# Approved domains #} +
  • Approved domains: {{ approved_domains_count }}
  • + {# Active requests #} +
  • Active requests: {{ active_requests_count }}
  • + {# Rejected requests #} +
  • Rejected requests: {{ rejected_requests_count }}
  • + {# Ineligible requests #} +
  • Ineligible requests: {{ ineligible_requests_count }}
  • + + + {% endwith %} + {% endwith %} + {% endwith %} +{% endwith %} From 739e24ea3258fba7a985d6b509a7a4eda54d9dc8 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:36:27 -0700 Subject: [PATCH 11/43] Create design-onboarding --- .github/ISSUE_TEMPLATE/design-onboarding | 56 ++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/design-onboarding diff --git a/.github/ISSUE_TEMPLATE/design-onboarding b/.github/ISSUE_TEMPLATE/design-onboarding new file mode 100644 index 000000000..bf7047706 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/design-onboarding @@ -0,0 +1,56 @@ +--- +name: Design Onboarding +about: Onboarding steps for designers. +title: 'Designer Onboarding: GH_HANDLE' +labels: design, onboarding +assignees: katherineosos + +--- + +# Designer Onboarding + +- Onboardee: _GH handle of person being onboarded_ +- Onboarder: _GH handle of onboard buddy_ + +Read the .gov onboarding document +Get access to Slack. Familiar yourself with the channels. Post a hi message in the disc channel. +Get access to Google doc. Navigate through our documents. Find the design folders. +Get access to our project on Github. Look at our project directories. Find our product repos. Find our Product backlog. +Know who to ask for what -- know your team mates. +Make sure you are invited to all our team meetings. +Get an introduction on our application and the design process from Katherine, our Design lead. +Understand the designer tools (Miro, Fisma, etc). +Familiarize with our design guides (e.g., USWDS, 21st Century Integrated Digital Experience Act) +Make a request to the dev lead to get your sandbox created and get access to /admin (added to fixatures). +Look at get.gov. Test out manage.get.gov. +Create your POM and present in the Team coffee. +Schedule a meet-n-greet with Paul, our Product Manager to learn about our application. +Schedule a meet-n-greet with Vicky, our Scrum master to get overview of our Scrum process, our backlog, how our sprint works and how to use your Scrum master to your advantage. +Check up with your manager on your EOD clearance process. + +## Access + +### Steps for the onboardee +- [ ] Setup [commit signing in Github](#setting-up-commit-signing) and with git locally. +- [ ] [Create a cloud.gov account](https://cloud.gov/docs/getting-started/accounts/) +- [ ] Email github@cisa.dhs.gov (cc: Cameron) to add you to the [CISA Github organization](https://github.com/getgov) and [.gov Team](https://github.com/orgs/cisagov/teams/gov). +- [ ] Ensure you can login to your cloud.gov account via the CLI +```bash +cf login -a api.fr.cloud.gov --sso +``` +- [ ] Have an admin add you to cloud.gov org and set up your [sandbox developer space](#setting-up-developer-sandbox). Ensure you can deploy to your sandbox space. +- [ ] Have an admin add you to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/). + + **Note:** As mentioned in the [Login documentation](https://developers.login.gov/testing/), the sandbox Login account is different account from your regular, production Login account. If you have not created a Login account for the sandbox before, you will need to create a new account first. + +- [ ] Optional- add yourself as a codeowner if desired. See the [Developer readme](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md) for how to do this and what it does. + +### Steps for the onboarder +- [ ] Add the onboardee to cloud.gov org (cisa-dotgov) +- [ ] Setup a [developer specific space for the new developer](#setting-up-developer-sandbox) +- [ ] Add the onboardee to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) + + +## Documents to Review + +- [ ] [Team Onboarding](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?usp=sharing) From 52bfcfa64defc0456d097214dee7ad1829800777 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:50:51 -0700 Subject: [PATCH 12/43] Update design-onboarding organizing steps --- .github/ISSUE_TEMPLATE/design-onboarding | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/design-onboarding b/.github/ISSUE_TEMPLATE/design-onboarding index bf7047706..01f1f8e83 100644 --- a/.github/ISSUE_TEMPLATE/design-onboarding +++ b/.github/ISSUE_TEMPLATE/design-onboarding @@ -29,25 +29,18 @@ Schedule a meet-n-greet with Vicky, our Scrum master to get overview of our Scru Check up with your manager on your EOD clearance process. ## Access +Make sure you have access / been added to the following: +- [] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub +- [] [Slack](dhscisa.enterprise.slack.com), and added to the necessary channels +- [] Google Drive Project folder +- [] Figma +- [] Team meetings ### Steps for the onboardee -- [ ] Setup [commit signing in Github](#setting-up-commit-signing) and with git locally. -- [ ] [Create a cloud.gov account](https://cloud.gov/docs/getting-started/accounts/) -- [ ] Email github@cisa.dhs.gov (cc: Cameron) to add you to the [CISA Github organization](https://github.com/getgov) and [.gov Team](https://github.com/orgs/cisagov/teams/gov). -- [ ] Ensure you can login to your cloud.gov account via the CLI -```bash -cf login -a api.fr.cloud.gov --sso -``` -- [ ] Have an admin add you to cloud.gov org and set up your [sandbox developer space](#setting-up-developer-sandbox). Ensure you can deploy to your sandbox space. -- [ ] Have an admin add you to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/). - - **Note:** As mentioned in the [Login documentation](https://developers.login.gov/testing/), the sandbox Login account is different account from your regular, production Login account. If you have not created a Login account for the sandbox before, you will need to create a new account first. - -- [ ] Optional- add yourself as a codeowner if desired. See the [Developer readme](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md) for how to do this and what it does. +- [ ] ### Steps for the onboarder -- [ ] Add the onboardee to cloud.gov org (cisa-dotgov) -- [ ] Setup a [developer specific space for the new developer](#setting-up-developer-sandbox) +- [ ] Setup a [sandbox] for the onboardee (#setting-up-developer-sandbox) - [ ] Add the onboardee to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) From 6548d3870f432d0e588937e0d098363984b79b9b Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:52:09 -0700 Subject: [PATCH 13/43] Rename design-onboarding to design-onboarding.md Forgot to make it an md file --- .../ISSUE_TEMPLATE/{design-onboarding => design-onboarding.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/ISSUE_TEMPLATE/{design-onboarding => design-onboarding.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/design-onboarding b/.github/ISSUE_TEMPLATE/design-onboarding.md similarity index 100% rename from .github/ISSUE_TEMPLATE/design-onboarding rename to .github/ISSUE_TEMPLATE/design-onboarding.md From db65cdba9b794359d6e0073d2463d31612d14b4a Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:53:12 -0700 Subject: [PATCH 14/43] Update design-onboarding.md --- .github/ISSUE_TEMPLATE/design-onboarding.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/design-onboarding.md b/.github/ISSUE_TEMPLATE/design-onboarding.md index 01f1f8e83..3cca6e96c 100644 --- a/.github/ISSUE_TEMPLATE/design-onboarding.md +++ b/.github/ISSUE_TEMPLATE/design-onboarding.md @@ -30,11 +30,11 @@ Check up with your manager on your EOD clearance process. ## Access Make sure you have access / been added to the following: -- [] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub -- [] [Slack](dhscisa.enterprise.slack.com), and added to the necessary channels -- [] Google Drive Project folder -- [] Figma -- [] Team meetings +- [ ] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub +- [ ] [Slack](dhscisa.enterprise.slack.com), and added to the necessary channels +- [ ] Google Drive Project folder +- [ ] Figma +- [ ] Team meetings ### Steps for the onboardee - [ ] From 7e70bb848783a530fc2af8c4f1031c13247e5456 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Mon, 8 Apr 2024 11:00:49 -0400 Subject: [PATCH 15/43] conditional display of user detail counts --- .../admin/includes/user_detail_list.html | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/registrar/templates/django/admin/includes/user_detail_list.html b/src/registrar/templates/django/admin/includes/user_detail_list.html index 522dfe3c4..be233af8e 100644 --- a/src/registrar/templates/django/admin/includes/user_detail_list.html +++ b/src/registrar/templates/django/admin/includes/user_detail_list.html @@ -4,18 +4,26 @@ {% with active_requests_count=user.get_active_requests_count %} {% with rejected_requests_count=user.get_rejected_requests_count %} {% with ineligible_requests_count=user.get_ineligible_requests_count %} -
      - - {# Approved domains #} -
    • Approved domains: {{ approved_domains_count }}
    • - {# Active requests #} -
    • Active requests: {{ active_requests_count }}
    • - {# Rejected requests #} -
    • Rejected requests: {{ rejected_requests_count }}
    • - {# Ineligible requests #} -
    • Ineligible requests: {{ ineligible_requests_count }}
    • - -
    + {% if approved_domains_count|add:active_requests_count|add:rejected_requests_count|add:ineligible_requests_count > 0 %} +
      + {% if approved_domains_count > 0 %} + {# Approved domains #} +
    • Approved domains: {{ approved_domains_count }}
    • + {% endif %} + {% if active_requests_count > 0 %} + {# Active requests #} +
    • Active requests: {{ active_requests_count }}
    • + {% endif %} + {% if rejected_requests_count > 0 %} + {# Rejected requests #} +
    • Rejected requests: {{ rejected_requests_count }}
    • + {% endif %} + {% if ineligible_requests_count > 0 %} + {# Ineligible requests #} +
    • Ineligible requests: {{ ineligible_requests_count }}
    • + {% endif %} +
    + {% endif %} {% endwith %} {% endwith %} {% endwith %} From 2c1844c7381b8a04e690bf8bb00929c46c15ab6f Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Mon, 8 Apr 2024 11:04:48 -0400 Subject: [PATCH 16/43] formatting changes --- src/registrar/models/user.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index e2b3840a6..830cac944 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -69,24 +69,24 @@ class User(AbstractUser): def get_approved_domains_count(self): """Return count of approved domains""" - allowed_states = ['unknown', 'dns needed', 'ready', 'on hold'] + allowed_states = ["unknown", "dns needed", "ready", "on hold"] approved_domains_count = self.domains.filter(state__in=allowed_states).count() return approved_domains_count - + def get_active_requests_count(self): """Return count of active requests""" - allowed_states = ['submitted', 'in review', 'action needed'] + allowed_states = ["submitted", "in review", "action needed"] active_requests_count = self.domain_requests_created.filter(status__in=allowed_states).count() return active_requests_count - + def get_rejected_requests_count(self): """Return count of rejected requests""" - return self.domain_requests_created.filter(status='rejected').count() + return self.domain_requests_created.filter(status="rejected").count() def get_ineligible_requests_count(self): """Return count of ineligible requests""" - return self.domain_requests_created.filter(status='ineligible').count() - + return self.domain_requests_created.filter(status="ineligible").count() + @classmethod def needs_identity_verification(cls, email, uuid): """A method used by our oidc classes to test whether a user needs email/uuid verification From d145389d9561baded4c6bab93763725356e2830f Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Mon, 8 Apr 2024 11:51:00 -0400 Subject: [PATCH 17/43] test cases written --- src/registrar/tests/test_models.py | 77 ++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py index c7fe5f94c..3c8d8b05b 100644 --- a/src/registrar/tests/test_models.py +++ b/src/registrar/tests/test_models.py @@ -1004,6 +1004,8 @@ class TestUser(TestCase): Domain.objects.all().delete() DomainInvitation.objects.all().delete() DomainInformation.objects.all().delete() + DomainRequest.objects.all().delete() + DraftDomain.objects.all().delete() TransitionDomain.objects.all().delete() User.objects.all().delete() UserDomainRole.objects.all().delete() @@ -1060,6 +1062,81 @@ class TestUser(TestCase): # Domain Invitation, then save routine should be called exactly once save_mock.assert_called_once() + def test_approved_domains_count(self): + """Test that the correct approved domain count is returned for a user""" + # with no associated approved domains, expect this to return 0 + self.assertEquals(self.user.get_approved_domains_count(), 0) + # with one approved domain, expect this to return 1 + UserDomainRole.objects.get_or_create(user=self.user, domain=self.domain, role=UserDomainRole.Roles.MANAGER) + self.assertEquals(self.user.get_approved_domains_count(), 1) + # with one approved domain, expect this to return 1 (domain2 is deleted, so not considered approved) + domain2, _ = Domain.objects.get_or_create(name="igorville2.gov", state=Domain.State.DELETED) + UserDomainRole.objects.get_or_create(user=self.user, domain=domain2, role=UserDomainRole.Roles.MANAGER) + self.assertEquals(self.user.get_approved_domains_count(), 1) + # with two approved domains, expect this to return 2 + domain3, _ = Domain.objects.get_or_create(name="igorville3.gov", state=Domain.State.DNS_NEEDED) + UserDomainRole.objects.get_or_create(user=self.user, domain=domain3, role=UserDomainRole.Roles.MANAGER) + self.assertEquals(self.user.get_approved_domains_count(), 2) + # with three approved domains, expect this to return 3 + domain4, _ = Domain.objects.get_or_create(name="igorville4.gov", state=Domain.State.ON_HOLD) + UserDomainRole.objects.get_or_create(user=self.user, domain=domain4, role=UserDomainRole.Roles.MANAGER) + self.assertEquals(self.user.get_approved_domains_count(), 3) + # with four approved domains, expect this to return 4 + domain5, _ = Domain.objects.get_or_create(name="igorville5.gov", state=Domain.State.READY) + UserDomainRole.objects.get_or_create(user=self.user, domain=domain5, role=UserDomainRole.Roles.MANAGER) + self.assertEquals(self.user.get_approved_domains_count(), 4) + + def test_active_requests_count(self): + """Test that the correct active domain requests count is returned for a user""" + # with no associated active requests, expect this to return 0 + self.assertEquals(self.user.get_active_requests_count(), 0) + # with one active request, expect this to return 1 + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville1.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.SUBMITTED + ) + self.assertEquals(self.user.get_active_requests_count(), 1) + # with two active requests, expect this to return 2 + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville2.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.IN_REVIEW + ) + self.assertEquals(self.user.get_active_requests_count(), 2) + # with three active requests, expect this to return 3 + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville3.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.ACTION_NEEDED + ) + self.assertEquals(self.user.get_active_requests_count(), 3) + # with three active requests, expect this to return 3 (STARTED is not considered active) + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville4.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.STARTED + ) + self.assertEquals(self.user.get_active_requests_count(), 3) + + def test_rejected_requests_count(self): + """Test that the correct rejected domain requests count is returned for a user""" + # with no associated rejected requests, expect this to return 0 + self.assertEquals(self.user.get_rejected_requests_count(), 0) + # with one rejected request, expect this to return 1 + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville1.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.REJECTED + ) + self.assertEquals(self.user.get_rejected_requests_count(), 1) + + def test_ineligible_requests_count(self): + """Test that the correct ineligible domain requests count is returned for a user""" + # with no associated ineligible requests, expect this to return 0 + self.assertEquals(self.user.get_ineligible_requests_count(), 0) + # with one ineligible request, expect this to return 1 + draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville1.gov") + DomainRequest.objects.create( + creator=self.user, requested_domain=draft_domain, status=DomainRequest.DomainRequestStatus.INELIGIBLE + ) + self.assertEquals(self.user.get_ineligible_requests_count(), 1) + class TestContact(TestCase): def setUp(self): From 80ce98bf9cacb93561f4e8c93b35f5a1dc8e22de Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Mon, 8 Apr 2024 10:50:31 -0700 Subject: [PATCH 18/43] Update and rename design-onboarding.md to designer-onboarding.md --- .github/ISSUE_TEMPLATE/design-onboarding.md | 49 ----------- .github/ISSUE_TEMPLATE/designer-onboarding.md | 88 +++++++++++++++++++ 2 files changed, 88 insertions(+), 49 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/design-onboarding.md create mode 100644 .github/ISSUE_TEMPLATE/designer-onboarding.md diff --git a/.github/ISSUE_TEMPLATE/design-onboarding.md b/.github/ISSUE_TEMPLATE/design-onboarding.md deleted file mode 100644 index 3cca6e96c..000000000 --- a/.github/ISSUE_TEMPLATE/design-onboarding.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: Design Onboarding -about: Onboarding steps for designers. -title: 'Designer Onboarding: GH_HANDLE' -labels: design, onboarding -assignees: katherineosos - ---- - -# Designer Onboarding - -- Onboardee: _GH handle of person being onboarded_ -- Onboarder: _GH handle of onboard buddy_ - -Read the .gov onboarding document -Get access to Slack. Familiar yourself with the channels. Post a hi message in the disc channel. -Get access to Google doc. Navigate through our documents. Find the design folders. -Get access to our project on Github. Look at our project directories. Find our product repos. Find our Product backlog. -Know who to ask for what -- know your team mates. -Make sure you are invited to all our team meetings. -Get an introduction on our application and the design process from Katherine, our Design lead. -Understand the designer tools (Miro, Fisma, etc). -Familiarize with our design guides (e.g., USWDS, 21st Century Integrated Digital Experience Act) -Make a request to the dev lead to get your sandbox created and get access to /admin (added to fixatures). -Look at get.gov. Test out manage.get.gov. -Create your POM and present in the Team coffee. -Schedule a meet-n-greet with Paul, our Product Manager to learn about our application. -Schedule a meet-n-greet with Vicky, our Scrum master to get overview of our Scrum process, our backlog, how our sprint works and how to use your Scrum master to your advantage. -Check up with your manager on your EOD clearance process. - -## Access -Make sure you have access / been added to the following: -- [ ] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub -- [ ] [Slack](dhscisa.enterprise.slack.com), and added to the necessary channels -- [ ] Google Drive Project folder -- [ ] Figma -- [ ] Team meetings - -### Steps for the onboardee -- [ ] - -### Steps for the onboarder -- [ ] Setup a [sandbox] for the onboardee (#setting-up-developer-sandbox) -- [ ] Add the onboardee to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) - - -## Documents to Review - -- [ ] [Team Onboarding](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?usp=sharing) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md new file mode 100644 index 000000000..b04ea4314 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -0,0 +1,88 @@ +--- +name: Designer Onboarding +about: Onboarding steps for designers. +title: 'Designer Onboarding: GH_HANDLE' +labels: design, onboarding +assignees: katherineosos + +--- + +# Designer Onboarding + +- Onboardee: _GH handle of person being onboarded_ +- Onboarder: _GH handle of onboard buddy_ + +Welcome to the .gov team! We're excited to have you here. Please follow the steps below to get everything set up. An onboarding buddy will help grant you access to all the tools and platforms we use. If you haven't been assigned an onboarding buddy, let us know in the #dotgov-disco channel. + +Read the .gov onboarding document +Get access to Slack. Familiar yourself with the channels. Post a hi message in the disc channel. +Get access to Google doc. Navigate through our documents. Find the design folders. +Get access to our project on Github. Look at our project directories. Find our product repos. Find our Product backlog. +Know who to ask for what -- know your team mates. +Make sure you are invited to all our team meetings. +Get an introduction on our application and the design process from Katherine, our Design lead. +Understand the designer tools (Miro, Fisma, etc). +Familiarize with our design guides (e.g., USWDS, 21st Century Integrated Digital Experience Act) +Make a request to the dev lead to get your sandbox created and get access to /admin (added to fixatures). +Look at get.gov. Test out manage.get.gov. +Create your POM and present in the Team coffee. +Schedule a meet-n-greet with Paul, our Product Manager to learn about our application. +Schedule a meet-n-greet with Vicky, our Scrum master to get overview of our Scrum process, our backlog, how our sprint works and how to use your Scrum master to your advantage. +Check up with your manager on your EOD clearance process. + +## Onboardee + +### Steps for the onboardee +- [ ] Read the [.gov onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?usp=sharing) thoroughly. +- [ ] Accept Slack invitation and fill out your profile. + - [ ] For our Slack profile names, we usually follow the naming convention of `Firstname Lastname (Org, State, pronouns)`. + Example: Katherine Osos (Truss, MN, she/her) + - [ ] Make sure you have been added to the necessary [channels](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.li3lqcygw8ax) and familiarize yourself with them. +- [ ] Get access to our [Project Folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) on Google Drive. + - [ ] Explore the folders and docs. Designers interface with the Product Design, Content, and Research folders most often. +- [ ] Make sure you have been invited to our [team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) on Google Meet. +- [ ] Get access to our design tools: [Figma](https://www.figma.com/files/1287135731043703282/team/1299882813146449644), Miro +- [ ] Follow the steps in [Preparing for your sandbox](####preparing-for-your-sandbox) section below. + +#### Preparing for your sandbox +- [ ] Create two identity sandbox accounts, this is login.gov’s test environment + - How to make it: + - [ ] Navigate to [identity sandbox](https://idp.int.identitysandbox.gov/) + - [ ] Click create an account + - [ ] Fill in the information with fake data, though you may choose to use your real name. For the social security field, input a SSN that starts with 666 or 900. Instead of uploading a picture of your ID, you may upload any picture (include a cat meme). + - [ ] See login.gov’s [developer section](https://developers.login.gov/testing/#testing-identity-proofing) for testing with identity sandbox if you encounter issues. + - One account should be your preferred work email for the username, the second should be the SAME email address followed by a plus one + - Ex: bob@dhs.gov for the first login account and bob+1@dhs.gov + - One account will represent a normal user while the other will be your way of simulating a “analyst” +- [ ] Sandbox: Have an engineer create a sandbox for you (message in #dotgov-dev Slack channel). This will be used to make content updates in the UI. + - [ ] You will receive a link for Cloud.gov to be added to an organization. Be sure to verify via that link or you may not be able to access any sandbox. + - [ ] Also ask that they add mock data to that sandbox. This will be helpful for testing various scenarios in the UI. + - Note: at any point you can add mock data to your sandbox and reset all test data in you sandbox by running the [reset action on github](https://github.com/cisagov/getgov/actions/workflows/reset-db.yaml) + - Go to the provided link. Click the Run Workflow dropdown + - Select your sandbox environment (your initials). + - Then click the green “Run workflow” button + - [ ] Your sandbox makes the app available online, and everyone should be able to access your sandbox once it is made. See the [sandbox section of the onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.cdlfxamcvus5), your sandbox url will be in this format: https://getgov-.app.cloud.gov/ where ENV refers to your initials. + - [ ] Make sure to check that you can log into your sandbox with the identity sandbox login credentials you made. +Request access to /admin (also known as “add to fixtures”) +Follow the steps in the developer readme for adding yourself to admin +When you get to the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team +OPTIONAL: Request an “analyst” account by using your second identity sandbox credential +This account will allow you to see what an analyst sees when they log in to the application +Use whichever identity sandbox account you did not use when requesting /admin access and follow the developer readme for creating an analyst account +Tip: You can add a ‘+1’ to the end of your gmail account to create a “new” email address that can be used for making a new Login.gov account (example: “orginalemailaddress+1@gmail.com”). Everything will still go to the same email without needing to make a new one. +Just like with /admin, in the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team + + +### Access +By following the steps, you should have access / been added to the following: +- [ ] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub +- [ ] [Slack](dhscisa.enterprise.slack.com), and have been added to the necessary channels +- [ ] [Google Drive Project folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) +- [ ] [.gov team on Figma](https://www.figma.com/files/1287135731043703282/team/1299882813146449644) (as an editor if you have a license) +- [ ] [Team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) + +## Onboarder + +### Steps for the onboarder +- [ ] Setup a [sandbox] for the onboardee (#setting-up-developer-sandbox) +- [ ] Add the onboardee to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) From a257e843af611e17108abc88f33bdea14901d15f Mon Sep 17 00:00:00 2001 From: Rachid Mrad Date: Mon, 8 Apr 2024 15:27:32 -0400 Subject: [PATCH 19/43] styling --- src/registrar/assets/sass/_theme/_admin.scss | 11 +++++++++++ .../django/admin/includes/user_detail_list.html | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/registrar/assets/sass/_theme/_admin.scss b/src/registrar/assets/sass/_theme/_admin.scss index 658ae5ca8..407163fff 100644 --- a/src/registrar/assets/sass/_theme/_admin.scss +++ b/src/registrar/assets/sass/_theme/_admin.scss @@ -435,3 +435,14 @@ address.dja-address-contact-list { color: var(--link-fg); } } + +.dja-status-list { + border-top: solid 1px var(--border-color); + margin-left: 0 !important; + padding-left: 0 !important; + padding-top: 15px; + li { + line-height: 1.15; + font-family: "Source Sans Pro Web", "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif !important; + } +} diff --git a/src/registrar/templates/django/admin/includes/user_detail_list.html b/src/registrar/templates/django/admin/includes/user_detail_list.html index be233af8e..829af933a 100644 --- a/src/registrar/templates/django/admin/includes/user_detail_list.html +++ b/src/registrar/templates/django/admin/includes/user_detail_list.html @@ -5,7 +5,7 @@ {% with rejected_requests_count=user.get_rejected_requests_count %} {% with ineligible_requests_count=user.get_ineligible_requests_count %} {% if approved_domains_count|add:active_requests_count|add:rejected_requests_count|add:ineligible_requests_count > 0 %} -
      +
        {% if approved_domains_count > 0 %} {# Approved domains #}
      • Approved domains: {{ approved_domains_count }}
      • From ca4490e3da8e972c7a9b272c2d500c2942bcba02 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Mon, 8 Apr 2024 20:28:19 -0700 Subject: [PATCH 20/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index b04ea4314..6f2374311 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -61,16 +61,15 @@ Check up with your manager on your EOD clearance process. - Go to the provided link. Click the Run Workflow dropdown - Select your sandbox environment (your initials). - Then click the green “Run workflow” button - - [ ] Your sandbox makes the app available online, and everyone should be able to access your sandbox once it is made. See the [sandbox section of the onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.cdlfxamcvus5), your sandbox url will be in this format: https://getgov-.app.cloud.gov/ where ENV refers to your initials. - - [ ] Make sure to check that you can log into your sandbox with the identity sandbox login credentials you made. -Request access to /admin (also known as “add to fixtures”) -Follow the steps in the developer readme for adding yourself to admin -When you get to the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team -OPTIONAL: Request an “analyst” account by using your second identity sandbox credential -This account will allow you to see what an analyst sees when they log in to the application -Use whichever identity sandbox account you did not use when requesting /admin access and follow the developer readme for creating an analyst account -Tip: You can add a ‘+1’ to the end of your gmail account to create a “new” email address that can be used for making a new Login.gov account (example: “orginalemailaddress+1@gmail.com”). Everything will still go to the same email without needing to make a new one. -Just like with /admin, in the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team + - [ ] Your sandbox makes the app available online, and everyone should be able to access your sandbox once it is made. See the [sandbox section of the onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.cdlfxamcvus5), your sandbox url will be in this format: `https://getgov-.app.cloud.gov/` where ENV refers to your initials. + - [ ] Make sure to check that you can log into your sandbox with the identity sandbox login credentials you made. +- [ ] Request access to /admin (also known as “add to fixtures”) + - [ ] Follow the steps in the [developer readme for adding yourself to admin](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md#adding-user-to-admin) + - When you get to the last step about editing the code, you can instead share the ID you found in the previous step with someone on the development team. +- [ ] OPTIONAL: Request an “analyst” account by using your second identity sandbox credential + - This account will allow you to see what an analyst sees when they log in to the application + - Use whichever identity sandbox account you did not use when requesting /admin access and follow the [developer readme for creating an analyst account](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md#adding-an-analyst-to-admin) + - Just like with /admin, in the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team ### Access From f6d95723cea38dea2605ceef6dd883930449ee26 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Mon, 8 Apr 2024 21:48:28 -0700 Subject: [PATCH 21/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 6f2374311..8f36462dc 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -14,35 +14,28 @@ assignees: katherineosos Welcome to the .gov team! We're excited to have you here. Please follow the steps below to get everything set up. An onboarding buddy will help grant you access to all the tools and platforms we use. If you haven't been assigned an onboarding buddy, let us know in the #dotgov-disco channel. -Read the .gov onboarding document -Get access to Slack. Familiar yourself with the channels. Post a hi message in the disc channel. -Get access to Google doc. Navigate through our documents. Find the design folders. -Get access to our project on Github. Look at our project directories. Find our product repos. Find our Product backlog. -Know who to ask for what -- know your team mates. -Make sure you are invited to all our team meetings. -Get an introduction on our application and the design process from Katherine, our Design lead. -Understand the designer tools (Miro, Fisma, etc). -Familiarize with our design guides (e.g., USWDS, 21st Century Integrated Digital Experience Act) -Make a request to the dev lead to get your sandbox created and get access to /admin (added to fixatures). -Look at get.gov. Test out manage.get.gov. -Create your POM and present in the Team coffee. -Schedule a meet-n-greet with Paul, our Product Manager to learn about our application. -Schedule a meet-n-greet with Vicky, our Scrum master to get overview of our Scrum process, our backlog, how our sprint works and how to use your Scrum master to your advantage. -Check up with your manager on your EOD clearance process. - ## Onboardee ### Steps for the onboardee - [ ] Read the [.gov onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?usp=sharing) thoroughly. -- [ ] Accept Slack invitation and fill out your profile. +- [ ] Accept an invitation to our Slack workspace and fill out your profile. - [ ] For our Slack profile names, we usually follow the naming convention of `Firstname Lastname (Org, State, pronouns)`. Example: Katherine Osos (Truss, MN, she/her) - [ ] Make sure you have been added to the necessary [channels](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.li3lqcygw8ax) and familiarize yourself with them. +- [ ] Create a [Google workspace enterprise account](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.xowzg9w0qlis) for CISA. - [ ] Get access to our [Project Folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) on Google Drive. - [ ] Explore the folders and docs. Designers interface with the Product Design, Content, and Research folders most often. - [ ] Make sure you have been invited to our [team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) on Google Meet. -- [ ] Get access to our design tools: [Figma](https://www.figma.com/files/1287135731043703282/team/1299882813146449644), Miro -- [ ] Follow the steps in [Preparing for your sandbox](####preparing-for-your-sandbox) section below. +- [ ] Review our [design tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.aprurp3z4gmv). +- [ ] Accept invitation to our [Figma workspace](https://www.figma.com/files/1287135731043703282/team/1299882813146449644). +- [ ] Follow the steps in [Preparing for your sandbox](#preparing-for-your-sandbox) section below. +- [ ] Schedule coffee chats with Design Lead, other designers, scrum master, and product manager ([team directory](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.1vq6r8e52e9f)). +- [ ] Look over [recommended reading](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.7ox9ee7v5q5n) and [relevant links](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.d9pac1gc751t). +- [ ] Fill out your own Personal Operating Manual (POM) on the [team norming board](https://miro.com/app/board/uXjVMxMu1SA=/). Present it on the next team coffee meeting. +- [ ] FOR FEDERAL EMPLOYEES: Check in with your manager on the CISA onboarding process and getting your PIV card. +- [ ] FOR CONTRACTORS: Check with your manager on your EOD clearance process. +- [ ] OPTIONAL: Request access to our [analytics tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.9q334hs4lbks). + #### Preparing for your sandbox - [ ] Create two identity sandbox accounts, this is login.gov’s test environment @@ -80,8 +73,13 @@ By following the steps, you should have access / been added to the following: - [ ] [.gov team on Figma](https://www.figma.com/files/1287135731043703282/team/1299882813146449644) (as an editor if you have a license) - [ ] [Team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) + ## Onboarder ### Steps for the onboarder -- [ ] Setup a [sandbox] for the onboardee (#setting-up-developer-sandbox) -- [ ] Add the onboardee to our login.gov sandbox team (`.gov Registrar`) via the [dashboard](https://dashboard.int.identitysandbox.gov/) +- [ ] Make sure onboardee is given an invitation to our Slack workspace +- [ ] Add onboardee to dotgov Slack channels +- [ ] Once onboardee has a Google workspace enterprise account, add onboardee to Project Folder as an editor +- [ ] Once onboardee has been granted a Figma license, add them as an editor to the Figma team workspace +- [ ] Add onboardee to our team meetings +- [ ] If applicable, invite onboardee to Google Analytics, Google Search Console, and Search.gov console From e6106c7946c1a5f93cfd9c6d416104d40c9da272 Mon Sep 17 00:00:00 2001 From: Alysia Broddrick Date: Tue, 9 Apr 2024 07:37:42 -0700 Subject: [PATCH 22/43] wait time changed from 20 to 30 business days --- src/registrar/templates/includes/domain_request.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/registrar/templates/includes/domain_request.html b/src/registrar/templates/includes/domain_request.html index a15a8673c..0e377f35c 100644 --- a/src/registrar/templates/includes/domain_request.html +++ b/src/registrar/templates/includes/domain_request.html @@ -3,7 +3,7 @@

        Next steps in this process

        -

        We received your .gov domain request. Our next step is to review your request. This usually takes 20 business days. We’ll email you if we have questions and when we complete our review. Contact us with any questions.

        +

        We received your .gov domain request. Our next step is to review your request. This usually takes 30 business days. We’ll email you if we have questions and when we complete our review. Contact us with any questions.

        Need to make changes? From ccf49040fd4d61ec33d1a945f727c513d476a463 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:56:27 -0700 Subject: [PATCH 23/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 42 ++++--------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 8f36462dc..0b810fd5c 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -14,6 +14,7 @@ assignees: katherineosos Welcome to the .gov team! We're excited to have you here. Please follow the steps below to get everything set up. An onboarding buddy will help grant you access to all the tools and platforms we use. If you haven't been assigned an onboarding buddy, let us know in the #dotgov-disco channel. + ## Onboardee ### Steps for the onboardee @@ -22,53 +23,25 @@ Welcome to the .gov team! We're excited to have you here. Please follow the step - [ ] For our Slack profile names, we usually follow the naming convention of `Firstname Lastname (Org, State, pronouns)`. Example: Katherine Osos (Truss, MN, she/her) - [ ] Make sure you have been added to the necessary [channels](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.li3lqcygw8ax) and familiarize yourself with them. -- [ ] Create a [Google workspace enterprise account](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.xowzg9w0qlis) for CISA. +- [ ] FOR FEDERAL EMPLOYEES: Create a [Google workspace enterprise account](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.xowzg9w0qlis) for CISA. - [ ] Get access to our [Project Folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) on Google Drive. - [ ] Explore the folders and docs. Designers interface with the Product Design, Content, and Research folders most often. - [ ] Make sure you have been invited to our [team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) on Google Meet. - [ ] Review our [design tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.aprurp3z4gmv). - [ ] Accept invitation to our [Figma workspace](https://www.figma.com/files/1287135731043703282/team/1299882813146449644). -- [ ] Follow the steps in [Preparing for your sandbox](#preparing-for-your-sandbox) section below. +- [ ] Follow the steps in [preparing for your sandbox](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.au66hq5e0l8s) section on the onboarding doc. - [ ] Schedule coffee chats with Design Lead, other designers, scrum master, and product manager ([team directory](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.1vq6r8e52e9f)). - [ ] Look over [recommended reading](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.7ox9ee7v5q5n) and [relevant links](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.d9pac1gc751t). -- [ ] Fill out your own Personal Operating Manual (POM) on the [team norming board](https://miro.com/app/board/uXjVMxMu1SA=/). Present it on the next team coffee meeting. +- [ ] Fill out your own Personal Operating Manual (POM) on the [team norming board](https://miro.com/app/board/uXjVMxMu1SA=/). OPTIONAL: Present it on the next team coffee meeting. - [ ] FOR FEDERAL EMPLOYEES: Check in with your manager on the CISA onboarding process and getting your PIV card. - [ ] FOR CONTRACTORS: Check with your manager on your EOD clearance process. - [ ] OPTIONAL: Request access to our [analytics tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.9q334hs4lbks). -#### Preparing for your sandbox -- [ ] Create two identity sandbox accounts, this is login.gov’s test environment - - How to make it: - - [ ] Navigate to [identity sandbox](https://idp.int.identitysandbox.gov/) - - [ ] Click create an account - - [ ] Fill in the information with fake data, though you may choose to use your real name. For the social security field, input a SSN that starts with 666 or 900. Instead of uploading a picture of your ID, you may upload any picture (include a cat meme). - - [ ] See login.gov’s [developer section](https://developers.login.gov/testing/#testing-identity-proofing) for testing with identity sandbox if you encounter issues. - - One account should be your preferred work email for the username, the second should be the SAME email address followed by a plus one - - Ex: bob@dhs.gov for the first login account and bob+1@dhs.gov - - One account will represent a normal user while the other will be your way of simulating a “analyst” -- [ ] Sandbox: Have an engineer create a sandbox for you (message in #dotgov-dev Slack channel). This will be used to make content updates in the UI. - - [ ] You will receive a link for Cloud.gov to be added to an organization. Be sure to verify via that link or you may not be able to access any sandbox. - - [ ] Also ask that they add mock data to that sandbox. This will be helpful for testing various scenarios in the UI. - - Note: at any point you can add mock data to your sandbox and reset all test data in you sandbox by running the [reset action on github](https://github.com/cisagov/getgov/actions/workflows/reset-db.yaml) - - Go to the provided link. Click the Run Workflow dropdown - - Select your sandbox environment (your initials). - - Then click the green “Run workflow” button - - [ ] Your sandbox makes the app available online, and everyone should be able to access your sandbox once it is made. See the [sandbox section of the onboarding doc](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.cdlfxamcvus5), your sandbox url will be in this format: `https://getgov-.app.cloud.gov/` where ENV refers to your initials. - - [ ] Make sure to check that you can log into your sandbox with the identity sandbox login credentials you made. -- [ ] Request access to /admin (also known as “add to fixtures”) - - [ ] Follow the steps in the [developer readme for adding yourself to admin](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md#adding-user-to-admin) - - When you get to the last step about editing the code, you can instead share the ID you found in the previous step with someone on the development team. -- [ ] OPTIONAL: Request an “analyst” account by using your second identity sandbox credential - - This account will allow you to see what an analyst sees when they log in to the application - - Use whichever identity sandbox account you did not use when requesting /admin access and follow the [developer readme for creating an analyst account](https://github.com/cisagov/getgov/blob/main/docs/developer/README.md#adding-an-analyst-to-admin) - - Just like with /admin, in the last step about editing the code you can instead share the ID you found in the previous step with someone on the development team - - ### Access By following the steps, you should have access / been added to the following: - [ ] The [.gov team](https://github.com/orgs/cisagov/teams/gov) under cisagov on GitHub -- [ ] [Slack](dhscisa.enterprise.slack.com), and have been added to the necessary channels +- [ ] [Slack](https://dhscisa.enterprise.slack.com), and have been added to the necessary channels - [ ] [Google Drive Project folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) - [ ] [.gov team on Figma](https://www.figma.com/files/1287135731043703282/team/1299882813146449644) (as an editor if you have a license) - [ ] [Team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) @@ -79,7 +52,8 @@ By following the steps, you should have access / been added to the following: ### Steps for the onboarder - [ ] Make sure onboardee is given an invitation to our Slack workspace - [ ] Add onboardee to dotgov Slack channels -- [ ] Once onboardee has a Google workspace enterprise account, add onboardee to Project Folder as an editor -- [ ] Once onboardee has been granted a Figma license, add them as an editor to the Figma team workspace +- [ ] Add onboardee is added to Project Folder as a "Contributor" (or if you do not have permissions, confirm with Cameron) + - If onboardee if a federal employee, add them as a "Content Manager" instead +- [ ] Once onboardee has been granted a Figma license, add them as an editor to the Figma team workspace, Otherwise, you can add them as a viewer in the meantime. - [ ] Add onboardee to our team meetings - [ ] If applicable, invite onboardee to Google Analytics, Google Search Console, and Search.gov console From 3d21e4912ce66ead90b652e914c18f68713b2349 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Wed, 10 Apr 2024 09:22:25 -0600 Subject: [PATCH 24/43] Fix migrations after merge --- .../{0082_create_groups_v11.py => 0084_create_groups_v11.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/registrar/migrations/{0082_create_groups_v11.py => 0084_create_groups_v11.py} (94%) diff --git a/src/registrar/migrations/0082_create_groups_v11.py b/src/registrar/migrations/0084_create_groups_v11.py similarity index 94% rename from src/registrar/migrations/0082_create_groups_v11.py rename to src/registrar/migrations/0084_create_groups_v11.py index 8bd0102cd..efb587520 100644 --- a/src/registrar/migrations/0082_create_groups_v11.py +++ b/src/registrar/migrations/0084_create_groups_v11.py @@ -25,7 +25,7 @@ def create_groups(apps, schema_editor) -> Any: class Migration(migrations.Migration): dependencies = [ - ("registrar", "0081_create_groups_v10"), + ("registrar", "0083_alter_contact_email_alter_publiccontact_email"), ] operations = [ From 14cfaa7f4c80bddd4def274ce9d8e423165af64d Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 10 Apr 2024 13:19:19 -0400 Subject: [PATCH 25/43] changed strings to constants --- src/registrar/models/user.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 830cac944..1ca2412ca 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -9,6 +9,7 @@ from .domain_invitation import DomainInvitation from .transition_domain import TransitionDomain from .verified_by_staff import VerifiedByStaff from .domain import Domain +from .domain_request import DomainRequest from phonenumber_field.modelfields import PhoneNumberField # type: ignore @@ -69,23 +70,27 @@ class User(AbstractUser): def get_approved_domains_count(self): """Return count of approved domains""" - allowed_states = ["unknown", "dns needed", "ready", "on hold"] + allowed_states = [Domain.State.UNKNOWN, Domain.State.DNS_NEEDED, Domain.State.READY, Domain.State.ON_HOLD] approved_domains_count = self.domains.filter(state__in=allowed_states).count() return approved_domains_count def get_active_requests_count(self): """Return count of active requests""" - allowed_states = ["submitted", "in review", "action needed"] + allowed_states = [ + DomainRequest.DomainRequestStatus.SUBMITTED, + DomainRequest.DomainRequestStatus.IN_REVIEW, + DomainRequest.DomainRequestStatus.ACTION_NEEDED, + ] active_requests_count = self.domain_requests_created.filter(status__in=allowed_states).count() return active_requests_count def get_rejected_requests_count(self): """Return count of rejected requests""" - return self.domain_requests_created.filter(status="rejected").count() + return self.domain_requests_created.filter(status=DomainRequest.DomainRequestStatus.REJECTED).count() def get_ineligible_requests_count(self): """Return count of ineligible requests""" - return self.domain_requests_created.filter(status="ineligible").count() + return self.domain_requests_created.filter(status=DomainRequest.DomainRequestStatus.INELIGIBLE).count() @classmethod def needs_identity_verification(cls, email, uuid): From 0db398321b08f8f2625dd9823d3976d4949b31a4 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 10 Apr 2024 13:51:35 -0400 Subject: [PATCH 26/43] added unit test --- src/registrar/tests/test_admin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py index 41700c0ae..73913abc2 100644 --- a/src/registrar/tests/test_admin.py +++ b/src/registrar/tests/test_admin.py @@ -1553,6 +1553,10 @@ class TestDomainRequestAdmin(MockEppLib): # Test for the copy link self.assertContains(response, "usa-button__clipboard", count=4) + # Test that Creator counts display properly + self.assertNotContains(response, "Approved domains") + self.assertContains(response, "Active requests") + def test_save_model_sets_restricted_status_on_user(self): with less_console_noise(): # make sure there is no user with this email From 6cdba8e995afc8fc6be26329b907647e47d43429 Mon Sep 17 00:00:00 2001 From: Alysia Broddrick Date: Wed, 10 Apr 2024 12:18:44 -0700 Subject: [PATCH 27/43] updated language regarding fixtures --- docs/developer/README.md | 25 ++++++++++++++++++------- docs/django-admin/roles.md | 4 ++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/docs/developer/README.md b/docs/developer/README.md index f894955e5..e36cfffab 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -73,14 +73,24 @@ cp ./.env-example .env Get the secrets from Cloud.gov by running `cf env getgov-YOURSANDBOX`. More information is available in [rotate_application_secrets.md](../operations/runbooks/rotate_application_secrets.md). -## Adding user to /admin +## Getting access to /admin on all development sandboxes (also referred to as "adding to fixtures") -The endpoint /admin can be used to view and manage site content, including but not limited to user information and the list of current applications in the database. To be able to view and use /admin locally: +The endpoint /admin can be used to view and manage site content, including but not limited to user information and the list of current applications in the database. However, access to this is limited to analysts and full-access users with regular domain requestors and domain managers not being able to see this page. + +While on production (the sandbox referred to as `stable`), an existing analyst or full-access user typically grants access /admin as part of onboarding ([see these instructions](../django-admin/roles.md)), doing this for all development sandboxes is very time consuming. Instead, to get access to /admin on all development sandboxes and when developing code locally, refer to the following sections depending on what level of user access you desire. + +Note: this process where a team member gets analyst/superuser permission on all non-production sandboxes is often called "Adding to fixtures". + +### Adding full-access user to /admin + + To get access to /admin on every non-production sandbox and to use /admin in local development, do the following: 1. Login via login.gov 2. Go to the home page and make sure you can see the part where you can submit a domain request -3. Go to /admin and it will tell you that UUID is not authorized, copy that UUID for use in 4 -4. in src/registrar/fixtures_users.py add to the `ADMINS` list in that file by adding your UUID as your username along with your first and last name. See below: +3. Go to /admin and it will tell you that your UUID is not authorized (it shows a very long string, this is your UUID). Copy that UUID for use in 4. +4. (Designers)- message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Please see the "Adding an Analyst to /admin" section below to complete similiar steps if you also desire an `analyst` user account. Engineers will handle the remaining steps for designers, stop here. + +(Engineers) In src/registrar/fixtures_users.py add to the `ADMINS` list in that file by adding your UUID as your username along with your first and last name. See below: ``` ADMINS = [ @@ -93,10 +103,10 @@ The endpoint /admin can be used to view and manage site content, including but n ] ``` -5. In the browser, navigate to /admin. To verify that all is working correctly, under "domain requests" you should see fake domains with various fake statuses. -6. Add an optional email key/value pair +5. (Engineer only) In the browser, navigate to /admin. To verify that all is working correctly, under "domain requests" you should see fake domains with various fake statuses. +6. (Engineer only) Add an optional email key/value pair -### Adding an Analyst to /admin +### Adding an analyst-level user to /admin Analysts are a variant of the admin role with limited permissions. The process for adding an Analyst is much the same as adding an admin: 1. Login via login.gov (if you already exist as an admin, you will need to create a separate login.gov account for this: i.e. first.last+1@email.com) @@ -119,6 +129,7 @@ Analysts are a variant of the admin role with limited permissions. The process f 6. Add an optional email key/value pair Do note that if you wish to have both an analyst and admin account, append `-Analyst` to your first and last name, or use a completely different first/last name to avoid confusion. Example: `Bob-Analyst` + ## Adding to CODEOWNERS (optional) The CODEOWNERS file sets the tagged individuals as default reviewers on any Pull Request that changes files that they are marked as owners of. diff --git a/docs/django-admin/roles.md b/docs/django-admin/roles.md index c527bbfa5..4e74a857f 100644 --- a/docs/django-admin/roles.md +++ b/docs/django-admin/roles.md @@ -9,7 +9,7 @@ our `user_group` model and run in a migration. For more details, refer to the [user group model](../../src/registrar/models/user_group.py). -## Adding a user as analyst or granting full access via django-admin +## Adding a user as analyst or granting full access via django-admin (/admin) If a new team member has joined, then they will need to be granted analyst (`cisa_analysts_group`) or full access (`full_access_group`) permissions in order to view the admin pages. These admin pages are the ones found at manage.get.gov/admin. To do this, do the following: @@ -21,7 +21,7 @@ To do this, do the following: 5. (Optional) If the user needs access to django admin (such as an analyst), then you will also need to make sure "Staff Status" is checked. This can be found in the same `User Permissions` section right below the checkbox for `Active`. 6. Click `Save` to apply all changes. -## Removing a user group permission via django-admin +## Removing a user group permission via django-admin (/admin) If an employee was given the wrong permissions or has had a change in roles that subsequently requires a permission change, then their permissions should be updated in django-admin. Much like in the previous section you can accomplish this by doing the following: From f7ba4a0404a235e9e737905358307037137cfdd3 Mon Sep 17 00:00:00 2001 From: Alysia Broddrick Date: Wed, 10 Apr 2024 12:35:26 -0700 Subject: [PATCH 28/43] duplicated content from above section --- docs/developer/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/developer/README.md b/docs/developer/README.md index e36cfffab..29bc0a530 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -112,7 +112,9 @@ Analysts are a variant of the admin role with limited permissions. The process f 1. Login via login.gov (if you already exist as an admin, you will need to create a separate login.gov account for this: i.e. first.last+1@email.com) 2. Go to the home page and make sure you can see the part where you can submit a domain request 3. Go to /admin and it will tell you that UUID is not authorized, copy that UUID for use in 4 (this will be a different UUID than the one obtained from creating an admin) -4. in src/registrar/fixtures_users.py add to the `STAFF` list in that file by adding your UUID as your username along with your first and last name. See below: +4. (Designers)- message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Please see the "Adding an Analyst to /admin" section below to complete similiar steps if you also desire an `analyst` user account. Engineers will handle the remaining steps for designers, stop here. + +(Engineers) In src/registrar/fixtures_users.py add to the `STAFF` list in that file by adding your UUID as your username along with your first and last name. See below: ``` STAFF = [ @@ -125,8 +127,8 @@ Analysts are a variant of the admin role with limited permissions. The process f ] ``` -5. In the browser, navigate to /admin. To verify that all is working correctly, verify that you can only see a sub-section of the modules and some are set to view-only. -6. Add an optional email key/value pair +5. (Engineer only) In the browser, navigate to /admin. To verify that all is working correctly, verify that you can only see a sub-section of the modules and some are set to view-only. +6. (Engineer only) Add an optional email key/value pair Do note that if you wish to have both an analyst and admin account, append `-Analyst` to your first and last name, or use a completely different first/last name to avoid confusion. Example: `Bob-Analyst` From 536a3f6684b468cc181563a530e263723cf1917d Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Wed, 10 Apr 2024 23:55:28 -0700 Subject: [PATCH 29/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 0b810fd5c..0921728ae 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -35,7 +35,9 @@ Welcome to the .gov team! We're excited to have you here. Please follow the step - [ ] Fill out your own Personal Operating Manual (POM) on the [team norming board](https://miro.com/app/board/uXjVMxMu1SA=/). OPTIONAL: Present it on the next team coffee meeting. - [ ] FOR FEDERAL EMPLOYEES: Check in with your manager on the CISA onboarding process and getting your PIV card. - [ ] FOR CONTRACTORS: Check with your manager on your EOD clearance process. -- [ ] OPTIONAL: Request access to our [analytics tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.9q334hs4lbks). +- [ ] OPTIONAL: Request access to our [analytics tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.9q334hs4lbks). +- [ ] OPTIONAL: If you would like to manage content updates by running code locally rather than through GitHub, follow the steps in the [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE). + - [ ] If you would like to run code locally on a CISA laptop, reference the "Setting up a developer environment on CISA laptops" section of the onboarding doc. ### Access From 8302fe1ae1e7704729fd0247ed03e9e37fa4d462 Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Wed, 10 Apr 2024 23:58:14 -0700 Subject: [PATCH 30/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f457e7e69..12efb2a31 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The .gov domain helps U.S.-based government organizations gain public trust by b ## Onboarding -For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open an [onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE). +For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open an [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE) or [designer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=design%2C+onboarding&template=designer-onboarding.md&title=Designer+Onboarding%3A+GH_HANDLE). ## Code From f954f3fcf30587e270ad7c3030fba62f4881738c Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Wed, 10 Apr 2024 23:59:00 -0700 Subject: [PATCH 31/43] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 12efb2a31..545b64f99 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The .gov domain helps U.S.-based government organizations gain public trust by b ## Onboarding -For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open an [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE) or [designer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=design%2C+onboarding&template=designer-onboarding.md&title=Designer+Onboarding%3A+GH_HANDLE). +For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open a [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE) or a [designer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=design%2C+onboarding&template=designer-onboarding.md&title=Designer+Onboarding%3A+GH_HANDLE). ## Code From 4297ed0d9d0043156f91a3e6203d8ff2e5197a96 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Thu, 11 Apr 2024 05:41:19 -0400 Subject: [PATCH 32/43] made css changes --- src/registrar/assets/sass/_theme/_admin.scss | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_admin.scss b/src/registrar/assets/sass/_theme/_admin.scss index d4eeaf990..27fce0136 100644 --- a/src/registrar/assets/sass/_theme/_admin.scss +++ b/src/registrar/assets/sass/_theme/_admin.scss @@ -539,10 +539,11 @@ address.dja-address-contact-list { .dja-status-list { border-top: solid 1px var(--border-color); margin-left: 0 !important; + margin-top: 10px; padding-left: 0 !important; - padding-top: 15px; + padding-top: 10px; li { - line-height: 1.15; + line-height: 1.5; font-family: "Source Sans Pro Web", "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif !important; } } From c0f83f7696a1057a71fa284b34b081a1c751e47d Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Thu, 11 Apr 2024 08:18:55 -0700 Subject: [PATCH 33/43] Update README.md Co-authored-by: Alysia Broddrick <109625347+abroddrick@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 545b64f99..4fa110464 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The .gov domain helps U.S.-based government organizations gain public trust by b ## Onboarding -For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open a [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE) or a [designer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=design%2C+onboarding&template=designer-onboarding.md&title=Designer+Onboarding%3A+GH_HANDLE). +For new members of the @cisagov/dotgov team looking to contribute to the registrar, please open a [developer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE) or a [designer onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=design%2C+onboarding&template=designer-onboarding.md&title=Designer+Onboarding%3A+GH_HANDLE). ## Code From 217604d753931b737e8ecfc863bf63b6138fcf4c Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:10:53 -0700 Subject: [PATCH 34/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 0921728ae..2a620a1f0 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -37,7 +37,7 @@ Welcome to the .gov team! We're excited to have you here. Please follow the step - [ ] FOR CONTRACTORS: Check with your manager on your EOD clearance process. - [ ] OPTIONAL: Request access to our [analytics tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.9q334hs4lbks). - [ ] OPTIONAL: If you would like to manage content updates by running code locally rather than through GitHub, follow the steps in the [dev onboarding ticket](https://github.com/cisagov/getgov/issues/new?assignees=loganmeetsworld&labels=dev%2C+onboarding&template=developer-onboarding.md&title=Developer+Onboarding%3A+GH_HANDLE). - - [ ] If you would like to run code locally on a CISA laptop, reference the "Setting up a developer environment on CISA laptops" section of the onboarding doc. + - [ ] If you would like to run code locally on a CISA laptop, reference the "[Setting up a developer environment on CISA laptops](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.2ctyba51d1zp)" section of the onboarding doc. ### Access From 0792d68608dffcb1f230f14f130fd29abd08a24c Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:20:06 -0700 Subject: [PATCH 35/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 2a620a1f0..0296b653d 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -26,7 +26,7 @@ Welcome to the .gov team! We're excited to have you here. Please follow the step - [ ] FOR FEDERAL EMPLOYEES: Create a [Google workspace enterprise account](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.xowzg9w0qlis) for CISA. - [ ] Get access to our [Project Folder](https://drive.google.com/drive/folders/1qkoFQBlzXA7axi9CZ_OBhlJqRcqlNfpW?usp=drive_link) on Google Drive. - [ ] Explore the folders and docs. Designers interface with the Product Design, Content, and Research folders most often. -- [ ] Make sure you have been invited to our [team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.h62kzew057p1) on Google Meet. +- [ ] Make sure you have been invited to our [team meetings](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit#heading=h.emgtp2hgvabr) on Google Meet. - [ ] Review our [design tools](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.aprurp3z4gmv). - [ ] Accept invitation to our [Figma workspace](https://www.figma.com/files/1287135731043703282/team/1299882813146449644). - [ ] Follow the steps in [preparing for your sandbox](https://docs.google.com/document/d/1ukbpW4LSqkb_CCt8LWfpehP03qqfyYfvK3Fl21NaEq8/edit?pli=1#heading=h.au66hq5e0l8s) section on the onboarding doc. @@ -54,7 +54,7 @@ By following the steps, you should have access / been added to the following: ### Steps for the onboarder - [ ] Make sure onboardee is given an invitation to our Slack workspace - [ ] Add onboardee to dotgov Slack channels -- [ ] Add onboardee is added to Project Folder as a "Contributor" (or if you do not have permissions, confirm with Cameron) +- [ ] Add onboardee to Project Folder as a "Contributor" (or if you do not have permissions, confirm with Cameron) - If onboardee if a federal employee, add them as a "Content Manager" instead - [ ] Once onboardee has been granted a Figma license, add them as an editor to the Figma team workspace, Otherwise, you can add them as a viewer in the meantime. - [ ] Add onboardee to our team meetings From 41406a76ea54364b5cf2dead56425d2e16048dd2 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Thu, 11 Apr 2024 13:41:01 -0400 Subject: [PATCH 36/43] aligned spacing --- src/registrar/assets/sass/_theme/_admin.scss | 3 ++- .../templates/django/admin/includes/contact_detail_list.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/registrar/assets/sass/_theme/_admin.scss b/src/registrar/assets/sass/_theme/_admin.scss index 27fce0136..4b69dc8e3 100644 --- a/src/registrar/assets/sass/_theme/_admin.scss +++ b/src/registrar/assets/sass/_theme/_admin.scss @@ -539,12 +539,13 @@ address.dja-address-contact-list { .dja-status-list { border-top: solid 1px var(--border-color); margin-left: 0 !important; - margin-top: 10px; padding-left: 0 !important; padding-top: 10px; li { line-height: 1.5; font-family: "Source Sans Pro Web", "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif !important; + padding-top: 0; + padding-bottom: 0; } } diff --git a/src/registrar/templates/django/admin/includes/contact_detail_list.html b/src/registrar/templates/django/admin/includes/contact_detail_list.html index 8ad6fb96d..b5ccb5a42 100644 --- a/src/registrar/templates/django/admin/includes/contact_detail_list.html +++ b/src/registrar/templates/django/admin/includes/contact_detail_list.html @@ -1,6 +1,6 @@ {% load i18n static %} -
        +
        {% if show_formatted_name %} {% if contact.get_formatted_name %} From 1d6c06208d4165aed78016013655561dffc70a2b Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 11 Apr 2024 15:50:34 -0600 Subject: [PATCH 37/43] Fix redirect --- src/registrar/admin.py | 14 ++++++-------- .../admin/includes/detail_table_fieldset.html | 4 +++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 74c6bc070..8e5d40c05 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -805,15 +805,13 @@ class WebsiteAdmin(ListHeaderAdmin): """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") - + return_path = request.GET.get('return_path') # Don't redirect to the website page on save if the user is an analyst. - # Rather, just redirect back to the same change page. - if analyst_perm and not superuser_perm: - opts = obj._meta - pk_value = obj._get_pk_val() - return HttpResponseRedirect( - reverse("admin:%s_%s_change" % (opts.app_label, opts.model_name), args=(pk_value,)) - ) + # Rather, just redirect back to the originating page. + if (analyst_perm and not superuser_perm) and return_path: + # Redirect to the return path if it exists + return HttpResponseRedirect(return_path) + return super().response_change(request, obj) diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index a0a679290..96d9eb547 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -49,9 +49,11 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)

    {% elif field.field.name == "alternative_domains" %}
    + {% with current_path=request.get_full_path %} {% for alt_domain in original.alternative_domains.all %} - {{ alt_domain }}{% if not forloop.last %}, {% endif %} + {{ alt_domain }}{% if not forloop.last %}, {% endif %} {% endfor %} + {% endwith %}
    {% else %}
    {{ field.contents }}
    From 61b71c298ebb230a3fa2996b4b1c3fa2dc6f77b4 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:05:42 -0600 Subject: [PATCH 38/43] Fix minor bug --- src/registrar/admin.py | 18 ++++++++---------- .../admin/includes/detail_table_fieldset.html | 4 ++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index 8e5d40c05..bce9087be 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -801,7 +801,7 @@ class WebsiteAdmin(ListHeaderAdmin): def response_change(self, request, obj): """ - Override to redirect users back to the same page after saving. + Override to redirect users back to the previous page after saving. """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") @@ -1956,19 +1956,17 @@ class DraftDomainAdmin(ListHeaderAdmin): def response_change(self, request, obj): """ - Override to redirect users back to the same page after saving. + Override to redirect users back to the previous page after saving. """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") - + return_path = request.GET.get('return_path') # Don't redirect to the website page on save if the user is an analyst. - # Rather, just redirect back to the same change page. - if analyst_perm and not superuser_perm: - opts = obj._meta - pk_value = obj._get_pk_val() - return HttpResponseRedirect( - reverse("admin:%s_%s_change" % (opts.app_label, opts.model_name), args=(pk_value,)) - ) + # Rather, just redirect back to the originating page. + if (analyst_perm and not superuser_perm) and return_path: + # Redirect to the return path if it exists + return HttpResponseRedirect(return_path) + return super().response_change(request, obj) diff --git a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html index 96d9eb547..3e832922d 100644 --- a/src/registrar/templates/django/admin/includes/detail_table_fieldset.html +++ b/src/registrar/templates/django/admin/includes/detail_table_fieldset.html @@ -27,6 +27,10 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html) {% endif %} + {% elif field.field.name == "requested_domain" %} + {% with current_path=request.get_full_path %} + {{ original.requested_domain }} + {% endwith%} {% elif field.field.name == "current_websites" %} {% comment %} The "website" model is essentially just a text field. From 5e15490d2c4a222f104877b62ad8dfdac0f2c788 Mon Sep 17 00:00:00 2001 From: Alysia Broddrick <109625347+abroddrick@users.noreply.github.com> Date: Thu, 11 Apr 2024 16:09:54 -0700 Subject: [PATCH 39/43] Apply suggestions from code review Co-authored-by: zandercymatics <141044360+zandercymatics@users.noreply.github.com> --- docs/developer/README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/developer/README.md b/docs/developer/README.md index 29bc0a530..9421d5856 100644 --- a/docs/developer/README.md +++ b/docs/developer/README.md @@ -79,7 +79,6 @@ The endpoint /admin can be used to view and manage site content, including but n While on production (the sandbox referred to as `stable`), an existing analyst or full-access user typically grants access /admin as part of onboarding ([see these instructions](../django-admin/roles.md)), doing this for all development sandboxes is very time consuming. Instead, to get access to /admin on all development sandboxes and when developing code locally, refer to the following sections depending on what level of user access you desire. -Note: this process where a team member gets analyst/superuser permission on all non-production sandboxes is often called "Adding to fixtures". ### Adding full-access user to /admin @@ -88,7 +87,7 @@ Note: this process where a team member gets analyst/superuser permission on all 1. Login via login.gov 2. Go to the home page and make sure you can see the part where you can submit a domain request 3. Go to /admin and it will tell you that your UUID is not authorized (it shows a very long string, this is your UUID). Copy that UUID for use in 4. -4. (Designers)- message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Please see the "Adding an Analyst to /admin" section below to complete similiar steps if you also desire an `analyst` user account. Engineers will handle the remaining steps for designers, stop here. +4. (Designers) Message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Please see the "Adding an Analyst to /admin" section below to complete similiar steps if you also desire an `analyst` user account. Engineers will handle the remaining steps for designers, stop here. (Engineers) In src/registrar/fixtures_users.py add to the `ADMINS` list in that file by adding your UUID as your username along with your first and last name. See below: @@ -103,8 +102,8 @@ Note: this process where a team member gets analyst/superuser permission on all ] ``` -5. (Engineer only) In the browser, navigate to /admin. To verify that all is working correctly, under "domain requests" you should see fake domains with various fake statuses. -6. (Engineer only) Add an optional email key/value pair +5. (Engineers) In the browser, navigate to /admin. To verify that all is working correctly, under "domain requests" you should see fake domains with various fake statuses. +6. (Engineers) Add an optional email key/value pair ### Adding an analyst-level user to /admin Analysts are a variant of the admin role with limited permissions. The process for adding an Analyst is much the same as adding an admin: @@ -112,9 +111,9 @@ Analysts are a variant of the admin role with limited permissions. The process f 1. Login via login.gov (if you already exist as an admin, you will need to create a separate login.gov account for this: i.e. first.last+1@email.com) 2. Go to the home page and make sure you can see the part where you can submit a domain request 3. Go to /admin and it will tell you that UUID is not authorized, copy that UUID for use in 4 (this will be a different UUID than the one obtained from creating an admin) -4. (Designers)- message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Please see the "Adding an Analyst to /admin" section below to complete similiar steps if you also desire an `analyst` user account. Engineers will handle the remaining steps for designers, stop here. +4. (Designers) Message in #getgov-dev that you need access to admin as a `superuser` and send them this UUID along with your desired email address. Engineers will handle the remaining steps for designers, stop here. -(Engineers) In src/registrar/fixtures_users.py add to the `STAFF` list in that file by adding your UUID as your username along with your first and last name. See below: +5. (Engineers) In src/registrar/fixtures_users.py add to the `STAFF` list in that file by adding your UUID as your username along with your first and last name. See below: ``` STAFF = [ @@ -127,8 +126,8 @@ Analysts are a variant of the admin role with limited permissions. The process f ] ``` -5. (Engineer only) In the browser, navigate to /admin. To verify that all is working correctly, verify that you can only see a sub-section of the modules and some are set to view-only. -6. (Engineer only) Add an optional email key/value pair +5. (Engineers) In the browser, navigate to /admin. To verify that all is working correctly, verify that you can only see a sub-section of the modules and some are set to view-only. +6. (Engineers) Add an optional email key/value pair Do note that if you wish to have both an analyst and admin account, append `-Analyst` to your first and last name, or use a completely different first/last name to avoid confusion. Example: `Bob-Analyst` From 53d5c3bd61afd0fd48b16c34f5ac23de08221ce9 Mon Sep 17 00:00:00 2001 From: zandercymatics <141044360+zandercymatics@users.noreply.github.com> Date: Fri, 12 Apr 2024 08:39:04 -0600 Subject: [PATCH 40/43] Propagate success message --- src/registrar/admin.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/registrar/admin.py b/src/registrar/admin.py index bce9087be..b3248a96f 100644 --- a/src/registrar/admin.py +++ b/src/registrar/admin.py @@ -805,14 +805,19 @@ class WebsiteAdmin(ListHeaderAdmin): """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") - return_path = request.GET.get('return_path') + return_path = request.GET.get("return_path") + + # First, call the super method to perform the standard operations and capture the response + response = super().response_change(request, obj) + # Don't redirect to the website page on save if the user is an analyst. # Rather, just redirect back to the originating page. if (analyst_perm and not superuser_perm) and return_path: # Redirect to the return path if it exists return HttpResponseRedirect(return_path) - return super().response_change(request, obj) + # If no redirection is needed, return the original response + return response class UserDomainRoleAdmin(ListHeaderAdmin): @@ -1960,14 +1965,19 @@ class DraftDomainAdmin(ListHeaderAdmin): """ superuser_perm = request.user.has_perm("registrar.full_access_permission") analyst_perm = request.user.has_perm("registrar.analyst_access_permission") - return_path = request.GET.get('return_path') + return_path = request.GET.get("return_path") + + # First, call the super method to perform the standard operations and capture the response + response = super().response_change(request, obj) + # Don't redirect to the website page on save if the user is an analyst. # Rather, just redirect back to the originating page. if (analyst_perm and not superuser_perm) and return_path: # Redirect to the return path if it exists return HttpResponseRedirect(return_path) - return super().response_change(request, obj) + # If no redirection is needed, return the original response + return response class PublicContactAdmin(ListHeaderAdmin): From 1fa0e63126eb6f2052a02d2ff1209939f544a9ff Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Fri, 12 Apr 2024 10:47:12 -0400 Subject: [PATCH 41/43] simplified contact detail list template --- src/registrar/models/contact.py | 8 ++++++++ src/registrar/models/user.py | 8 ++++++++ .../django/admin/includes/contact_detail_list.html | 4 ++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/registrar/models/contact.py b/src/registrar/models/contact.py index d3de5a293..0b097974e 100644 --- a/src/registrar/models/contact.py +++ b/src/registrar/models/contact.py @@ -93,6 +93,14 @@ class Contact(TimeStampedModel): names = [n for n in [self.first_name, self.middle_name, self.last_name] if n] return " ".join(names) if names else "Unknown" + def has_contact_info(self): + has_contact_info = ( + self.title or + self.email or + self.phone + ) + return has_contact_info + def save(self, *args, **kwargs): # Call the parent class's save method to perform the actual save super().save(*args, **kwargs) diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 1ca2412ca..7e9cdf73e 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -92,6 +92,14 @@ class User(AbstractUser): """Return count of ineligible requests""" return self.domain_requests_created.filter(status=DomainRequest.DomainRequestStatus.INELIGIBLE).count() + def has_contact_info(self): + has_contact_info = ( + self.contact.title or + self.email.title or + self.contact.phone + ) + return has_contact_info + @classmethod def needs_identity_verification(cls, email, uuid): """A method used by our oidc classes to test whether a user needs email/uuid verification diff --git a/src/registrar/templates/django/admin/includes/contact_detail_list.html b/src/registrar/templates/django/admin/includes/contact_detail_list.html index b5ccb5a42..0ac9c4c49 100644 --- a/src/registrar/templates/django/admin/includes/contact_detail_list.html +++ b/src/registrar/templates/django/admin/includes/contact_detail_list.html @@ -1,6 +1,6 @@ {% load i18n static %} -
    +
    {% if show_formatted_name %} {% if contact.get_formatted_name %} @@ -10,7 +10,7 @@ {% endif %} {% endif %} - {% if user.title or user.contact.title or user.email or user.contact.email or user.phone or user.contact.phone %} + {% if user.has_contact_info %} {# Title #} {% if user.title or user.contact.title %} {% if user.contact.title %} From ed0ffe2962e837f5853619faafb2ee80c971494e Mon Sep 17 00:00:00 2001 From: Kristina Yin <140533113+kristinacyin@users.noreply.github.com> Date: Fri, 12 Apr 2024 08:22:38 -0700 Subject: [PATCH 42/43] Update designer-onboarding.md --- .github/ISSUE_TEMPLATE/designer-onboarding.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/designer-onboarding.md b/.github/ISSUE_TEMPLATE/designer-onboarding.md index 0296b653d..461850b60 100644 --- a/.github/ISSUE_TEMPLATE/designer-onboarding.md +++ b/.github/ISSUE_TEMPLATE/designer-onboarding.md @@ -56,6 +56,7 @@ By following the steps, you should have access / been added to the following: - [ ] Add onboardee to dotgov Slack channels - [ ] Add onboardee to Project Folder as a "Contributor" (or if you do not have permissions, confirm with Cameron) - If onboardee if a federal employee, add them as a "Content Manager" instead -- [ ] Once onboardee has been granted a Figma license, add them as an editor to the Figma team workspace, Otherwise, you can add them as a viewer in the meantime. +- [ ] Coordinate with Cameron to grant onboardee a Figma license +- [ ] Add onboardee as an editor to the Figma team workspace, If they do not have a license (yet), you can add them as a viewer. - [ ] Add onboardee to our team meetings - [ ] If applicable, invite onboardee to Google Analytics, Google Search Console, and Search.gov console From 673c092ea9f9f8e6fda5b893e2fe679a2ca7b085 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Fri, 12 Apr 2024 11:50:24 -0400 Subject: [PATCH 43/43] updated tests --- src/registrar/models/contact.py | 7 +------ src/registrar/models/user.py | 7 +------ src/registrar/tests/test_models.py | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/registrar/models/contact.py b/src/registrar/models/contact.py index 0b097974e..c5cb03a6e 100644 --- a/src/registrar/models/contact.py +++ b/src/registrar/models/contact.py @@ -94,12 +94,7 @@ class Contact(TimeStampedModel): return " ".join(names) if names else "Unknown" def has_contact_info(self): - has_contact_info = ( - self.title or - self.email or - self.phone - ) - return has_contact_info + return bool(self.title or self.email or self.phone) def save(self, *args, **kwargs): # Call the parent class's save method to perform the actual save diff --git a/src/registrar/models/user.py b/src/registrar/models/user.py index 7e9cdf73e..2688ef57f 100644 --- a/src/registrar/models/user.py +++ b/src/registrar/models/user.py @@ -93,12 +93,7 @@ class User(AbstractUser): return self.domain_requests_created.filter(status=DomainRequest.DomainRequestStatus.INELIGIBLE).count() def has_contact_info(self): - has_contact_info = ( - self.contact.title or - self.email.title or - self.contact.phone - ) - return has_contact_info + return bool(self.contact.title or self.contact.email or self.contact.phone) @classmethod def needs_identity_verification(cls, email, uuid): diff --git a/src/registrar/tests/test_models.py b/src/registrar/tests/test_models.py index 3c8d8b05b..d6a561c7f 100644 --- a/src/registrar/tests/test_models.py +++ b/src/registrar/tests/test_models.py @@ -1137,6 +1137,16 @@ class TestUser(TestCase): ) self.assertEquals(self.user.get_ineligible_requests_count(), 1) + def test_has_contact_info(self): + """Test that has_contact_info properly returns""" + # test with a user with contact info defined + self.assertTrue(self.user.has_contact_info()) + # test with a user without contact info defined + self.user.contact.title = None + self.user.contact.email = None + self.user.contact.phone = None + self.assertFalse(self.user.has_contact_info()) + class TestContact(TestCase): def setUp(self): @@ -1238,3 +1248,13 @@ class TestContact(TestCase): # test for a contact which is assigned as an authorizing official on a domain request self.assertFalse(self.contact_as_ao.has_more_than_one_join("authorizing_official")) self.assertTrue(self.contact_as_ao.has_more_than_one_join("submitted_domain_requests")) + + def test_has_contact_info(self): + """Test that has_contact_info properly returns""" + # test with a contact with contact info defined + self.assertTrue(self.contact.has_contact_info()) + # test with a contact without contact info defined + self.contact.title = None + self.contact.email = None + self.contact.phone = None + self.assertFalse(self.contact.has_contact_info())