Skip to content

Commit

Permalink
Merge pull request #1012 from cisagov/dk/853-domain-app-admin-states
Browse files Browse the repository at this point in the history
Dk/853 domain app admin states
  • Loading branch information
dave-kennedy-ecs authored Sep 13, 2023
2 parents c6670bd + af5ca2a commit 4daec21
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/registrar/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
from django import forms
from django_fsm import get_available_FIELD_transitions
from django.contrib import admin, messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.contenttypes.models import ContentType
Expand Down Expand Up @@ -379,6 +381,37 @@ class DomainInformationAdmin(ListHeaderAdmin):
search_help_text = "Search by domain."


class DomainApplicationAdminForm(forms.ModelForm):
"""Custom form to limit transitions to available transitions"""

class Meta:
model = models.DomainApplication
fields = "__all__"

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

application = kwargs.get("instance")
if application and application.pk:
current_state = application.status

# first option in status transitions is current state
available_transitions = [(current_state, current_state)]

transitions = get_available_FIELD_transitions(
application, models.DomainApplication._meta.get_field("status")
)

for transition in transitions:
available_transitions.append((transition.target, transition.target))

# only set the available transitions if the user is not restricted
# from editing the domain application; otherwise, the form will be
# readonly and the status field will not have a widget
if not application.creator.is_restricted():
self.fields["status"].widget.choices = available_transitions


class DomainApplicationAdmin(ListHeaderAdmin):

"""Custom domain applications admin class."""
Expand Down Expand Up @@ -410,6 +443,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
search_help_text = "Search by domain or submitter."

# Detail view
form = DomainApplicationAdminForm
fieldsets = [
(None, {"fields": ["status", "investigator", "creator"]}),
(
Expand Down
43 changes: 43 additions & 0 deletions src/registrar/tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from registrar.admin import (
DomainAdmin,
DomainApplicationAdmin,
DomainApplicationAdminForm,
ListHeaderAdmin,
MyUserAdmin,
AuditedAdmin,
Expand Down Expand Up @@ -92,6 +93,48 @@ def tearDown(self):
User.objects.all().delete()


class TestDomainApplicationAdminForm(TestCase):
def setUp(self):
# Create a test application with an initial state of started
self.application = completed_application()

def test_form_choices(self):
# Create a form instance with the test application
form = DomainApplicationAdminForm(instance=self.application)

# Verify that the form choices match the available transitions for started
expected_choices = [("started", "started"), ("submitted", "submitted")]
self.assertEqual(form.fields["status"].widget.choices, expected_choices)

def test_form_choices_when_no_instance(self):
# Create a form instance without an instance
form = DomainApplicationAdminForm()

# Verify that the form choices show all choices when no instance is provided;
# this is necessary to show all choices when creating a new domain
# application in django admin;
# note that FSM ensures that no domain application exists with invalid status,
# so don't need to test for invalid status
self.assertEqual(
form.fields["status"].widget.choices,
DomainApplication._meta.get_field("status").choices,
)

def test_form_choices_when_ineligible(self):
# Create a form instance with a domain application with ineligible status
ineligible_application = DomainApplication(status="ineligible")

# Attempt to create a form with the ineligible application
# The form should not raise an error, but choices should be the
# full list of possible choices
form = DomainApplicationAdminForm(instance=ineligible_application)

self.assertEqual(
form.fields["status"].widget.choices,
DomainApplication._meta.get_field("status").choices,
)


class TestDomainApplicationAdmin(TestCase):
def setUp(self):
self.site = AdminSite()
Expand Down

0 comments on commit 4daec21

Please sign in to comment.