mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-07-13 22:45:05 +02:00
Renaming files, lots and lots of find-replace (with manual, step-through inspections where needed). Still IN PROGRESS and I'm sure there are breakages that need repair at this stage...
This commit is contained in:
parent
0ce03d21c7
commit
0eafad3fb6
65 changed files with 1069 additions and 1070 deletions
4
.github/ISSUE_TEMPLATE/bug.yml
vendored
4
.github/ISSUE_TEMPLATE/bug.yml
vendored
|
@ -33,8 +33,8 @@ body:
|
|||
How can the issue be reliably reproduced? Feel free to include screenshots or other supporting artifacts
|
||||
|
||||
Example:
|
||||
1. In the test environment, fill out the application for a new domain
|
||||
2. Click the button to trigger a save/submit on the final page and complete the application
|
||||
1. In the test environment, fill out the domain request for a new domain
|
||||
2. Click the button to trigger a save/submit on the final page and complete the domain request
|
||||
3. See the error
|
||||
value: |
|
||||
1.
|
||||
|
|
|
@ -15,7 +15,7 @@ rules in the application code that control what changes are permitted to the
|
|||
statuses are called “domain logic”.
|
||||
|
||||
In a large piece of software, domain logic often spreads around the code base
|
||||
because while handling a single request like “mark this application as
|
||||
because while handling a single request like “mark this domain request as
|
||||
approved”, requirements can be enforced at many different points during the
|
||||
process.
|
||||
|
||||
|
@ -28,7 +28,7 @@ states and can change states (or “transition”) according to fixed rules.
|
|||
We will use the django-fsm library to represent the status of our domain
|
||||
registration applications as a finite state machine. The library allows us to
|
||||
list what statuses are possible and describe which state transitions are
|
||||
possible (e.g. Can an approved application ever be marked as “in-process”?).
|
||||
possible (e.g. Can an approved domain request ever be marked as “in-process”?).
|
||||
|
||||
## Consequences
|
||||
|
||||
|
|
|
@ -8,11 +8,11 @@ Accepted
|
|||
|
||||
## Context
|
||||
|
||||
The application form by which registrants apply for a .gov domain is presented over many pages.
|
||||
The domain request form by which registrants apply for a .gov domain is presented over many pages.
|
||||
|
||||
Because we use server-side rendering, each page of the application is a unique HTML page with form fields surrounded by a form tag.
|
||||
Because we use server-side rendering, each page of the domain request is a unique HTML page with form fields surrounded by a form tag.
|
||||
|
||||
Needing a way to coordinate state between the pages as a user fills in their application, we initially used the Form wizard from [django-formtools](https://django-formtools.readthedocs.io/en/latest/wizard.html). This eventually proved unworkable due to the lack of native ability to have more than one Django form object displayed on a single HTML page.
|
||||
Needing a way to coordinate state between the pages as a user fills in their domain request, we initially used the Form wizard from [django-formtools](https://django-formtools.readthedocs.io/en/latest/wizard.html). This eventually proved unworkable due to the lack of native ability to have more than one Django form object displayed on a single HTML page.
|
||||
|
||||
However, a significant portion of the user workflow had already been coded, so it seemed prudent to port some of the formtools logic into our codebase.
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ Approved
|
|||
## Context
|
||||
|
||||
Our application needs to be able to send email to applicants for various
|
||||
purposes including notifying them that their application has been submitted.
|
||||
purposes including notifying them that their domain request has been submitted.
|
||||
We need infrastructure for programmatically sending email. Amazon Web Services
|
||||
(AWS) provides the Simple Email Service (SES) that can do that. CISA can
|
||||
provide access to AWS SES for our application.
|
||||
|
|
|
@ -8,8 +8,7 @@ Accepted
|
|||
|
||||
## Context
|
||||
|
||||
CISA needs a way to perform administrative actions to manage the new get.gov application as well as the .gov domain
|
||||
application requests submitted. Analysts need to be able to view, review, and approve domain applications. Other
|
||||
CISA needs a way to perform administrative actions to manage the new get.gov application as well as the .gov domain requests submitted. Analysts need to be able to view, review, and approve domain requests. Other
|
||||
dashboard views, reports, searches (with filters and sorting) are also highly desired.
|
||||
|
||||
## Decision
|
||||
|
|
|
@ -12,9 +12,9 @@ Historically, the .gov vendor managed initial identity verification and organiza
|
|||
|
||||
## Considered Options
|
||||
|
||||
**Option 1:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. We would add a page alert informing the user that they cannot submit their application because they have an application in one of these "3" statuses (Submitted, In Review or Action Needed). They would still be able to create and edit new applications, just not submit them. The benefits of this option are that it would allow users to have multiple applications essentially in "draft mode" that are queued up and ready for submission after they are permitted to submit.
|
||||
**Option 1:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. We would add a page alert informing the user that they cannot submit their application because they have a domain request in one of these "3" statuses (Submitted, In Review or Action Needed). They would still be able to create and edit new applications, just not submit them. The benefits of this option are that it would allow users to have multiple applications essentially in "draft mode" that are queued up and ready for submission after they are permitted to submit.
|
||||
|
||||
**Option 2:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. Additionally, we would remove the ability to edit any application with the started/withdrawn/rejected status, or start a new application. The benefit of this option is that a user would not be able to begin an action (submitting an application) that they are not allowed to complete.
|
||||
**Option 2:** Users will not be able to submit any new applications if they have 0 prior approved applications OR prior registered .gov domains. Additionally, we would remove the ability to edit any application with the started/withdrawn/rejected status, or start a new application. The benefit of this option is that a user would not be able to begin an action (submitting a domain request) that they are not allowed to complete.
|
||||
|
||||
## Decision
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ This diagram connects the data models along with various workflow stages.
|
|||
1. The applicant starts the process at `/request` interacting with the
|
||||
`DomainRequest` object.
|
||||
|
||||
2. The analyst approves the application using the `DomainRequest`'s
|
||||
2. The analyst approves the domain request using the `DomainRequest`'s
|
||||
`approve()` method which creates many related objects: `UserDomainRole`,
|
||||
`Domain`, and `DomainInformation`.
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ Get the secrets from Cloud.gov by running `cf env getgov-YOURSANDBOX`. More info
|
|||
The endpoint /admin can be used to view and manage site content, including but not limited to user information and the list of current applications in the database. To be able to view and use /admin locally:
|
||||
|
||||
1. Login via login.gov
|
||||
2. Go to the home page and make sure you can see the part where you can submit an application
|
||||
2. Go to the home page and make sure you can see the part where you can submit a domain request
|
||||
3. Go to /admin and it will tell you that UUID is not authorized, copy that UUID for use in 4
|
||||
4. in src/registrar/fixtures_users.py add to the `ADMINS` list in that file by adding your UUID as your username along with your first and last name. See below:
|
||||
|
||||
|
@ -93,14 +93,14 @@ The endpoint /admin can be used to view and manage site content, including but n
|
|||
]
|
||||
```
|
||||
|
||||
5. In the browser, navigate to /admin. To verify that all is working correctly, under "domain applications" you should see fake domains with various fake statuses.
|
||||
5. In the browser, navigate to /admin. To verify that all is working correctly, under "domain requests" you should see fake domains with various fake statuses.
|
||||
6. Add an optional email key/value pair
|
||||
|
||||
### Adding an Analyst to /admin
|
||||
Analysts are a variant of the admin role with limited permissions. The process for adding an Analyst is much the same as adding an admin:
|
||||
|
||||
1. Login via login.gov (if you already exist as an admin, you will need to create a separate login.gov account for this: i.e. first.last+1@email.com)
|
||||
2. Go to the home page and make sure you can see the part where you can submit an application
|
||||
2. Go to the home page and make sure you can see the part where you can submit a domain request
|
||||
3. Go to /admin and it will tell you that UUID is not authorized, copy that UUID for use in 4 (this will be a different UUID than the one obtained from creating an admin)
|
||||
4. in src/registrar/fixtures_users.py add to the `STAFF` list in that file by adding your UUID as your username along with your first and last name. See below:
|
||||
|
||||
|
@ -145,7 +145,7 @@ You can change the logging verbosity, if needed. Do a web search for "django log
|
|||
|
||||
## Mock data
|
||||
|
||||
[load.py](../../src/registrar/management/commands/load.py) called from docker-compose (locally) and reset-db.yml (upper) loads the fixtures from [fixtures_user.py](../../src/registrar/fixtures_users.py) and [fixtures_applications.py](../../src/registrar/fixtures_applications.py), giving you some test data to play with while developing.
|
||||
[load.py](../../src/registrar/management/commands/load.py) called from docker-compose (locally) and reset-db.yml (upper) loads the fixtures from [fixtures_user.py](../../src/registrar/fixtures_users.py) and [fixtures_domain_requests.py](../../src/registrar/fixtures_domain_requests.py), giving you some test data to play with while developing.
|
||||
|
||||
See the [database-access README](./database-access.md) for information on how to pull data to update these fixtures.
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
## Status Change Approved
|
||||
- Starting Location: Django Admin
|
||||
- Workflow: Analyst Admin
|
||||
- Workflow Step: Click "Domain applications" -> Click an application in a status of "submitted", "In review", "rejected", or "ineligible" -> Click status dropdown -> (select "approved") -> click "Save"
|
||||
- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create an application, then set the status to "approved". This will send you an email.
|
||||
- Workflow Step: Click "domain requests" -> Click a domain request in a status of "submitted", "In review", "rejected", or "ineligible" -> Click status dropdown -> (select "approved") -> click "Save"
|
||||
- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create a domain request, then set the status to "approved". This will send you an email.
|
||||
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/status_change_approved.txt)
|
||||
|
||||
### Status Change Approved Subject
|
||||
|
@ -35,8 +35,8 @@
|
|||
## Status Change Rejected
|
||||
- Starting Location: Django Admin
|
||||
- Workflow: Analyst Admin
|
||||
- Workflow Step: Click "Domain applications" -> Click an application in a status of "In review", or "approved" -> Click status dropdown -> (select "rejected") -> click "Save"
|
||||
- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create an application, then set the status to "in review" (and click save). Then, go back to the same application and set the status to "rejected". This will send you an email.
|
||||
- Workflow Step: Click "domain requests" -> Click a domain request in a status of "In review", or "approved" -> Click status dropdown -> (select "rejected") -> click "Save"
|
||||
- Notes: Note that this will send an email to the submitter (email listed on Your Contact Information). To test this with your own email, you need to create a domain request, then set the status to "in review" (and click save). Then, go back to the same application and set the status to "rejected". This will send you an email.
|
||||
- [Email Content](https://github.com/cisagov/manage.get.gov/blob/main/src/registrar/templates/emails/status_change_rejected.txt)
|
||||
|
||||
### Status Change Rejected Subject
|
||||
|
|
|
@ -114,7 +114,7 @@ that can be used for specific tasks.
|
|||
## Cloud.gov dashboard
|
||||
|
||||
At <https://dashboard.fr.cloud.gov/applications> there is a list for all of the
|
||||
applications that a Cloud.gov user has access to. Clicking on an application
|
||||
applications that a Cloud.gov user has access to. Clicking on a domain request
|
||||
goes to a screen for that individual application, e.g.
|
||||
<https://dashboard.fr.cloud.gov/applications/2oBn9LBurIXUNpfmtZCQTCHnxUM/53b88024-1492-46aa-8fb6-1429bdb35f95/summary>.
|
||||
On that page is a left-hand link for "Log Stream" e.g.
|
||||
|
|
|
@ -85,15 +85,15 @@ class DomainRequestAdminForm(forms.ModelForm):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
application = kwargs.get("instance")
|
||||
if application and application.pk:
|
||||
current_state = application.status
|
||||
domain_request = kwargs.get("instance")
|
||||
if domain_request and domain_request.pk:
|
||||
current_state = domain_request.status
|
||||
|
||||
# first option in status transitions is current state
|
||||
available_transitions = [(current_state, application.get_status_display())]
|
||||
available_transitions = [(current_state, domain_request.get_status_display())]
|
||||
|
||||
transitions = get_available_FIELD_transitions(
|
||||
application, models.DomainRequest._meta.get_field("status")
|
||||
domain_request, models.DomainRequest._meta.get_field("status")
|
||||
)
|
||||
|
||||
for transition in transitions:
|
||||
|
@ -102,7 +102,7 @@ class DomainRequestAdminForm(forms.ModelForm):
|
|||
# only set the available transitions if the user is not restricted
|
||||
# from editing the domain request; otherwise, the form will be
|
||||
# readonly and the status field will not have a widget
|
||||
if not application.creator.is_restricted():
|
||||
if not domain_request.creator.is_restricted():
|
||||
self.fields["status"].widget.choices = available_transitions
|
||||
|
||||
|
||||
|
@ -867,7 +867,7 @@ class DomainInformationAdmin(ListHeaderAdmin):
|
|||
|
||||
|
||||
class DomainRequestAdmin(ListHeaderAdmin):
|
||||
"""Custom domain applications admin class."""
|
||||
"""Custom domain requests admin class."""
|
||||
|
||||
form = DomainRequestAdminForm
|
||||
|
||||
|
@ -1061,8 +1061,8 @@ class DomainRequestAdmin(ListHeaderAdmin):
|
|||
|
||||
if (
|
||||
obj
|
||||
and original_obj.status == models.DomainRequest.ApplicationStatus.APPROVED
|
||||
and obj.status != models.DomainRequest.ApplicationStatus.APPROVED
|
||||
and original_obj.status == models.DomainRequest.DomainRequestStatus.APPROVED
|
||||
and obj.status != models.DomainRequest.DomainRequestStatus.APPROVED
|
||||
and not obj.domain_is_not_active()
|
||||
):
|
||||
# If an admin tried to set an approved application to
|
||||
|
@ -1082,7 +1082,7 @@ class DomainRequestAdmin(ListHeaderAdmin):
|
|||
|
||||
elif (
|
||||
obj
|
||||
and obj.status == models.DomainRequest.ApplicationStatus.REJECTED
|
||||
and obj.status == models.DomainRequest.DomainRequestStatus.REJECTED
|
||||
and not obj.rejection_reason
|
||||
):
|
||||
# This condition should never be triggered.
|
||||
|
@ -1100,14 +1100,14 @@ class DomainRequestAdmin(ListHeaderAdmin):
|
|||
else:
|
||||
if obj.status != original_obj.status:
|
||||
status_method_mapping = {
|
||||
models.DomainRequest.ApplicationStatus.STARTED: None,
|
||||
models.DomainRequest.ApplicationStatus.SUBMITTED: obj.submit,
|
||||
models.DomainRequest.ApplicationStatus.IN_REVIEW: obj.in_review,
|
||||
models.DomainRequest.ApplicationStatus.ACTION_NEEDED: obj.action_needed,
|
||||
models.DomainRequest.ApplicationStatus.APPROVED: obj.approve,
|
||||
models.DomainRequest.ApplicationStatus.WITHDRAWN: obj.withdraw,
|
||||
models.DomainRequest.ApplicationStatus.REJECTED: obj.reject,
|
||||
models.DomainRequest.ApplicationStatus.INELIGIBLE: (obj.reject_with_prejudice),
|
||||
models.DomainRequest.DomainRequestStatus.STARTED: None,
|
||||
models.DomainRequest.DomainRequestStatus.SUBMITTED: obj.submit,
|
||||
models.DomainRequest.DomainRequestStatus.IN_REVIEW: obj.in_review,
|
||||
models.DomainRequest.DomainRequestStatus.ACTION_NEEDED: obj.action_needed,
|
||||
models.DomainRequest.DomainRequestStatus.APPROVED: obj.approve,
|
||||
models.DomainRequest.DomainRequestStatus.WITHDRAWN: obj.withdraw,
|
||||
models.DomainRequest.DomainRequestStatus.REJECTED: obj.reject,
|
||||
models.DomainRequest.DomainRequestStatus.INELIGIBLE: (obj.reject_with_prejudice),
|
||||
}
|
||||
selected_method = status_method_mapping.get(obj.status)
|
||||
if selected_method is None:
|
||||
|
@ -1158,7 +1158,7 @@ class DomainRequestAdmin(ListHeaderAdmin):
|
|||
if obj and obj.creator.status == models.User.RESTRICTED:
|
||||
messages.warning(
|
||||
request,
|
||||
"Cannot edit an application with a restricted creator.",
|
||||
"Cannot edit a domain request with a restricted creator.",
|
||||
)
|
||||
|
||||
def change_view(self, request, object_id, form_url="", extra_context=None):
|
||||
|
|
|
@ -13,18 +13,18 @@ from registrar import views
|
|||
from registrar.views.admin_views import ExportData
|
||||
|
||||
|
||||
from registrar.views.application import Step
|
||||
from registrar.views.domain_request import Step
|
||||
from registrar.views.utility import always_404
|
||||
from api.views import available, get_current_federal, get_current_full
|
||||
|
||||
|
||||
APPLICATION_NAMESPACE = views.ApplicationWizard.URL_NAMESPACE
|
||||
application_urls = [
|
||||
path("", views.ApplicationWizard.as_view(), name=""),
|
||||
DOMAIN_REQUEST_NAMESPACE = views.DomainRequestWizard.URL_NAMESPACE
|
||||
domain_request_urls = [
|
||||
path("", views.DomainRequestWizard.as_view(), name=""),
|
||||
path("finished/", views.Finished.as_view(), name="finished"),
|
||||
]
|
||||
|
||||
# dynamically generate the other application_urls
|
||||
# dynamically generate the other domain_request_urls
|
||||
for step, view in [
|
||||
# add/remove steps here
|
||||
(Step.ORGANIZATION_TYPE, views.OrganizationType),
|
||||
|
@ -43,7 +43,7 @@ for step, view in [
|
|||
(Step.REQUIREMENTS, views.Requirements),
|
||||
(Step.REVIEW, views.Review),
|
||||
]:
|
||||
application_urls.append(path(f"{step}/", view.as_view(), name=step))
|
||||
domain_request_urls.append(path(f"{step}/", view.as_view(), name=step))
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -56,12 +56,12 @@ urlpatterns = [
|
|||
path("admin/", admin.site.urls),
|
||||
path(
|
||||
"application/<id>/edit/",
|
||||
views.ApplicationWizard.as_view(),
|
||||
name=views.ApplicationWizard.EDIT_URL_NAME,
|
||||
views.DomainRequestWizard.as_view(),
|
||||
name=views.DomainRequestWizard.EDIT_URL_NAME,
|
||||
),
|
||||
path(
|
||||
"application/<int:pk>",
|
||||
views.ApplicationStatus.as_view(),
|
||||
views.DomainRequestStatus.as_view(),
|
||||
name="application-status",
|
||||
),
|
||||
path(
|
||||
|
@ -76,7 +76,7 @@ urlpatterns = [
|
|||
),
|
||||
path("health", views.health, name="health"),
|
||||
path("openid/", include("djangooidc.urls")),
|
||||
path("request/", include((application_urls, APPLICATION_NAMESPACE))),
|
||||
path("request/", include((domain_request_urls, DOMAIN_REQUEST_NAMESPACE))),
|
||||
path("api/v1/available/", available, name="available"),
|
||||
path("api/v1/get-report/current-federal", get_current_federal, name="get-current-federal"),
|
||||
path("api/v1/get-report/current-full", get_current_full, name="get-current-full"),
|
||||
|
|
|
@ -16,7 +16,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class DomainRequestFixture:
|
||||
"""
|
||||
Load domain applications into the database.
|
||||
Load domain requests into the database.
|
||||
|
||||
Make sure this class' `load` method is called from `handle`
|
||||
in management/commands/load.py, then use `./manage.py load`
|
||||
|
@ -49,27 +49,27 @@ class DomainRequestFixture:
|
|||
# },
|
||||
DA = [
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.STARTED,
|
||||
"status": DomainRequest.DomainRequestStatus.STARTED,
|
||||
"organization_name": "Example - Finished but not submitted",
|
||||
},
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.SUBMITTED,
|
||||
"status": DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
"organization_name": "Example - Submitted but pending investigation",
|
||||
},
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.IN_REVIEW,
|
||||
"status": DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||
"organization_name": "Example - In investigation",
|
||||
},
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.IN_REVIEW,
|
||||
"status": DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||
"organization_name": "Example - Approved",
|
||||
},
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.WITHDRAWN,
|
||||
"status": DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||
"organization_name": "Example - Withdrawn",
|
||||
},
|
||||
{
|
||||
"status": DomainRequest.ApplicationStatus.ACTION_NEEDED,
|
||||
"status": DomainRequest.DomainRequestStatus.ACTION_NEEDED,
|
||||
"organization_name": "Example - Action needed",
|
||||
},
|
||||
{
|
||||
|
@ -176,8 +176,8 @@ class DomainRequestFixture:
|
|||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
"""Creates domain applications for each user in the database."""
|
||||
logger.info("Going to load %s domain applications" % len(cls.DA))
|
||||
"""Creates domain requests for each user in the database."""
|
||||
logger.info("Going to load %s domain requests" % len(cls.DA))
|
||||
try:
|
||||
users = list(User.objects.all()) # force evaluation to catch db errors
|
||||
except Exception as e:
|
||||
|
@ -185,7 +185,7 @@ class DomainRequestFixture:
|
|||
return
|
||||
|
||||
for user in users:
|
||||
logger.debug("Loading domain applications for %s" % user)
|
||||
logger.debug("Loading domain requests for %s" % user)
|
||||
for app in cls.DA:
|
||||
try:
|
||||
da, _ = DomainRequest.objects.get_or_create(
|
||||
|
@ -213,12 +213,12 @@ class DomainFixture(DomainRequestFixture):
|
|||
|
||||
for user in users:
|
||||
# approve one of each users in review status domains
|
||||
application = DomainRequest.objects.filter(
|
||||
creator=user, status=DomainRequest.ApplicationStatus.IN_REVIEW
|
||||
domain_request = DomainRequest.objects.filter(
|
||||
creator=user, status=DomainRequest.DomainRequestStatus.IN_REVIEW
|
||||
).last()
|
||||
logger.debug(f"Approving {application} for {user}")
|
||||
logger.debug(f"Approving {domain_request} for {user}")
|
||||
|
||||
# We don't want fixtures sending out real emails to
|
||||
# fake email addresses, so we just skip that and log it instead
|
||||
application.approve(send_email=False)
|
||||
application.save()
|
||||
domain_request.approve(send_email=False)
|
||||
domain_request.save()
|
|
@ -1,4 +1,4 @@
|
|||
from .application_wizard import *
|
||||
from .domain_request_wizard import *
|
||||
from .domain import (
|
||||
DomainAddUserForm,
|
||||
NameserverFormset,
|
||||
|
|
|
@ -29,8 +29,8 @@ class RegistrarForm(forms.Form):
|
|||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault("label_suffix", "")
|
||||
# save a reference to an application object
|
||||
self.application = kwargs.pop("application", None)
|
||||
# save a reference to a domain request object
|
||||
self.domain_request = kwargs.pop("domain_request", None)
|
||||
super(RegistrarForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def to_database(self, obj: DomainRequest | Contact):
|
||||
|
@ -61,8 +61,8 @@ class RegistrarFormSet(forms.BaseFormSet):
|
|||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# save a reference to an application object
|
||||
self.application = kwargs.pop("application", None)
|
||||
# save a reference to an domain_request object
|
||||
self.domain_request = kwargs.pop("domain_request", None)
|
||||
super(RegistrarFormSet, self).__init__(*args, **kwargs)
|
||||
# quick workaround to ensure that the HTML `required`
|
||||
# attribute shows up on required fields for any forms
|
||||
|
@ -137,14 +137,14 @@ class RegistrarFormSet(forms.BaseFormSet):
|
|||
if should_delete(cleaned):
|
||||
if hasattr(db_obj, "has_more_than_one_join") and db_obj.has_more_than_one_join(related_name):
|
||||
# Remove the specific relationship without deleting the object
|
||||
getattr(db_obj, related_name).remove(self.application)
|
||||
getattr(db_obj, related_name).remove(self.domain_request)
|
||||
else:
|
||||
# If there are no other relationships, delete the object
|
||||
db_obj.delete()
|
||||
else:
|
||||
if hasattr(db_obj, "has_more_than_one_join") and db_obj.has_more_than_one_join(related_name):
|
||||
# create a new db_obj and disconnect existing one
|
||||
getattr(db_obj, related_name).remove(self.application)
|
||||
getattr(db_obj, related_name).remove(self.domain_request)
|
||||
kwargs = pre_create(db_obj, cleaned)
|
||||
getattr(obj, join).create(**kwargs)
|
||||
else:
|
||||
|
@ -170,7 +170,7 @@ class RegistrarFormSet(forms.BaseFormSet):
|
|||
|
||||
class OrganizationTypeForm(RegistrarForm):
|
||||
organization_type = forms.ChoiceField(
|
||||
# use the long names in the application form
|
||||
# use the long names in the domain request form
|
||||
choices=DomainRequest.OrganizationChoicesVerbose.choices,
|
||||
widget=forms.RadioSelect,
|
||||
error_messages={"required": "Select the type of organization you represent."},
|
||||
|
@ -201,7 +201,7 @@ class TribalGovernmentForm(RegistrarForm):
|
|||
# into a link. There should be no user-facing input in the
|
||||
# HTML indicated here.
|
||||
mark_safe( # nosec
|
||||
"You can’t complete this application yet. "
|
||||
"You can’t complete this domain request yet. "
|
||||
"Only tribes recognized by the U.S. federal government "
|
||||
"or by a U.S. state government are eligible for .gov "
|
||||
'domains. Use our <a href="{}">contact form</a> to '
|
||||
|
@ -294,8 +294,8 @@ class OrganizationContactForm(RegistrarForm):
|
|||
def clean_federal_agency(self):
|
||||
"""Require something to be selected when this is a federal agency."""
|
||||
federal_agency = self.cleaned_data.get("federal_agency", None)
|
||||
# need the application object to know if this is federal
|
||||
if self.application is None:
|
||||
# need the domain request object to know if this is federal
|
||||
if self.domain_request is None:
|
||||
# hmm, no saved application object?, default require the agency
|
||||
if not federal_agency:
|
||||
# no answer was selected
|
||||
|
@ -303,7 +303,7 @@ class OrganizationContactForm(RegistrarForm):
|
|||
"Select the federal agency your organization is in.",
|
||||
code="required",
|
||||
)
|
||||
if self.application.is_federal():
|
||||
if self.domain_request.is_federal():
|
||||
if not federal_agency:
|
||||
# no answer was selected
|
||||
raise forms.ValidationError(
|
||||
|
@ -530,7 +530,7 @@ class YourContactForm(RegistrarForm):
|
|||
if not self.is_valid():
|
||||
return
|
||||
contact = getattr(obj, "submitter", None)
|
||||
if contact is not None and not contact.has_more_than_one_join("submitted_applications"):
|
||||
if contact is not None and not contact.has_more_than_one_join("submitted_domain_requests"):
|
||||
# if contact exists in the database and is not joined to other entities
|
||||
super().to_database(contact)
|
||||
else:
|
||||
|
@ -579,9 +579,9 @@ class OtherContactsYesNoForm(RegistrarForm):
|
|||
"""Extend the initialization of the form from RegistrarForm __init__"""
|
||||
super().__init__(*args, **kwargs)
|
||||
# set the initial value based on attributes of application
|
||||
if self.application and self.application.has_other_contacts():
|
||||
if self.domain_request and self.domain_request.has_other_contacts():
|
||||
initial_value = True
|
||||
elif self.application and self.application.has_rationale():
|
||||
elif self.domain_request and self.domain_request.has_rationale():
|
||||
initial_value = False
|
||||
else:
|
||||
# No pre-selection for new applications
|
||||
|
@ -687,7 +687,7 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
|
|||
this case, all forms in formset are marked for deletion. Both of these conditions
|
||||
must co-exist.
|
||||
Also, other_contacts have db relationships to multiple db objects. When attempting
|
||||
to delete an other_contact from an application, those db relationships must be
|
||||
to delete an other_contact from a domain request, those db relationships must be
|
||||
tested and handled.
|
||||
"""
|
||||
|
||||
|
@ -701,7 +701,7 @@ class BaseOtherContactsFormSet(RegistrarFormSet):
|
|||
Override __init__ for RegistrarFormSet.
|
||||
"""
|
||||
self.formset_data_marked_for_deletion = False
|
||||
self.application = kwargs.pop("application", None)
|
||||
self.domain_request = kwargs.pop("domain_request", None)
|
||||
super(RegistrarFormSet, self).__init__(*args, **kwargs)
|
||||
# quick workaround to ensure that the HTML `required`
|
||||
# attribute shows up on required fields for the first form
|
|
@ -5,7 +5,7 @@ from auditlog.context import disable_auditlog # type: ignore
|
|||
|
||||
|
||||
from registrar.fixtures_users import UserFixture
|
||||
from registrar.fixtures_applications import DomainRequestFixture, DomainFixture
|
||||
from registrar.fixtures_domain_requests import DomainRequestFixture, DomainFixture
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class DomainInformation(TimeStampedModel):
|
|||
DomainRequest. We use these field from DomainRequest with few exceptions
|
||||
which are 'removed' via pop at the bottom of this file. Most of design for domain
|
||||
management's user information are based on application, but we cannot change
|
||||
the application once approved, so copying them that way we can make changes
|
||||
the domain request once approved, so copying them that way we can make changes
|
||||
after its approved. Most fields here are copied from Application."""
|
||||
|
||||
StateTerritoryChoices = DomainRequest.StateTerritoryChoices
|
||||
|
@ -30,7 +30,7 @@ class DomainInformation(TimeStampedModel):
|
|||
|
||||
AGENCY_CHOICES = DomainRequest.AGENCY_CHOICES
|
||||
|
||||
# This is the application user who created this application. The contact
|
||||
# This is the domain request user who created this domain request. The contact
|
||||
# information that they gave is in the `submitter` field
|
||||
creator = models.ForeignKey(
|
||||
"registrar.User",
|
||||
|
@ -169,7 +169,7 @@ class DomainInformation(TimeStampedModel):
|
|||
"registrar.Contact",
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="submitted_applications_information",
|
||||
related_name="submitted_domain_requests_information",
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
|
||||
|
@ -182,7 +182,7 @@ class DomainInformation(TimeStampedModel):
|
|||
other_contacts = models.ManyToManyField(
|
||||
"registrar.Contact",
|
||||
blank=True,
|
||||
related_name="contact_applications_information",
|
||||
related_name="contact_domain_requests_information",
|
||||
verbose_name="contacts",
|
||||
)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class DomainRequest(TimeStampedModel):
|
|||
"""A registrant's application for a new domain."""
|
||||
|
||||
# Constants for choice fields
|
||||
class ApplicationStatus(models.TextChoices):
|
||||
class DomainRequestStatus(models.TextChoices):
|
||||
STARTED = "started", "Started"
|
||||
SUBMITTED = "submitted", "Submitted"
|
||||
IN_REVIEW = "in review", "In review"
|
||||
|
@ -115,7 +115,7 @@ class DomainRequest(TimeStampedModel):
|
|||
class OrganizationChoicesVerbose(models.TextChoices):
|
||||
"""
|
||||
Secondary organization choices
|
||||
For use in the application form and on the templates
|
||||
For use in the domain request form and on the templates
|
||||
Keys need to match OrganizationChoices
|
||||
"""
|
||||
|
||||
|
@ -366,10 +366,10 @@ class DomainRequest(TimeStampedModel):
|
|||
NAMING_REQUIREMENTS = "naming_not_met", "Naming requirements not met"
|
||||
OTHER = "other", "Other/Unspecified"
|
||||
|
||||
# #### Internal fields about the application #####
|
||||
# #### Internal fields about the domain request #####
|
||||
status = FSMField(
|
||||
choices=ApplicationStatus.choices, # possible states as an array of constants
|
||||
default=ApplicationStatus.STARTED, # sensible default
|
||||
choices=DomainRequestStatus.choices, # possible states as an array of constants
|
||||
default=DomainRequestStatus.STARTED, # sensible default
|
||||
protected=False, # can change state directly, particularly in Django admin
|
||||
)
|
||||
|
||||
|
@ -379,7 +379,7 @@ class DomainRequest(TimeStampedModel):
|
|||
blank=True,
|
||||
)
|
||||
|
||||
# This is the application user who created this application. The contact
|
||||
# This is the domain request user who created this domain request. The contact
|
||||
# information that they gave is in the `submitter` field
|
||||
creator = models.ForeignKey(
|
||||
"registrar.User",
|
||||
|
@ -536,7 +536,7 @@ class DomainRequest(TimeStampedModel):
|
|||
"registrar.Contact",
|
||||
null=True,
|
||||
blank=True,
|
||||
related_name="submitted_applications",
|
||||
related_name="submitted_domain_requests",
|
||||
on_delete=models.PROTECT,
|
||||
)
|
||||
|
||||
|
@ -549,7 +549,7 @@ class DomainRequest(TimeStampedModel):
|
|||
other_contacts = models.ManyToManyField(
|
||||
"registrar.Contact",
|
||||
blank=True,
|
||||
related_name="contact_applications",
|
||||
related_name="contact_domain_requests",
|
||||
verbose_name="contacts",
|
||||
)
|
||||
|
||||
|
@ -638,7 +638,7 @@ class DomainRequest(TimeStampedModel):
|
|||
email_template,
|
||||
email_template_subject,
|
||||
self.submitter.email,
|
||||
context={"application": self},
|
||||
context={"domain_request": self},
|
||||
bcc_address=bcc_address,
|
||||
)
|
||||
logger.info(f"The {new_status} email sent to: {self.submitter.email}")
|
||||
|
@ -648,15 +648,15 @@ class DomainRequest(TimeStampedModel):
|
|||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
ApplicationStatus.STARTED,
|
||||
ApplicationStatus.IN_REVIEW,
|
||||
ApplicationStatus.ACTION_NEEDED,
|
||||
ApplicationStatus.WITHDRAWN,
|
||||
DomainRequestStatus.STARTED,
|
||||
DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequestStatus.ACTION_NEEDED,
|
||||
DomainRequestStatus.WITHDRAWN,
|
||||
],
|
||||
target=ApplicationStatus.SUBMITTED,
|
||||
target=DomainRequestStatus.SUBMITTED,
|
||||
)
|
||||
def submit(self):
|
||||
"""Submit an application that is started.
|
||||
"""Submit a domain request that is started.
|
||||
|
||||
As a side effect, an email notification is sent."""
|
||||
|
||||
|
@ -679,7 +679,7 @@ class DomainRequest(TimeStampedModel):
|
|||
self.save()
|
||||
|
||||
# Limit email notifications to transitions from Started and Withdrawn
|
||||
limited_statuses = [self.ApplicationStatus.STARTED, self.ApplicationStatus.WITHDRAWN]
|
||||
limited_statuses = [self.DomainRequestStatus.STARTED, self.DomainRequestStatus.WITHDRAWN]
|
||||
|
||||
bcc_address = ""
|
||||
if settings.IS_PRODUCTION:
|
||||
|
@ -697,17 +697,17 @@ class DomainRequest(TimeStampedModel):
|
|||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
ApplicationStatus.SUBMITTED,
|
||||
ApplicationStatus.ACTION_NEEDED,
|
||||
ApplicationStatus.APPROVED,
|
||||
ApplicationStatus.REJECTED,
|
||||
ApplicationStatus.INELIGIBLE,
|
||||
DomainRequestStatus.SUBMITTED,
|
||||
DomainRequestStatus.ACTION_NEEDED,
|
||||
DomainRequestStatus.APPROVED,
|
||||
DomainRequestStatus.REJECTED,
|
||||
DomainRequestStatus.INELIGIBLE,
|
||||
],
|
||||
target=ApplicationStatus.IN_REVIEW,
|
||||
target=DomainRequestStatus.IN_REVIEW,
|
||||
conditions=[domain_is_not_active],
|
||||
)
|
||||
def in_review(self):
|
||||
"""Investigate an application that has been submitted.
|
||||
"""Investigate a domain request that has been submitted.
|
||||
|
||||
This action is logged.
|
||||
|
||||
|
@ -716,13 +716,13 @@ class DomainRequest(TimeStampedModel):
|
|||
As side effects this will delete the domain and domain_information
|
||||
(will cascade) when they exist."""
|
||||
|
||||
if self.status == self.ApplicationStatus.APPROVED:
|
||||
if self.status == self.DomainRequestStatus.APPROVED:
|
||||
self.delete_and_clean_up_domain("in_review")
|
||||
|
||||
if self.status == self.ApplicationStatus.REJECTED:
|
||||
if self.status == self.DomainRequestStatus.REJECTED:
|
||||
self.rejection_reason = None
|
||||
|
||||
literal = DomainRequest.ApplicationStatus.IN_REVIEW
|
||||
literal = DomainRequest.DomainRequestStatus.IN_REVIEW
|
||||
# Check if the tuple exists, then grab its value
|
||||
in_review = literal if literal is not None else "In Review"
|
||||
logger.info(f"A status change occurred. {self} was changed to '{in_review}'")
|
||||
|
@ -730,16 +730,16 @@ class DomainRequest(TimeStampedModel):
|
|||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
ApplicationStatus.IN_REVIEW,
|
||||
ApplicationStatus.APPROVED,
|
||||
ApplicationStatus.REJECTED,
|
||||
ApplicationStatus.INELIGIBLE,
|
||||
DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequestStatus.APPROVED,
|
||||
DomainRequestStatus.REJECTED,
|
||||
DomainRequestStatus.INELIGIBLE,
|
||||
],
|
||||
target=ApplicationStatus.ACTION_NEEDED,
|
||||
target=DomainRequestStatus.ACTION_NEEDED,
|
||||
conditions=[domain_is_not_active],
|
||||
)
|
||||
def action_needed(self):
|
||||
"""Send back an application that is under investigation or rejected.
|
||||
"""Send back a domain request that is under investigation or rejected.
|
||||
|
||||
This action is logged.
|
||||
|
||||
|
@ -748,13 +748,13 @@ class DomainRequest(TimeStampedModel):
|
|||
As side effects this will delete the domain and domain_information
|
||||
(will cascade) when they exist."""
|
||||
|
||||
if self.status == self.ApplicationStatus.APPROVED:
|
||||
if self.status == self.DomainRequestStatus.APPROVED:
|
||||
self.delete_and_clean_up_domain("reject_with_prejudice")
|
||||
|
||||
if self.status == self.ApplicationStatus.REJECTED:
|
||||
if self.status == self.DomainRequestStatus.REJECTED:
|
||||
self.rejection_reason = None
|
||||
|
||||
literal = DomainRequest.ApplicationStatus.ACTION_NEEDED
|
||||
literal = DomainRequest.DomainRequestStatus.ACTION_NEEDED
|
||||
# Check if the tuple is setup correctly, then grab its value
|
||||
action_needed = literal if literal is not None else "Action Needed"
|
||||
logger.info(f"A status change occurred. {self} was changed to '{action_needed}'")
|
||||
|
@ -762,15 +762,15 @@ class DomainRequest(TimeStampedModel):
|
|||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
ApplicationStatus.SUBMITTED,
|
||||
ApplicationStatus.IN_REVIEW,
|
||||
ApplicationStatus.ACTION_NEEDED,
|
||||
ApplicationStatus.REJECTED,
|
||||
DomainRequestStatus.SUBMITTED,
|
||||
DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequestStatus.ACTION_NEEDED,
|
||||
DomainRequestStatus.REJECTED,
|
||||
],
|
||||
target=ApplicationStatus.APPROVED,
|
||||
target=DomainRequestStatus.APPROVED,
|
||||
)
|
||||
def approve(self, send_email=True):
|
||||
"""Approve an application that has been submitted.
|
||||
"""Approve a domain request that has been submitted.
|
||||
|
||||
This action cleans up the rejection status if moving away from rejected.
|
||||
|
||||
|
@ -796,7 +796,7 @@ class DomainRequest(TimeStampedModel):
|
|||
user=self.creator, domain=created_domain, role=UserDomainRole.Roles.MANAGER
|
||||
)
|
||||
|
||||
if self.status == self.ApplicationStatus.REJECTED:
|
||||
if self.status == self.DomainRequestStatus.REJECTED:
|
||||
self.rejection_reason = None
|
||||
|
||||
self._send_status_update_email(
|
||||
|
@ -808,11 +808,11 @@ class DomainRequest(TimeStampedModel):
|
|||
|
||||
@transition(
|
||||
field="status",
|
||||
source=[ApplicationStatus.SUBMITTED, ApplicationStatus.IN_REVIEW, ApplicationStatus.ACTION_NEEDED],
|
||||
target=ApplicationStatus.WITHDRAWN,
|
||||
source=[DomainRequestStatus.SUBMITTED, DomainRequestStatus.IN_REVIEW, DomainRequestStatus.ACTION_NEEDED],
|
||||
target=DomainRequestStatus.WITHDRAWN,
|
||||
)
|
||||
def withdraw(self):
|
||||
"""Withdraw an application that has been submitted."""
|
||||
"""Withdraw a domain request that has been submitted."""
|
||||
|
||||
self._send_status_update_email(
|
||||
"withdraw",
|
||||
|
@ -822,17 +822,17 @@ class DomainRequest(TimeStampedModel):
|
|||
|
||||
@transition(
|
||||
field="status",
|
||||
source=[ApplicationStatus.IN_REVIEW, ApplicationStatus.ACTION_NEEDED, ApplicationStatus.APPROVED],
|
||||
target=ApplicationStatus.REJECTED,
|
||||
source=[DomainRequestStatus.IN_REVIEW, DomainRequestStatus.ACTION_NEEDED, DomainRequestStatus.APPROVED],
|
||||
target=DomainRequestStatus.REJECTED,
|
||||
conditions=[domain_is_not_active],
|
||||
)
|
||||
def reject(self):
|
||||
"""Reject an application that has been submitted.
|
||||
"""Reject a domain request that has been submitted.
|
||||
|
||||
As side effects this will delete the domain and domain_information
|
||||
(will cascade), and send an email notification."""
|
||||
|
||||
if self.status == self.ApplicationStatus.APPROVED:
|
||||
if self.status == self.DomainRequestStatus.APPROVED:
|
||||
self.delete_and_clean_up_domain("reject")
|
||||
|
||||
self._send_status_update_email(
|
||||
|
@ -844,12 +844,12 @@ class DomainRequest(TimeStampedModel):
|
|||
@transition(
|
||||
field="status",
|
||||
source=[
|
||||
ApplicationStatus.IN_REVIEW,
|
||||
ApplicationStatus.ACTION_NEEDED,
|
||||
ApplicationStatus.APPROVED,
|
||||
ApplicationStatus.REJECTED,
|
||||
DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequestStatus.ACTION_NEEDED,
|
||||
DomainRequestStatus.APPROVED,
|
||||
DomainRequestStatus.REJECTED,
|
||||
],
|
||||
target=ApplicationStatus.INELIGIBLE,
|
||||
target=DomainRequestStatus.INELIGIBLE,
|
||||
conditions=[domain_is_not_active],
|
||||
)
|
||||
def reject_with_prejudice(self):
|
||||
|
@ -861,7 +861,7 @@ class DomainRequest(TimeStampedModel):
|
|||
permissions classes test against. This will also delete the domain
|
||||
and domain_information (will cascade) when they exist."""
|
||||
|
||||
if self.status == self.ApplicationStatus.APPROVED:
|
||||
if self.status == self.DomainRequestStatus.APPROVED:
|
||||
self.delete_and_clean_up_domain("reject_with_prejudice")
|
||||
|
||||
self.creator.restrict_user()
|
||||
|
@ -869,7 +869,7 @@ class DomainRequest(TimeStampedModel):
|
|||
# ## Form policies ###
|
||||
#
|
||||
# These methods control what questions need to be answered by applicants
|
||||
# during the application flow. They are policies about the application so
|
||||
# during the domain request flow. They are policies about the domain request so
|
||||
# they appear here.
|
||||
|
||||
def show_organization_federal(self) -> bool:
|
||||
|
@ -905,15 +905,15 @@ class DomainRequest(TimeStampedModel):
|
|||
]
|
||||
|
||||
def has_rationale(self) -> bool:
|
||||
"""Does this application have no_other_contacts_rationale?"""
|
||||
"""Does this domain request have no_other_contacts_rationale?"""
|
||||
return bool(self.no_other_contacts_rationale)
|
||||
|
||||
def has_other_contacts(self) -> bool:
|
||||
"""Does this application have other contacts listed?"""
|
||||
"""Does this domain request have other contacts listed?"""
|
||||
return self.other_contacts.exists()
|
||||
|
||||
def is_federal(self) -> Union[bool, None]:
|
||||
"""Is this application for a federal agency?
|
||||
"""Is this domain request for a federal agency?
|
||||
|
||||
organization_type can be both null and blank,
|
||||
"""
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load static field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load static field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -6,12 +6,12 @@
|
|||
<div class="grid-container">
|
||||
<div class="grid-row grid-gap">
|
||||
<div class="tablet:grid-col-3">
|
||||
{% include 'application_sidebar.html' %}
|
||||
{% include 'domain_request_sidebar.html' %}
|
||||
</div>
|
||||
<div class="tablet:grid-col-9">
|
||||
<main id="main-content" class="grid-container register-form-step">
|
||||
{% if steps.prev %}
|
||||
<a href="{% namespaced_url 'application' steps.prev %}" class="breadcrumb__back">
|
||||
<a href="{% namespaced_url 'domain_request' steps.prev %}" class="breadcrumb__back">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24" height="24">
|
||||
<use xlink:href="{%static 'img/sprite.svg'%}#arrow_back"></use>
|
||||
</svg><span class="margin-left-05">Previous step</span>
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load static field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers url_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load static url_helpers %}
|
||||
{% load custom_filters %}
|
||||
|
||||
|
@ -23,98 +23,98 @@
|
|||
<section class="summary-item margin-top-3">
|
||||
|
||||
{% if step == Step.ORGANIZATION_TYPE %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.organization_type is not None %}
|
||||
{% with title=form_titles|get_item:step value=application.get_organization_type_display|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.organization_type is not None %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.get_organization_type_display|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value="Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.TRIBAL_GOVERNMENT %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.tribe_name|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.tribe_name|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% if application.federally_recognized_tribe %}<p>Federally-recognized tribe</p>{% endif %}
|
||||
{% if application.state_recognized_tribe %}<p>State-recognized tribe</p>{% endif %}
|
||||
{% if domain_request.federally_recognized_tribe %}<p>Federally-recognized tribe</p>{% endif %}
|
||||
{% if domain_request.state_recognized_tribe %}<p>State-recognized tribe</p>{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if step == Step.ORGANIZATION_FEDERAL %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.get_federal_type_display|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.get_federal_type_display|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.ORGANIZATION_ELECTION %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.is_election_board|yesno:"Yes,No,Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.is_election_board|yesno:"Yes,No,Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.ORGANIZATION_CONTACT %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.organization_name %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.organization_name %}
|
||||
{% with title=form_titles|get_item:step value=application %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url address='true' %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url address='true' %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value='Incomplete' %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.ABOUT_YOUR_ORGANIZATION %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.about_your_organization|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.about_your_organization|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.AUTHORIZING_OFFICIAL %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.authorizing_official is not None %}
|
||||
{% with title=form_titles|get_item:step value=application.authorizing_official %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url contact='true' %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.authorizing_official is not None %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.authorizing_official %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value="Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.CURRENT_SITES %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.current_websites.all %}
|
||||
{% with title=form_titles|get_item:step value=application.current_websites.all %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url list='true' %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.current_websites.all %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.current_websites.all %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url list='true' %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value='None' %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.DOTGOV_DOMAIN %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.requested_domain.name|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.requested_domain.name|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
|
||||
{% if application.alternative_domains.all %}
|
||||
{% if domain_request.alternative_domains.all %}
|
||||
<h3 class="register-form-review-header">Alternative domains</h3>
|
||||
<ul class="usa-list usa-list--unstyled margin-top-0">
|
||||
{% for site in application.alternative_domains.all %}
|
||||
{% for site in domain_request.alternative_domains.all %}
|
||||
<li>{{ site.website }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -122,51 +122,51 @@
|
|||
{% endif %}
|
||||
|
||||
{% if step == Step.PURPOSE %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.purpose|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.purpose|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.YOUR_CONTACT %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.submitter is not None %}
|
||||
{% with title=form_titles|get_item:step value=application.submitter %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url contact='true' %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.submitter is not None %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.submitter %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value="Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if step == Step.OTHER_CONTACTS %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% if application.other_contacts.all %}
|
||||
{% with title=form_titles|get_item:step value=application.other_contacts.all %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url contact='true' list='true' %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% if domain_request.other_contacts.all %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.other_contacts.all %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' list='true' %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with title=form_titles|get_item:step value=application.no_other_contacts_rationale|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.no_other_contacts_rationale|default:"Incomplete" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if step == Step.ANYTHING_ELSE %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.anything_else|default:"No" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.anything_else|default:"No" %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if step == Step.REQUIREMENTS %}
|
||||
{% namespaced_url 'application' step as application_url %}
|
||||
{% with title=form_titles|get_item:step value=application.is_policy_acknowledged|yesno:"I agree.,I do not agree.,I do not agree." %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=application_url %}
|
||||
{% namespaced_url 'domain_request' step as domain_request_url %}
|
||||
{% with title=form_titles|get_item:step value=domain_request.is_policy_acknowledged|yesno:"I agree.,I do not agree.,I do not agree." %}
|
||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
</svg>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="{% namespaced_url 'application' this_step %}"
|
||||
<a href="{% namespaced_url 'domain_request' this_step %}"
|
||||
{% if this_step == steps.current %}
|
||||
class="usa-current"
|
||||
{% else %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,4 +1,4 @@
|
|||
{% extends 'application_form.html' %}
|
||||
{% extends 'domain_request_form.html' %}
|
||||
{% load field_helpers %}
|
||||
|
||||
{% block form_instructions %}
|
|
@ -1,10 +1,10 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
Hi, {{ application.submitter.first_name }}.
|
||||
Hi, {{ domain_request.submitter.first_name }}.
|
||||
|
||||
Your .gov domain request has been withdrawn and will not be reviewed by our team.
|
||||
|
||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
|
||||
STATUS: Withdrawn
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
|
|
@ -1 +1 @@
|
|||
Update on your .gov request: {{ application.requested_domain.name }}
|
||||
Update on your .gov request: {{ domain_request.requested_domain.name }}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
SUMMARY OF YOUR DOMAIN REQUEST
|
||||
|
||||
Type of organization:
|
||||
{{ application.get_organization_type_display }}
|
||||
{% if application.show_organization_federal %}
|
||||
{{ domain_request.get_organization_type_display }}
|
||||
{% if domain_request.show_organization_federal %}
|
||||
Federal government branch:
|
||||
{{ application.get_federal_type_display }}
|
||||
{% elif application.show_tribal_government %}
|
||||
{{ domain_request.get_federal_type_display }}
|
||||
{% elif domain_request.show_tribal_government %}
|
||||
Tribal government:
|
||||
{{ application.tribe_name|default:"Incomplete" }}{% if application.federally_recognized_tribe %}
|
||||
{{ domain_request.tribe_name|default:"Incomplete" }}{% if domain_request.federally_recognized_tribe %}
|
||||
Federally-recognized tribe
|
||||
{% endif %}{% if application.state_recognized_tribe %}
|
||||
{% endif %}{% if domain_request.state_recognized_tribe %}
|
||||
State-recognized tribe
|
||||
{% endif %}{% endif %}{% if application.show_organization_election %}
|
||||
{% endif %}{% endif %}{% if domain_request.show_organization_election %}
|
||||
Election office:
|
||||
{{ application.is_election_board|yesno:"Yes,No,Incomplete" }}
|
||||
{{ domain_request.is_election_board|yesno:"Yes,No,Incomplete" }}
|
||||
{% endif %}
|
||||
Organization name and mailing address:
|
||||
{% spaceless %}{{ application.federal_agency }}
|
||||
{{ application.organization_name }}
|
||||
{{ application.address_line1 }}{% if application.address_line2 %}
|
||||
{{ application.address_line2 }}{% endif %}
|
||||
{{ application.city }}, {{ application.state_territory }}
|
||||
{{ application.zipcode }}{% if application.urbanization %}
|
||||
{{ application.urbanization }}{% endif %}{% endspaceless %}
|
||||
{% if application.about_your_organization %}{# if block makes one newline if it's false #}
|
||||
{% spaceless %}{{ domain_request.federal_agency }}
|
||||
{{ domain_request.organization_name }}
|
||||
{{ domain_request.address_line1 }}{% if domain_request.address_line2 %}
|
||||
{{ domain_request.address_line2 }}{% endif %}
|
||||
{{ domain_request.city }}, {{ domain_request.state_territory }}
|
||||
{{ domain_request.zipcode }}{% if domain_request.urbanization %}
|
||||
{{ domain_request.urbanization }}{% endif %}{% endspaceless %}
|
||||
{% if domain_request.about_your_organization %}{# if block makes one newline if it's false #}
|
||||
About your organization:
|
||||
{% spaceless %}{{ application.about_your_organization }}{% endspaceless %}
|
||||
{% spaceless %}{{ domain_request.about_your_organization }}{% endspaceless %}
|
||||
{% endif %}
|
||||
Authorizing official:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.authorizing_official %}{% endspaceless %}
|
||||
{% if application.current_websites.exists %}{# if block makes a newline #}
|
||||
Current websites: {% for site in application.current_websites.all %}
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=domain_request.authorizing_official %}{% endspaceless %}
|
||||
{% if domain_request.current_websites.exists %}{# if block makes a newline #}
|
||||
Current websites: {% for site in domain_request.current_websites.all %}
|
||||
{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}{% endif %}
|
||||
.gov domain:
|
||||
{{ application.requested_domain.name }}
|
||||
{% if application.alternative_domains.all %}
|
||||
{{ domain_request.requested_domain.name }}
|
||||
{% if domain_request.alternative_domains.all %}
|
||||
Alternative domains:
|
||||
{% for site in application.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% for site in domain_request.alternative_domains.all %}{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||
{% endfor %}{% endif %}
|
||||
Purpose of your domain:
|
||||
{{ application.purpose }}
|
||||
{{ domain_request.purpose }}
|
||||
|
||||
Your contact information:
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=application.submitter %}{% endspaceless %}
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=domain_request.submitter %}{% endspaceless %}
|
||||
|
||||
Other employees from your organization:{% for other in application.other_contacts.all %}
|
||||
Other employees from your organization:{% for other in domain_request.other_contacts.all %}
|
||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=other %}{% endspaceless %}
|
||||
{% empty %}
|
||||
{{ application.no_other_contacts_rationale }}
|
||||
{% endfor %}{% if application.anything_else %}
|
||||
{{ domain_request.no_other_contacts_rationale }}
|
||||
{% endfor %}{% if domain_request.anything_else %}
|
||||
Anything else?
|
||||
{{ application.anything_else }}
|
||||
{{ domain_request.anything_else }}
|
||||
{% endif %}
|
|
@ -1,10 +1,10 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
Hi, {{ application.submitter.first_name }}.
|
||||
Hi, {{ domain_request.submitter.first_name }}.
|
||||
|
||||
Congratulations! Your .gov domain request has been approved.
|
||||
|
||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
|
||||
STATUS: Approved
|
||||
|
||||
You can manage your approved domain on the .gov registrar <https://manage.get.gov>.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Update on your .gov request: {{ application.requested_domain.name }}
|
||||
Update on your .gov request: {{ domain_request.requested_domain.name }}
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
Hi, {{ application.submitter.first_name }}.
|
||||
Hi, {{ domain_request.submitter.first_name }}.
|
||||
|
||||
Your .gov domain request has been rejected.
|
||||
|
||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
|
||||
STATUS: Rejected
|
||||
|
||||
----------------------------------------------------------------
|
||||
{% if application.rejection_reason != 'other' %}
|
||||
REJECTION REASON{% endif %}{% if application.rejection_reason == 'purpose_not_met' %}
|
||||
{% if domain_request.rejection_reason != 'other' %}
|
||||
REJECTION REASON{% endif %}{% if domain_request.rejection_reason == 'purpose_not_met' %}
|
||||
Your domain request was rejected because the purpose you provided did not meet our
|
||||
requirements. You didn’t provide enough information about how you intend to use the
|
||||
domain.
|
||||
|
@ -18,16 +18,16 @@ Learn more about:
|
|||
- Eligibility for a .gov domain <https://get.gov/domains/eligibility>
|
||||
- What you can and can’t do with .gov domains <https://get.gov/domains/requirements/>
|
||||
|
||||
If you have questions or comments, reply to this email.{% elif application.rejection_reason == 'requestor_not_eligible' %}
|
||||
If you have questions or comments, reply to this email.{% elif domain_request.rejection_reason == 'requestor_not_eligible' %}
|
||||
Your domain request was rejected because we don’t believe you’re eligible to request a
|
||||
.gov domain on behalf of {{ application.organization_name }}. You must be a government employee, or be
|
||||
.gov domain on behalf of {{ domain_request.organization_name }}. You must be a government employee, or be
|
||||
working on behalf of a government organization, to request a .gov domain.
|
||||
|
||||
|
||||
DEMONSTRATE ELIGIBILITY
|
||||
If you can provide more information that demonstrates your eligibility, or you want to
|
||||
discuss further, reply to this email.{% elif application.rejection_reason == 'org_has_domain' %}
|
||||
Your domain request was rejected because {{ application.organization_name }} has a .gov domain. Our
|
||||
discuss further, reply to this email.{% elif domain_request.rejection_reason == 'org_has_domain' %}
|
||||
Your domain request was rejected because {{ domain_request.organization_name }} has a .gov domain. Our
|
||||
practice is to approve one domain per online service per government organization. We
|
||||
evaluate additional requests on a case-by-case basis. You did not provide sufficient
|
||||
justification for an additional domain.
|
||||
|
@ -35,10 +35,10 @@ justification for an additional domain.
|
|||
Read more about our practice of approving one domain per online service
|
||||
<https://get.gov/domains/before/#one-domain-per-service>.
|
||||
|
||||
If you have questions or comments, reply to this email.{% elif application.rejection_reason == 'contacts_not_verified' %}
|
||||
If you have questions or comments, reply to this email.{% elif domain_request.rejection_reason == 'contacts_not_verified' %}
|
||||
Your domain request was rejected because we could not verify the organizational
|
||||
contacts you provided. If you have questions or comments, reply to this email.{% elif application.rejection_reason == 'org_not_eligible' %}
|
||||
Your domain request was rejected because we determined that {{ application.organization_name }} is not
|
||||
contacts you provided. If you have questions or comments, reply to this email.{% elif domain_request.rejection_reason == 'org_not_eligible' %}
|
||||
Your domain request was rejected because we determined that {{ domain_request.organization_name }} is not
|
||||
eligible for a .gov domain. .Gov domains are only available to official U.S.-based
|
||||
government organizations.
|
||||
|
||||
|
@ -48,7 +48,7 @@ If you can provide documentation that demonstrates your eligibility, reply to th
|
|||
This can include links to (or copies of) your authorizing legislation, your founding
|
||||
charter or bylaws, or other similar documentation. Without this, we can’t approve a
|
||||
.gov domain for your organization. Learn more about eligibility for .gov domains
|
||||
<https://get.gov/domains/eligibility/>.{% elif application.rejection_reason == 'naming_not_met' %}
|
||||
<https://get.gov/domains/eligibility/>.{% elif domain_request.rejection_reason == 'naming_not_met' %}
|
||||
Your domain request was rejected because it does not meet our naming requirements.
|
||||
Domains should uniquely identify a government organization and be clear to the
|
||||
general public. Learn more about naming requirements for your type of organization
|
||||
|
@ -57,7 +57,7 @@ general public. Learn more about naming requirements for your type of organizati
|
|||
|
||||
YOU CAN SUBMIT A NEW REQUEST
|
||||
We encourage you to request a domain that meets our requirements. If you have
|
||||
questions or want to discuss potential domain names, reply to this email.{% elif application.rejection_reason == 'other' %}
|
||||
questions or want to discuss potential domain names, reply to this email.{% elif domain_request.rejection_reason == 'other' %}
|
||||
YOU CAN SUBMIT A NEW REQUEST
|
||||
If your organization is eligible for a .gov domain and you meet our other requirements, you can submit a new request.
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Update on your .gov request: {{ application.requested_domain.name }}
|
||||
Update on your .gov request: {{ domain_request.requested_domain.name }}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{% autoescape off %}{# In a text file, we don't want to have HTML entities escaped #}
|
||||
Hi, {{ application.submitter.first_name }}.
|
||||
Hi, {{ domain_request.submitter.first_name }}.
|
||||
|
||||
We received your .gov domain request.
|
||||
|
||||
DOMAIN REQUESTED: {{ application.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ application.submission_date|date }}
|
||||
DOMAIN REQUESTED: {{ domain_request.requested_domain.name }}
|
||||
REQUEST RECEIVED ON: {{ domain_request.submission_date|date }}
|
||||
STATUS: Submitted
|
||||
|
||||
----------------------------------------------------------------
|
||||
|
@ -29,7 +29,7 @@ THANK YOU
|
|||
|
||||
----------------------------------------------------------------
|
||||
|
||||
{% include 'emails/includes/application_summary.txt' %}
|
||||
{% include 'emails/includes/domain_request_summary.txt' %}
|
||||
----------------------------------------------------------------
|
||||
|
||||
The .gov team
|
||||
|
|
|
@ -1 +1 @@
|
|||
Update on your .gov request: {{ application.requested_domain.name }}
|
||||
Update on your .gov request: {{ domain_request.requested_domain.name }}
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
<th data-sortable scope="col" role="columnheader">Date submitted</th>
|
||||
<th data-sortable scope="col" role="columnheader">Status</th>
|
||||
<th scope="col" role="columnheader"><span class="usa-sr-only">Action</span></th>
|
||||
{% if has_deletable_applications %}
|
||||
{% if has_deletable_domain_requests %}
|
||||
<th scope="col" role="columnheader"><span class="usa-sr-only">Delete Action</span></th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
|
@ -121,52 +121,52 @@
|
|||
{% for application in domain_requests %}
|
||||
<tr>
|
||||
<th th scope="row" role="rowheader" data-label="Domain name">
|
||||
{% if application.requested_domain is None %}
|
||||
{% if domain_request.requested_domain is None %}
|
||||
New domain request
|
||||
{# Add a breakpoint #}
|
||||
<div aria-hidden="true"></div>
|
||||
<span class="text-base font-body-xs">({{ application.created_at }} UTC)</span>
|
||||
<span class="text-base font-body-xs">({{ domain_request.created_at }} UTC)</span>
|
||||
{% else %}
|
||||
{{ application.requested_domain.name }}
|
||||
{{ domain_request.requested_domain.name }}
|
||||
{% endif %}
|
||||
</th>
|
||||
<td data-sort-value="{{ application.submission_date|date:"U" }}" data-label="Date submitted">
|
||||
{% if application.submission_date %}
|
||||
{{ application.submission_date|date }}
|
||||
<td data-sort-value="{{ domain_request.submission_date|date:"U" }}" data-label="Date submitted">
|
||||
{% if domain_request.submission_date %}
|
||||
{{ domain_request.submission_date|date }}
|
||||
{% else %}
|
||||
<span class="text-base">Not submitted</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td data-label="Status">{{ application.get_status_display }}</td>
|
||||
<td data-label="Status">{{ domain_request.get_status_display }}</td>
|
||||
<td>
|
||||
{% with prefix="New domain request ("%}
|
||||
{% with date=application.created_at|date:"DATETIME_FORMAT"%}
|
||||
{% with date=domain_request.created_at|date:"DATETIME_FORMAT"%}
|
||||
{% with name_default=prefix|add:date|add:" UTC)"%}
|
||||
{% if application.status == application.ApplicationStatus.STARTED or application.status == application.ApplicationStatus.ACTION_NEEDED or application.status == application.ApplicationStatus.WITHDRAWN %}
|
||||
<a href="{% url 'edit-application' application.pk %}">
|
||||
{% if domain_request.status == domain_request.DomainRequestStatus.STARTED or domain_request.status == domain_request.DomainRequestStatus.ACTION_NEEDED or domain_request.status == domain_request.DomainRequestStatus.WITHDRAWN %}
|
||||
<a href="{% url 'edit-application' domain_request.pk %}">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
|
||||
<use xlink:href="{%static 'img/sprite.svg'%}#edit"></use>
|
||||
</svg>
|
||||
{% if application.requested_domain is not None%}
|
||||
Edit <span class="usa-sr-only">{{ application.requested_domain.name }}</span>
|
||||
{% if domain_request.requested_domain is not None%}
|
||||
Edit <span class="usa-sr-only">{{ domain_request.requested_domain.name }}</span>
|
||||
{% else %}
|
||||
Edit <span class="usa-sr-only">{{ name_default }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<a href="{% url 'application-status' application.pk %}">
|
||||
<a href="{% url 'application-status' domain_request.pk %}">
|
||||
<svg class="usa-icon" aria-hidden="true" focusable="false" role="img" width="24">
|
||||
<use xlink:href="{%static 'img/sprite.svg'%}#settings"></use>
|
||||
</svg>
|
||||
Manage <span class="usa-sr-only">{{ application.requested_domain.name|default:name_default }}</span>
|
||||
Manage <span class="usa-sr-only">{{ domain_request.requested_domain.name|default:name_default }}</span>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
</a>
|
||||
</td>
|
||||
{% if has_deletable_applications %}
|
||||
{% if has_deletable_domain_requests %}
|
||||
<td>
|
||||
{% if application.status == "started" or application.status == "withdrawn" %}
|
||||
{% if domain_request.status == "started" or domain_request.status == "withdrawn" %}
|
||||
<a
|
||||
role="button"
|
||||
id="button-toggle-delete-domain-alert-{{ forloop.counter }}"
|
||||
|
@ -179,10 +179,10 @@
|
|||
<use xlink:href="{%static 'img/sprite.svg'%}#delete"></use>
|
||||
</svg>
|
||||
{% with prefix="New domain request ("%}
|
||||
{% with date=application.created_at|date:"DATETIME_FORMAT"%}
|
||||
{% with date=domain_request.created_at|date:"DATETIME_FORMAT"%}
|
||||
{% with name_default=prefix|add:date|add:" UTC)"%}
|
||||
{% if application.requested_domain is not None %}
|
||||
Delete <span class="usa-sr-only">{{ application.requested_domain.name }}</span>
|
||||
{% if domain_request.requested_domain is not None %}
|
||||
Delete <span class="usa-sr-only">{{ domain_request.requested_domain.name }}</span>
|
||||
{% else %}
|
||||
Delete <span class="usa-sr-only">{{ name_default }}</span>
|
||||
{% endif %}
|
||||
|
@ -198,11 +198,11 @@
|
|||
aria-describedby="Domain will be removed"
|
||||
data-force-action
|
||||
>
|
||||
<form method="POST" action="{% url "application-delete" pk=application.id %}">
|
||||
{% if application.requested_domain is None %}
|
||||
{% if application.created_at %}
|
||||
<form method="POST" action="{% url "application-delete" pk=domain_request.id %}">
|
||||
{% if domain_request.requested_domain is None %}
|
||||
{% if domain_request.created_at %}
|
||||
{% with prefix="(created " %}
|
||||
{% with formatted_date=application.created_at|date:"DATETIME_FORMAT" %}
|
||||
{% with formatted_date=domain_request.created_at|date:"DATETIME_FORMAT" %}
|
||||
{% with modal_content=prefix|add:formatted_date|add:" UTC)" %}
|
||||
{% include 'includes/modal.html' with modal_heading="Are you sure you want to delete this domain request?" modal_description="This will remove the domain request "|add:modal_content|add:" from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %}
|
||||
{% endwith %}
|
||||
|
@ -212,7 +212,7 @@
|
|||
{% include 'includes/modal.html' with modal_heading="Are you sure you want to delete New domain request?" modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% with modal_heading_value=application.requested_domain.name|add:"?" %}
|
||||
{% with modal_heading_value=domain_request.requested_domain.name|add:"?" %}
|
||||
{% include 'includes/modal.html' with modal_heading="Are you sure you want to delete" heading_value=modal_heading_value modal_description="This will remove the domain request from the .gov registrar. This action cannot be undone." modal_button=modal_button|safe %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
|
|
@ -221,7 +221,7 @@ class AuditedAdminMockData:
|
|||
|
||||
# Constants for different domain object types
|
||||
INFORMATION = "information"
|
||||
APPLICATION = "application"
|
||||
DOMAIN_REQUEST = "domain_request"
|
||||
INVITATION = "invitation"
|
||||
|
||||
def dummy_user(self, item_name, short_hand):
|
||||
|
@ -365,7 +365,7 @@ class AuditedAdminMockData:
|
|||
self,
|
||||
domain_type,
|
||||
item_name,
|
||||
status=DomainRequest.ApplicationStatus.STARTED,
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
org_type="federal",
|
||||
federal_type="executive",
|
||||
purpose="Purpose of the site",
|
||||
|
@ -374,7 +374,7 @@ class AuditedAdminMockData:
|
|||
Returns a prebuilt kwarg dictionary for DomainRequest,
|
||||
DomainInformation, or DomainInvitation.
|
||||
Args:
|
||||
domain_type (str): is either 'application', 'information',
|
||||
domain_type (str): is either 'domain_request', 'information',
|
||||
or 'invitation'.
|
||||
|
||||
item_name (str): A shared str value appended to first_name, last_name,
|
||||
|
@ -382,7 +382,7 @@ class AuditedAdminMockData:
|
|||
title, email, and username.
|
||||
|
||||
status (str - optional): Defines the status for DomainRequest,
|
||||
e.g. DomainRequest.ApplicationStatus.STARTED
|
||||
e.g. DomainRequest.DomainRequestStatus.STARTED
|
||||
|
||||
org_type (str - optional): Sets a domains org_type
|
||||
|
||||
|
@ -397,7 +397,7 @@ class AuditedAdminMockData:
|
|||
common_args = self.get_common_domain_arg_dictionary(item_name, org_type, federal_type, purpose)
|
||||
full_arg_dict = None
|
||||
match domain_type:
|
||||
case self.APPLICATION:
|
||||
case self.DOMAIN_REQUEST:
|
||||
full_arg_dict = dict(
|
||||
**common_args,
|
||||
requested_domain=self.dummy_draft_domain(item_name),
|
||||
|
@ -419,22 +419,22 @@ class AuditedAdminMockData:
|
|||
)
|
||||
return full_arg_dict
|
||||
|
||||
def create_full_dummy_domain_request(self, item_name, status=DomainRequest.ApplicationStatus.STARTED):
|
||||
def create_full_dummy_domain_request(self, item_name, status=DomainRequest.DomainRequestStatus.STARTED):
|
||||
"""Creates a dummy domain request object"""
|
||||
domain_request_kwargs = self.dummy_kwarg_boilerplate(self.APPLICATION, item_name, status)
|
||||
application = DomainRequest.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
domain_request_kwargs = self.dummy_kwarg_boilerplate(self.DOMAIN_REQUEST, item_name, status)
|
||||
domain_request = DomainRequest.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
return application
|
||||
|
||||
def create_full_dummy_domain_information(self, item_name, status=DomainRequest.ApplicationStatus.STARTED):
|
||||
def create_full_dummy_domain_information(self, item_name, status=DomainRequest.DomainRequestStatus.STARTED):
|
||||
"""Creates a dummy domain information object"""
|
||||
domain_request_kwargs = self.dummy_kwarg_boilerplate(self.INFORMATION, item_name, status)
|
||||
application = DomainInformation.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
domain_request = DomainInformation.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
return application
|
||||
|
||||
def create_full_dummy_domain_invitation(self, item_name, status=DomainRequest.ApplicationStatus.STARTED):
|
||||
def create_full_dummy_domain_invitation(self, item_name, status=DomainRequest.DomainRequestStatus.STARTED):
|
||||
"""Creates a dummy domain invitation object"""
|
||||
domain_request_kwargs = self.dummy_kwarg_boilerplate(self.INVITATION, item_name, status)
|
||||
application = DomainInvitation.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
domain_request = DomainInvitation.objects.get_or_create(**domain_request_kwargs)[0]
|
||||
|
||||
return application
|
||||
|
||||
|
@ -445,29 +445,29 @@ class AuditedAdminMockData:
|
|||
has_other_contacts=True,
|
||||
has_current_website=True,
|
||||
has_alternative_gov_domain=True,
|
||||
status=DomainRequest.ApplicationStatus.STARTED,
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
):
|
||||
"""A helper to create a dummy domain request object"""
|
||||
application = None
|
||||
domain_request = None
|
||||
match domain_type:
|
||||
case self.APPLICATION:
|
||||
application = self.create_full_dummy_domain_request(item_name, status)
|
||||
case self.DOMAIN_REQUEST:
|
||||
domain_request = self.create_full_dummy_domain_request(item_name, status)
|
||||
case self.INVITATION:
|
||||
application = self.create_full_dummy_domain_invitation(item_name, status)
|
||||
domain_request = self.create_full_dummy_domain_invitation(item_name, status)
|
||||
case self.INFORMATION:
|
||||
application = self.create_full_dummy_domain_information(item_name, status)
|
||||
domain_request = self.create_full_dummy_domain_information(item_name, status)
|
||||
case _:
|
||||
raise ValueError("Invalid domain_type, must conform to given constants")
|
||||
|
||||
if has_other_contacts and domain_type != self.INVITATION:
|
||||
other = self.dummy_contact(item_name, "other")
|
||||
application.other_contacts.add(other)
|
||||
if has_current_website and domain_type == self.APPLICATION:
|
||||
domain_request.other_contacts.add(other)
|
||||
if has_current_website and domain_type == self.DOMAIN_REQUEST:
|
||||
current = self.dummy_current(item_name)
|
||||
application.current_websites.add(current)
|
||||
if has_alternative_gov_domain and domain_type == self.APPLICATION:
|
||||
domain_request.current_websites.add(current)
|
||||
if has_alternative_gov_domain and domain_type == self.DOMAIN_REQUEST:
|
||||
alt = self.dummy_alt(item_name)
|
||||
application.alternative_domains.add(alt)
|
||||
domain_request.alternative_domains.add(alt)
|
||||
|
||||
return application
|
||||
|
||||
|
@ -520,13 +520,13 @@ def create_ready_domain():
|
|||
return domain
|
||||
|
||||
|
||||
def completed_application(
|
||||
def completed_domain_request(
|
||||
has_other_contacts=True,
|
||||
has_current_website=True,
|
||||
has_alternative_gov_domain=True,
|
||||
has_about_your_organization=True,
|
||||
has_anything_else=True,
|
||||
status=DomainRequest.ApplicationStatus.STARTED,
|
||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||
user=False,
|
||||
submitter=False,
|
||||
name="city.gov",
|
||||
|
@ -583,17 +583,17 @@ def completed_application(
|
|||
application, _ = DomainRequest.objects.get_or_create(**domain_request_kwargs)
|
||||
|
||||
if has_other_contacts:
|
||||
application.other_contacts.add(other)
|
||||
domain_request.other_contacts.add(other)
|
||||
if has_current_website:
|
||||
application.current_websites.add(current)
|
||||
domain_request.current_websites.add(current)
|
||||
if has_alternative_gov_domain:
|
||||
application.alternative_domains.add(alt)
|
||||
domain_request.alternative_domains.add(alt)
|
||||
|
||||
return application
|
||||
|
||||
|
||||
def multiple_unalphabetical_domain_objects(
|
||||
domain_type=AuditedAdminMockData.APPLICATION,
|
||||
domain_type=AuditedAdminMockData.DOMAIN_REQUEST,
|
||||
):
|
||||
"""Returns a list of generic domain objects for testing purposes"""
|
||||
applications = []
|
||||
|
@ -602,16 +602,16 @@ def multiple_unalphabetical_domain_objects(
|
|||
|
||||
mock = AuditedAdminMockData()
|
||||
for object_name in list_of_letters:
|
||||
application = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
domain_request = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
applications.append(application)
|
||||
return applications
|
||||
|
||||
|
||||
def generic_domain_object(domain_type, object_name):
|
||||
"""Returns a generic domain object of
|
||||
domain_type 'application', 'information', or 'invitation'"""
|
||||
domain_type 'domain_request', 'information', or 'invitation'"""
|
||||
mock = AuditedAdminMockData()
|
||||
application = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
domain_request = mock.create_full_dummy_domain_object(domain_type, object_name)
|
||||
return application
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ from registrar.models.verified_by_staff import VerifiedByStaff
|
|||
from .common import (
|
||||
MockSESClient,
|
||||
AuditedAdminMockData,
|
||||
completed_application,
|
||||
completed_domain_request,
|
||||
generic_domain_object,
|
||||
less_console_noise,
|
||||
mock_user,
|
||||
|
@ -236,10 +236,10 @@ class TestDomainAdmin(MockEppLib, WebTest):
|
|||
"""
|
||||
with less_console_noise():
|
||||
self.client.force_login(self.superuser)
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
mock_client = MockSESClient()
|
||||
with boto3_mocking.clients.handler_for("sesv2", mock_client):
|
||||
application.approve()
|
||||
domain_request.approve()
|
||||
|
||||
response = self.client.get("/admin/registrar/domain/")
|
||||
|
||||
|
@ -442,12 +442,12 @@ class TestDomainAdmin(MockEppLib, WebTest):
|
|||
class TestDomainRequestAdminForm(TestCase):
|
||||
def setUp(self):
|
||||
# Create a test application with an initial state of started
|
||||
self.application = completed_application()
|
||||
self.domain_request = completed_domain_request()
|
||||
|
||||
def test_form_choices(self):
|
||||
with less_console_noise():
|
||||
# Create a form instance with the test application
|
||||
form = DomainRequestAdminForm(instance=self.application)
|
||||
form = DomainRequestAdminForm(instance=self.domain_request)
|
||||
|
||||
# Verify that the form choices match the available transitions for started
|
||||
expected_choices = [("started", "Started"), ("submitted", "Submitted")]
|
||||
|
@ -471,12 +471,12 @@ class TestDomainRequestAdminForm(TestCase):
|
|||
def test_form_choices_when_ineligible(self):
|
||||
with less_console_noise():
|
||||
# Create a form instance with a domain request with ineligible status
|
||||
ineligible_application = DomainRequest(status="ineligible")
|
||||
ineligible_domain_request = DomainRequest(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 = DomainRequestAdminForm(instance=ineligible_application)
|
||||
form = DomainRequestAdminForm(instance=ineligible_domain_request)
|
||||
|
||||
self.assertEqual(
|
||||
form.fields["status"].widget.choices,
|
||||
|
@ -509,7 +509,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
multiple_unalphabetical_domain_objects("application")
|
||||
multiple_unalphabetical_domain_objects("domain_request")
|
||||
|
||||
# Assert that our sort works correctly
|
||||
self.test_helper.assert_table_sorted("1", ("requested_domain__name",))
|
||||
|
@ -523,10 +523,10 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
multiple_unalphabetical_domain_objects("application")
|
||||
multiple_unalphabetical_domain_objects("domain_request")
|
||||
|
||||
additional_application = generic_domain_object("application", "Xylophone")
|
||||
new_user = User.objects.filter(username=additional_application.investigator.username).get()
|
||||
additional_domain_request = generic_domain_object("domain_request", "Xylophone")
|
||||
new_user = User.objects.filter(username=additional_domain_request.investigator.username).get()
|
||||
new_user.first_name = "Xylophonic"
|
||||
new_user.save()
|
||||
|
||||
|
@ -554,9 +554,9 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
p = "adminpass"
|
||||
self.client.login(username="superuser", password=p)
|
||||
|
||||
multiple_unalphabetical_domain_objects("application")
|
||||
additional_application = generic_domain_object("application", "Xylophone")
|
||||
new_user = User.objects.filter(username=additional_application.investigator.username).get()
|
||||
multiple_unalphabetical_domain_objects("domain_request")
|
||||
additional_domain_request = generic_domain_object("domain_request", "Xylophone")
|
||||
new_user = User.objects.filter(username=additional_domain_request.investigator.username).get()
|
||||
new_user.first_name = "Xylophonic"
|
||||
new_user.save()
|
||||
|
||||
|
@ -578,13 +578,13 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
),
|
||||
)
|
||||
|
||||
def test_short_org_name_in_applications_list(self):
|
||||
def test_short_org_name_in_domain_requests_list(self):
|
||||
"""
|
||||
Make sure the short name is displaying in admin on the list page
|
||||
"""
|
||||
with less_console_noise():
|
||||
self.client.force_login(self.superuser)
|
||||
completed_application()
|
||||
completed_domain_request()
|
||||
response = self.client.get("/admin/registrar/DomainRequest/")
|
||||
# There are 4 template references to Federal (4) plus two references in the table
|
||||
# for our actual application
|
||||
|
@ -594,20 +594,20 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
# Now let's make sure the long description does not exist
|
||||
self.assertNotContains(response, "Federal: an agency of the U.S. government")
|
||||
|
||||
def transition_state_and_send_email(self, application, status, rejection_reason=None):
|
||||
def transition_state_and_send_email(self, domain_request, status, rejection_reason=None):
|
||||
"""Helper method for the email test cases."""
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
|
||||
# Modify the application's properties
|
||||
application.status = status
|
||||
application.rejection_reason = rejection_reason
|
||||
# Modify the domain request's properties
|
||||
domain_request.status = status
|
||||
domain_request.rejection_reason = rejection_reason
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
self.admin.save_model(request, domain_request, form=None, change=True)
|
||||
|
||||
def assert_email_is_accurate(
|
||||
self, expected_string, email_index, email_address, test_that_no_bcc=False, bcc_email_address=""
|
||||
|
@ -658,42 +658,42 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application()
|
||||
domain_request = completed_domain_request()
|
||||
|
||||
# Test Submitted Status from started
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, True)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.WITHDRAWN)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.WITHDRAWN)
|
||||
self.assert_email_is_accurate(
|
||||
"Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, EMAIL, True
|
||||
)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (from withdrawn)
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to IN_REVIEW
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Test Submitted Status Again from in IN_REVIEW, no new email should be sent
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to IN_REVIEW
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to ACTION_NEEDED
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Test Submitted Status Again from in ACTION_NEEDED, no new email should be sent
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
@override_settings(IS_PRODUCTION=True)
|
||||
|
@ -715,43 +715,43 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
BCC_EMAIL = settings.DEFAULT_FROM_EMAIL
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application()
|
||||
domain_request = completed_domain_request()
|
||||
|
||||
# Test Submitted Status from started
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, False, BCC_EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.WITHDRAWN)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.WITHDRAWN)
|
||||
self.assert_email_is_accurate(
|
||||
"Your .gov domain request has been withdrawn and will not be reviewed by our team.", 1, EMAIL
|
||||
)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (from withdrawn)
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 0, EMAIL, False, BCC_EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to IN_REVIEW
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Test Submitted Status Again from in IN_REVIEW, no new email should be sent
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to IN_REVIEW
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Move it to ACTION_NEEDED
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
# Test Submitted Status Again from in ACTION_NEEDED, no new email should be sent
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
def test_save_model_sends_approved_email(self):
|
||||
|
@ -764,24 +764,24 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 0, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.DOMAIN_PURPOSE,
|
||||
)
|
||||
self.assert_email_is_accurate("Your .gov domain request has been rejected.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
def test_save_model_sends_rejected_email_purpose_not_met(self):
|
||||
|
@ -794,12 +794,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason DOMAIN_PURPOSE and test email
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.DOMAIN_PURPOSE,
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
|
@ -810,7 +810,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -824,11 +824,11 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason REQUESTOR and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application, DomainRequest.ApplicationStatus.REJECTED, DomainRequest.RejectionReasons.REQUESTOR
|
||||
application, DomainRequest.DomainRequestStatus.REJECTED, DomainRequest.RejectionReasons.REQUESTOR
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
"Your domain request was rejected because we don’t believe you’re eligible to request a \n.gov "
|
||||
|
@ -839,7 +839,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -853,12 +853,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason SECOND_DOMAIN_REASONING and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.SECOND_DOMAIN_REASONING,
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
|
@ -867,7 +867,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -881,12 +881,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason CONTACTS_OR_ORGANIZATION_LEGITIMACY and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.CONTACTS_OR_ORGANIZATION_LEGITIMACY,
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
|
@ -898,7 +898,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -912,12 +912,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason ORGANIZATION_ELIGIBILITY and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.ORGANIZATION_ELIGIBILITY,
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
|
@ -929,7 +929,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -943,12 +943,12 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason NAMING_REQUIREMENTS and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.NAMING_REQUIREMENTS,
|
||||
)
|
||||
self.assert_email_is_accurate(
|
||||
|
@ -957,7 +957,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -971,19 +971,19 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Reject for reason NAMING_REQUIREMENTS and test email including dynamic organization name
|
||||
self.transition_state_and_send_email(
|
||||
application,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.OTHER,
|
||||
)
|
||||
self.assert_email_is_accurate("Choosing a .gov domain name", 0, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Approve
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assert_email_is_accurate("Congratulations! Your .gov domain request has been approved.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
|
@ -995,25 +995,25 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"""
|
||||
|
||||
with less_console_noise():
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.APPROVED)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
|
||||
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
request.user = self.superuser
|
||||
|
||||
with ExitStack() as stack:
|
||||
stack.enter_context(patch.object(messages, "error"))
|
||||
application.status = DomainRequest.ApplicationStatus.REJECTED
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.REJECTED
|
||||
|
||||
self.admin.save_model(request, application, None, True)
|
||||
self.admin.save_model(request, domain_request, None, True)
|
||||
|
||||
messages.error.assert_called_once_with(
|
||||
request,
|
||||
"A rejection reason is required.",
|
||||
)
|
||||
|
||||
application.refresh_from_db()
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.APPROVED)
|
||||
domain_request.refresh_from_db()
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
|
||||
def test_transition_to_rejected_with_rejection_reason_does_not_trigger_error(self):
|
||||
"""
|
||||
|
@ -1023,23 +1023,23 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"""
|
||||
|
||||
with less_console_noise():
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.APPROVED)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
|
||||
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
request.user = self.superuser
|
||||
|
||||
with ExitStack() as stack:
|
||||
stack.enter_context(patch.object(messages, "error"))
|
||||
application.status = DomainRequest.ApplicationStatus.REJECTED
|
||||
application.rejection_reason = DomainRequest.RejectionReasons.CONTACTS_OR_ORGANIZATION_LEGITIMACY
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.REJECTED
|
||||
domain_request.rejection_reason = DomainRequest.RejectionReasons.CONTACTS_OR_ORGANIZATION_LEGITIMACY
|
||||
|
||||
self.admin.save_model(request, application, None, True)
|
||||
self.admin.save_model(request, domain_request, None, True)
|
||||
|
||||
messages.error.assert_not_called()
|
||||
|
||||
application.refresh_from_db()
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.REJECTED)
|
||||
domain_request.refresh_from_db()
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.REJECTED)
|
||||
|
||||
def test_save_model_sends_withdrawn_email(self):
|
||||
"""When transitioning to withdrawn on a domain request,
|
||||
|
@ -1051,22 +1051,22 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Test Submitted Status
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.WITHDRAWN)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.WITHDRAWN)
|
||||
self.assert_email_is_accurate(
|
||||
"Your .gov domain request has been withdrawn and will not be reviewed by our team.", 0, EMAIL
|
||||
)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 1)
|
||||
|
||||
# Test Withdrawn Status
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.SUBMITTED)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.SUBMITTED)
|
||||
self.assert_email_is_accurate("We received your .gov domain request.", 1, EMAIL)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 2)
|
||||
|
||||
# Test Submitted Status Again (No new email should be sent)
|
||||
self.transition_state_and_send_email(application, DomainRequest.ApplicationStatus.WITHDRAWN)
|
||||
self.transition_state_and_send_email(application, DomainRequest.DomainRequestStatus.WITHDRAWN)
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||
|
||||
def test_save_model_sets_approved_domain(self):
|
||||
|
@ -1076,20 +1076,20 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
# Modify the application's property
|
||||
application.status = DomainRequest.ApplicationStatus.APPROVED
|
||||
# Modify the domain request's property
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.APPROVED
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
self.admin.save_model(request, domain_request, form=None, change=True)
|
||||
|
||||
# Test that approved domain exists and equals requested domain
|
||||
self.assertEqual(application.requested_domain.name, application.approved_domain.name)
|
||||
self.assertEqual(domain_request.requested_domain.name, domain_request.approved_domain.name)
|
||||
|
||||
def test_save_model_sets_restricted_status_on_user(self):
|
||||
with less_console_noise():
|
||||
|
@ -1098,32 +1098,32 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
User.objects.filter(email=EMAIL).delete()
|
||||
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
# Modify the application's property
|
||||
application.status = DomainRequest.ApplicationStatus.INELIGIBLE
|
||||
# Modify the domain request's property
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.INELIGIBLE
|
||||
|
||||
# Use the model admin's save_model method
|
||||
self.admin.save_model(request, application, form=None, change=True)
|
||||
self.admin.save_model(request, domain_request, form=None, change=True)
|
||||
|
||||
# Test that approved domain exists and equals requested domain
|
||||
self.assertEqual(application.creator.status, "restricted")
|
||||
self.assertEqual(domain_request.creator.status, "restricted")
|
||||
|
||||
def test_readonly_when_restricted_creator(self):
|
||||
with less_console_noise():
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.creator.status = User.RESTRICTED
|
||||
application.creator.save()
|
||||
domain_request.creator.status = User.RESTRICTED
|
||||
domain_request.creator.save()
|
||||
|
||||
request = self.factory.get("/")
|
||||
request.user = self.superuser
|
||||
|
||||
readonly_fields = self.admin.get_readonly_fields(request, application)
|
||||
readonly_fields = self.admin.get_readonly_fields(request, domain_request)
|
||||
|
||||
expected_fields = [
|
||||
"id",
|
||||
|
@ -1201,10 +1201,10 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
def test_saving_when_restricted_creator(self):
|
||||
with less_console_noise():
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.creator.status = User.RESTRICTED
|
||||
application.creator.save()
|
||||
domain_request.creator.status = User.RESTRICTED
|
||||
domain_request.creator.save()
|
||||
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.get("/")
|
||||
|
@ -1212,7 +1212,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
with patch("django.contrib.messages.error") as mock_error:
|
||||
# Simulate saving the model
|
||||
self.admin.save_model(request, application, None, False)
|
||||
self.admin.save_model(request, domain_request, None, False)
|
||||
|
||||
# Assert that the error message was called with the correct argument
|
||||
mock_error.assert_called_once_with(
|
||||
|
@ -1221,27 +1221,27 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
)
|
||||
|
||||
# Assert that the status has not changed
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
def test_change_view_with_restricted_creator(self):
|
||||
with less_console_noise():
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.creator.status = User.RESTRICTED
|
||||
application.creator.save()
|
||||
domain_request.creator.status = User.RESTRICTED
|
||||
domain_request.creator.save()
|
||||
|
||||
with patch("django.contrib.messages.warning") as mock_warning:
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.get("/admin/your_app/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.get("/admin/your_app/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
request.user = self.superuser
|
||||
|
||||
self.admin.display_restricted_warning(request, application)
|
||||
self.admin.display_restricted_warning(request, domain_request)
|
||||
|
||||
# Assert that the error message was called with the correct argument
|
||||
mock_warning.assert_called_once_with(
|
||||
request,
|
||||
"Cannot edit an application with a restricted creator.",
|
||||
"Cannot edit a domain request with a restricted creator.",
|
||||
)
|
||||
|
||||
def trigger_saving_approved_to_another_state(self, domain_is_active, another_state, rejection_reason=None):
|
||||
|
@ -1253,14 +1253,14 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
with less_console_noise():
|
||||
# Create an instance of the model
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.APPROVED)
|
||||
domain = Domain.objects.create(name=application.requested_domain.name)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
|
||||
domain = Domain.objects.create(name=domain_request.requested_domain.name)
|
||||
domain_information = DomainInformation.objects.create(creator=self.superuser, domain=domain)
|
||||
application.approved_domain = domain
|
||||
application.save()
|
||||
domain_request.approved_domain = domain
|
||||
domain_request.save()
|
||||
|
||||
# Create a request object with a superuser
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
request.user = self.superuser
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
|
@ -1273,10 +1273,10 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
stack.enter_context(patch.object(Domain, "is_active", custom_is_active))
|
||||
stack.enter_context(patch.object(messages, "error"))
|
||||
|
||||
application.status = another_state
|
||||
application.rejection_reason = rejection_reason
|
||||
domain_request.status = another_state
|
||||
domain_request.rejection_reason = rejection_reason
|
||||
|
||||
self.admin.save_model(request, application, None, True)
|
||||
self.admin.save_model(request, domain_request, None, True)
|
||||
|
||||
# Assert that the error message was called with the correct argument
|
||||
if domain_is_active:
|
||||
|
@ -1288,7 +1288,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
# Assert that the error message was never called
|
||||
messages.error.assert_not_called()
|
||||
|
||||
self.assertEqual(application.approved_domain, None)
|
||||
self.assertEqual(domain_request.approved_domain, None)
|
||||
|
||||
# Assert that Domain got Deleted
|
||||
with self.assertRaises(Domain.DoesNotExist):
|
||||
|
@ -1299,32 +1299,32 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
domain_information.refresh_from_db()
|
||||
|
||||
def test_error_when_saving_approved_to_in_review_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
def test_error_when_saving_approved_to_action_needed_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
|
||||
def test_error_when_saving_approved_to_rejected_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.ApplicationStatus.REJECTED)
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.DomainRequestStatus.REJECTED)
|
||||
|
||||
def test_error_when_saving_approved_to_ineligible_and_domain_is_active(self):
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.ApplicationStatus.INELIGIBLE)
|
||||
self.trigger_saving_approved_to_another_state(True, DomainRequest.DomainRequestStatus.INELIGIBLE)
|
||||
|
||||
def test_side_effects_when_saving_approved_to_in_review(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
|
||||
def test_side_effects_when_saving_approved_to_action_needed(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
|
||||
def test_side_effects_when_saving_approved_to_rejected(self):
|
||||
self.trigger_saving_approved_to_another_state(
|
||||
False,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.RejectionReasons.CONTACTS_OR_ORGANIZATION_LEGITIMACY,
|
||||
)
|
||||
|
||||
def test_side_effects_when_saving_approved_to_ineligible(self):
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.ApplicationStatus.INELIGIBLE)
|
||||
self.trigger_saving_approved_to_another_state(False, DomainRequest.DomainRequestStatus.INELIGIBLE)
|
||||
|
||||
def test_has_correct_filters(self):
|
||||
"""
|
||||
|
@ -1362,7 +1362,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"""
|
||||
with less_console_noise():
|
||||
# Creates a list of DomainRequests in scrambled order
|
||||
multiple_unalphabetical_domain_objects("application")
|
||||
multiple_unalphabetical_domain_objects("domain_request")
|
||||
|
||||
request = self.factory.get("/")
|
||||
request.user = self.superuser
|
||||
|
@ -1395,8 +1395,8 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
with less_console_noise():
|
||||
# Create a mock DomainRequest object, with a fake investigator
|
||||
application: DomainRequest = generic_domain_object("application", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=application.investigator.username).get()
|
||||
application: DomainRequest = generic_domain_object("domain_request", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=domain_request.investigator.username).get()
|
||||
investigator_user.is_staff = True
|
||||
investigator_user.save()
|
||||
|
||||
|
@ -1440,21 +1440,21 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
|
||||
with less_console_noise():
|
||||
# Create a mock DomainRequest object, with a fake investigator
|
||||
application: DomainRequest = generic_domain_object("application", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=application.investigator.username).get()
|
||||
application: DomainRequest = generic_domain_object("domain_request", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=domain_request.investigator.username).get()
|
||||
investigator_user.is_staff = True
|
||||
investigator_user.save()
|
||||
|
||||
# Create a mock DomainRequest object, with a user that is not staff
|
||||
application_2: DomainRequest = generic_domain_object("application", "SomeOtherGuy")
|
||||
investigator_user_2 = User.objects.filter(username=application_2.investigator.username).get()
|
||||
domain_request_2: DomainRequest = generic_domain_object("domain_request", "SomeOtherGuy")
|
||||
investigator_user_2 = User.objects.filter(username=domain_request_2.investigator.username).get()
|
||||
investigator_user_2.is_staff = False
|
||||
investigator_user_2.save()
|
||||
|
||||
p = "userpass"
|
||||
self.client.login(username="staffuser", password=p)
|
||||
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(application.pk))
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(domain_request.pk))
|
||||
|
||||
# Get the actual field from the model's meta information
|
||||
investigator_field = DomainRequest._meta.get_field("investigator")
|
||||
|
@ -1464,18 +1464,18 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
expected_dropdown = list(User.objects.filter(is_staff=True).order_by(*sorted_fields))
|
||||
|
||||
# Grab the current dropdown. We do an API call to autocomplete to get this info.
|
||||
application_queryset = self.admin.formfield_for_foreignkey(investigator_field, request).queryset
|
||||
domain_request_queryset = self.admin.formfield_for_foreignkey(investigator_field, request).queryset
|
||||
user_request = self.factory.post(
|
||||
"/admin/autocomplete/?app_label=registrar&model_name=DomainRequest&field_name=investigator"
|
||||
)
|
||||
user_admin = MyUserAdmin(User, self.site)
|
||||
user_queryset = user_admin.get_search_results(user_request, application_queryset, None)[0]
|
||||
user_queryset = user_admin.get_search_results(user_request, domain_request_queryset, None)[0]
|
||||
current_dropdown = list(user_queryset)
|
||||
|
||||
self.assertEqual(expected_dropdown, current_dropdown)
|
||||
|
||||
# Non staff users should not be in the list
|
||||
self.assertNotIn(application_2, current_dropdown)
|
||||
self.assertNotIn(domain_request_2, current_dropdown)
|
||||
|
||||
def test_investigator_list_is_alphabetically_sorted(self):
|
||||
"""
|
||||
|
@ -1484,19 +1484,19 @@ class TestDomainRequestAdmin(MockEppLib):
|
|||
"""
|
||||
with less_console_noise():
|
||||
# Create a mock DomainRequest object, with a fake investigator
|
||||
application: DomainRequest = generic_domain_object("application", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=application.investigator.username).get()
|
||||
application: DomainRequest = generic_domain_object("domain_request", "SomeGuy")
|
||||
investigator_user = User.objects.filter(username=domain_request.investigator.username).get()
|
||||
investigator_user.is_staff = True
|
||||
investigator_user.save()
|
||||
|
||||
application_2: DomainRequest = generic_domain_object("application", "AGuy")
|
||||
investigator_user_2 = User.objects.filter(username=application_2.investigator.username).get()
|
||||
domain_request_2: DomainRequest = generic_domain_object("domain_request", "AGuy")
|
||||
investigator_user_2 = User.objects.filter(username=domain_request_2.investigator.username).get()
|
||||
investigator_user_2.first_name = "AGuy"
|
||||
investigator_user_2.is_staff = True
|
||||
investigator_user_2.save()
|
||||
|
||||
application_3: DomainRequest = generic_domain_object("application", "FinalGuy")
|
||||
investigator_user_3 = User.objects.filter(username=application_3.investigator.username).get()
|
||||
domain_request_3: DomainRequest = generic_domain_object("domain_request", "FinalGuy")
|
||||
investigator_user_3 = User.objects.filter(username=domain_request_3.investigator.username).get()
|
||||
investigator_user_3.first_name = "FinalGuy"
|
||||
investigator_user_3.is_staff = True
|
||||
investigator_user_3.save()
|
||||
|
@ -1946,18 +1946,18 @@ class AuditedAdminTest(TestCase):
|
|||
def test_alphabetically_sorted_domain_request_investigator(self):
|
||||
"""Tests if the investigator field is alphabetically sorted by mimicking
|
||||
the call event flow"""
|
||||
# Creates multiple domain applications - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("application")
|
||||
# Creates multiple domain requests - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("domain_request")
|
||||
|
||||
# Create a mock request
|
||||
application_request = self.factory.post(
|
||||
domain_request_request = self.factory.post(
|
||||
"/admin/registrar/DomainRequest/{}/change/".format(applications[0].pk)
|
||||
)
|
||||
|
||||
# Get the formfield data from the application page
|
||||
application_admin = AuditedAdmin(DomainRequest, self.site)
|
||||
# Get the formfield data from the domain request page
|
||||
domain_request_admin = AuditedAdmin(DomainRequest, self.site)
|
||||
field = DomainRequest.investigator.field
|
||||
application_queryset = application_admin.formfield_for_foreignkey(field, application_request).queryset
|
||||
domain_request_queryset = domain_request_admin.formfield_for_foreignkey(field, domain_request_request).queryset
|
||||
|
||||
request = self.factory.post(
|
||||
"/admin/autocomplete/?app_label=registrar&model_name=DomainRequest&field_name=investigator"
|
||||
|
@ -1968,7 +1968,7 @@ class AuditedAdminTest(TestCase):
|
|||
|
||||
# Grab the data returned from get search results
|
||||
admin = MyUserAdmin(User, self.site)
|
||||
search_queryset = admin.get_search_results(request, application_queryset, None)[0]
|
||||
search_queryset = admin.get_search_results(request, domain_request_queryset, None)[0]
|
||||
current_sort_order = list(search_queryset)
|
||||
|
||||
self.assertEqual(
|
||||
|
@ -1988,8 +1988,8 @@ class AuditedAdminTest(TestCase):
|
|||
DomainRequest.requested_domain.field,
|
||||
]
|
||||
|
||||
# Creates multiple domain applications - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("application")
|
||||
# Creates multiple domain requests - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("domain_request")
|
||||
|
||||
# Create a mock request
|
||||
request = self.factory.post("/admin/registrar/DomainRequest/{}/change/".format(applications[0].pk))
|
||||
|
@ -2045,7 +2045,7 @@ class AuditedAdminTest(TestCase):
|
|||
(DomainInformation.domain.field, ["name"]),
|
||||
(DomainInformation.domain_request.field, ["requested_domain__name"]),
|
||||
]
|
||||
# Creates multiple domain applications - review status does not matter
|
||||
# Creates multiple domain requests - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("information")
|
||||
|
||||
# Create a mock request
|
||||
|
@ -2100,7 +2100,7 @@ class AuditedAdminTest(TestCase):
|
|||
with less_console_noise():
|
||||
tested_fields = [DomainInvitation.domain.field]
|
||||
|
||||
# Creates multiple domain applications - review status does not matter
|
||||
# Creates multiple domain requests - review status does not matter
|
||||
applications = multiple_unalphabetical_domain_objects("invitation")
|
||||
|
||||
# Create a mock request
|
||||
|
@ -2328,10 +2328,10 @@ class ContactAdminTest(TestCase):
|
|||
contact, _ = Contact.objects.get_or_create(user=self.staffuser)
|
||||
|
||||
# join it to 4 domain requests. The 5th join will be a user.
|
||||
application1 = completed_application(submitter=contact, name="city1.gov")
|
||||
application2 = completed_application(submitter=contact, name="city2.gov")
|
||||
application3 = completed_application(submitter=contact, name="city3.gov")
|
||||
application4 = completed_application(submitter=contact, name="city4.gov")
|
||||
application1 = completed_domain_request(submitter=contact, name="city1.gov")
|
||||
application2 = completed_domain_request(submitter=contact, name="city2.gov")
|
||||
application3 = completed_domain_request(submitter=contact, name="city3.gov")
|
||||
application4 = completed_domain_request(submitter=contact, name="city4.gov")
|
||||
|
||||
with patch("django.contrib.messages.warning") as mock_warning:
|
||||
# Use the test client to simulate the request
|
||||
|
@ -2363,11 +2363,11 @@ class ContactAdminTest(TestCase):
|
|||
# Create an instance of the model
|
||||
# join it to 5 domain requests. The 6th join will be a user.
|
||||
contact, _ = Contact.objects.get_or_create(user=self.staffuser)
|
||||
application1 = completed_application(submitter=contact, name="city1.gov")
|
||||
application2 = completed_application(submitter=contact, name="city2.gov")
|
||||
application3 = completed_application(submitter=contact, name="city3.gov")
|
||||
application4 = completed_application(submitter=contact, name="city4.gov")
|
||||
application5 = completed_application(submitter=contact, name="city5.gov")
|
||||
application1 = completed_domain_request(submitter=contact, name="city1.gov")
|
||||
application2 = completed_domain_request(submitter=contact, name="city2.gov")
|
||||
application3 = completed_domain_request(submitter=contact, name="city3.gov")
|
||||
application4 = completed_domain_request(submitter=contact, name="city4.gov")
|
||||
application5 = completed_domain_request(submitter=contact, name="city5.gov")
|
||||
with patch("django.contrib.messages.warning") as mock_warning:
|
||||
# Use the test client to simulate the request
|
||||
response = self.client.get(reverse("admin:registrar_contact_change", args=[contact.pk]))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from unittest.mock import MagicMock
|
||||
|
||||
from django.test import TestCase
|
||||
from .common import completed_application, less_console_noise
|
||||
from .common import completed_domain_request, less_console_noise
|
||||
|
||||
|
||||
import boto3_mocking # type: ignore
|
||||
|
@ -17,11 +17,11 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation(self):
|
||||
"""Submission confirmation email works."""
|
||||
application = completed_application()
|
||||
domain_request = completed_domain_request()
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
|
||||
# check that an email was sent
|
||||
self.assertTrue(self.mock_client.send_email.called)
|
||||
|
@ -55,10 +55,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_current_website_spacing(self):
|
||||
"""Test line spacing without current_website."""
|
||||
application = completed_application(has_current_website=False)
|
||||
domain_request = completed_domain_request(has_current_website=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertNotIn("Current websites:", body)
|
||||
|
@ -68,10 +68,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_current_website_spacing(self):
|
||||
"""Test line spacing with current_website."""
|
||||
application = completed_application(has_current_website=True)
|
||||
domain_request = completed_domain_request(has_current_website=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertIn("Current websites:", body)
|
||||
|
@ -82,10 +82,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_other_contacts_spacing(self):
|
||||
"""Test line spacing with other contacts."""
|
||||
application = completed_application(has_other_contacts=True)
|
||||
domain_request = completed_domain_request(has_other_contacts=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertIn("Other employees from your organization:", body)
|
||||
|
@ -96,10 +96,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_other_contacts_spacing(self):
|
||||
"""Test line spacing without other contacts."""
|
||||
application = completed_application(has_other_contacts=False)
|
||||
domain_request = completed_domain_request(has_other_contacts=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
# spacing should be right between adjacent elements
|
||||
|
@ -109,10 +109,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_alternative_govdomain_spacing(self):
|
||||
"""Test line spacing with alternative .gov domain."""
|
||||
application = completed_application(has_alternative_gov_domain=True)
|
||||
domain_request = completed_domain_request(has_alternative_gov_domain=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertIn("city1.gov", body)
|
||||
|
@ -122,10 +122,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_alternative_govdomain_spacing(self):
|
||||
"""Test line spacing without alternative .gov domain."""
|
||||
application = completed_application(has_alternative_gov_domain=False)
|
||||
domain_request = completed_domain_request(has_alternative_gov_domain=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertNotIn("city1.gov", body)
|
||||
|
@ -135,10 +135,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_about_your_organization_spacing(self):
|
||||
"""Test line spacing with about your organization."""
|
||||
application = completed_application(has_about_your_organization=True)
|
||||
domain_request = completed_domain_request(has_about_your_organization=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertIn("About your organization:", body)
|
||||
|
@ -148,10 +148,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_about_your_organization_spacing(self):
|
||||
"""Test line spacing without about your organization."""
|
||||
application = completed_application(has_about_your_organization=False)
|
||||
domain_request = completed_domain_request(has_about_your_organization=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertNotIn("About your organization:", body)
|
||||
|
@ -161,10 +161,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_anything_else_spacing(self):
|
||||
"""Test line spacing with anything else."""
|
||||
application = completed_application(has_anything_else=True)
|
||||
domain_request = completed_domain_request(has_anything_else=True)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
# spacing should be right between adjacent elements
|
||||
|
@ -173,10 +173,10 @@ class TestEmails(TestCase):
|
|||
@boto3_mocking.patching
|
||||
def test_submission_confirmation_no_anything_else_spacing(self):
|
||||
"""Test line spacing without anything else."""
|
||||
application = completed_application(has_anything_else=False)
|
||||
domain_request = completed_domain_request(has_anything_else=False)
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client_class):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
_, kwargs = self.mock_client.send_email.call_args
|
||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||
self.assertNotIn("Anything else", body)
|
||||
|
|
|
@ -4,7 +4,7 @@ import json
|
|||
from django.test import TestCase, RequestFactory
|
||||
from api.views import available
|
||||
|
||||
from registrar.forms.application_wizard import (
|
||||
from registrar.forms.domain_request_wizard import (
|
||||
AlternativeDomainForm,
|
||||
CurrentSitesForm,
|
||||
DotGovDomainForm,
|
||||
|
|
|
@ -17,7 +17,7 @@ from registrar.models import (
|
|||
import boto3_mocking
|
||||
from registrar.models.transition_domain import TransitionDomain
|
||||
from registrar.models.verified_by_staff import VerifiedByStaff # type: ignore
|
||||
from .common import MockSESClient, less_console_noise, completed_application
|
||||
from .common import MockSESClient, less_console_noise, completed_domain_request
|
||||
from django_fsm import TransitionNotAllowed
|
||||
|
||||
|
||||
|
@ -27,29 +27,29 @@ from django_fsm import TransitionNotAllowed
|
|||
@boto3_mocking.patching
|
||||
class TestDomainRequest(TestCase):
|
||||
def setUp(self):
|
||||
self.started_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.STARTED, name="started.gov"
|
||||
self.started_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.STARTED, name="started.gov"
|
||||
)
|
||||
self.submitted_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.SUBMITTED, name="submitted.gov"
|
||||
self.submitted_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.SUBMITTED, name="submitted.gov"
|
||||
)
|
||||
self.in_review_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.IN_REVIEW, name="in-review.gov"
|
||||
self.in_review_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.IN_REVIEW, name="in-review.gov"
|
||||
)
|
||||
self.action_needed_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.ACTION_NEEDED, name="action-needed.gov"
|
||||
self.action_needed_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.ACTION_NEEDED, name="action-needed.gov"
|
||||
)
|
||||
self.approved_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.APPROVED, name="approved.gov"
|
||||
self.approved_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.APPROVED, name="approved.gov"
|
||||
)
|
||||
self.withdrawn_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.WITHDRAWN, name="withdrawn.gov"
|
||||
self.withdrawn_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN, name="withdrawn.gov"
|
||||
)
|
||||
self.rejected_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.REJECTED, name="rejected.gov"
|
||||
self.rejected_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.REJECTED, name="rejected.gov"
|
||||
)
|
||||
self.ineligible_application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.INELIGIBLE, name="ineligible.gov"
|
||||
self.ineligible_domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.INELIGIBLE, name="ineligible.gov"
|
||||
)
|
||||
|
||||
self.mock_client = MockSESClient()
|
||||
|
@ -75,8 +75,8 @@ class TestDomainRequest(TestCase):
|
|||
"""Can create with just a creator."""
|
||||
with less_console_noise():
|
||||
user, _ = User.objects.get_or_create(username="testy")
|
||||
application = DomainRequest.objects.create(creator=user)
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.STARTED)
|
||||
domain_request = DomainRequest.objects.create(creator=user)
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.STARTED)
|
||||
|
||||
def test_full_create(self):
|
||||
"""Can create with all fields."""
|
||||
|
@ -86,7 +86,7 @@ class TestDomainRequest(TestCase):
|
|||
com_website, _ = Website.objects.get_or_create(website="igorville.com")
|
||||
gov_website, _ = Website.objects.get_or_create(website="igorville.gov")
|
||||
domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||
application = DomainRequest.objects.create(
|
||||
domain_request = DomainRequest.objects.create(
|
||||
creator=user,
|
||||
investigator=user,
|
||||
organization_type=DomainRequest.OrganizationChoices.FEDERAL,
|
||||
|
@ -104,10 +104,10 @@ class TestDomainRequest(TestCase):
|
|||
anything_else="All of Igorville loves the dotgov program.",
|
||||
is_policy_acknowledged=True,
|
||||
)
|
||||
application.current_websites.add(com_website)
|
||||
application.alternative_domains.add(gov_website)
|
||||
application.other_contacts.add(contact)
|
||||
application.save()
|
||||
domain_request.current_websites.add(com_website)
|
||||
domain_request.alternative_domains.add(gov_website)
|
||||
domain_request.other_contacts.add(contact)
|
||||
domain_request.save()
|
||||
|
||||
def test_domain_info(self):
|
||||
"""Can create domain info with all fields."""
|
||||
|
@ -140,28 +140,28 @@ class TestDomainRequest(TestCase):
|
|||
def test_status_fsm_submit_fail(self):
|
||||
with less_console_noise():
|
||||
user, _ = User.objects.get_or_create(username="testy")
|
||||
application = DomainRequest.objects.create(creator=user)
|
||||
domain_request = DomainRequest.objects.create(creator=user)
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
with self.assertRaises(ValueError):
|
||||
# can't submit an application with a null domain name
|
||||
application.submit()
|
||||
# can't submit a domain request with a null domain name
|
||||
domain_request.submit()
|
||||
|
||||
def test_status_fsm_submit_succeed(self):
|
||||
with less_console_noise():
|
||||
user, _ = User.objects.get_or_create(username="testy")
|
||||
site = DraftDomain.objects.create(name="igorville.gov")
|
||||
application = DomainRequest.objects.create(creator=user, requested_domain=site)
|
||||
domain_request = DomainRequest.objects.create(creator=user, requested_domain=site)
|
||||
|
||||
# no submitter email so this emits a log warning
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
application.submit()
|
||||
self.assertEqual(application.status, application.ApplicationStatus.SUBMITTED)
|
||||
domain_request.submit()
|
||||
self.assertEqual(domain_request.status, domain_request.DomainRequestStatus.SUBMITTED)
|
||||
|
||||
def check_email_sent(self, application, msg, action, expected_count):
|
||||
def check_email_sent(self, domain_request, msg, action, expected_count):
|
||||
"""Check if an email was sent after performing an action."""
|
||||
|
||||
with self.subTest(msg=msg, action=action):
|
||||
|
@ -180,43 +180,43 @@ class TestDomainRequest(TestCase):
|
|||
self.assertEqual(len(sent_emails), expected_count)
|
||||
|
||||
def test_submit_from_started_sends_email(self):
|
||||
msg = "Create an application and submit it and see if email was sent."
|
||||
application = completed_application()
|
||||
msg = "Create a domain request and submit it and see if email was sent."
|
||||
domain_request = completed_domain_request()
|
||||
self.check_email_sent(application, msg, "submit", 1)
|
||||
|
||||
def test_submit_from_withdrawn_sends_email(self):
|
||||
msg = "Create a withdrawn application and submit it and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.WITHDRAWN)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.WITHDRAWN)
|
||||
self.check_email_sent(application, msg, "submit", 1)
|
||||
|
||||
def test_submit_from_action_needed_does_not_send_email(self):
|
||||
msg = "Create an application with ACTION_NEEDED status and submit it, check if email was not sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
msg = "Create a domain request with ACTION_NEEDED status and submit it, check if email was not sent."
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
self.check_email_sent(application, msg, "submit", 0)
|
||||
|
||||
def test_submit_from_in_review_does_not_send_email(self):
|
||||
msg = "Create a withdrawn application and submit it and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.check_email_sent(application, msg, "submit", 0)
|
||||
|
||||
def test_approve_sends_email(self):
|
||||
msg = "Create an application and approve it and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
msg = "Create a domain request and approve it and see if email was sent."
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.check_email_sent(application, msg, "approve", 1)
|
||||
|
||||
def test_withdraw_sends_email(self):
|
||||
msg = "Create an application and withdraw it and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
msg = "Create a domain request and withdraw it and see if email was sent."
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.check_email_sent(application, msg, "withdraw", 1)
|
||||
|
||||
def test_reject_sends_email(self):
|
||||
msg = "Create an application and reject it and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.APPROVED)
|
||||
msg = "Create a domain request and reject it and see if email was sent."
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.check_email_sent(application, msg, "reject", 1)
|
||||
|
||||
def test_reject_with_prejudice_does_not_send_email(self):
|
||||
msg = "Create an application and reject it with prejudice and see if email was sent."
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.APPROVED)
|
||||
msg = "Create a domain request and reject it with prejudice and see if email was sent."
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.check_email_sent(application, msg, "reject_with_prejudice", 0)
|
||||
|
||||
def test_submit_transition_allowed(self):
|
||||
|
@ -224,10 +224,10 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling submit from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -235,7 +235,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -244,10 +244,10 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling submit against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -255,18 +255,18 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.submit()
|
||||
domain_request.submit()
|
||||
|
||||
def test_in_review_transition_allowed(self):
|
||||
"""
|
||||
Test that calling in_review from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -274,7 +274,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.in_review()
|
||||
domain_request.in_review()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -283,9 +283,9 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling in_review against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -293,23 +293,23 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.in_review()
|
||||
domain_request.in_review()
|
||||
|
||||
def test_action_needed_transition_allowed(self):
|
||||
"""
|
||||
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
with less_console_noise():
|
||||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.action_needed()
|
||||
domain_request.action_needed()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -318,26 +318,26 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
with less_console_noise():
|
||||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.action_needed()
|
||||
domain_request.action_needed()
|
||||
|
||||
def test_approved_transition_allowed(self):
|
||||
"""
|
||||
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -345,7 +345,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.approve()
|
||||
domain_request.approve()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -357,7 +357,7 @@ class TestDomainRequest(TestCase):
|
|||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
self.submitted_application.approve(send_email=False)
|
||||
self.submitted_domain_request.approve(send_email=False)
|
||||
|
||||
# Assert that no emails were sent
|
||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 0)
|
||||
|
@ -367,10 +367,10 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -378,16 +378,16 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.approve()
|
||||
domain_request.approve()
|
||||
|
||||
def test_withdraw_transition_allowed(self):
|
||||
"""
|
||||
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -395,7 +395,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.withdraw()
|
||||
domain_request.withdraw()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -404,11 +404,11 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -416,16 +416,16 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.withdraw()
|
||||
domain_request.withdraw()
|
||||
|
||||
def test_reject_transition_allowed(self):
|
||||
"""
|
||||
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -433,7 +433,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.reject()
|
||||
domain_request.reject()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -442,11 +442,11 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -454,17 +454,17 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.reject()
|
||||
domain_request.reject()
|
||||
|
||||
def test_reject_with_prejudice_transition_allowed(self):
|
||||
"""
|
||||
Test that calling action_needed from allowable statuses does raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.in_review_application, TransitionNotAllowed),
|
||||
(self.action_needed_application, TransitionNotAllowed),
|
||||
(self.approved_application, TransitionNotAllowed),
|
||||
(self.rejected_application, TransitionNotAllowed),
|
||||
(self.in_review_domain_request, TransitionNotAllowed),
|
||||
(self.action_needed_domain_request, TransitionNotAllowed),
|
||||
(self.approved_domain_request, TransitionNotAllowed),
|
||||
(self.rejected_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -472,7 +472,7 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
try:
|
||||
application.reject_with_prejudice()
|
||||
domain_request.reject_with_prejudice()
|
||||
except TransitionNotAllowed:
|
||||
self.fail("TransitionNotAllowed was raised, but it was not expected.")
|
||||
|
||||
|
@ -481,10 +481,10 @@ class TestDomainRequest(TestCase):
|
|||
Test that calling action_needed against transition rules raises TransitionNotAllowed.
|
||||
"""
|
||||
test_cases = [
|
||||
(self.started_application, TransitionNotAllowed),
|
||||
(self.submitted_application, TransitionNotAllowed),
|
||||
(self.withdrawn_application, TransitionNotAllowed),
|
||||
(self.ineligible_application, TransitionNotAllowed),
|
||||
(self.started_domain_request, TransitionNotAllowed),
|
||||
(self.submitted_domain_request, TransitionNotAllowed),
|
||||
(self.withdrawn_domain_request, TransitionNotAllowed),
|
||||
(self.ineligible_domain_request, TransitionNotAllowed),
|
||||
]
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
|
@ -492,15 +492,15 @@ class TestDomainRequest(TestCase):
|
|||
for application, exception_type in test_cases:
|
||||
with self.subTest(application=application, exception_type=exception_type):
|
||||
with self.assertRaises(exception_type):
|
||||
application.reject_with_prejudice()
|
||||
domain_request.reject_with_prejudice()
|
||||
|
||||
def test_transition_not_allowed_approved_in_review_when_domain_is_active(self):
|
||||
"""Create an application with status approved, create a matching domain that
|
||||
"""Create a domain request with status approved, create a matching domain that
|
||||
is active, and call in_review against transition rules"""
|
||||
|
||||
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||
self.approved_application.approved_domain = domain
|
||||
self.approved_application.save()
|
||||
domain = Domain.objects.create(name=self.approved_domain_request.requested_domain.name)
|
||||
self.approved_domain_request.approved_domain = domain
|
||||
self.approved_domain_request.save()
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
|
@ -512,15 +512,15 @@ class TestDomainRequest(TestCase):
|
|||
with patch.object(Domain, "is_active", custom_is_active):
|
||||
# Now, when you call is_active on Domain, it will return True
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
self.approved_application.in_review()
|
||||
self.approved_domain_request.in_review()
|
||||
|
||||
def test_transition_not_allowed_approved_action_needed_when_domain_is_active(self):
|
||||
"""Create an application with status approved, create a matching domain that
|
||||
"""Create a domain request with status approved, create a matching domain that
|
||||
is active, and call action_needed against transition rules"""
|
||||
|
||||
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||
self.approved_application.approved_domain = domain
|
||||
self.approved_application.save()
|
||||
domain = Domain.objects.create(name=self.approved_domain_request.requested_domain.name)
|
||||
self.approved_domain_request.approved_domain = domain
|
||||
self.approved_domain_request.save()
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
|
@ -532,15 +532,15 @@ class TestDomainRequest(TestCase):
|
|||
with patch.object(Domain, "is_active", custom_is_active):
|
||||
# Now, when you call is_active on Domain, it will return True
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
self.approved_application.action_needed()
|
||||
self.approved_domain_request.action_needed()
|
||||
|
||||
def test_transition_not_allowed_approved_rejected_when_domain_is_active(self):
|
||||
"""Create an application with status approved, create a matching domain that
|
||||
"""Create a domain request with status approved, create a matching domain that
|
||||
is active, and call reject against transition rules"""
|
||||
|
||||
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||
self.approved_application.approved_domain = domain
|
||||
self.approved_application.save()
|
||||
domain = Domain.objects.create(name=self.approved_domain_request.requested_domain.name)
|
||||
self.approved_domain_request.approved_domain = domain
|
||||
self.approved_domain_request.save()
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
|
@ -552,15 +552,15 @@ class TestDomainRequest(TestCase):
|
|||
with patch.object(Domain, "is_active", custom_is_active):
|
||||
# Now, when you call is_active on Domain, it will return True
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
self.approved_application.reject()
|
||||
self.approved_domain_request.reject()
|
||||
|
||||
def test_transition_not_allowed_approved_ineligible_when_domain_is_active(self):
|
||||
"""Create an application with status approved, create a matching domain that
|
||||
"""Create a domain request with status approved, create a matching domain that
|
||||
is active, and call reject_with_prejudice against transition rules"""
|
||||
|
||||
domain = Domain.objects.create(name=self.approved_application.requested_domain.name)
|
||||
self.approved_application.approved_domain = domain
|
||||
self.approved_application.save()
|
||||
domain = Domain.objects.create(name=self.approved_domain_request.requested_domain.name)
|
||||
self.approved_domain_request.approved_domain = domain
|
||||
self.approved_domain_request.save()
|
||||
|
||||
# Define a custom implementation for is_active
|
||||
def custom_is_active(self):
|
||||
|
@ -572,7 +572,7 @@ class TestDomainRequest(TestCase):
|
|||
with patch.object(Domain, "is_active", custom_is_active):
|
||||
# Now, when you call is_active on Domain, it will return True
|
||||
with self.assertRaises(TransitionNotAllowed):
|
||||
self.approved_application.reject_with_prejudice()
|
||||
self.approved_domain_request.reject_with_prejudice()
|
||||
|
||||
def test_approve_from_rejected_clears_rejection_reason(self):
|
||||
"""When transitioning from rejected to approved on a domain request,
|
||||
|
@ -580,15 +580,15 @@ class TestDomainRequest(TestCase):
|
|||
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.REJECTED)
|
||||
application.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.REJECTED)
|
||||
domain_request.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
|
||||
# Approve
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.approve()
|
||||
domain_request.approve()
|
||||
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.APPROVED)
|
||||
self.assertEqual(application.rejection_reason, None)
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.APPROVED)
|
||||
self.assertEqual(domain_request.rejection_reason, None)
|
||||
|
||||
def test_in_review_from_rejected_clears_rejection_reason(self):
|
||||
"""When transitioning from rejected to in_review on a domain request,
|
||||
|
@ -596,16 +596,16 @@ class TestDomainRequest(TestCase):
|
|||
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.REJECTED)
|
||||
application.domain_is_not_active = True
|
||||
application.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.REJECTED)
|
||||
domain_request.domain_is_not_active = True
|
||||
domain_request.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
|
||||
# Approve
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.in_review()
|
||||
domain_request.in_review()
|
||||
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.IN_REVIEW)
|
||||
self.assertEqual(application.rejection_reason, None)
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.IN_REVIEW)
|
||||
self.assertEqual(domain_request.rejection_reason, None)
|
||||
|
||||
def test_action_needed_from_rejected_clears_rejection_reason(self):
|
||||
"""When transitioning from rejected to action_needed on a domain request,
|
||||
|
@ -613,42 +613,42 @@ class TestDomainRequest(TestCase):
|
|||
|
||||
with less_console_noise():
|
||||
# Create a sample application
|
||||
application = completed_application(status=DomainRequest.ApplicationStatus.REJECTED)
|
||||
application.domain_is_not_active = True
|
||||
application.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
domain_request = completed_domain_request(status=DomainRequest.DomainRequestStatus.REJECTED)
|
||||
domain_request.domain_is_not_active = True
|
||||
domain_request.rejection_reason = DomainRequest.RejectionReasons.DOMAIN_PURPOSE
|
||||
|
||||
# Approve
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
application.action_needed()
|
||||
domain_request.action_needed()
|
||||
|
||||
self.assertEqual(application.status, DomainRequest.ApplicationStatus.ACTION_NEEDED)
|
||||
self.assertEqual(application.rejection_reason, None)
|
||||
self.assertEqual(domain_request.status, DomainRequest.DomainRequestStatus.ACTION_NEEDED)
|
||||
self.assertEqual(domain_request.rejection_reason, None)
|
||||
|
||||
def test_has_rationale_returns_true(self):
|
||||
"""has_rationale() returns true when an application has no_other_contacts_rationale"""
|
||||
"""has_rationale() returns true when a domain request has no_other_contacts_rationale"""
|
||||
with less_console_noise():
|
||||
self.started_application.no_other_contacts_rationale = "You talkin' to me?"
|
||||
self.started_application.save()
|
||||
self.assertEquals(self.started_application.has_rationale(), True)
|
||||
self.started_domain_request.no_other_contacts_rationale = "You talkin' to me?"
|
||||
self.started_domain_request.save()
|
||||
self.assertEquals(self.started_domain_request.has_rationale(), True)
|
||||
|
||||
def test_has_rationale_returns_false(self):
|
||||
"""has_rationale() returns false when an application has no no_other_contacts_rationale"""
|
||||
"""has_rationale() returns false when a domain request has no no_other_contacts_rationale"""
|
||||
with less_console_noise():
|
||||
self.assertEquals(self.started_application.has_rationale(), False)
|
||||
self.assertEquals(self.started_domain_request.has_rationale(), False)
|
||||
|
||||
def test_has_other_contacts_returns_true(self):
|
||||
"""has_other_contacts() returns true when an application has other_contacts"""
|
||||
"""has_other_contacts() returns true when a domain request has other_contacts"""
|
||||
with less_console_noise():
|
||||
# completed_application has other contacts by default
|
||||
self.assertEquals(self.started_application.has_other_contacts(), True)
|
||||
# completed_domain_request has other contacts by default
|
||||
self.assertEquals(self.started_domain_request.has_other_contacts(), True)
|
||||
|
||||
def test_has_other_contacts_returns_false(self):
|
||||
"""has_other_contacts() returns false when an application has no other_contacts"""
|
||||
"""has_other_contacts() returns false when a domain request has no other_contacts"""
|
||||
with less_console_noise():
|
||||
application = completed_application(
|
||||
status=DomainRequest.ApplicationStatus.STARTED, name="no-others.gov", has_other_contacts=False
|
||||
domain_request = completed_domain_request(
|
||||
status=DomainRequest.DomainRequestStatus.STARTED, name="no-others.gov", has_other_contacts=False
|
||||
)
|
||||
self.assertEquals(application.has_other_contacts(), False)
|
||||
self.assertEquals(domain_request.has_other_contacts(), False)
|
||||
|
||||
|
||||
class TestPermissions(TestCase):
|
||||
|
@ -666,13 +666,13 @@ class TestPermissions(TestCase):
|
|||
def test_approval_creates_role(self):
|
||||
draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||
user, _ = User.objects.get_or_create()
|
||||
application = DomainRequest.objects.create(creator=user, requested_domain=draft_domain)
|
||||
domain_request = DomainRequest.objects.create(creator=user, requested_domain=draft_domain)
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# skip using the submit method
|
||||
application.status = DomainRequest.ApplicationStatus.SUBMITTED
|
||||
application.approve()
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.SUBMITTED
|
||||
domain_request.approve()
|
||||
|
||||
# should be a role for this user
|
||||
domain = Domain.objects.get(name="igorville.gov")
|
||||
|
@ -700,13 +700,13 @@ class TestDomainInformation(TestCase):
|
|||
self.maxDiff = None
|
||||
draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||
user, _ = User.objects.get_or_create()
|
||||
application = DomainRequest.objects.create(creator=user, requested_domain=draft_domain, notes="test notes")
|
||||
domain_request = DomainRequest.objects.create(creator=user, requested_domain=draft_domain, notes="test notes")
|
||||
|
||||
with boto3_mocking.clients.handler_for("sesv2", self.mock_client):
|
||||
with less_console_noise():
|
||||
# skip using the submit method
|
||||
application.status = DomainRequest.ApplicationStatus.SUBMITTED
|
||||
application.approve()
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.SUBMITTED
|
||||
domain_request.approve()
|
||||
|
||||
# should be an information present for this domain
|
||||
domain = Domain.objects.get(name="igorville.gov")
|
||||
|
@ -852,7 +852,7 @@ class TestContact(TestCase):
|
|||
self.contact, _ = Contact.objects.get_or_create(user=self.user)
|
||||
|
||||
self.contact_as_ao, _ = Contact.objects.get_or_create(email="newguy@igorville.gov")
|
||||
self.application = DomainRequest.objects.create(creator=self.user, authorizing_official=self.contact_as_ao)
|
||||
self.domain_request = DomainRequest.objects.create(creator=self.user, authorizing_official=self.contact_as_ao)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
|
@ -936,6 +936,6 @@ class TestContact(TestCase):
|
|||
# test for a contact which has one user defined
|
||||
self.assertFalse(self.contact.has_more_than_one_join("user"))
|
||||
self.assertTrue(self.contact.has_more_than_one_join("authorizing_official"))
|
||||
# test for a contact which is assigned as an authorizing official on an application
|
||||
# test for a contact which is assigned as an authorizing official on a domain request
|
||||
self.assertFalse(self.contact_as_ao.has_more_than_one_join("authorizing_official"))
|
||||
self.assertTrue(self.contact_as_ao.has_more_than_one_join("submitted_applications"))
|
||||
self.assertTrue(self.contact_as_ao.has_more_than_one_join("submitted_domain_requests"))
|
||||
|
|
|
@ -314,7 +314,7 @@ class TestDomainCreation(MockEppLib):
|
|||
"""Rule: An approved domain request must result in a domain"""
|
||||
|
||||
@boto3_mocking.patching
|
||||
def test_approved_application_creates_domain_locally(self):
|
||||
def test_approved_domain_request_creates_domain_locally(self):
|
||||
"""
|
||||
Scenario: Analyst approves a domain request
|
||||
When the DomainRequest transitions to approved
|
||||
|
@ -324,14 +324,14 @@ class TestDomainCreation(MockEppLib):
|
|||
with less_console_noise():
|
||||
draft_domain, _ = DraftDomain.objects.get_or_create(name="igorville.gov")
|
||||
user, _ = User.objects.get_or_create()
|
||||
application = DomainRequest.objects.create(creator=user, requested_domain=draft_domain)
|
||||
domain_request = DomainRequest.objects.create(creator=user, requested_domain=draft_domain)
|
||||
|
||||
mock_client = MockSESClient()
|
||||
with boto3_mocking.clients.handler_for("sesv2", mock_client):
|
||||
# skip using the submit method
|
||||
application.status = DomainRequest.ApplicationStatus.SUBMITTED
|
||||
domain_request.status = DomainRequest.DomainRequestStatus.SUBMITTED
|
||||
# transition to approve state
|
||||
application.approve()
|
||||
domain_request.approve()
|
||||
# should have information present for this domain
|
||||
domain = Domain.objects.get(name="igorville.gov")
|
||||
self.assertTrue(domain)
|
||||
|
|
|
@ -27,7 +27,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class TestProcessedMigrations(TestCase):
|
||||
"""This test case class is designed to verify the idempotency of migrations
|
||||
related to domain transitions in the application."""
|
||||
related to domain transitions in the domain_request."""
|
||||
|
||||
def setUp(self):
|
||||
"""Defines the file name of migration_json and the folder its contained in"""
|
||||
|
|
|
@ -26,8 +26,8 @@ class TestViews(TestCase):
|
|||
response = self.client.get("/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
def test_application_form_not_logged_in(self):
|
||||
"""Application form not accessible without a logged-in user."""
|
||||
def test_domain_request_form_not_logged_in(self):
|
||||
"""Domain request form not accessible without a logged-in user."""
|
||||
response = self.client.get("/request/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertIn("/login?next=/request/", response.headers["Location"])
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -309,7 +309,7 @@ class TestDomainDetail(TestDomainOverview):
|
|||
self.assertContains(detail_page, "(1.2.3.4,")
|
||||
self.assertContains(detail_page, "2.3.4.5)")
|
||||
|
||||
def test_domain_detail_with_no_information_or_application(self):
|
||||
def test_domain_detail_with_no_information_or_domain_request(self):
|
||||
"""Test that domain management page returns 200 and displays error
|
||||
when no domain information or domain request exist"""
|
||||
with less_console_noise():
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .application import *
|
||||
from .domain_request import *
|
||||
from .domain import (
|
||||
DomainView,
|
||||
DomainAuthorizingOfficialView,
|
||||
|
|
|
@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from django.views.generic import TemplateView
|
||||
from django.contrib import messages
|
||||
|
||||
from registrar.forms import application_wizard as forms
|
||||
from registrar.forms import domain_request_wizard as forms
|
||||
from registrar.models import DomainRequest
|
||||
from registrar.models.contact import Contact
|
||||
from registrar.models.user import User
|
||||
|
@ -19,7 +19,7 @@ from registrar.views.utility.permission_views import DomainRequestPermissionDele
|
|||
from .utility import (
|
||||
DomainRequestPermissionView,
|
||||
DomainRequestPermissionWithdrawView,
|
||||
ApplicationWizardPermissionView,
|
||||
DomainRequestWizardPermissionView,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -27,7 +27,7 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
class Step(StrEnum):
|
||||
"""
|
||||
Names for each page of the application wizard.
|
||||
Names for each page of the domain request wizard.
|
||||
|
||||
As with Django's own `TextChoices` class, steps will
|
||||
appear in the order they are defined. (Order matters.)
|
||||
|
@ -50,7 +50,7 @@ class Step(StrEnum):
|
|||
REVIEW = "review"
|
||||
|
||||
|
||||
class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
||||
class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
||||
"""
|
||||
A common set of methods and configuration.
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
Together, these steps constitute a "wizard".
|
||||
|
||||
This base class sets up a shared state (stored in the user's session)
|
||||
between pages of the application and provides common methods for
|
||||
between pages of the domain request and provides common methods for
|
||||
processing form data.
|
||||
|
||||
Views for each step should inherit from this base class.
|
||||
|
@ -73,7 +73,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
# (this is not seen _in_ urls, only for Django's internal naming)
|
||||
# NB: this is included here for reference. Do not change it without
|
||||
# also changing the many places it is hardcoded in the HTML templates
|
||||
URL_NAMESPACE = "application"
|
||||
URL_NAMESPACE = "domain_request"
|
||||
# name for accessing /application/<id>/edit
|
||||
EDIT_URL_NAME = "edit-application"
|
||||
NEW_URL_NAME = "/request/"
|
||||
|
@ -108,28 +108,28 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
self.steps = StepsHelper(self)
|
||||
self._application = None # for caching
|
||||
self._domain_request = None # for caching
|
||||
|
||||
def has_pk(self):
|
||||
"""Does this wizard know about a DomainRequest database record?"""
|
||||
return "application_id" in self.storage
|
||||
return "domain_request_id" in self.storage
|
||||
|
||||
@property
|
||||
def prefix(self):
|
||||
"""Namespace the wizard to avoid clashes in session variable names."""
|
||||
# this is a string literal but can be made dynamic if we'd like
|
||||
# users to have multiple applications open for editing simultaneously
|
||||
return "wizard_application"
|
||||
return "wizard_domain_request"
|
||||
|
||||
@property
|
||||
def application(self) -> DomainRequest:
|
||||
"""
|
||||
Attempt to match the current wizard with a DomainRequest.
|
||||
|
||||
Will create an application if none exists.
|
||||
Will create a domain request if none exists.
|
||||
"""
|
||||
if self._application:
|
||||
return self._application
|
||||
if self._domain_request:
|
||||
return self._domain_request
|
||||
|
||||
# For linter. The else block should never be hit, but if it does,
|
||||
# there may be a UI consideration. That will need to be handled in another ticket.
|
||||
|
@ -140,20 +140,20 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
raise ValueError("Invalid value for User")
|
||||
|
||||
if self.has_pk():
|
||||
id = self.storage["application_id"]
|
||||
id = self.storage["domain_request_id"]
|
||||
try:
|
||||
self._application = DomainRequest.objects.get(
|
||||
self._domain_request = DomainRequest.objects.get(
|
||||
creator=creator,
|
||||
pk=id,
|
||||
)
|
||||
return self._application
|
||||
return self._domain_request
|
||||
except DomainRequest.DoesNotExist:
|
||||
logger.debug("Application id %s did not have a DomainRequest" % id)
|
||||
|
||||
self._application = DomainRequest.objects.create(creator=self.request.user)
|
||||
self._domain_request = DomainRequest.objects.create(creator=self.request.user)
|
||||
|
||||
self.storage["application_id"] = self._application.id
|
||||
return self._application
|
||||
self.storage["domain_request_id"] = self._domain_request.id
|
||||
return self._domain_request
|
||||
|
||||
@property
|
||||
def storage(self):
|
||||
|
@ -179,9 +179,9 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
|
||||
def done(self):
|
||||
"""Called when the user clicks the submit button, if all forms are valid."""
|
||||
self.application.submit() # change the status to submitted
|
||||
self.application.save()
|
||||
logger.debug("Application object saved: %s", self.application.id)
|
||||
self.domain_request.submit() # change the status to submitted
|
||||
self.domain_request.save()
|
||||
logger.debug("Application object saved: %s", self.domain_request.id)
|
||||
return redirect(reverse(f"{self.URL_NAMESPACE}:finished"))
|
||||
|
||||
def from_model(self, attribute: str, default, *args, **kwargs):
|
||||
|
@ -214,20 +214,20 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
# and remove any prior wizard data from their session
|
||||
if current_url == self.EDIT_URL_NAME and "id" in kwargs:
|
||||
del self.storage
|
||||
self.storage["application_id"] = kwargs["id"]
|
||||
self.storage["domain_request_id"] = kwargs["id"]
|
||||
self.storage["step_history"] = self.db_check_for_unlocking_steps()
|
||||
|
||||
# if accessing this class directly, redirect to the first step
|
||||
# in other words, if `ApplicationWizard` is called as view
|
||||
# in other words, if `DomainRequestWizard` is called as view
|
||||
# directly by some redirect or url handler, we'll send users
|
||||
# either to an acknowledgement page or to the first step in
|
||||
# the processes (if an edit rather than a new request); subclasses
|
||||
# will NOT be redirected. The purpose of this is to allow code to
|
||||
# send users "to the application wizard" without needing to
|
||||
# send users "to the domain request wizard" without needing to
|
||||
# know which view is first in the list of steps.
|
||||
if self.__class__ == ApplicationWizard:
|
||||
if self.__class__ == DomainRequestWizard:
|
||||
if request.path_info == self.NEW_URL_NAME:
|
||||
return render(request, "application_intro.html")
|
||||
return render(request, "domain_request_intro.html")
|
||||
else:
|
||||
return self.goto(self.steps.first)
|
||||
|
||||
|
@ -278,7 +278,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
kwargs = {
|
||||
"files": files,
|
||||
"prefix": self.steps.current,
|
||||
"application": self.application, # this is a property, not an object
|
||||
"domain_request": self.application, # this is a property, not an object
|
||||
}
|
||||
|
||||
if step is None:
|
||||
|
@ -303,72 +303,72 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
def pending_requests(self):
|
||||
"""return an array of pending requests if user has pending requests
|
||||
and no approved requests"""
|
||||
if self.approved_applications_exist() or self.approved_domains_exist():
|
||||
if self.approved_domain_requests_exist() or self.approved_domains_exist():
|
||||
return []
|
||||
else:
|
||||
return self.pending_applications()
|
||||
return self.pending_domain_requests()
|
||||
|
||||
def approved_applications_exist(self):
|
||||
"""Checks if user is creator of applications with ApplicationStatus.APPROVED status"""
|
||||
approved_application_count = DomainRequest.objects.filter(
|
||||
creator=self.request.user, status=DomainRequest.ApplicationStatus.APPROVED
|
||||
def approved_domain_requests_exist(self):
|
||||
"""Checks if user is creator of applications with DomainRequestStatus.APPROVED status"""
|
||||
approved_domain_request_count = DomainRequest.objects.filter(
|
||||
creator=self.request.user, status=DomainRequest.DomainRequestStatus.APPROVED
|
||||
).count()
|
||||
return approved_application_count > 0
|
||||
return approved_domain_request_count > 0
|
||||
|
||||
def approved_domains_exist(self):
|
||||
"""Checks if user has permissions on approved domains
|
||||
|
||||
This additional check is necessary to account for domains which were migrated
|
||||
and do not have an application"""
|
||||
and do not have a domain request"""
|
||||
return self.request.user.permissions.count() > 0
|
||||
|
||||
def pending_applications(self):
|
||||
def pending_domain_requests(self):
|
||||
"""Returns a List of user's applications with one of the following states:
|
||||
ApplicationStatus.SUBMITTED, ApplicationStatus.IN_REVIEW, ApplicationStatus.ACTION_NEEDED"""
|
||||
# if the current application has ApplicationStatus.ACTION_NEEDED status, this check should not be performed
|
||||
if self.application.status == DomainRequest.ApplicationStatus.ACTION_NEEDED:
|
||||
DomainRequestStatus.SUBMITTED, DomainRequestStatus.IN_REVIEW, DomainRequestStatus.ACTION_NEEDED"""
|
||||
# if the current application has DomainRequestStatus.ACTION_NEEDED status, this check should not be performed
|
||||
if self.domain_request.status == DomainRequest.DomainRequestStatus.ACTION_NEEDED:
|
||||
return []
|
||||
check_statuses = [
|
||||
DomainRequest.ApplicationStatus.SUBMITTED,
|
||||
DomainRequest.ApplicationStatus.IN_REVIEW,
|
||||
DomainRequest.ApplicationStatus.ACTION_NEEDED,
|
||||
DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||
DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequest.DomainRequestStatus.ACTION_NEEDED,
|
||||
]
|
||||
return DomainRequest.objects.filter(creator=self.request.user, status__in=check_statuses)
|
||||
|
||||
def db_check_for_unlocking_steps(self):
|
||||
"""Helper for get_context_data
|
||||
|
||||
Queries the DB for an application and returns a list of unlocked steps."""
|
||||
Queries the DB for a domain request and returns a list of unlocked steps."""
|
||||
history_dict = {
|
||||
"organization_type": self.application.organization_type is not None,
|
||||
"tribal_government": self.application.tribe_name is not None,
|
||||
"organization_federal": self.application.federal_type is not None,
|
||||
"organization_election": self.application.is_election_board is not None,
|
||||
"organization_type": self.domain_request.organization_type is not None,
|
||||
"tribal_government": self.domain_request.tribe_name is not None,
|
||||
"organization_federal": self.domain_request.federal_type is not None,
|
||||
"organization_election": self.domain_request.is_election_board is not None,
|
||||
"organization_contact": (
|
||||
self.application.federal_agency is not None
|
||||
or self.application.organization_name is not None
|
||||
or self.application.address_line1 is not None
|
||||
or self.application.city is not None
|
||||
or self.application.state_territory is not None
|
||||
or self.application.zipcode is not None
|
||||
or self.application.urbanization is not None
|
||||
self.domain_request.federal_agency is not None
|
||||
or self.domain_request.organization_name is not None
|
||||
or self.domain_request.address_line1 is not None
|
||||
or self.domain_request.city is not None
|
||||
or self.domain_request.state_territory is not None
|
||||
or self.domain_request.zipcode is not None
|
||||
or self.domain_request.urbanization is not None
|
||||
),
|
||||
"about_your_organization": self.application.about_your_organization is not None,
|
||||
"authorizing_official": self.application.authorizing_official is not None,
|
||||
"about_your_organization": self.domain_request.about_your_organization is not None,
|
||||
"authorizing_official": self.domain_request.authorizing_official is not None,
|
||||
"current_sites": (
|
||||
self.application.current_websites.exists() or self.application.requested_domain is not None
|
||||
self.domain_request.current_websites.exists() or self.domain_request.requested_domain is not None
|
||||
),
|
||||
"dotgov_domain": self.application.requested_domain is not None,
|
||||
"purpose": self.application.purpose is not None,
|
||||
"your_contact": self.application.submitter is not None,
|
||||
"dotgov_domain": self.domain_request.requested_domain is not None,
|
||||
"purpose": self.domain_request.purpose is not None,
|
||||
"your_contact": self.domain_request.submitter is not None,
|
||||
"other_contacts": (
|
||||
self.application.other_contacts.exists() or self.application.no_other_contacts_rationale is not None
|
||||
self.domain_request.other_contacts.exists() or self.domain_request.no_other_contacts_rationale is not None
|
||||
),
|
||||
"anything_else": (
|
||||
self.application.anything_else is not None or self.application.is_policy_acknowledged is not None
|
||||
self.domain_request.anything_else is not None or self.domain_request.is_policy_acknowledged is not None
|
||||
),
|
||||
"requirements": self.application.is_policy_acknowledged is not None,
|
||||
"review": self.application.is_policy_acknowledged is not None,
|
||||
"requirements": self.domain_request.is_policy_acknowledged is not None,
|
||||
"review": self.domain_request.is_policy_acknowledged is not None,
|
||||
}
|
||||
return [key for key, value in history_dict.items() if value]
|
||||
|
||||
|
@ -377,8 +377,8 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
# Build the submit button that we'll pass to the modal.
|
||||
modal_button = '<button type="submit" ' 'class="usa-button" ' ">Submit request</button>"
|
||||
# Concatenate the modal header that we'll pass to the modal.
|
||||
if self.application.requested_domain:
|
||||
modal_heading = "You are about to submit a domain request for " + str(self.application.requested_domain)
|
||||
if self.domain_request.requested_domain:
|
||||
modal_heading = "You are about to submit a domain request for " + str(self.domain_request.requested_domain)
|
||||
else:
|
||||
modal_heading = "You are about to submit an incomplete request"
|
||||
|
||||
|
@ -387,7 +387,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
"steps": self.steps,
|
||||
# Add information about which steps should be unlocked
|
||||
"visited": self.storage.get("step_history", []),
|
||||
"is_federal": self.application.is_federal(),
|
||||
"is_federal": self.domain_request.is_federal(),
|
||||
"modal_button": modal_button,
|
||||
"modal_heading": modal_heading,
|
||||
}
|
||||
|
@ -434,7 +434,7 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
return self.goto(self.steps.first)
|
||||
|
||||
# if accessing this class directly, redirect to the first step
|
||||
if self.__class__ == ApplicationWizard:
|
||||
if self.__class__ == DomainRequestWizard:
|
||||
return self.goto(self.steps.first)
|
||||
|
||||
forms = self.get_forms(use_post=True)
|
||||
|
@ -462,86 +462,86 @@ class ApplicationWizard(ApplicationWizardPermissionView, TemplateView):
|
|||
"""
|
||||
Unpack the form responses onto the model object properties.
|
||||
|
||||
Saves the application to the database.
|
||||
Saves the domain request to the database.
|
||||
"""
|
||||
for form in forms:
|
||||
if form is not None and hasattr(form, "to_database"):
|
||||
form.to_database(self.application)
|
||||
|
||||
|
||||
class OrganizationType(ApplicationWizard):
|
||||
template_name = "application_org_type.html"
|
||||
class OrganizationType(DomainRequestWizard):
|
||||
template_name = "domain_request_org_type.html"
|
||||
forms = [forms.OrganizationTypeForm]
|
||||
|
||||
|
||||
class TribalGovernment(ApplicationWizard):
|
||||
template_name = "application_tribal_government.html"
|
||||
class TribalGovernment(DomainRequestWizard):
|
||||
template_name = "domain_request_tribal_government.html"
|
||||
forms = [forms.TribalGovernmentForm]
|
||||
|
||||
|
||||
class OrganizationFederal(ApplicationWizard):
|
||||
template_name = "application_org_federal.html"
|
||||
class OrganizationFederal(DomainRequestWizard):
|
||||
template_name = "domain_request_org_federal.html"
|
||||
forms = [forms.OrganizationFederalForm]
|
||||
|
||||
|
||||
class OrganizationElection(ApplicationWizard):
|
||||
template_name = "application_org_election.html"
|
||||
class OrganizationElection(DomainRequestWizard):
|
||||
template_name = "domain_request_org_election.html"
|
||||
forms = [forms.OrganizationElectionForm]
|
||||
|
||||
|
||||
class OrganizationContact(ApplicationWizard):
|
||||
template_name = "application_org_contact.html"
|
||||
class OrganizationContact(DomainRequestWizard):
|
||||
template_name = "domain_request_org_contact.html"
|
||||
forms = [forms.OrganizationContactForm]
|
||||
|
||||
|
||||
class AboutYourOrganization(ApplicationWizard):
|
||||
template_name = "application_about_your_organization.html"
|
||||
class AboutYourOrganization(DomainRequestWizard):
|
||||
template_name = "domain_request_about_your_organization.html"
|
||||
forms = [forms.AboutYourOrganizationForm]
|
||||
|
||||
|
||||
class AuthorizingOfficial(ApplicationWizard):
|
||||
template_name = "application_authorizing_official.html"
|
||||
class AuthorizingOfficial(DomainRequestWizard):
|
||||
template_name = "domain_request_authorizing_official.html"
|
||||
forms = [forms.AuthorizingOfficialForm]
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["organization_type"] = self.application.organization_type
|
||||
context["federal_type"] = self.application.federal_type
|
||||
context["organization_type"] = self.domain_request.organization_type
|
||||
context["federal_type"] = self.domain_request.federal_type
|
||||
return context
|
||||
|
||||
|
||||
class CurrentSites(ApplicationWizard):
|
||||
template_name = "application_current_sites.html"
|
||||
class CurrentSites(DomainRequestWizard):
|
||||
template_name = "domain_request_current_sites.html"
|
||||
forms = [forms.CurrentSitesFormSet]
|
||||
|
||||
|
||||
class DotgovDomain(ApplicationWizard):
|
||||
template_name = "application_dotgov_domain.html"
|
||||
class DotgovDomain(DomainRequestWizard):
|
||||
template_name = "domain_request_dotgov_domain.html"
|
||||
forms = [forms.DotGovDomainForm, forms.AlternativeDomainFormSet]
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["organization_type"] = self.application.organization_type
|
||||
context["federal_type"] = self.application.federal_type
|
||||
context["organization_type"] = self.domain_request.organization_type
|
||||
context["federal_type"] = self.domain_request.federal_type
|
||||
return context
|
||||
|
||||
|
||||
class Purpose(ApplicationWizard):
|
||||
template_name = "application_purpose.html"
|
||||
class Purpose(DomainRequestWizard):
|
||||
template_name = "domain_request_purpose.html"
|
||||
forms = [forms.PurposeForm]
|
||||
|
||||
|
||||
class YourContact(ApplicationWizard):
|
||||
template_name = "application_your_contact.html"
|
||||
class YourContact(DomainRequestWizard):
|
||||
template_name = "domain_request_your_contact.html"
|
||||
forms = [forms.YourContactForm]
|
||||
|
||||
|
||||
class OtherContacts(ApplicationWizard):
|
||||
template_name = "application_other_contacts.html"
|
||||
class OtherContacts(DomainRequestWizard):
|
||||
template_name = "domain_request_other_contacts.html"
|
||||
forms = [forms.OtherContactsYesNoForm, forms.OtherContactsFormSet, forms.NoOtherContactsForm]
|
||||
|
||||
def is_valid(self, forms: list) -> bool:
|
||||
"""Overrides default behavior defined in ApplicationWizard.
|
||||
"""Overrides default behavior defined in DomainRequestWizard.
|
||||
Depending on value in other_contacts_yes_no_form, marks forms in
|
||||
other_contacts or no_other_contacts for deletion. Then validates
|
||||
all forms.
|
||||
|
@ -580,24 +580,24 @@ class OtherContacts(ApplicationWizard):
|
|||
return all_forms_valid
|
||||
|
||||
|
||||
class AnythingElse(ApplicationWizard):
|
||||
template_name = "application_anything_else.html"
|
||||
class AnythingElse(DomainRequestWizard):
|
||||
template_name = "domain_request_anything_else.html"
|
||||
forms = [forms.AnythingElseForm]
|
||||
|
||||
|
||||
class Requirements(ApplicationWizard):
|
||||
template_name = "application_requirements.html"
|
||||
class Requirements(DomainRequestWizard):
|
||||
template_name = "domain_request_requirements.html"
|
||||
forms = [forms.RequirementsForm]
|
||||
|
||||
|
||||
class Review(ApplicationWizard):
|
||||
template_name = "application_review.html"
|
||||
class Review(DomainRequestWizard):
|
||||
template_name = "domain_request_review.html"
|
||||
forms = [] # type: ignore
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
context["Step"] = Step.__members__
|
||||
context["application"] = self.application
|
||||
context["domain_request"] = self.application
|
||||
return context
|
||||
|
||||
def goto_next_step(self):
|
||||
|
@ -623,30 +623,30 @@ class Review(ApplicationWizard):
|
|||
# return self.goto(self.steps.current)
|
||||
|
||||
|
||||
class Finished(ApplicationWizard):
|
||||
template_name = "application_done.html"
|
||||
class Finished(DomainRequestWizard):
|
||||
template_name = "domain_request_done.html"
|
||||
forms = [] # type: ignore
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
context = self.get_context_data()
|
||||
context["application_id"] = self.application.id
|
||||
context["domain_request_id"] = self.domain_request.id
|
||||
# clean up this wizard session, because we are done with it
|
||||
del self.storage
|
||||
return render(self.request, self.template_name, context)
|
||||
|
||||
|
||||
class ApplicationStatus(DomainRequestPermissionView):
|
||||
template_name = "application_status.html"
|
||||
class DomainRequestStatus(DomainRequestPermissionView):
|
||||
template_name = "domain_request_status.html"
|
||||
|
||||
|
||||
class ApplicationWithdrawConfirmation(DomainRequestPermissionWithdrawView):
|
||||
"""This page will ask user to confirm if they want to withdraw
|
||||
|
||||
The DomainRequestPermissionView restricts access so that only the
|
||||
`creator` of the application may withdraw it.
|
||||
`creator` of the domain request may withdraw it.
|
||||
"""
|
||||
|
||||
template_name = "application_withdraw_confirmation.html"
|
||||
template_name = "domain_request_withdraw_confirmation.html"
|
||||
|
||||
|
||||
class ApplicationWithdrawn(DomainRequestPermissionWithdrawView):
|
||||
|
@ -659,9 +659,9 @@ class ApplicationWithdrawn(DomainRequestPermissionWithdrawView):
|
|||
If user click on withdraw confirm button, this view updates the status
|
||||
to withdraw and send back to homepage.
|
||||
"""
|
||||
application = DomainRequest.objects.get(id=self.kwargs["pk"])
|
||||
application.withdraw()
|
||||
application.save()
|
||||
domain_request = DomainRequest.objects.get(id=self.kwargs["pk"])
|
||||
domain_request.withdraw()
|
||||
domain_request.save()
|
||||
return HttpResponseRedirect(reverse("home"))
|
||||
|
||||
|
||||
|
@ -677,7 +677,7 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
|||
return False
|
||||
|
||||
status = self.get_object().status
|
||||
valid_statuses = [DomainRequest.ApplicationStatus.WITHDRAWN, DomainRequest.ApplicationStatus.STARTED]
|
||||
valid_statuses = [DomainRequest.DomainRequestStatus.WITHDRAWN, DomainRequest.DomainRequestStatus.STARTED]
|
||||
if status not in valid_statuses:
|
||||
return False
|
||||
|
||||
|
@ -707,13 +707,13 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
|||
|
||||
return response
|
||||
|
||||
def _get_orphaned_contacts(self, application: DomainRequest, check_db=False):
|
||||
def _get_orphaned_contacts(self, domain_request: DomainRequest, check_db=False):
|
||||
"""
|
||||
Collects all orphaned contacts associated with a given DomainRequest object.
|
||||
|
||||
An orphaned contact is defined as a contact that is associated with the application,
|
||||
but not with any other application. This includes the authorizing official, the submitter,
|
||||
and any other contacts linked to the application.
|
||||
An orphaned contact is defined as a contact that is associated with the domain request,
|
||||
but not with any other domain_request. This includes the authorizing official, the submitter,
|
||||
and any other contacts linked to the domain_request.
|
||||
|
||||
Parameters:
|
||||
application (DomainRequest): The DomainRequest object for which to find orphaned contacts.
|
||||
|
@ -727,10 +727,10 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
|||
contacts_to_delete = []
|
||||
|
||||
# Get each contact object on the DomainRequest object
|
||||
ao = application.authorizing_official
|
||||
submitter = application.submitter
|
||||
other_contacts = list(application.other_contacts.all())
|
||||
other_contact_ids = application.other_contacts.all().values_list("id", flat=True)
|
||||
ao = domain_request.authorizing_official
|
||||
submitter = domain_request.submitter
|
||||
other_contacts = list(domain_request.other_contacts.all())
|
||||
other_contact_ids = domain_request.other_contacts.all().values_list("id", flat=True)
|
||||
|
||||
# Check if the desired item still exists in the DB
|
||||
if check_db:
|
||||
|
@ -739,8 +739,8 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
|||
other_contacts = self._get_contacts_by_id(other_contact_ids)
|
||||
|
||||
# Pair each contact with its db related name for use in checking if it has joins
|
||||
checked_contacts = [(ao, "authorizing_official"), (submitter, "submitted_applications")]
|
||||
checked_contacts.extend((contact, "contact_applications") for contact in other_contacts)
|
||||
checked_contacts = [(ao, "authorizing_official"), (submitter, "submitted_domain_requests")]
|
||||
checked_contacts.extend((contact, "contact_domain_requests") for contact in other_contacts)
|
||||
|
||||
for contact, related_name in checked_contacts:
|
||||
if contact is not None and not contact.has_more_than_one_join(related_name):
|
|
@ -7,8 +7,8 @@ def index(request):
|
|||
"""This page is available to anyone without logging in."""
|
||||
context = {}
|
||||
if request.user.is_authenticated:
|
||||
# Get all domain applications the user has access to
|
||||
applications, deletable_applications = _get_applications(request)
|
||||
# Get all domain requests the user has access to
|
||||
applications, deletable_domain_requests = _get_domain_requests(request)
|
||||
|
||||
context["domain_requests"] = applications
|
||||
|
||||
|
@ -17,11 +17,11 @@ def index(request):
|
|||
context["domains"] = domains
|
||||
|
||||
# Determine if the user will see applications that they can delete
|
||||
has_deletable_applications = deletable_applications.exists()
|
||||
context["has_deletable_applications"] = has_deletable_applications
|
||||
has_deletable_domain_requests = deletable_domain_requests.exists()
|
||||
context["has_deletable_domain_requests"] = has_deletable_domain_requests
|
||||
|
||||
# If they can delete applications, add the delete button to the context
|
||||
if has_deletable_applications:
|
||||
if has_deletable_domain_requests:
|
||||
# Add the delete modal button to the context
|
||||
modal_button = (
|
||||
'<button type="submit" '
|
||||
|
@ -33,7 +33,7 @@ def index(request):
|
|||
return render(request, "home.html", context)
|
||||
|
||||
|
||||
def _get_applications(request):
|
||||
def _get_domain_requests(request):
|
||||
"""Given the current request,
|
||||
get all DomainRequests that are associated with the UserDomainRole object.
|
||||
|
||||
|
@ -43,14 +43,14 @@ def _get_applications(request):
|
|||
# domain_requests context will be used to populate
|
||||
# the active applications table
|
||||
applications = DomainRequest.objects.filter(creator=request.user).exclude(
|
||||
status=DomainRequest.ApplicationStatus.APPROVED
|
||||
status=DomainRequest.DomainRequestStatus.APPROVED
|
||||
)
|
||||
|
||||
# Create a placeholder DraftDomain for each incomplete draft
|
||||
valid_statuses = [DomainRequest.ApplicationStatus.STARTED, DomainRequest.ApplicationStatus.WITHDRAWN]
|
||||
deletable_applications = applications.filter(status__in=valid_statuses)
|
||||
valid_statuses = [DomainRequest.DomainRequestStatus.STARTED, DomainRequest.DomainRequestStatus.WITHDRAWN]
|
||||
deletable_domain_requests = applications.filter(status__in=valid_statuses)
|
||||
|
||||
return (applications, deletable_applications)
|
||||
return (applications, deletable_domain_requests)
|
||||
|
||||
|
||||
def _get_domains(request):
|
||||
|
|
|
@ -6,5 +6,5 @@ from .permission_views import (
|
|||
DomainRequestPermissionView,
|
||||
DomainRequestPermissionWithdrawView,
|
||||
DomainInvitationPermissionDeleteView,
|
||||
ApplicationWizardPermissionView,
|
||||
DomainRequestWizardPermissionView,
|
||||
)
|
||||
|
|
|
@ -230,10 +230,10 @@ class DomainPermission(PermissionsLoginMixin):
|
|||
|
||||
# Analysts may manage domains, when they are in these statuses:
|
||||
valid_domain_statuses = [
|
||||
DomainRequest.ApplicationStatus.APPROVED,
|
||||
DomainRequest.ApplicationStatus.IN_REVIEW,
|
||||
DomainRequest.ApplicationStatus.REJECTED,
|
||||
DomainRequest.ApplicationStatus.ACTION_NEEDED,
|
||||
DomainRequest.DomainRequestStatus.APPROVED,
|
||||
DomainRequest.DomainRequestStatus.IN_REVIEW,
|
||||
DomainRequest.DomainRequestStatus.REJECTED,
|
||||
DomainRequest.DomainRequestStatus.ACTION_NEEDED,
|
||||
# Edge case - some domains do not have
|
||||
# a status or DomainInformation... aka a status of 'None'.
|
||||
# It is necessary to access those to correct errors.
|
||||
|
@ -274,7 +274,7 @@ class DomainRequestPermission(PermissionsLoginMixin):
|
|||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# user needs to be the creator of the application
|
||||
# user needs to be the creator of the domain request
|
||||
# this query is empty if there isn't a domain request with this
|
||||
# id and this user as creator
|
||||
if not DomainRequest.objects.filter(creator=self.request.user, id=self.kwargs["pk"]).exists():
|
||||
|
@ -328,7 +328,7 @@ class DomainRequestPermissionWithdraw(PermissionsLoginMixin):
|
|||
if not self.request.user.is_authenticated:
|
||||
return False
|
||||
|
||||
# user needs to be the creator of the application
|
||||
# user needs to be the creator of the domain request
|
||||
# this query is empty if there isn't a domain request with this
|
||||
# id and this user as creator
|
||||
if not DomainRequest.objects.filter(creator=self.request.user, id=self.kwargs["pk"]).exists():
|
||||
|
@ -341,12 +341,12 @@ class DomainRequestPermissionWithdraw(PermissionsLoginMixin):
|
|||
return True
|
||||
|
||||
|
||||
class ApplicationWizardPermission(PermissionsLoginMixin):
|
||||
class DomainRequestWizardPermission(PermissionsLoginMixin):
|
||||
"""Permission mixin that redirects to start or edit domain request if
|
||||
user has access, otherwise 403"""
|
||||
|
||||
def has_permission(self):
|
||||
"""Check if this user has permission to start or edit an application.
|
||||
"""Check if this user has permission to start or edit a domain request.
|
||||
|
||||
The user is in self.request.user
|
||||
"""
|
||||
|
|
|
@ -11,7 +11,7 @@ from .mixins import (
|
|||
DomainRequestPermission,
|
||||
DomainRequestPermissionWithdraw,
|
||||
DomainInvitationPermission,
|
||||
ApplicationWizardPermission,
|
||||
DomainRequestWizardPermission,
|
||||
UserDeleteDomainRolePermission,
|
||||
)
|
||||
import logging
|
||||
|
@ -57,7 +57,7 @@ class DomainPermissionView(DomainPermission, DetailView, abc.ABC):
|
|||
|
||||
|
||||
class DomainRequestPermissionView(DomainRequestPermission, DetailView, abc.ABC):
|
||||
"""Abstract base view for domain applications that enforces permissions
|
||||
"""Abstract base view for domain requests that enforces permissions
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
|
@ -94,8 +94,8 @@ class DomainRequestPermissionWithdrawView(DomainRequestPermissionWithdraw, Detai
|
|||
raise NotImplementedError
|
||||
|
||||
|
||||
class ApplicationWizardPermissionView(ApplicationWizardPermission, TemplateView, abc.ABC):
|
||||
"""Abstract base view for the application form that enforces permissions
|
||||
class DomainRequestWizardPermissionView(DomainRequestWizardPermission, TemplateView, abc.ABC):
|
||||
"""Abstract base view for the domain request form that enforces permissions
|
||||
|
||||
This abstract view cannot be instantiated. Actual views must specify
|
||||
`template_name`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue