Merge pull request #2423 from cisagov/za/profile-page-update-label

(on getgov-za) Ticket #2421/#2422:  Missing first name and last name gets a green checkmark next to “Unknown” and make field label consistent
This commit is contained in:
zandercymatics 2024-07-17 13:09:23 -06:00 committed by GitHub
commit 502f6b9444
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 150 additions and 6 deletions

View file

@ -1826,6 +1826,9 @@ document.addEventListener('DOMContentLoaded', function() {
}
function setupListener(){
document.querySelectorAll('[id$="__edit-button"]').forEach(function(button) {
// Get the "{field_name}" and "edit-button"
let fieldIdParts = button.id.split("__")
@ -1834,12 +1837,61 @@ document.addEventListener('DOMContentLoaded', function() {
// When the edit button is clicked, show the input field under it
handleEditButtonClick(fieldName, button);
let editableFormGroup = button.parentElement.parentElement.parentElement;
if (editableFormGroup){
let readonlyField = editableFormGroup.querySelector(".input-with-edit-button__readonly-field")
let inputField = document.getElementById(`id_${fieldName}`);
if (!inputField || !readonlyField) {
return;
}
let inputFieldValue = inputField.value
if (inputFieldValue || fieldName == "full_name"){
if (fieldName == "full_name"){
let firstName = document.querySelector("#id_first_name");
let middleName = document.querySelector("#id_middle_name");
let lastName = document.querySelector("#id_last_name");
if (firstName && lastName && firstName.value && lastName.value) {
let values = [firstName.value, middleName.value, lastName.value]
readonlyField.innerHTML = values.join(" ");
}else {
let fullNameField = document.querySelector('#full_name__edit-button-readonly');
let svg = fullNameField.querySelector("svg use")
if (svg) {
const currentHref = svg.getAttribute('xlink:href');
if (currentHref) {
const parts = currentHref.split('#');
if (parts.length === 2) {
// Keep the path before '#' and replace the part after '#' with 'invalid'
const newHref = parts[0] + '#error';
svg.setAttribute('xlink:href', newHref);
fullNameField.classList.add("input-with-edit-button__error")
label = fullNameField.querySelector(".input-with-edit-button__readonly-field")
label.innerHTML = "Unknown";
}
}
}
}
// Technically, the full_name field is optional, but we want to display it as required.
// This style is applied to readonly fields (gray text). This just removes it, as
// this is difficult to achieve otherwise by modifying the .readonly property.
if (readonlyField.classList.contains("text-base")) {
readonlyField.classList.remove("text-base")
}
}else {
readonlyField.innerHTML = inputFieldValue
}
}
}
}
});
}
function showInputOnErrorFields(){
document.addEventListener('DOMContentLoaded', function() {
// Get all input elements within the form
let form = document.querySelector("#finish-profile-setup-form");
let inputs = form ? form.querySelectorAll("input") : null;
@ -1878,9 +1930,9 @@ document.addEventListener('DOMContentLoaded', function() {
});
};
// Hookup all edit buttons to the `handleEditButtonClick` function
setupListener();
// Show the input fields if an error exists
showInputOnErrorFields();
})();

View file

@ -190,7 +190,7 @@ abbr[title] {
svg.usa-icon {
color: #{$dhs-red};
}
div.readonly-field {
div.input-with-edit-button__readonly-field {
color: #{$dhs-red};
}
}

View file

@ -71,7 +71,7 @@ class UserProfileForm(forms.ModelForm):
class FinishSetupProfileForm(UserProfileForm):
"""Form for updating user profile."""
full_name = forms.CharField(required=True, label="Full name")
full_name = forms.CharField(required=False, label="Full name")
def clean(self):
cleaned_data = super().clean()
@ -93,4 +93,7 @@ class FinishSetupProfileForm(UserProfileForm):
self.fields["title"].label = "Title or role in your organization"
# Define the "full_name" value
self.fields["full_name"].initial = self.instance.get_formatted_name()
full_name = None
if self.instance.first_name and self.instance.last_name:
full_name = self.instance.get_formatted_name()
self.fields["full_name"].initial = full_name

View file

@ -115,7 +115,8 @@ class User(AbstractUser):
self.title,
self.phone,
]
return None not in user_values
return None not in user_values and "" not in user_values
def __str__(self):
# this info is pulled from Login.gov

View file

@ -8,7 +8,7 @@
<use xlink:href="{%static 'img/sprite.svg'%}#error"></use>
{%endif %}
</svg>
<div class="display-inline padding-left-05 margin-left-3 readonly-field {% if not field.field.required %}text-base{% endif %}">
<div class="display-inline padding-left-05 margin-left-3 input-with-edit-button__readonly-field {% if not field.field.required %}text-base{% endif %}">
{% if field.name != "phone" %}
{{ field.value }}
{% else %}

View file

@ -208,6 +208,7 @@ class ExportDataTest(MockDb, MockEppLib):
@less_console_noise_decorator
def test_domain_data_type(self):
"""Shows security contacts, domain managers, so"""
self.maxDiff = None
# Add security email information
self.domain_1.name = "defaultsecurity.gov"
self.domain_1.save()
@ -402,6 +403,7 @@ class ExportDataTest(MockDb, MockEppLib):
squeaker@rocks.com is invited to domain2 (DNS_NEEDED) and domain10 (No managers).
She should show twice in this report but not in test_DomainManaged."""
self.maxDiff = None
# Create a CSV file in memory
csv_file = StringIO()
# Call the export functions

View file

@ -538,6 +538,49 @@ class FinishUserProfileTests(TestWithUser, WebTest):
self._set_session_cookie()
return page.follow() if follow else page
@less_console_noise_decorator
@override_flag("profile_feature", active=True)
def test_full_name_initial_value(self):
"""Test that full_name initial value is empty when first_name or last_name is empty.
This will later be displayed as "unknown" using javascript."""
self.app.set_user(self.incomplete_regular_user.username)
# Test when first_name is empty
self.incomplete_regular_user.first_name = ""
self.incomplete_regular_user.last_name = "Doe"
self.incomplete_regular_user.save()
finish_setup_page = self.app.get(reverse("home")).follow()
form = finish_setup_page.form
self.assertEqual(form["full_name"].value, "")
# Test when last_name is empty
self.incomplete_regular_user.first_name = "John"
self.incomplete_regular_user.last_name = ""
self.incomplete_regular_user.save()
finish_setup_page = self.app.get(reverse("home")).follow()
form = finish_setup_page.form
self.assertEqual(form["full_name"].value, "")
# Test when both first_name and last_name are empty
self.incomplete_regular_user.first_name = ""
self.incomplete_regular_user.last_name = ""
self.incomplete_regular_user.save()
finish_setup_page = self.app.get(reverse("home")).follow()
form = finish_setup_page.form
self.assertEqual(form["full_name"].value, "")
# Test when both first_name and last_name are present
self.incomplete_regular_user.first_name = "John"
self.incomplete_regular_user.last_name = "Doe"
self.incomplete_regular_user.save()
finish_setup_page = self.app.get(reverse("home")).follow()
form = finish_setup_page.form
self.assertEqual(form["full_name"].value, "John Doe")
@less_console_noise_decorator
def test_new_user_with_profile_feature_on(self):
"""Tests that a new user is redirected to the profile setup page when profile_feature is on"""
@ -576,6 +619,49 @@ class FinishUserProfileTests(TestWithUser, WebTest):
completed_setup_page = self.app.get(reverse("home"))
self.assertContains(completed_setup_page, "Manage your domain")
@less_console_noise_decorator
def test_new_user_with_empty_name_can_add_name(self):
"""Tests that a new user without a name can still enter this information accordingly"""
self.incomplete_regular_user.first_name = ""
self.incomplete_regular_user.last_name = ""
self.incomplete_regular_user.save()
self.app.set_user(self.incomplete_regular_user.username)
with override_flag("profile_feature", active=True):
# This will redirect the user to the setup page.
# Follow implicity checks if our redirect is working.
finish_setup_page = self.app.get(reverse("home")).follow()
self._set_session_cookie()
# Assert that we're on the right page
self.assertContains(finish_setup_page, "Finish setting up your profile")
finish_setup_page = self._submit_form_webtest(finish_setup_page.form)
self.assertEqual(finish_setup_page.status_code, 200)
# We're missing a phone number, so the page should tell us that
self.assertContains(finish_setup_page, "Enter your phone number.")
# Check for the name of the save button
self.assertContains(finish_setup_page, "user_setup_save_button")
# Add a phone number
finish_setup_form = finish_setup_page.form
finish_setup_form["first_name"] = "test"
finish_setup_form["last_name"] = "test2"
finish_setup_form["phone"] = "(201) 555-0123"
finish_setup_form["title"] = "CEO"
finish_setup_form["last_name"] = "example"
save_page = self._submit_form_webtest(finish_setup_form, follow=True)
self.assertEqual(save_page.status_code, 200)
self.assertContains(save_page, "Your profile has been updated.")
# Try to navigate back to the home page.
# This is the same as clicking the back button.
completed_setup_page = self.app.get(reverse("home"))
self.assertContains(completed_setup_page, "Manage your domain")
@less_console_noise_decorator
def test_new_user_goes_to_domain_request_with_profile_feature_on(self):
"""Tests that a new user is redirected to the domain request page when profile_feature is on"""