Merge branch 'za/bugfix-failing-migrations' into gd/1900-add-action-needed-reason

This commit is contained in:
zandercymatics 2024-06-07 09:49:34 -06:00
commit 2a9d33defe
No known key found for this signature in database
GPG key ID: FF4636ABEC9682B7
12 changed files with 154 additions and 38 deletions

View file

@ -609,7 +609,7 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
None,
{"fields": ("username", "password", "status", "verification_type")},
),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "title", "email", "phone")}),
(
"Permissions",
{
@ -640,7 +640,7 @@ class MyUserAdmin(BaseUserAdmin, ImportExportModelAdmin):
)
},
),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "title", "email", "phone")}),
(
"Permissions",
{

View file

@ -10,6 +10,7 @@ from registrar.management.commands.utility.terminal_helper import (
)
from registrar.models.contact import Contact
from registrar.models.user import User
from registrar.models.utility.domain_helper import DomainHelper
logger = logging.getLogger(__name__)
@ -110,15 +111,21 @@ class Command(BaseCommand):
{TerminalColors.ENDC}""", # noqa
)
# ---- UPDATE THE USER IF IT DOES NOT HAVE A FIRST AND LAST NAMES
# ---- LET'S KEEP A LIGHT TOUCH
if not eligible_user.first_name and not eligible_user.last_name:
# (expression has type "str | None", variable has type "str | int | Combinable")
# so we'll ignore type
eligible_user.first_name = contact.first_name # type: ignore
eligible_user.last_name = contact.last_name # type: ignore
eligible_user.save()
processed_user = eligible_user
# Get the fields that exist on both User and Contact. Excludes id.
common_fields = DomainHelper.get_common_fields(User, Contact)
if "email" in common_fields:
# Don't change the email field.
common_fields.remove("email")
for field in common_fields:
# Grab the value that contact has stored for this field
new_value = getattr(contact, field)
# Set it on the user field
setattr(eligible_user, field, new_value)
eligible_user.save()
processed_user = eligible_user
return (
eligible_user,

View file

@ -0,0 +1,19 @@
# Generated by Django 4.2.10 on 2024-06-06 18:38
from django.db import migrations
import phonenumber_field.modelfields
class Migration(migrations.Migration):
dependencies = [
("registrar", "0096_alter_contact_email_alter_contact_first_name_and_more"),
]
operations = [
migrations.AlterField(
model_name="user",
name="phone",
field=phonenumber_field.modelfields.PhoneNumberField(blank=True, max_length=128, null=True, region=None),
),
]

View file

@ -0,0 +1,32 @@
# Generated by Django 4.2.10 on 2024-06-07 15:27
from django.db import migrations
import django_fsm
class Migration(migrations.Migration):
dependencies = [
("registrar", "0097_alter_user_phone"),
]
operations = [
migrations.AlterField(
model_name="domainrequest",
name="status",
field=django_fsm.FSMField(
choices=[
("in review", "In review"),
("action needed", "Action needed"),
("approved", "Approved"),
("rejected", "Rejected"),
("ineligible", "Ineligible"),
("submitted", "Submitted"),
("withdrawn", "Withdrawn"),
("started", "Started"),
],
default="started",
max_length=50,
),
),
]

View file

@ -123,11 +123,21 @@ class Contact(TimeStampedModel):
self.user.last_name = self.last_name
updated = True
# Update middle_name if necessary
if not self.user.middle_name:
self.user.middle_name = self.middle_name
updated = True
# Update phone if necessary
if not self.user.phone:
self.user.phone = self.phone
updated = True
# Update title if necessary
if not self.user.title:
self.user.title = self.title
updated = True
# Save user if any updates were made
if updated:
self.user.save()

View file

@ -42,14 +42,14 @@ class DomainRequest(TimeStampedModel):
# Constants for choice fields
class DomainRequestStatus(models.TextChoices):
STARTED = "started", "Started"
SUBMITTED = "submitted", "Submitted"
IN_REVIEW = "in review", "In review"
ACTION_NEEDED = "action needed", "Action needed"
APPROVED = "approved", "Approved"
WITHDRAWN = "withdrawn", "Withdrawn"
REJECTED = "rejected", "Rejected"
INELIGIBLE = "ineligible", "Ineligible"
SUBMITTED = "submitted", "Submitted"
WITHDRAWN = "withdrawn", "Withdrawn"
STARTED = "started", "Started"
class StateTerritoryChoices(models.TextChoices):
ALABAMA = "AL", "Alabama (AL)"

View file

@ -87,7 +87,6 @@ class User(AbstractUser):
phone = PhoneNumberField(
null=True,
blank=True,
help_text="Phone",
)
middle_name = models.CharField(

View file

@ -24,9 +24,11 @@ def handle_profile(sender, instance, **kwargs):
"""
first_name = getattr(instance, "first_name", "")
middle_name = getattr(instance, "middle_name", "")
last_name = getattr(instance, "last_name", "")
email = getattr(instance, "email", "")
phone = getattr(instance, "phone", "")
title = getattr(instance, "title", "")
is_new_user = kwargs.get("created", False)
@ -39,9 +41,11 @@ def handle_profile(sender, instance, **kwargs):
Contact.objects.create(
user=instance,
first_name=first_name,
middle_name=middle_name,
last_name=last_name,
email=email,
phone=phone,
title=title,
)
if len(contacts) >= 1 and is_new_user: # a matching contact

View file

@ -3590,7 +3590,7 @@ class TestMyUserAdmin(TestCase):
)
},
),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "email", "title")}),
("Personal Info", {"fields": ("first_name", "middle_name", "last_name", "title", "email", "phone")}),
("Permissions", {"fields": ("is_active", "groups")}),
("Important dates", {"fields": ("last_login", "date_joined")}),
)

View file

@ -23,15 +23,32 @@ class TestDataUpdates(TestCase):
self.bs_user = User.objects.create()
self.contact1 = Contact.objects.create(
user=self.user1, email="email1@igorville.gov", first_name="first1", last_name="last1"
user=self.user1,
email="email1@igorville.gov",
first_name="first1",
last_name="last1",
middle_name="middle1",
title="title1",
)
self.contact2 = Contact.objects.create(
user=self.user2, email="email2@igorville.gov", first_name="first2", last_name="last2"
user=self.user2,
email="email2@igorville.gov",
first_name="first2",
last_name="last2",
middle_name="middle2",
title="title2",
)
self.contact3 = Contact.objects.create(
user=self.user3, email="email3@igorville.gov", first_name="first3", last_name="last3"
user=self.user3,
email="email3@igorville.gov",
first_name="first3",
last_name="last3",
middle_name="middle3",
title="title3",
)
self.contact4 = Contact.objects.create(
email="email4@igorville.gov", first_name="first4", last_name="last4", middle_name="middle4", title="title4"
)
self.contact4 = Contact.objects.create(email="email4@igorville.gov", first_name="first4", last_name="last4")
self.command = Command()
@ -42,14 +59,15 @@ class TestDataUpdates(TestCase):
Contact.objects.all().delete()
def test_script_updates_linked_users(self):
"""Test the script that copies contacts' first and last names into associated users that
are eligible (first or last are blank or undefined)"""
"""Test the script that copies contact information to the user object"""
# Set up the users' first and last names here so
# they that they don't get overwritten by Contact's save()
# User with no first or last names
self.user1.first_name = ""
self.user1.last_name = ""
self.user1.title = "dummytitle"
self.user1.middle_name = "dummymiddle"
self.user1.save()
# User with a first name but no last name
@ -87,12 +105,20 @@ class TestDataUpdates(TestCase):
# The user that has no first and last names will get them from the contact
self.assertEqual(self.user1.first_name, "first1")
self.assertEqual(self.user1.last_name, "last1")
# The user that has a first but no last will be left alone
self.assertEqual(self.user2.first_name, "First name but no last name")
self.assertEqual(self.user2.last_name, "")
# The user that has a first and a last will be left alone
self.assertEqual(self.user3.first_name, "An existing first name")
self.assertEqual(self.user3.last_name, "An existing last name")
self.assertEqual(self.user1.middle_name, "middle1")
self.assertEqual(self.user1.title, "title1")
# The user that has a first but no last will be updated
self.assertEqual(self.user2.first_name, "first2")
self.assertEqual(self.user2.last_name, "last2")
self.assertEqual(self.user2.middle_name, "middle2")
self.assertEqual(self.user2.title, "title2")
# The user that has a first and a last will be updated
self.assertEqual(self.user3.first_name, "first3")
self.assertEqual(self.user3.last_name, "last3")
self.assertEqual(self.user3.middle_name, "middle3")
self.assertEqual(self.user3.title, "title3")
# The unlinked user will be left alone
self.assertEqual(self.user4.first_name, "")
self.assertEqual(self.user4.last_name, "")
self.assertEqual(self.user4.middle_name, None)
self.assertEqual(self.user4.title, None)