Change ineligible to restricted on User, fix status tempplate for DAs

This commit is contained in:
Rachid Mrad 2023-08-29 14:16:39 -04:00
parent b6af335e03
commit 501cddebde
No known key found for this signature in database
GPG key ID: EF38E4CEC4A8F3CF
8 changed files with 57 additions and 37 deletions

View file

@ -116,7 +116,7 @@ class MyUserAdmin(BaseUserAdmin):
( (
None, None,
{"fields": ("username", "password", "status")}, {"fields": ("username", "password", "status")},
), # Add the 'status' field here ),
("Personal Info", {"fields": ("first_name", "last_name", "email")}), ("Personal Info", {"fields": ("first_name", "last_name", "email")}),
( (
"Permissions", "Permissions",
@ -301,7 +301,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
# Trigger action when a fieldset is changed # Trigger action when a fieldset is changed
def save_model(self, request, obj, form, change): def save_model(self, request, obj, form, change):
if obj and obj.creator.status != "ineligible": if obj and obj.creator.status != models.User.RESTRICTED:
if change: # Check if the application is being edited if change: # Check if the application is being edited
# Get the original application from the database # Get the original application from the database
original_obj = models.DomainApplication.objects.get(pk=obj.pk) original_obj = models.DomainApplication.objects.get(pk=obj.pk)
@ -336,7 +336,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
messages.error( messages.error(
request, request,
"This action is not permitted for applications " "This action is not permitted for applications "
+ "with an ineligible creator.", + "with a restricted creator.",
) )
def get_readonly_fields(self, request, obj=None): def get_readonly_fields(self, request, obj=None):
@ -348,8 +348,8 @@ class DomainApplicationAdmin(ListHeaderAdmin):
readonly_fields = list(self.readonly_fields) readonly_fields = list(self.readonly_fields)
# Check if the creator is ineligible # Check if the creator is restricted
if obj and obj.creator.status == "ineligible": if obj and obj.creator.status == models.User.RESTRICTED:
# For fields like CharField, IntegerField, etc., the widget used is # For fields like CharField, IntegerField, etc., the widget used is
# straightforward and the readonly_fields list can control their behavior # straightforward and the readonly_fields list can control their behavior
readonly_fields.extend([field.name for field in self.model._meta.fields]) readonly_fields.extend([field.name for field in self.model._meta.fields])
@ -365,17 +365,16 @@ class DomainApplicationAdmin(ListHeaderAdmin):
readonly_fields.extend([field for field in self.analyst_readonly_fields]) readonly_fields.extend([field for field in self.analyst_readonly_fields])
return readonly_fields return readonly_fields
def display_ineligible_warning(self, request, obj): def display_restricted_warning(self, request, obj):
if obj and obj.creator.status == "ineligible": if obj and obj.creator.status == models.User.RESTRICTED:
messages.warning( messages.warning(
request, request,
"Cannot edit an application when its creator " "Cannot edit an application with a restricted creator.",
+ "has a status of ineligible.",
) )
def change_view(self, request, object_id, form_url="", extra_context=None): def change_view(self, request, object_id, form_url="", extra_context=None):
obj = self.get_object(request, object_id) obj = self.get_object(request, object_id)
self.display_ineligible_warning(request, obj) self.display_restricted_warning(request, obj)
return super().change_view(request, object_id, form_url, extra_context) return super().change_view(request, object_id, form_url, extra_context)

View file

@ -0,0 +1,23 @@
# Generated by Django 4.2.1 on 2023-08-29 17:09
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("registrar", "0029_user_status_alter_domainapplication_status"),
]
operations = [
migrations.AlterField(
model_name="user",
name="status",
field=models.CharField(
blank=True,
choices=[("restricted", "restricted")],
default=None,
max_length=10,
null=True,
),
),
]

View file

@ -621,7 +621,7 @@ class DomainApplication(TimeStampedModel):
We do this by setting an ineligible status on the user, which the We do this by setting an ineligible status on the user, which the
permissions classes test against""" permissions classes test against"""
self.creator.block_user() self.creator.restrict_user()
# ## Form policies ### # ## Form policies ###
# #

View file

@ -18,8 +18,8 @@ class User(AbstractUser):
""" """
# #### Constants for choice fields #### # #### Constants for choice fields ####
INELIGIBLE = "ineligible" RESTRICTED = "restricted"
STATUS_CHOICES = ((INELIGIBLE, INELIGIBLE),) STATUS_CHOICES = ((RESTRICTED, RESTRICTED),)
status = models.CharField( status = models.CharField(
max_length=10, max_length=10,
@ -51,18 +51,16 @@ class User(AbstractUser):
else: else:
return self.username return self.username
def block_user(self): def restrict_user(self):
self.status = "ineligible" self.status = self.RESTRICTED
self.save() self.save()
def unblock_user(self): def unrestrict_user(self):
self.status = None self.status = None
self.save() self.save()
def is_blocked(self): def is_restricted(self):
if self.status == "ineligible": return self.status == self.RESTRICTED
return True
return False
def first_login(self): def first_login(self):
"""Callback when the user is authenticated for the very first time. """Callback when the user is authenticated for the very first time.

View file

@ -23,6 +23,7 @@
{% elif domainapplication.status == 'in review' %} In Review {% elif domainapplication.status == 'in review' %} In Review
{% elif domainapplication.status == 'rejected' %} Rejected {% elif domainapplication.status == 'rejected' %} Rejected
{% elif domainapplication.status == 'submitted' %} Submitted {% elif domainapplication.status == 'submitted' %} Submitted
{% elif domainapplication.status == 'ineligible' %} Ineligible
{% else %}ERROR Please contact technical support/dev {% else %}ERROR Please contact technical support/dev
{% endif %} {% endif %}
</p> </p>

View file

@ -284,7 +284,7 @@ class TestDomainApplicationAdmin(TestCase):
# Perform assertions on the mock call itself # Perform assertions on the mock call itself
mock_client_instance.send_email.assert_called_once() mock_client_instance.send_email.assert_called_once()
def test_save_model_sets_ineligible_status_on_user(self): def test_save_model_sets_restricted_status_on_user(self):
# make sure there is no user with this email # make sure there is no user with this email
EMAIL = "mayor@igorville.gov" EMAIL = "mayor@igorville.gov"
User.objects.filter(email=EMAIL).delete() User.objects.filter(email=EMAIL).delete()
@ -304,11 +304,11 @@ class TestDomainApplicationAdmin(TestCase):
self.admin.save_model(request, application, form=None, change=True) self.admin.save_model(request, application, form=None, change=True)
# Test that approved domain exists and equals requested domain # Test that approved domain exists and equals requested domain
self.assertEqual(application.creator.status, "ineligible") self.assertEqual(application.creator.status, "restricted")
def test_readonly_when_ineligible_creator(self): def test_readonly_when_restricted_creator(self):
application = completed_application(status=DomainApplication.IN_REVIEW) application = completed_application(status=DomainApplication.IN_REVIEW)
application.creator.status = "ineligible" application.creator.status = User.RESTRICTED
application.creator.save() application.creator.save()
request = self.factory.get("/") request = self.factory.get("/")
@ -388,10 +388,10 @@ class TestDomainApplicationAdmin(TestCase):
self.assertEqual(readonly_fields, expected_fields) self.assertEqual(readonly_fields, expected_fields)
def test_saving_when_ineligible_creator(self): def test_saving_when_restricted_creator(self):
# Create an instance of the model # Create an instance of the model
application = completed_application(status=DomainApplication.IN_REVIEW) application = completed_application(status=DomainApplication.IN_REVIEW)
application.creator.status = "ineligible" application.creator.status = User.RESTRICTED
application.creator.save() application.creator.save()
# Create a request object with a superuser # Create a request object with a superuser
@ -405,17 +405,17 @@ class TestDomainApplicationAdmin(TestCase):
# Assert that the error message was called with the correct argument # Assert that the error message was called with the correct argument
mock_error.assert_called_once_with( mock_error.assert_called_once_with(
request, request,
"This action is not permitted for applications with " "This action is not permitted for applications "
+ "an ineligible creator.", + "with a restricted creator.",
) )
# Assert that the status has not changed # Assert that the status has not changed
self.assertEqual(application.status, DomainApplication.IN_REVIEW) self.assertEqual(application.status, DomainApplication.IN_REVIEW)
def test_change_view_with_ineligible_creator(self): def test_change_view_with_restricted_creator(self):
# Create an instance of the model # Create an instance of the model
application = completed_application(status=DomainApplication.IN_REVIEW) application = completed_application(status=DomainApplication.IN_REVIEW)
application.creator.status = "ineligible" application.creator.status = User.RESTRICTED
application.creator.save() application.creator.save()
with patch("django.contrib.messages.warning") as mock_warning: with patch("django.contrib.messages.warning") as mock_warning:
@ -425,13 +425,12 @@ class TestDomainApplicationAdmin(TestCase):
) )
request.user = self.superuser request.user = self.superuser
self.admin.display_ineligible_warning(request, application) self.admin.display_restricted_warning(request, application)
# Assert that the error message was called with the correct argument # Assert that the error message was called with the correct argument
mock_warning.assert_called_once_with( mock_warning.assert_called_once_with(
request, request,
"Cannot edit an application when its creator " "Cannot edit an application with a restricted creator.",
+ "has a status of ineligible.",
) )
def tearDown(self): def tearDown(self):

View file

@ -105,7 +105,7 @@ class LoggedInTests(TestWithUser):
"""Application form not accessible for an ineligible user. """Application form not accessible for an ineligible user.
This test should be solid enough since all application wizard This test should be solid enough since all application wizard
views share the same permissions class""" views share the same permissions class"""
self.user.status = "ineligible" self.user.status = User.RESTRICTED
self.user.save() self.user.save()
with less_console_noise(): with less_console_noise():
@ -1439,7 +1439,7 @@ class TestDomainDetail(TestWithDomainPermissions, WebTest):
"""We could easily duplicate this test for all domain management """We could easily duplicate this test for all domain management
views, but a single url test should be solid enough since all domain views, but a single url test should be solid enough since all domain
management pages share the same permissions class""" management pages share the same permissions class"""
self.user.status = "ineligible" self.user.status = User.RESTRICTED
self.user.save() self.user.save()
home_page = self.app.get("/") home_page = self.app.get("/")
self.assertContains(home_page, "igorville.gov") self.assertContains(home_page, "igorville.gov")

View file

@ -40,7 +40,7 @@ class DomainPermission(PermissionsLoginMixin):
return False return False
# The user has an ineligible flag # The user has an ineligible flag
if self.request.user.is_blocked(): if self.request.user.is_restricted():
return False return False
# if we need to check more about the nature of role, do it here. # if we need to check more about the nature of role, do it here.
@ -82,7 +82,7 @@ class ApplicationWizardPermission(PermissionsLoginMixin):
""" """
# The user has an ineligible flag # The user has an ineligible flag
if self.request.user.is_blocked(): if self.request.user.is_restricted():
return False return False
return True return True