mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-16 17:47:02 +02:00
Merge pull request #1012 from cisagov/dk/853-domain-app-admin-states
Dk/853 domain app admin states
This commit is contained in:
commit
4daec217d7
2 changed files with 77 additions and 0 deletions
|
@ -1,4 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
from django import forms
|
||||||
|
from django_fsm import get_available_FIELD_transitions
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin, messages
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
@ -379,6 +381,37 @@ class DomainInformationAdmin(ListHeaderAdmin):
|
||||||
search_help_text = "Search by domain."
|
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):
|
class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
|
|
||||||
"""Custom domain applications admin class."""
|
"""Custom domain applications admin class."""
|
||||||
|
@ -410,6 +443,7 @@ class DomainApplicationAdmin(ListHeaderAdmin):
|
||||||
search_help_text = "Search by domain or submitter."
|
search_help_text = "Search by domain or submitter."
|
||||||
|
|
||||||
# Detail view
|
# Detail view
|
||||||
|
form = DomainApplicationAdminForm
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None, {"fields": ["status", "investigator", "creator"]}),
|
(None, {"fields": ["status", "investigator", "creator"]}),
|
||||||
(
|
(
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django.urls import reverse
|
||||||
from registrar.admin import (
|
from registrar.admin import (
|
||||||
DomainAdmin,
|
DomainAdmin,
|
||||||
DomainApplicationAdmin,
|
DomainApplicationAdmin,
|
||||||
|
DomainApplicationAdminForm,
|
||||||
ListHeaderAdmin,
|
ListHeaderAdmin,
|
||||||
MyUserAdmin,
|
MyUserAdmin,
|
||||||
AuditedAdmin,
|
AuditedAdmin,
|
||||||
|
@ -92,6 +93,48 @@ class TestDomainAdmin(TestCase):
|
||||||
User.objects.all().delete()
|
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):
|
class TestDomainApplicationAdmin(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.site = AdminSite()
|
self.site = AdminSite()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue