mirror of
https://github.com/cisagov/manage.get.gov.git
synced 2025-05-15 17:17:02 +02:00
Merge pull request #2374 from cisagov/rh/2258-update-ao-to-so
ISSUE #2258: Update Authorizing Official to Senior Official
This commit is contained in:
commit
43697a5237
45 changed files with 565 additions and 442 deletions
|
@ -41,7 +41,7 @@ class DomainRequest {
|
||||||
--
|
--
|
||||||
creator (User)
|
creator (User)
|
||||||
investigator (User)
|
investigator (User)
|
||||||
authorizing_official (Contact)
|
senior_official (Contact)
|
||||||
submitter (Contact)
|
submitter (Contact)
|
||||||
other_contacts (Contacts)
|
other_contacts (Contacts)
|
||||||
approved_domain (Domain)
|
approved_domain (Domain)
|
||||||
|
@ -80,7 +80,7 @@ class Contact {
|
||||||
--
|
--
|
||||||
}
|
}
|
||||||
|
|
||||||
DomainRequest *-r-* Contact : authorizing_official, submitter, other_contacts
|
DomainRequest *-r-* Contact : senior_official, submitter, other_contacts
|
||||||
|
|
||||||
class DraftDomain {
|
class DraftDomain {
|
||||||
Requested domain
|
Requested domain
|
||||||
|
|
|
@ -20,7 +20,7 @@ docker compose exec app ./manage.py generate_puml --include registrar
|
||||||
## How To regenerate the database svg image
|
## How To regenerate the database svg image
|
||||||
|
|
||||||
1. Copy your puml file contents into the bottom of this file and replace the current code marked by `plantuml`
|
1. Copy your puml file contents into the bottom of this file and replace the current code marked by `plantuml`
|
||||||
2. Run the following command
|
2. Navigate to the `diagram` folder and then run the following command below:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -v $(pwd):$(pwd) -w $(pwd) -it plantuml/plantuml -tsvg models_diagram.md
|
docker run -v $(pwd):$(pwd) -w $(pwd) -it plantuml/plantuml -tsvg models_diagram.md
|
||||||
|
@ -103,6 +103,21 @@ class "registrar.PublicContact <Registrar>" as registrar.PublicContact #d6f4e9 {
|
||||||
registrar.PublicContact -- registrar.Domain
|
registrar.PublicContact -- registrar.Domain
|
||||||
|
|
||||||
|
|
||||||
|
class "registrar.UserDomainRole <Registrar>" as registrar.UserDomainRole #d6f4e9 {
|
||||||
|
user domain role
|
||||||
|
--
|
||||||
|
+ id (BigAutoField)
|
||||||
|
+ created_at (DateTimeField)
|
||||||
|
+ updated_at (DateTimeField)
|
||||||
|
~ user (ForeignKey)
|
||||||
|
~ domain (ForeignKey)
|
||||||
|
+ role (TextField)
|
||||||
|
--
|
||||||
|
}
|
||||||
|
registrar.UserDomainRole -- registrar.User
|
||||||
|
registrar.UserDomainRole -- registrar.Domain
|
||||||
|
|
||||||
|
|
||||||
class "registrar.Domain <Registrar>" as registrar.Domain #d6f4e9 {
|
class "registrar.Domain <Registrar>" as registrar.Domain #d6f4e9 {
|
||||||
domain
|
domain
|
||||||
--
|
--
|
||||||
|
@ -115,6 +130,7 @@ class "registrar.Domain <Registrar>" as registrar.Domain #d6f4e9 {
|
||||||
+ security_contact_registry_id (TextField)
|
+ security_contact_registry_id (TextField)
|
||||||
+ deleted (DateField)
|
+ deleted (DateField)
|
||||||
+ first_ready (DateField)
|
+ first_ready (DateField)
|
||||||
|
+ dsdata_last_change (TextField)
|
||||||
--
|
--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +142,7 @@ class "registrar.FederalAgency <Registrar>" as registrar.FederalAgency #d6f4e9 {
|
||||||
+ created_at (DateTimeField)
|
+ created_at (DateTimeField)
|
||||||
+ updated_at (DateTimeField)
|
+ updated_at (DateTimeField)
|
||||||
+ agency (CharField)
|
+ agency (CharField)
|
||||||
|
+ federal_type (CharField)
|
||||||
--
|
--
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +155,10 @@ class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
|
||||||
+ updated_at (DateTimeField)
|
+ updated_at (DateTimeField)
|
||||||
+ status (FSMField)
|
+ status (FSMField)
|
||||||
+ rejection_reason (TextField)
|
+ rejection_reason (TextField)
|
||||||
|
+ action_needed_reason (TextField)
|
||||||
|
+ action_needed_reason_email (TextField)
|
||||||
~ federal_agency (ForeignKey)
|
~ federal_agency (ForeignKey)
|
||||||
|
~ portfolio (ForeignKey)
|
||||||
~ creator (ForeignKey)
|
~ creator (ForeignKey)
|
||||||
~ investigator (ForeignKey)
|
~ investigator (ForeignKey)
|
||||||
+ generic_org_type (CharField)
|
+ generic_org_type (CharField)
|
||||||
|
@ -156,7 +176,7 @@ class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
|
||||||
+ zipcode (CharField)
|
+ zipcode (CharField)
|
||||||
+ urbanization (CharField)
|
+ urbanization (CharField)
|
||||||
+ about_your_organization (TextField)
|
+ about_your_organization (TextField)
|
||||||
~ authorizing_official (ForeignKey)
|
~ senior_official (ForeignKey)
|
||||||
~ approved_domain (OneToOneField)
|
~ approved_domain (OneToOneField)
|
||||||
~ requested_domain (OneToOneField)
|
~ requested_domain (OneToOneField)
|
||||||
~ submitter (ForeignKey)
|
~ submitter (ForeignKey)
|
||||||
|
@ -165,6 +185,8 @@ class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
|
||||||
+ anything_else (TextField)
|
+ anything_else (TextField)
|
||||||
+ has_anything_else_text (BooleanField)
|
+ has_anything_else_text (BooleanField)
|
||||||
+ cisa_representative_email (EmailField)
|
+ cisa_representative_email (EmailField)
|
||||||
|
+ cisa_representative_first_name (CharField)
|
||||||
|
+ cisa_representative_last_name (CharField)
|
||||||
+ has_cisa_representative (BooleanField)
|
+ has_cisa_representative (BooleanField)
|
||||||
+ is_policy_acknowledged (BooleanField)
|
+ is_policy_acknowledged (BooleanField)
|
||||||
+ submission_date (DateField)
|
+ submission_date (DateField)
|
||||||
|
@ -175,6 +197,7 @@ class "registrar.DomainRequest <Registrar>" as registrar.DomainRequest #d6f4e9 {
|
||||||
--
|
--
|
||||||
}
|
}
|
||||||
registrar.DomainRequest -- registrar.FederalAgency
|
registrar.DomainRequest -- registrar.FederalAgency
|
||||||
|
registrar.DomainRequest -- registrar.Portfolio
|
||||||
registrar.DomainRequest -- registrar.User
|
registrar.DomainRequest -- registrar.User
|
||||||
registrar.DomainRequest -- registrar.User
|
registrar.DomainRequest -- registrar.User
|
||||||
registrar.DomainRequest -- registrar.Contact
|
registrar.DomainRequest -- registrar.Contact
|
||||||
|
@ -194,6 +217,7 @@ class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #
|
||||||
+ updated_at (DateTimeField)
|
+ updated_at (DateTimeField)
|
||||||
~ federal_agency (ForeignKey)
|
~ federal_agency (ForeignKey)
|
||||||
~ creator (ForeignKey)
|
~ creator (ForeignKey)
|
||||||
|
~ portfolio (ForeignKey)
|
||||||
~ domain_request (OneToOneField)
|
~ domain_request (OneToOneField)
|
||||||
+ generic_org_type (CharField)
|
+ generic_org_type (CharField)
|
||||||
+ organization_type (CharField)
|
+ organization_type (CharField)
|
||||||
|
@ -210,13 +234,17 @@ class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #
|
||||||
+ zipcode (CharField)
|
+ zipcode (CharField)
|
||||||
+ urbanization (CharField)
|
+ urbanization (CharField)
|
||||||
+ about_your_organization (TextField)
|
+ about_your_organization (TextField)
|
||||||
~ authorizing_official (ForeignKey)
|
~ senior_official (ForeignKey)
|
||||||
~ domain (OneToOneField)
|
~ domain (OneToOneField)
|
||||||
~ submitter (ForeignKey)
|
~ submitter (ForeignKey)
|
||||||
+ purpose (TextField)
|
+ purpose (TextField)
|
||||||
+ no_other_contacts_rationale (TextField)
|
+ no_other_contacts_rationale (TextField)
|
||||||
+ anything_else (TextField)
|
+ anything_else (TextField)
|
||||||
|
+ has_anything_else_text (BooleanField)
|
||||||
+ cisa_representative_email (EmailField)
|
+ cisa_representative_email (EmailField)
|
||||||
|
+ cisa_representative_first_name (CharField)
|
||||||
|
+ cisa_representative_last_name (CharField)
|
||||||
|
+ has_cisa_representative (BooleanField)
|
||||||
+ is_policy_acknowledged (BooleanField)
|
+ is_policy_acknowledged (BooleanField)
|
||||||
+ notes (TextField)
|
+ notes (TextField)
|
||||||
# other_contacts (ManyToManyField)
|
# other_contacts (ManyToManyField)
|
||||||
|
@ -224,6 +252,7 @@ class "registrar.DomainInformation <Registrar>" as registrar.DomainInformation #
|
||||||
}
|
}
|
||||||
registrar.DomainInformation -- registrar.FederalAgency
|
registrar.DomainInformation -- registrar.FederalAgency
|
||||||
registrar.DomainInformation -- registrar.User
|
registrar.DomainInformation -- registrar.User
|
||||||
|
registrar.DomainInformation -- registrar.Portfolio
|
||||||
registrar.DomainInformation -- registrar.DomainRequest
|
registrar.DomainInformation -- registrar.DomainRequest
|
||||||
registrar.DomainInformation -- registrar.Contact
|
registrar.DomainInformation -- registrar.Contact
|
||||||
registrar.DomainInformation -- registrar.Domain
|
registrar.DomainInformation -- registrar.Domain
|
||||||
|
@ -242,21 +271,6 @@ class "registrar.DraftDomain <Registrar>" as registrar.DraftDomain #d6f4e9 {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class "registrar.UserDomainRole <Registrar>" as registrar.UserDomainRole #d6f4e9 {
|
|
||||||
user domain role
|
|
||||||
--
|
|
||||||
+ id (BigAutoField)
|
|
||||||
+ created_at (DateTimeField)
|
|
||||||
+ updated_at (DateTimeField)
|
|
||||||
~ user (ForeignKey)
|
|
||||||
~ domain (ForeignKey)
|
|
||||||
+ role (TextField)
|
|
||||||
--
|
|
||||||
}
|
|
||||||
registrar.UserDomainRole -- registrar.User
|
|
||||||
registrar.UserDomainRole -- registrar.Domain
|
|
||||||
|
|
||||||
|
|
||||||
class "registrar.DomainInvitation <Registrar>" as registrar.DomainInvitation #d6f4e9 {
|
class "registrar.DomainInvitation <Registrar>" as registrar.DomainInvitation #d6f4e9 {
|
||||||
domain invitation
|
domain invitation
|
||||||
--
|
--
|
||||||
|
@ -388,6 +402,58 @@ class "registrar.WaffleFlag <Registrar>" as registrar.WaffleFlag #d6f4e9 {
|
||||||
registrar.WaffleFlag *--* registrar.User
|
registrar.WaffleFlag *--* registrar.User
|
||||||
|
|
||||||
|
|
||||||
|
class "registrar.Portfolio <Registrar>" as registrar.Portfolio #d6f4e9 {
|
||||||
|
portfolio
|
||||||
|
--
|
||||||
|
+ id (BigAutoField)
|
||||||
|
+ created_at (DateTimeField)
|
||||||
|
+ updated_at (DateTimeField)
|
||||||
|
~ creator (ForeignKey)
|
||||||
|
+ notes (TextField)
|
||||||
|
~ federal_agency (ForeignKey)
|
||||||
|
+ organization_type (CharField)
|
||||||
|
+ organization_name (CharField)
|
||||||
|
+ address_line1 (CharField)
|
||||||
|
+ address_line2 (CharField)
|
||||||
|
+ city (CharField)
|
||||||
|
+ state_territory (CharField)
|
||||||
|
+ zipcode (CharField)
|
||||||
|
+ urbanization (CharField)
|
||||||
|
+ security_contact_email (EmailField)
|
||||||
|
--
|
||||||
|
}
|
||||||
|
registrar.Portfolio -- registrar.User
|
||||||
|
registrar.Portfolio -- registrar.FederalAgency
|
||||||
|
|
||||||
|
|
||||||
|
class "registrar.DomainGroup <Registrar>" as registrar.DomainGroup #d6f4e9 {
|
||||||
|
domain group
|
||||||
|
--
|
||||||
|
+ id (BigAutoField)
|
||||||
|
+ created_at (DateTimeField)
|
||||||
|
+ updated_at (DateTimeField)
|
||||||
|
+ name (CharField)
|
||||||
|
~ portfolio (ForeignKey)
|
||||||
|
# domains (ManyToManyField)
|
||||||
|
--
|
||||||
|
}
|
||||||
|
registrar.DomainGroup -- registrar.Portfolio
|
||||||
|
registrar.DomainGroup *--* registrar.DomainInformation
|
||||||
|
|
||||||
|
|
||||||
|
class "registrar.Suborganization <Registrar>" as registrar.Suborganization #d6f4e9 {
|
||||||
|
suborganization
|
||||||
|
--
|
||||||
|
+ id (BigAutoField)
|
||||||
|
+ created_at (DateTimeField)
|
||||||
|
+ updated_at (DateTimeField)
|
||||||
|
+ name (CharField)
|
||||||
|
~ portfolio (ForeignKey)
|
||||||
|
--
|
||||||
|
}
|
||||||
|
registrar.Suborganization -- registrar.Portfolio
|
||||||
|
|
||||||
|
|
||||||
@enduml
|
@enduml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 116 KiB |
|
@ -11,7 +11,7 @@
|
||||||
"http://localhost:8080/request/org_federal/",
|
"http://localhost:8080/request/org_federal/",
|
||||||
"http://localhost:8080/request/org_election/",
|
"http://localhost:8080/request/org_election/",
|
||||||
"http://localhost:8080/request/org_contact/",
|
"http://localhost:8080/request/org_contact/",
|
||||||
"http://localhost:8080/request/authorizing_official/",
|
"http://localhost:8080/request/senior_official/",
|
||||||
"http://localhost:8080/request/current_sites/",
|
"http://localhost:8080/request/current_sites/",
|
||||||
"http://localhost:8080/request/dotgov_domain/",
|
"http://localhost:8080/request/dotgov_domain/",
|
||||||
"http://localhost:8080/request/purpose/",
|
"http://localhost:8080/request/purpose/",
|
||||||
|
|
|
@ -444,7 +444,7 @@ class AdminSortFields:
|
||||||
sort_mapping = {
|
sort_mapping = {
|
||||||
# == Contact == #
|
# == Contact == #
|
||||||
"other_contacts": (Contact, _name_sort),
|
"other_contacts": (Contact, _name_sort),
|
||||||
"authorizing_official": (Contact, _name_sort),
|
"senior_official": (Contact, _name_sort),
|
||||||
"submitter": (Contact, _name_sort),
|
"submitter": (Contact, _name_sort),
|
||||||
# == User == #
|
# == User == #
|
||||||
"creator": (User, _name_sort),
|
"creator": (User, _name_sort),
|
||||||
|
@ -1235,7 +1235,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None, {"fields": ["portfolio", "creator", "submitter", "domain_request", "notes"]}),
|
(None, {"fields": ["portfolio", "creator", "submitter", "domain_request", "notes"]}),
|
||||||
(".gov domain", {"fields": ["domain"]}),
|
(".gov domain", {"fields": ["domain"]}),
|
||||||
("Contacts", {"fields": ["authorizing_official", "other_contacts", "no_other_contacts_rationale"]}),
|
("Contacts", {"fields": ["senior_official", "other_contacts", "no_other_contacts_rationale"]}),
|
||||||
("Background info", {"fields": ["anything_else"]}),
|
("Background info", {"fields": ["anything_else"]}),
|
||||||
(
|
(
|
||||||
"Type of organization",
|
"Type of organization",
|
||||||
|
@ -1309,7 +1309,7 @@ class DomainInformationAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
autocomplete_fields = [
|
autocomplete_fields = [
|
||||||
"creator",
|
"creator",
|
||||||
"domain_request",
|
"domain_request",
|
||||||
"authorizing_official",
|
"senior_official",
|
||||||
"domain",
|
"domain",
|
||||||
"submitter",
|
"submitter",
|
||||||
]
|
]
|
||||||
|
@ -1525,7 +1525,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
"Contacts",
|
"Contacts",
|
||||||
{
|
{
|
||||||
"fields": [
|
"fields": [
|
||||||
"authorizing_official",
|
"senior_official",
|
||||||
"other_contacts",
|
"other_contacts",
|
||||||
"no_other_contacts_rationale",
|
"no_other_contacts_rationale",
|
||||||
"cisa_representative_first_name",
|
"cisa_representative_first_name",
|
||||||
|
@ -1614,7 +1614,7 @@ class DomainRequestAdmin(ListHeaderAdmin, ImportExportModelAdmin):
|
||||||
"requested_domain",
|
"requested_domain",
|
||||||
"submitter",
|
"submitter",
|
||||||
"creator",
|
"creator",
|
||||||
"authorizing_official",
|
"senior_official",
|
||||||
"investigator",
|
"investigator",
|
||||||
]
|
]
|
||||||
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
|
filter_horizontal = ("current_websites", "alternative_domains", "other_contacts")
|
||||||
|
@ -2039,7 +2039,7 @@ class DomainInformationInline(admin.StackedInline):
|
||||||
autocomplete_fields = [
|
autocomplete_fields = [
|
||||||
"creator",
|
"creator",
|
||||||
"domain_request",
|
"domain_request",
|
||||||
"authorizing_official",
|
"senior_official",
|
||||||
"domain",
|
"domain",
|
||||||
"submitter",
|
"submitter",
|
||||||
]
|
]
|
||||||
|
|
|
@ -44,7 +44,7 @@ for step, view in [
|
||||||
(Step.ORGANIZATION_ELECTION, views.OrganizationElection),
|
(Step.ORGANIZATION_ELECTION, views.OrganizationElection),
|
||||||
(Step.ORGANIZATION_CONTACT, views.OrganizationContact),
|
(Step.ORGANIZATION_CONTACT, views.OrganizationContact),
|
||||||
(Step.ABOUT_YOUR_ORGANIZATION, views.AboutYourOrganization),
|
(Step.ABOUT_YOUR_ORGANIZATION, views.AboutYourOrganization),
|
||||||
(Step.AUTHORIZING_OFFICIAL, views.AuthorizingOfficial),
|
(Step.SENIOR_OFFICIAL, views.SeniorOfficial),
|
||||||
(Step.CURRENT_SITES, views.CurrentSites),
|
(Step.CURRENT_SITES, views.CurrentSites),
|
||||||
(Step.DOTGOV_DOMAIN, views.DotgovDomain),
|
(Step.DOTGOV_DOMAIN, views.DotgovDomain),
|
||||||
(Step.PURPOSE, views.Purpose),
|
(Step.PURPOSE, views.Purpose),
|
||||||
|
@ -183,9 +183,9 @@ urlpatterns = [
|
||||||
name="domain-org-name-address",
|
name="domain-org-name-address",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"domain/<int:pk>/authorizing-official",
|
"domain/<int:pk>/senior-official",
|
||||||
views.DomainAuthorizingOfficialView.as_view(),
|
views.DomainSeniorOfficialView.as_view(),
|
||||||
name="domain-authorizing-official",
|
name="domain-senior-official",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"domain/<int:pk>/security-email",
|
"domain/<int:pk>/security-email",
|
||||||
|
|
|
@ -36,7 +36,7 @@ class DomainRequestFixture:
|
||||||
# "purpose": None,
|
# "purpose": None,
|
||||||
# "anything_else": None,
|
# "anything_else": None,
|
||||||
# "is_policy_acknowledged": None,
|
# "is_policy_acknowledged": None,
|
||||||
# "authorizing_official": None,
|
# "senior_official": None,
|
||||||
# "submitter": None,
|
# "submitter": None,
|
||||||
# "other_contacts": [],
|
# "other_contacts": [],
|
||||||
# "current_websites": [],
|
# "current_websites": [],
|
||||||
|
@ -117,11 +117,11 @@ class DomainRequestFixture:
|
||||||
if not da.investigator:
|
if not da.investigator:
|
||||||
da.investigator = User.objects.get(username=user.username) if "investigator" in app else None
|
da.investigator = User.objects.get(username=user.username) if "investigator" in app else None
|
||||||
|
|
||||||
if not da.authorizing_official:
|
if not da.senior_official:
|
||||||
if "authorizing_official" in app and app["authorizing_official"] is not None:
|
if "senior_official" in app and app["senior_official"] is not None:
|
||||||
da.authorizing_official, _ = Contact.objects.get_or_create(**app["authorizing_official"])
|
da.senior_official, _ = Contact.objects.get_or_create(**app["senior_official"])
|
||||||
else:
|
else:
|
||||||
da.authorizing_official = Contact.objects.create(**cls.fake_contact())
|
da.senior_official = Contact.objects.create(**cls.fake_contact())
|
||||||
|
|
||||||
if not da.submitter:
|
if not da.submitter:
|
||||||
if "submitter" in app and app["submitter"] is not None:
|
if "submitter" in app and app["submitter"] is not None:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from .domain import (
|
||||||
DomainSecurityEmailForm,
|
DomainSecurityEmailForm,
|
||||||
DomainOrgNameAddressForm,
|
DomainOrgNameAddressForm,
|
||||||
ContactForm,
|
ContactForm,
|
||||||
AuthorizingOfficialContactForm,
|
SeniorOfficialContactForm,
|
||||||
DomainDnssecForm,
|
DomainDnssecForm,
|
||||||
DomainDsdataFormset,
|
DomainDsdataFormset,
|
||||||
DomainDsdataForm,
|
DomainDsdataForm,
|
||||||
|
|
|
@ -260,10 +260,10 @@ class ContactForm(forms.ModelForm):
|
||||||
self.domainInfo = domainInfo
|
self.domainInfo = domainInfo
|
||||||
|
|
||||||
|
|
||||||
class AuthorizingOfficialContactForm(ContactForm):
|
class SeniorOfficialContactForm(ContactForm):
|
||||||
"""Form for updating authorizing official contacts."""
|
"""Form for updating senior official contacts."""
|
||||||
|
|
||||||
JOIN = "authorizing_official"
|
JOIN = "senior_official"
|
||||||
|
|
||||||
def __init__(self, disable_fields=False, *args, **kwargs):
|
def __init__(self, disable_fields=False, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
@ -273,13 +273,13 @@ class AuthorizingOfficialContactForm(ContactForm):
|
||||||
|
|
||||||
# Set custom error messages
|
# Set custom error messages
|
||||||
self.fields["first_name"].error_messages = {
|
self.fields["first_name"].error_messages = {
|
||||||
"required": "Enter the first name / given name of your authorizing official."
|
"required": "Enter the first name / given name of your senior official."
|
||||||
}
|
}
|
||||||
self.fields["last_name"].error_messages = {
|
self.fields["last_name"].error_messages = {
|
||||||
"required": "Enter the last name / family name of your authorizing official."
|
"required": "Enter the last name / family name of your senior official."
|
||||||
}
|
}
|
||||||
self.fields["title"].error_messages = {
|
self.fields["title"].error_messages = {
|
||||||
"required": "Enter the title or role your authorizing official has in your \
|
"required": "Enter the title or role your senior official has in your \
|
||||||
organization (e.g., Chief Information Officer)."
|
organization (e.g., Chief Information Officer)."
|
||||||
}
|
}
|
||||||
self.fields["email"].error_messages = {
|
self.fields["email"].error_messages = {
|
||||||
|
@ -306,21 +306,21 @@ class AuthorizingOfficialContactForm(ContactForm):
|
||||||
is_federal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL
|
is_federal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.FEDERAL
|
||||||
is_tribal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.TRIBAL
|
is_tribal = self.domainInfo.generic_org_type == DomainRequest.OrganizationChoices.TRIBAL
|
||||||
|
|
||||||
# Get the Contact object from the db for the Authorizing Official
|
# Get the Contact object from the db for the Senior Official
|
||||||
db_ao = Contact.objects.get(id=self.instance.id)
|
db_so = Contact.objects.get(id=self.instance.id)
|
||||||
|
|
||||||
if (is_federal or is_tribal) and self.has_changed():
|
if (is_federal or is_tribal) and self.has_changed():
|
||||||
# This action should be blocked by the UI, as the text fields are readonly.
|
# This action should be blocked by the UI, as the text fields are readonly.
|
||||||
# If they get past this point, we forbid it this way.
|
# If they get past this point, we forbid it this way.
|
||||||
# This could be malicious, so lets reserve information for the backend only.
|
# This could be malicious, so lets reserve information for the backend only.
|
||||||
raise ValueError("Authorizing Official cannot be modified for federal or tribal domains.")
|
raise ValueError("Senior Official cannot be modified for federal or tribal domains.")
|
||||||
elif db_ao.has_more_than_one_join("information_authorizing_official"):
|
elif db_so.has_more_than_one_join("information_senior_official"):
|
||||||
# Handle the case where the domain information object is available and the AO Contact
|
# Handle the case where the domain information object is available and the SO Contact
|
||||||
# has more than one joined object.
|
# has more than one joined object.
|
||||||
# In this case, create a new Contact, and update the new Contact with form data.
|
# In this case, create a new Contact, and update the new Contact with form data.
|
||||||
# Then associate with domain information object as the authorizing_official
|
# Then associate with domain information object as the senior_official
|
||||||
data = dict(self.cleaned_data.items())
|
data = dict(self.cleaned_data.items())
|
||||||
self.domainInfo.authorizing_official = Contact.objects.create(**data)
|
self.domainInfo.senior_official = Contact.objects.create(**data)
|
||||||
self.domainInfo.save()
|
self.domainInfo.save()
|
||||||
else:
|
else:
|
||||||
# If all checks pass, just save normally
|
# If all checks pass, just save normally
|
||||||
|
|
|
@ -183,14 +183,14 @@ class AboutYourOrganizationForm(RegistrarForm):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class AuthorizingOfficialForm(RegistrarForm):
|
class SeniorOfficialForm(RegistrarForm):
|
||||||
JOIN = "authorizing_official"
|
JOIN = "senior_official"
|
||||||
|
|
||||||
def to_database(self, obj):
|
def to_database(self, obj):
|
||||||
if not self.is_valid():
|
if not self.is_valid():
|
||||||
return
|
return
|
||||||
contact = getattr(obj, "authorizing_official", None)
|
contact = getattr(obj, "senior_official", None)
|
||||||
if contact is not None and not contact.has_more_than_one_join("authorizing_official"):
|
if contact is not None and not contact.has_more_than_one_join("senior_official"):
|
||||||
# if contact exists in the database and is not joined to other entities
|
# if contact exists in the database and is not joined to other entities
|
||||||
super().to_database(contact)
|
super().to_database(contact)
|
||||||
else:
|
else:
|
||||||
|
@ -198,27 +198,27 @@ class AuthorizingOfficialForm(RegistrarForm):
|
||||||
# in either case, create a new contact and update it
|
# in either case, create a new contact and update it
|
||||||
contact = Contact()
|
contact = Contact()
|
||||||
super().to_database(contact)
|
super().to_database(contact)
|
||||||
obj.authorizing_official = contact
|
obj.senior_official = contact
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_database(cls, obj):
|
def from_database(cls, obj):
|
||||||
contact = getattr(obj, "authorizing_official", None)
|
contact = getattr(obj, "senior_official", None)
|
||||||
return super().from_database(contact)
|
return super().from_database(contact)
|
||||||
|
|
||||||
first_name = forms.CharField(
|
first_name = forms.CharField(
|
||||||
label="First name / given name",
|
label="First name / given name",
|
||||||
error_messages={"required": ("Enter the first name / given name of your authorizing official.")},
|
error_messages={"required": ("Enter the first name / given name of your senior official.")},
|
||||||
)
|
)
|
||||||
last_name = forms.CharField(
|
last_name = forms.CharField(
|
||||||
label="Last name / family name",
|
label="Last name / family name",
|
||||||
error_messages={"required": ("Enter the last name / family name of your authorizing official.")},
|
error_messages={"required": ("Enter the last name / family name of your senior official.")},
|
||||||
)
|
)
|
||||||
title = forms.CharField(
|
title = forms.CharField(
|
||||||
label="Title or role in your organization",
|
label="Title or role in your organization",
|
||||||
error_messages={
|
error_messages={
|
||||||
"required": (
|
"required": (
|
||||||
"Enter the title or role your authorizing official has in your"
|
"Enter the title or role your senior official has in your"
|
||||||
" organization (e.g., Chief Information Officer)."
|
" organization (e.g., Chief Information Officer)."
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
|
@ -390,7 +390,7 @@ class Command(BaseCommand):
|
||||||
fed_type = transition_domain.federal_type
|
fed_type = transition_domain.federal_type
|
||||||
fed_agency = transition_domain.federal_agency
|
fed_agency = transition_domain.federal_agency
|
||||||
|
|
||||||
# = AO Information = #
|
# = SO Information = #
|
||||||
first_name = transition_domain.first_name
|
first_name = transition_domain.first_name
|
||||||
middle_name = transition_domain.middle_name
|
middle_name = transition_domain.middle_name
|
||||||
last_name = transition_domain.last_name
|
last_name = transition_domain.last_name
|
||||||
|
@ -429,7 +429,7 @@ class Command(BaseCommand):
|
||||||
"domain": domain,
|
"domain": domain,
|
||||||
"organization_name": transition_domain.organization_name,
|
"organization_name": transition_domain.organization_name,
|
||||||
"creator": default_creator,
|
"creator": default_creator,
|
||||||
"authorizing_official": contact,
|
"senior_official": contact,
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid_org_type:
|
if valid_org_type:
|
||||||
|
|
|
@ -177,7 +177,7 @@ class LoadExtraTransitionDomain:
|
||||||
# STEP 3: Parse agency data
|
# STEP 3: Parse agency data
|
||||||
updated_transition_domain = self.parse_agency_data(domain_name, transition_domain)
|
updated_transition_domain = self.parse_agency_data(domain_name, transition_domain)
|
||||||
|
|
||||||
# STEP 4: Parse ao data
|
# STEP 4: Parse so data
|
||||||
updated_transition_domain = self.parse_authority_data(domain_name, transition_domain)
|
updated_transition_domain = self.parse_authority_data(domain_name, transition_domain)
|
||||||
|
|
||||||
# STEP 5: Parse creation and expiration data
|
# STEP 5: Parse creation and expiration data
|
||||||
|
@ -326,7 +326,7 @@ class LoadExtraTransitionDomain:
|
||||||
)
|
)
|
||||||
|
|
||||||
def parse_authority_data(self, domain_name, transition_domain) -> TransitionDomain:
|
def parse_authority_data(self, domain_name, transition_domain) -> TransitionDomain:
|
||||||
"""Grabs authorizing_offical data from the parsed files and associates it
|
"""Grabs senior_offical data from the parsed files and associates it
|
||||||
with a transition_domain object, then returns that object."""
|
with a transition_domain object, then returns that object."""
|
||||||
if not isinstance(transition_domain, TransitionDomain):
|
if not isinstance(transition_domain, TransitionDomain):
|
||||||
raise ValueError("Not a valid object, must be TransitionDomain")
|
raise ValueError("Not a valid object, must be TransitionDomain")
|
||||||
|
@ -336,7 +336,7 @@ class LoadExtraTransitionDomain:
|
||||||
self.parse_logs.create_log_item(
|
self.parse_logs.create_log_item(
|
||||||
EnumFilenames.AGENCY_ADHOC,
|
EnumFilenames.AGENCY_ADHOC,
|
||||||
LogCode.ERROR,
|
LogCode.ERROR,
|
||||||
f"Could not add authorizing_official on {domain_name}, no data exists.",
|
f"Could not add senior_official on {domain_name}, no data exists.",
|
||||||
domain_name,
|
domain_name,
|
||||||
not self.debug,
|
not self.debug,
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
# Generated by Django 4.2.10 on 2024-06-24 19:00
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("registrar", "0107_domainrequest_action_needed_reason_email"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="authorizing_official",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="authorizing_official",
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domaininformation",
|
||||||
|
name="senior_official",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="information_senior_official",
|
||||||
|
to="registrar.contact",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="senior_official",
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="senior_official",
|
||||||
|
to="registrar.contact",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="domainrequest",
|
||||||
|
name="action_needed_reason",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
("eligibility_unclear", "Unclear organization eligibility"),
|
||||||
|
("questionable_senior_official", "Questionable senior official"),
|
||||||
|
("already_has_domains", "Already has domains"),
|
||||||
|
("bad_name", "Doesn’t meet naming requirements"),
|
||||||
|
("other", "Other (no auto-email sent)"),
|
||||||
|
],
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -171,11 +171,11 @@ class DomainInformation(TimeStampedModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
authorizing_official = models.ForeignKey(
|
senior_official = models.ForeignKey(
|
||||||
"registrar.Contact",
|
"registrar.Contact",
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name="information_authorizing_official",
|
related_name="information_senior_official",
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -266,7 +266,7 @@ class DomainRequest(TimeStampedModel):
|
||||||
"""Defines common action needed reasons for domain requests"""
|
"""Defines common action needed reasons for domain requests"""
|
||||||
|
|
||||||
ELIGIBILITY_UNCLEAR = ("eligibility_unclear", "Unclear organization eligibility")
|
ELIGIBILITY_UNCLEAR = ("eligibility_unclear", "Unclear organization eligibility")
|
||||||
QUESTIONABLE_AUTHORIZING_OFFICIAL = ("questionable_authorizing_official", "Questionable authorizing official")
|
QUESTIONABLE_SENIOR_OFFICIAL = ("questionable_senior_official", "Questionable senior official")
|
||||||
ALREADY_HAS_DOMAINS = ("already_has_domains", "Already has domains")
|
ALREADY_HAS_DOMAINS = ("already_has_domains", "Already has domains")
|
||||||
BAD_NAME = ("bad_name", "Doesn’t meet naming requirements")
|
BAD_NAME = ("bad_name", "Doesn’t meet naming requirements")
|
||||||
OTHER = ("other", "Other (no auto-email sent)")
|
OTHER = ("other", "Other (no auto-email sent)")
|
||||||
|
@ -423,11 +423,11 @@ class DomainRequest(TimeStampedModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
authorizing_official = models.ForeignKey(
|
senior_official = models.ForeignKey(
|
||||||
"registrar.Contact",
|
"registrar.Contact",
|
||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
related_name="authorizing_official",
|
related_name="senior_official",
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -1128,8 +1128,8 @@ class DomainRequest(TimeStampedModel):
|
||||||
and self.zipcode is None
|
and self.zipcode is None
|
||||||
)
|
)
|
||||||
|
|
||||||
def _is_authorizing_official_complete(self):
|
def _is_senior_official_complete(self):
|
||||||
return self.authorizing_official is not None
|
return self.senior_official is not None
|
||||||
|
|
||||||
def _is_requested_domain_complete(self):
|
def _is_requested_domain_complete(self):
|
||||||
return self.requested_domain is not None
|
return self.requested_domain is not None
|
||||||
|
@ -1191,10 +1191,10 @@ class DomainRequest(TimeStampedModel):
|
||||||
has_profile_feature_flag = flag_is_active(request, "profile_feature")
|
has_profile_feature_flag = flag_is_active(request, "profile_feature")
|
||||||
return (
|
return (
|
||||||
self._is_organization_name_and_address_complete()
|
self._is_organization_name_and_address_complete()
|
||||||
and self._is_authorizing_official_complete()
|
and self._is_senior_official_complete()
|
||||||
and self._is_requested_domain_complete()
|
and self._is_requested_domain_complete()
|
||||||
and self._is_purpose_complete()
|
and self._is_purpose_complete()
|
||||||
# NOTE: This flag leaves submitter as empty (request wont submit) hence preset to True
|
# NOTE: This flag leaves submitter as empty (request wont submit) hence set to True
|
||||||
and (self._is_submitter_complete() if not has_profile_feature_flag else True)
|
and (self._is_submitter_complete() if not has_profile_feature_flag else True)
|
||||||
and self._is_other_contacts_complete()
|
and self._is_other_contacts_complete()
|
||||||
and self._is_additional_details_complete()
|
and self._is_additional_details_complete()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<p>
|
<p>
|
||||||
Contacts include anyone who has access to the registrar (known as “users”) and anyone listed in a domain request,
|
Contacts include anyone who has access to the registrar (known as “users”) and anyone listed in a domain request,
|
||||||
including other employees and authorizing officials.
|
including other employees and senior officials.
|
||||||
Only contacts who have access to the registrar will have
|
Only contacts who have access to the registrar will have
|
||||||
a corresponding record within the <a class="text-underline" href="{% url 'admin:registrar_user_changelist' %}">Users</a> table.
|
a corresponding record within the <a class="text-underline" href="{% url 'admin:registrar_user_changelist' %}">Users</a> table.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -153,10 +153,10 @@ This is using a custom implementation fieldset.html (see admin/fieldset.html)
|
||||||
<label aria-label="Submitter contact details"></label>
|
<label aria-label="Submitter contact details"></label>
|
||||||
{% include "django/admin/includes/contact_detail_list.html" with user=original_object.submitter no_title_top_padding=field.is_readonly %}
|
{% include "django/admin/includes/contact_detail_list.html" with user=original_object.submitter no_title_top_padding=field.is_readonly %}
|
||||||
</div>
|
</div>
|
||||||
{% elif field.field.name == "authorizing_official" %}
|
{% elif field.field.name == "senior_official" %}
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<label aria-label="Authorizing official contact details"></label>
|
<label aria-label="Senior official contact details"></label>
|
||||||
{% include "django/admin/includes/contact_detail_list.html" with user=original_object.authorizing_official no_title_top_padding=field.is_readonly %}
|
{% include "django/admin/includes/contact_detail_list.html" with user=original_object.senior_official no_title_top_padding=field.is_readonly %}
|
||||||
</div>
|
</div>
|
||||||
{% elif field.field.name == "other_contacts" and original_object.other_contacts.all %}
|
{% elif field.field.name == "other_contacts" and original_object.other_contacts.all %}
|
||||||
{% with all_contacts=original_object.other_contacts.all %}
|
{% with all_contacts=original_object.other_contacts.all %}
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
{% url 'domain-org-name-address' pk=domain.id as url %}
|
{% url 'domain-org-name-address' pk=domain.id as url %}
|
||||||
{% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url editable=domain.is_editable %}
|
{% include "includes/summary_item.html" with title='Organization name and mailing address' value=domain.domain_info address='true' edit_link=url editable=domain.is_editable %}
|
||||||
|
|
||||||
{% url 'domain-authorizing-official' pk=domain.id as url %}
|
{% url 'domain-senior-official' pk=domain.id as url %}
|
||||||
{% include "includes/summary_item.html" with title='Authorizing official' value=domain.domain_info.authorizing_official contact='true' edit_link=url editable=domain.is_editable %}
|
{% include "includes/summary_item.html" with title='Senior official' value=domain.domain_info.senior_official contact='true' edit_link=url editable=domain.is_editable %}
|
||||||
|
|
||||||
{# Conditionally display profile #}
|
{# Conditionally display profile #}
|
||||||
{% if not has_profile_feature_flag %}
|
{% if not has_profile_feature_flag %}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
{% extends 'domain_request_form.html' %}
|
|
||||||
{% load field_helpers url_helpers %}
|
|
||||||
|
|
||||||
{% block form_instructions %}
|
|
||||||
<h2 class="margin-bottom-05">
|
|
||||||
Who is the authorizing official for your organization?
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
{% if not is_federal %}
|
|
||||||
<p>Your authorizing official is a person within your organization who can authorize your domain request. This person must be in a role of significant, executive responsibility within the organization.</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<div class="ao_example">
|
|
||||||
{% include "includes/ao_example.html" %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p>We typically don’t reach out to the authorizing official, but if contact is necessary, our practice is to coordinate with you, the requestor, first.</p>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
|
|
||||||
{% block form_fields %}
|
|
||||||
<fieldset class="usa-fieldset">
|
|
||||||
<legend class="usa-sr-only">
|
|
||||||
Who is the authorizing official for your organization?
|
|
||||||
</legend>
|
|
||||||
|
|
||||||
{% input_with_errors forms.0.first_name %}
|
|
||||||
|
|
||||||
{% input_with_errors forms.0.last_name %}
|
|
||||||
|
|
||||||
{% input_with_errors forms.0.title %}
|
|
||||||
|
|
||||||
{% input_with_errors forms.0.email %}
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
{% endblock %}
|
|
|
@ -40,7 +40,7 @@
|
||||||
<p>We may need to suspend or terminate a domain registration for violations of these requirements. When we discover a violation, we’ll make reasonable efforts to contact a registrant, including emails or phone calls to:
|
<p>We may need to suspend or terminate a domain registration for violations of these requirements. When we discover a violation, we’ll make reasonable efforts to contact a registrant, including emails or phone calls to:
|
||||||
<ul class="usa-list">
|
<ul class="usa-list">
|
||||||
<li>Domain contacts</li>
|
<li>Domain contacts</li>
|
||||||
<li>The authorizing official</li>
|
<li>The senior official</li>
|
||||||
<li>The government organization, a parent organization, or affiliated entities</li>
|
<li>The government organization, a parent organization, or affiliated entities</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -79,10 +79,10 @@
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if step == Step.AUTHORIZING_OFFICIAL %}
|
{% if step == Step.SENIOR_OFFICIAL %}
|
||||||
{% namespaced_url 'domain-request' step as domain_request_url %}
|
{% namespaced_url 'domain-request' step as domain_request_url %}
|
||||||
{% if domain_request.authorizing_official is not None %}
|
{% if domain_request.senior_official is not None %}
|
||||||
{% with title=form_titles|get_item:step value=domain_request.authorizing_official %}
|
{% with title=form_titles|get_item:step value=domain_request.senior_official %}
|
||||||
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' %}
|
{% include "includes/summary_item.html" with title=title value=value heading_level=heading_level editable=True edit_link=domain_request_url contact='true' %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
37
src/registrar/templates/domain_request_senior_official.html
Normal file
37
src/registrar/templates/domain_request_senior_official.html
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
{% extends 'domain_request_form.html' %}
|
||||||
|
{% load field_helpers url_helpers %}
|
||||||
|
|
||||||
|
{% block form_instructions %}
|
||||||
|
<h2 class="margin-bottom-05">
|
||||||
|
Who is the senior official for your organization?
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
{% if not is_federal %}
|
||||||
|
<p>Your senior official is a person within your organization who can authorize your domain request. This person must be in a role of significant, executive responsibility within the organization.</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="so_example">
|
||||||
|
{% include "includes/so_example.html" %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>We typically don’t reach out to the senior official, but if contact is necessary, our practice is to coordinate with you, the requestor, first.</p>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block form_fields %}
|
||||||
|
<fieldset class="usa-fieldset">
|
||||||
|
<legend class="usa-sr-only">
|
||||||
|
Who is the senior official for your organization?
|
||||||
|
</legend>
|
||||||
|
|
||||||
|
{% input_with_errors forms.0.first_name %}
|
||||||
|
|
||||||
|
{% input_with_errors forms.0.last_name %}
|
||||||
|
|
||||||
|
{% input_with_errors forms.0.title %}
|
||||||
|
|
||||||
|
{% input_with_errors forms.0.email %}
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
{% endblock %}
|
|
@ -86,8 +86,8 @@
|
||||||
{% include "includes/summary_item.html" with title='About your organization' value=DomainRequest.about_your_organization heading_level=heading_level %}
|
{% include "includes/summary_item.html" with title='About your organization' value=DomainRequest.about_your_organization heading_level=heading_level %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if DomainRequest.authorizing_official %}
|
{% if DomainRequest.senior_official %}
|
||||||
{% include "includes/summary_item.html" with title='Authorizing official' value=DomainRequest.authorizing_official contact='true' heading_level=heading_level %}
|
{% include "includes/summary_item.html" with title='Senior official' value=DomainRequest.senior_official contact='true' heading_level=heading_level %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if DomainRequest.current_websites.all %}
|
{% if DomainRequest.current_websites.all %}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
{% extends "domain_base.html" %}
|
{% extends "domain_base.html" %}
|
||||||
{% load static field_helpers url_helpers %}
|
{% load static field_helpers url_helpers %}
|
||||||
|
|
||||||
{% block title %}Authorizing official | {{ domain.name }} | {% endblock %}
|
{% block title %}Senior official | {{ domain.name }} | {% endblock %}
|
||||||
|
|
||||||
{% block domain_content %}
|
{% block domain_content %}
|
||||||
{# this is right after the messages block in the parent template #}
|
{# this is right after the messages block in the parent template #}
|
||||||
{% include "includes/form_errors.html" with form=form %}
|
{% include "includes/form_errors.html" with form=form %}
|
||||||
|
|
||||||
<h1>Authorizing official</h1>
|
<h1>Senior official</h1>
|
||||||
|
|
||||||
<p>Your authorizing official is a person within your organization who can
|
<p>Your senior official is a person within your organization who can
|
||||||
authorize domain requests. This person must be in a role of significant, executive responsibility within the organization. Read more about <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'domains/eligibility/#you-must-have-approval-from-an-authorizing-official-within-your-organization' %}">who can serve as an authorizing official</a>.</p>
|
authorize domain requests. This person must be in a role of significant, executive responsibility within the organization. Read more about <a class="usa-link" rel="noopener noreferrer" target="_blank" href="{% public_site_url 'domains/eligibility/#you-must-have-approval-from-a-senior-official-within-your-organization' %}">who can serve as a senior official</a>.</p>
|
||||||
|
|
||||||
{% if generic_org_type == "federal" or generic_org_type == "tribal" %}
|
{% if generic_org_type == "federal" or generic_org_type == "tribal" %}
|
||||||
<p>
|
<p>
|
||||||
The authorizing official for your organization can’t be updated here.
|
The senior official for your organization can’t be updated here.
|
||||||
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
|
To suggest an update, email <a href="mailto:help@get.gov" class="usa-link">help@get.gov</a>.
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -27,10 +27,10 @@
|
||||||
|
|
||||||
{% if generic_org_type == "federal" or generic_org_type == "tribal" %}
|
{% if generic_org_type == "federal" or generic_org_type == "tribal" %}
|
||||||
{# If all fields are disabled, add SR content #}
|
{# If all fields are disabled, add SR content #}
|
||||||
<div class="usa-sr-only" aria-labelledby="id_first_name" id="sr-ao-first-name">{{ form.first_name.value }}</div>
|
<div class="usa-sr-only" aria-labelledby="id_first_name" id="sr-so-first-name">{{ form.first_name.value }}</div>
|
||||||
<div class="usa-sr-only" aria-labelledby="id_last_name" id="sr-ao-last-name">{{ form.last_name.value }}</div>
|
<div class="usa-sr-only" aria-labelledby="id_last_name" id="sr-so-last-name">{{ form.last_name.value }}</div>
|
||||||
<div class="usa-sr-only" aria-labelledby="id_title" id="sr-ao-title">{{ form.title.value }}</div>
|
<div class="usa-sr-only" aria-labelledby="id_title" id="sr-so-title">{{ form.title.value }}</div>
|
||||||
<div class="usa-sr-only" aria-labelledby="id_email" id="sr-ao-email">{{ form.email.value }}</div>
|
<div class="usa-sr-only" aria-labelledby="id_email" id="sr-so-email">{{ form.email.value }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% input_with_errors form.first_name %}
|
{% input_with_errors form.first_name %}
|
|
@ -65,11 +65,11 @@
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="usa-sidenav__item">
|
<li class="usa-sidenav__item">
|
||||||
{% url 'domain-authorizing-official' pk=domain.id as url %}
|
{% url 'domain-senior-official' pk=domain.id as url %}
|
||||||
<a href="{{ url }}"
|
<a href="{{ url }}"
|
||||||
{% if request.path == url %}class="usa-current"{% endif %}
|
{% if request.path == url %}class="usa-current"{% endif %}
|
||||||
>
|
>
|
||||||
Authorizing official
|
Senior official
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Domain managers can update all information related to a domain within the
|
Domain managers can update all information related to a domain within the
|
||||||
.gov registrar, including contact details, authorizing official, security
|
.gov registrar, including contact details, senior official, security
|
||||||
email, and DNS name servers.
|
email, and DNS name servers.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
@ -9,18 +9,18 @@ STATUS: Action needed
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
AUTHORIZING OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS
|
SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS
|
||||||
We've reviewed your domain request, but we need more information about the authorizing official listed on the request:
|
We've reviewed your domain request, but we need more information about the senior official listed on the request:
|
||||||
- {{ domain_request.authorizing_official.get_formatted_name }}
|
- {{ domain_request.senior_official.get_formatted_name }}
|
||||||
- {{ domain_request.authorizing_official.title }}
|
- {{ domain_request.senior_official.title }}
|
||||||
|
|
||||||
We expect an authorizing official to be someone in a role of significant, executive responsibility within the organization. Our guidelines are open-ended to accommodate the wide variety of government organizations that are eligible for .gov domains, but the person you listed does not meet our expectations for your type of organization. Read more about our guidelines for authorizing officials. <https://get.gov/domains/eligibility/>
|
We expect a senior official to be someone in a role of significant, executive responsibility within the organization. Our guidelines are open-ended to accommodate the wide variety of government organizations that are eligible for .gov domains, but the person you listed does not meet our expectations for your type of organization. Read more about our guidelines for senior officials. <https://get.gov/domains/eligibility/>
|
||||||
|
|
||||||
|
|
||||||
ACTION NEEDED
|
ACTION NEEDED
|
||||||
Reply to this email with a justification for naming {{ domain_request.authorizing_official.get_formatted_name }} as the authorizing official. If you have questions or comments, include those in your reply.
|
Reply to this email with a justification for naming {{ domain_request.senior_official.get_formatted_name }} as the senior official. If you have questions or comments, include those in your reply.
|
||||||
|
|
||||||
Alternatively, you can log in to the registrar and enter a different authorizing official for this domain request. <https://manage.get.gov/> Once you submit your updated request, we’ll resume the adjudication process.
|
Alternatively, you can log in to the registrar and enter a different senior official for this domain request. <https://manage.get.gov/> Once you submit your updated request, we’ll resume the adjudication process.
|
||||||
|
|
||||||
|
|
||||||
THANK YOU
|
THANK YOU
|
|
@ -27,8 +27,8 @@ Organization name and mailing address:
|
||||||
About your organization:
|
About your organization:
|
||||||
{% spaceless %}{{ domain_request.about_your_organization }}{% endspaceless %}
|
{% spaceless %}{{ domain_request.about_your_organization }}{% endspaceless %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
Authorizing official:
|
Senior official:
|
||||||
{% spaceless %}{% include "emails/includes/contact.txt" with contact=domain_request.authorizing_official %}{% endspaceless %}
|
{% spaceless %}{% include "emails/includes/contact.txt" with contact=domain_request.senior_official %}{% endspaceless %}
|
||||||
{% if domain_request.current_websites.exists %}{# if block makes a newline #}
|
{% if domain_request.current_websites.exists %}{# if block makes a newline #}
|
||||||
Current websites: {% for site in domain_request.current_websites.all %}
|
Current websites: {% for site in domain_request.current_websites.all %}
|
||||||
{% spaceless %}{{ site.website }}{% endspaceless %}
|
{% spaceless %}{{ site.website }}{% endspaceless %}
|
||||||
|
|
|
@ -389,7 +389,7 @@ class AuditedAdminMockData:
|
||||||
zipcode: str = "10002",
|
zipcode: str = "10002",
|
||||||
about_your_organization: str = "e-Government",
|
about_your_organization: str = "e-Government",
|
||||||
anything_else: str = "There is more",
|
anything_else: str = "There is more",
|
||||||
authorizing_official: Contact = self.dummy_contact(item_name, "authorizing_official"),
|
senior_official: Contact = self.dummy_contact(item_name, "senior_official"),
|
||||||
submitter: Contact = self.dummy_contact(item_name, "submitter"),
|
submitter: Contact = self.dummy_contact(item_name, "submitter"),
|
||||||
creator: User = self.dummy_user(item_name, "creator"),
|
creator: User = self.dummy_user(item_name, "creator"),
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ class AuditedAdminMockData:
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
about_your_organization="e-Government",
|
about_your_organization="e-Government",
|
||||||
anything_else="There is more",
|
anything_else="There is more",
|
||||||
authorizing_official=self.dummy_contact(item_name, "authorizing_official"),
|
senior_official=self.dummy_contact(item_name, "senior_official"),
|
||||||
submitter=self.dummy_contact(item_name, "submitter"),
|
submitter=self.dummy_contact(item_name, "submitter"),
|
||||||
creator=creator,
|
creator=creator,
|
||||||
)
|
)
|
||||||
|
@ -864,7 +864,7 @@ def completed_domain_request( # noqa
|
||||||
"""A completed domain request."""
|
"""A completed domain request."""
|
||||||
if not user:
|
if not user:
|
||||||
user = get_user_model().objects.create(username="username" + str(uuid.uuid4())[:8])
|
user = get_user_model().objects.create(username="username" + str(uuid.uuid4())[:8])
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -908,7 +908,7 @@ def completed_domain_request( # noqa
|
||||||
address_line2="address 2",
|
address_line2="address 2",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
requested_domain=domain,
|
requested_domain=domain,
|
||||||
submitter=submitter,
|
submitter=submitter,
|
||||||
creator=user,
|
creator=user,
|
||||||
|
|
|
@ -288,7 +288,7 @@ class TestDomainAdmin(MockEppLib, WebTest):
|
||||||
self.assertContains(response, "(555) 555 5556")
|
self.assertContains(response, "(555) 555 5556")
|
||||||
self.assertContains(response, "Testy2 Tester2")
|
self.assertContains(response, "Testy2 Tester2")
|
||||||
|
|
||||||
# == Check for the authorizing_official == #
|
# == Check for the senior_official == #
|
||||||
self.assertContains(response, "testy@town.com")
|
self.assertContains(response, "testy@town.com")
|
||||||
self.assertContains(response, "Chief Tester")
|
self.assertContains(response, "Chief Tester")
|
||||||
self.assertContains(response, "(555) 555 5555")
|
self.assertContains(response, "(555) 555 5555")
|
||||||
|
@ -1464,11 +1464,11 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
)
|
)
|
||||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
self.assertEqual(len(self.mock_client.EMAILS_SENT), 3)
|
||||||
|
|
||||||
# Test the email sent out for questionable_ao
|
# Test the email sent out for questionable_so
|
||||||
questionable_ao = DomainRequest.ActionNeededReasons.QUESTIONABLE_AUTHORIZING_OFFICIAL
|
questionable_so = DomainRequest.ActionNeededReasons.QUESTIONABLE_SENIOR_OFFICIAL
|
||||||
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=questionable_ao)
|
self.transition_state_and_send_email(domain_request, action_needed, action_needed_reason=questionable_so)
|
||||||
self.assert_email_is_accurate(
|
self.assert_email_is_accurate(
|
||||||
"AUTHORIZING OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, EMAIL, bcc_email_address=BCC_EMAIL
|
"SENIOR OFFICIAL DOES NOT MEET ELIGIBILITY REQUIREMENTS", 3, EMAIL, bcc_email_address=BCC_EMAIL
|
||||||
)
|
)
|
||||||
self.assertEqual(len(self.mock_client.EMAILS_SENT), 4)
|
self.assertEqual(len(self.mock_client.EMAILS_SENT), 4)
|
||||||
|
|
||||||
|
@ -2114,16 +2114,15 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
|
self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
|
||||||
self.assertContains(response, "Testy2 Tester2")
|
self.assertContains(response, "Testy2 Tester2")
|
||||||
|
|
||||||
# == Check for the authorizing_official == #
|
# == Check for the senior_official == #
|
||||||
self.assertContains(response, "testy@town.com", count=2)
|
self.assertContains(response, "testy@town.com", count=2)
|
||||||
expected_ao_fields = [
|
expected_so_fields = [
|
||||||
# Field, expected value
|
# Field, expected value
|
||||||
("phone", "(555) 555 5555"),
|
("phone", "(555) 555 5555"),
|
||||||
]
|
]
|
||||||
self.test_helper.assert_response_contains_distinct_values(response, expected_ao_fields)
|
|
||||||
self.assertContains(response, "Chief Tester")
|
|
||||||
|
|
||||||
self.assertContains(response, "Testy Tester")
|
self.test_helper.assert_response_contains_distinct_values(response, expected_so_fields)
|
||||||
|
self.assertContains(response, "Chief Tester")
|
||||||
|
|
||||||
# == Test the other_employees field == #
|
# == Test the other_employees field == #
|
||||||
self.assertContains(response, "testy2@town.com")
|
self.assertContains(response, "testy2@town.com")
|
||||||
|
@ -2267,7 +2266,7 @@ class TestDomainRequestAdmin(MockEppLib):
|
||||||
"zipcode",
|
"zipcode",
|
||||||
"urbanization",
|
"urbanization",
|
||||||
"about_your_organization",
|
"about_your_organization",
|
||||||
"authorizing_official",
|
"senior_official",
|
||||||
"approved_domain",
|
"approved_domain",
|
||||||
"requested_domain",
|
"requested_domain",
|
||||||
"submitter",
|
"submitter",
|
||||||
|
@ -3157,14 +3156,14 @@ class TestDomainInformationAdmin(TestCase):
|
||||||
self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
|
self.test_helper.assert_response_contains_distinct_values(response, expected_submitter_fields)
|
||||||
self.assertContains(response, "Testy2 Tester2")
|
self.assertContains(response, "Testy2 Tester2")
|
||||||
|
|
||||||
# == Check for the authorizing_official == #
|
# == Check for the senior_official == #
|
||||||
self.assertContains(response, "testy@town.com", count=2)
|
self.assertContains(response, "testy@town.com", count=2)
|
||||||
expected_ao_fields = [
|
expected_so_fields = [
|
||||||
# Field, expected value
|
# Field, expected value
|
||||||
("title", "Chief Tester"),
|
("title", "Chief Tester"),
|
||||||
("phone", "(555) 555 5555"),
|
("phone", "(555) 555 5555"),
|
||||||
]
|
]
|
||||||
self.test_helper.assert_response_contains_distinct_values(response, expected_ao_fields)
|
self.test_helper.assert_response_contains_distinct_values(response, expected_so_fields)
|
||||||
|
|
||||||
self.assertContains(response, "Testy Tester", count=10)
|
self.assertContains(response, "Testy Tester", count=10)
|
||||||
|
|
||||||
|
@ -3712,7 +3711,7 @@ class AuditedAdminTest(TestCase):
|
||||||
def test_alphabetically_sorted_fk_fields_domain_request(self):
|
def test_alphabetically_sorted_fk_fields_domain_request(self):
|
||||||
with less_console_noise():
|
with less_console_noise():
|
||||||
tested_fields = [
|
tested_fields = [
|
||||||
DomainRequest.authorizing_official.field,
|
DomainRequest.senior_official.field,
|
||||||
DomainRequest.submitter.field,
|
DomainRequest.submitter.field,
|
||||||
# DomainRequest.investigator.field,
|
# DomainRequest.investigator.field,
|
||||||
DomainRequest.creator.field,
|
DomainRequest.creator.field,
|
||||||
|
@ -3770,7 +3769,7 @@ class AuditedAdminTest(TestCase):
|
||||||
def test_alphabetically_sorted_fk_fields_domain_information(self):
|
def test_alphabetically_sorted_fk_fields_domain_information(self):
|
||||||
with less_console_noise():
|
with less_console_noise():
|
||||||
tested_fields = [
|
tested_fields = [
|
||||||
DomainInformation.authorizing_official.field,
|
DomainInformation.senior_official.field,
|
||||||
DomainInformation.submitter.field,
|
DomainInformation.submitter.field,
|
||||||
# DomainInformation.creator.field,
|
# DomainInformation.creator.field,
|
||||||
(DomainInformation.domain.field, ["name"]),
|
(DomainInformation.domain.field, ["name"]),
|
||||||
|
|
|
@ -59,7 +59,7 @@ class TestEmails(TestCase):
|
||||||
|
|
||||||
self.assertIn("Type of organization:", body)
|
self.assertIn("Type of organization:", body)
|
||||||
self.assertIn("Federal", body)
|
self.assertIn("Federal", body)
|
||||||
self.assertIn("Authorizing official:", body)
|
self.assertIn("Senior official:", body)
|
||||||
self.assertIn("Testy Tester", body)
|
self.assertIn("Testy Tester", body)
|
||||||
self.assertIn(".gov domain:", body)
|
self.assertIn(".gov domain:", body)
|
||||||
self.assertIn("city.gov", body)
|
self.assertIn("city.gov", body)
|
||||||
|
@ -177,7 +177,7 @@ class TestEmails(TestCase):
|
||||||
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
body = kwargs["Content"]["Simple"]["Body"]["Text"]["Data"]
|
||||||
self.assertNotIn("About your organization:", body)
|
self.assertNotIn("About your organization:", body)
|
||||||
# spacing should be right between adjacent elements
|
# spacing should be right between adjacent elements
|
||||||
self.assertRegex(body, r"10002\n\nAuthorizing official:")
|
self.assertRegex(body, r"10002\n\nSenior official:")
|
||||||
|
|
||||||
@boto3_mocking.patching
|
@boto3_mocking.patching
|
||||||
def test_submission_confirmation_anything_else_spacing(self):
|
def test_submission_confirmation_anything_else_spacing(self):
|
||||||
|
|
|
@ -8,7 +8,7 @@ from registrar.forms.domain_request_wizard import (
|
||||||
AlternativeDomainForm,
|
AlternativeDomainForm,
|
||||||
CurrentSitesForm,
|
CurrentSitesForm,
|
||||||
DotGovDomainForm,
|
DotGovDomainForm,
|
||||||
AuthorizingOfficialForm,
|
SeniorOfficialForm,
|
||||||
OrganizationContactForm,
|
OrganizationContactForm,
|
||||||
YourContactForm,
|
YourContactForm,
|
||||||
OtherContactsForm,
|
OtherContactsForm,
|
||||||
|
@ -217,9 +217,9 @@ class TestFormValidation(MockEppLib):
|
||||||
["Enter a domain using only letters, numbers, or hyphens (though we don't recommend using hyphens)."],
|
["Enter a domain using only letters, numbers, or hyphens (though we don't recommend using hyphens)."],
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_authorizing_official_email_invalid(self):
|
def test_senior_official_email_invalid(self):
|
||||||
"""must be a valid email address."""
|
"""must be a valid email address."""
|
||||||
form = AuthorizingOfficialForm(data={"email": "boss@boss"})
|
form = SeniorOfficialForm(data={"email": "boss@boss"})
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
form.errors["email"],
|
form.errors["email"],
|
||||||
["Enter an email address in the required format, like name@example.com."],
|
["Enter an email address in the required format, like name@example.com."],
|
||||||
|
|
|
@ -151,7 +151,7 @@ class TestDomainRequest(TestCase):
|
||||||
address_line2="APT 1A",
|
address_line2="APT 1A",
|
||||||
state_territory="CA",
|
state_territory="CA",
|
||||||
zipcode="12345-6789",
|
zipcode="12345-6789",
|
||||||
authorizing_official=contact,
|
senior_official=contact,
|
||||||
requested_domain=domain,
|
requested_domain=domain,
|
||||||
submitter=contact,
|
submitter=contact,
|
||||||
purpose="Igorville rules!",
|
purpose="Igorville rules!",
|
||||||
|
@ -179,7 +179,7 @@ class TestDomainRequest(TestCase):
|
||||||
address_line2="APT 1A",
|
address_line2="APT 1A",
|
||||||
state_territory="CA",
|
state_territory="CA",
|
||||||
zipcode="12345-6789",
|
zipcode="12345-6789",
|
||||||
authorizing_official=contact,
|
senior_official=contact,
|
||||||
submitter=contact,
|
submitter=contact,
|
||||||
purpose="Igorville rules!",
|
purpose="Igorville rules!",
|
||||||
anything_else="All of Igorville loves the dotgov program.",
|
anything_else="All of Igorville loves the dotgov program.",
|
||||||
|
@ -1233,8 +1233,8 @@ class TestContact(TestCase):
|
||||||
)
|
)
|
||||||
self.contact, _ = Contact.objects.get_or_create(user=self.user)
|
self.contact, _ = Contact.objects.get_or_create(user=self.user)
|
||||||
|
|
||||||
self.contact_as_ao, _ = Contact.objects.get_or_create(email="newguy@igorville.gov")
|
self.contact_as_so, _ = Contact.objects.get_or_create(email="newguy@igorville.gov")
|
||||||
self.domain_request = DomainRequest.objects.create(creator=self.user, authorizing_official=self.contact_as_ao)
|
self.domain_request = DomainRequest.objects.create(creator=self.user, senior_official=self.contact_as_so)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
super().tearDown()
|
super().tearDown()
|
||||||
|
@ -1327,10 +1327,10 @@ class TestContact(TestCase):
|
||||||
"""Test the Contact model method, has_more_than_one_join"""
|
"""Test the Contact model method, has_more_than_one_join"""
|
||||||
# test for a contact which has one user defined
|
# test for a contact which has one user defined
|
||||||
self.assertFalse(self.contact.has_more_than_one_join("user"))
|
self.assertFalse(self.contact.has_more_than_one_join("user"))
|
||||||
self.assertTrue(self.contact.has_more_than_one_join("authorizing_official"))
|
self.assertTrue(self.contact.has_more_than_one_join("senior_official"))
|
||||||
# test for a contact which is assigned as an authorizing official on a domain request
|
# test for a contact which is assigned as a senior official on a domain request
|
||||||
self.assertFalse(self.contact_as_ao.has_more_than_one_join("authorizing_official"))
|
self.assertFalse(self.contact_as_so.has_more_than_one_join("senior_official"))
|
||||||
self.assertTrue(self.contact_as_ao.has_more_than_one_join("submitted_domain_requests"))
|
self.assertTrue(self.contact_as_so.has_more_than_one_join("submitted_domain_requests"))
|
||||||
|
|
||||||
def test_has_contact_info(self):
|
def test_has_contact_info(self):
|
||||||
"""Test that has_contact_info properly returns"""
|
"""Test that has_contact_info properly returns"""
|
||||||
|
@ -1660,7 +1660,7 @@ class TestDomainRequestIncomplete(TestCase):
|
||||||
self.user = get_user_model().objects.create(
|
self.user = get_user_model().objects.create(
|
||||||
username=username, first_name=first_name, last_name=last_name, email=email
|
username=username, first_name=first_name, last_name=last_name, email=email
|
||||||
)
|
)
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Meowy",
|
first_name="Meowy",
|
||||||
last_name="Meoward",
|
last_name="Meoward",
|
||||||
title="Chief Cat",
|
title="Chief Cat",
|
||||||
|
@ -1695,7 +1695,7 @@ class TestDomainRequestIncomplete(TestCase):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="CA",
|
state_territory="CA",
|
||||||
zipcode="94044",
|
zipcode="94044",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
requested_domain=draft_domain,
|
requested_domain=draft_domain,
|
||||||
purpose="Some purpose",
|
purpose="Some purpose",
|
||||||
submitter=you,
|
submitter=you,
|
||||||
|
@ -1793,11 +1793,11 @@ class TestDomainRequestIncomplete(TestCase):
|
||||||
self.domain_request.save()
|
self.domain_request.save()
|
||||||
self.assertTrue(self.domain_request._is_organization_name_and_address_complete())
|
self.assertTrue(self.domain_request._is_organization_name_and_address_complete())
|
||||||
|
|
||||||
def test_is_authorizing_official_complete(self):
|
def test_is_senior_official_complete(self):
|
||||||
self.assertTrue(self.domain_request._is_authorizing_official_complete())
|
self.assertTrue(self.domain_request._is_senior_official_complete())
|
||||||
self.domain_request.authorizing_official = None
|
self.domain_request.senior_official = None
|
||||||
self.domain_request.save()
|
self.domain_request.save()
|
||||||
self.assertFalse(self.domain_request._is_authorizing_official_complete())
|
self.assertFalse(self.domain_request._is_senior_official_complete())
|
||||||
|
|
||||||
def test_is_requested_domain_complete(self):
|
def test_is_requested_domain_complete(self):
|
||||||
self.assertTrue(self.domain_request._is_requested_domain_complete())
|
self.assertTrue(self.domain_request._is_requested_domain_complete())
|
||||||
|
|
|
@ -232,8 +232,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
"Organization name",
|
"Organization name",
|
||||||
"City",
|
"City",
|
||||||
"State",
|
"State",
|
||||||
"AO",
|
"SO",
|
||||||
"AO email",
|
"SO email",
|
||||||
"Security contact email",
|
"Security contact email",
|
||||||
"Status",
|
"Status",
|
||||||
"Expiration date",
|
"Expiration date",
|
||||||
|
@ -265,8 +265,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
# We expect READY domains,
|
# We expect READY domains,
|
||||||
# sorted alphabetially by domain name
|
# sorted alphabetially by domain name
|
||||||
expected_content = (
|
expected_content = (
|
||||||
"Domain name,Domain type,Agency,Organization name,City,State,AO,"
|
"Domain name,Domain type,Agency,Organization name,City,State,SO,"
|
||||||
"AO email,Security contact email,Status,Expiration date, First ready on\n"
|
"SO email,Security contact email,Status,Expiration date, First ready on\n"
|
||||||
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready,(blank),2024-04-03\n"
|
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready,(blank),2024-04-03\n"
|
||||||
"adomain2.gov,Interstate,(blank),Dns needed,(blank),(blank)\n"
|
"adomain2.gov,Interstate,(blank),Dns needed,(blank),(blank)\n"
|
||||||
"cdomain11.gov,Federal-Executive,WorldWarICentennialCommission,Ready,(blank),2024-04-02\n"
|
"cdomain11.gov,Federal-Executive,WorldWarICentennialCommission,Ready,(blank),2024-04-02\n"
|
||||||
|
@ -299,8 +299,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
"Organization name",
|
"Organization name",
|
||||||
"City",
|
"City",
|
||||||
"State",
|
"State",
|
||||||
"AO",
|
"SO",
|
||||||
"AO email",
|
"SO email",
|
||||||
"Submitter",
|
"Submitter",
|
||||||
"Submitter title",
|
"Submitter title",
|
||||||
"Submitter email",
|
"Submitter email",
|
||||||
|
@ -332,8 +332,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
# We expect READY domains,
|
# We expect READY domains,
|
||||||
# sorted alphabetially by domain name
|
# sorted alphabetially by domain name
|
||||||
expected_content = (
|
expected_content = (
|
||||||
"Domain name,Domain type,Agency,Organization name,City,State,AO,"
|
"Domain name,Domain type,Agency,Organization name,City,State,SO,"
|
||||||
"AO email,Submitter,Submitter title,Submitter email,Submitter phone,"
|
"SO email,Submitter,Submitter title,Submitter email,Submitter phone,"
|
||||||
"Security contact email,Status\n"
|
"Security contact email,Status\n"
|
||||||
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n"
|
"adomain10.gov,Federal,Armed Forces Retirement Home,Ready\n"
|
||||||
"adomain2.gov,Interstate,Dns needed\n"
|
"adomain2.gov,Interstate,Dns needed\n"
|
||||||
|
@ -522,8 +522,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
"Organization name",
|
"Organization name",
|
||||||
"City",
|
"City",
|
||||||
"State",
|
"State",
|
||||||
"AO",
|
"SO",
|
||||||
"AO email",
|
"SO email",
|
||||||
"Security contact email",
|
"Security contact email",
|
||||||
]
|
]
|
||||||
sort_fields = ["domain__name"]
|
sort_fields = ["domain__name"]
|
||||||
|
@ -553,7 +553,7 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
# sorted alphabetially by domain name
|
# sorted alphabetially by domain name
|
||||||
expected_content = (
|
expected_content = (
|
||||||
"Domain name,Status,Expiration date,Domain type,Agency,"
|
"Domain name,Status,Expiration date,Domain type,Agency,"
|
||||||
"Organization name,City,State,AO,AO email,"
|
"Organization name,City,State,SO,SO email,"
|
||||||
"Security contact email,Domain manager 1,DM1 status,Domain manager 2,DM2 status,"
|
"Security contact email,Domain manager 1,DM1 status,Domain manager 2,DM2 status,"
|
||||||
"Domain manager 3,DM3 status,Domain manager 4,DM4 status\n"
|
"Domain manager 3,DM3 status,Domain manager 4,DM4 status\n"
|
||||||
"adomain10.gov,Ready,(blank),Federal,Armed Forces Retirement Home,,,, , ,squeaker@rocks.com, I\n"
|
"adomain10.gov,Ready,(blank),Federal,Armed Forces Retirement Home,,,, , ,squeaker@rocks.com, I\n"
|
||||||
|
@ -717,10 +717,10 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
additional_values = [
|
additional_values = [
|
||||||
"requested_domain__name",
|
"requested_domain__name",
|
||||||
"federal_agency__agency",
|
"federal_agency__agency",
|
||||||
"authorizing_official__first_name",
|
"senior_official__first_name",
|
||||||
"authorizing_official__last_name",
|
"senior_official__last_name",
|
||||||
"authorizing_official__email",
|
"senior_official__email",
|
||||||
"authorizing_official__title",
|
"senior_official__title",
|
||||||
"creator__first_name",
|
"creator__first_name",
|
||||||
"creator__last_name",
|
"creator__last_name",
|
||||||
"creator__email",
|
"creator__email",
|
||||||
|
@ -741,8 +741,8 @@ class ExportDataTest(MockDb, MockEppLib):
|
||||||
"Domain request,Submitted at,Status,Domain type,Federal type,"
|
"Domain request,Submitted at,Status,Domain type,Federal type,"
|
||||||
"Federal agency,Organization name,Election office,City,State/territory,"
|
"Federal agency,Organization name,Election office,City,State/territory,"
|
||||||
"Region,Creator first name,Creator last name,Creator email,Creator approved domains count,"
|
"Region,Creator first name,Creator last name,Creator email,Creator approved domains count,"
|
||||||
"Creator active requests count,Alternative domains,AO first name,AO last name,AO email,"
|
"Creator active requests count,Alternative domains,SO first name,SO last name,SO email,"
|
||||||
"AO title/role,Request purpose,Request additional details,Other contacts,"
|
"SO title/role,Request purpose,Request additional details,Other contacts,"
|
||||||
"CISA regional representative,Current websites,Investigator\n"
|
"CISA regional representative,Current websites,Investigator\n"
|
||||||
# Content
|
# Content
|
||||||
"city2.gov,,In review,Federal,Executive,,Testorg,N/A,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com,"
|
"city2.gov,,In review,Federal,Executive,,Testorg,N/A,,NY,2,,,,0,1,city1.gov,Testy,Tester,testy@town.com,"
|
||||||
|
|
|
@ -398,7 +398,7 @@ class TestOrganizationMigration(TestCase):
|
||||||
federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
|
federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
|
||||||
|
|
||||||
expected_creator = User.objects.filter(username="System").get()
|
expected_creator = User.objects.filter(username="System").get()
|
||||||
expected_ao = Contact.objects.filter(
|
expected_so = Contact.objects.filter(
|
||||||
first_name="Seline", middle_name="testmiddle2", last_name="Tower"
|
first_name="Seline", middle_name="testmiddle2", last_name="Tower"
|
||||||
).get()
|
).get()
|
||||||
expected_domain_information = DomainInformation(
|
expected_domain_information = DomainInformation(
|
||||||
|
@ -411,7 +411,7 @@ class TestOrganizationMigration(TestCase):
|
||||||
city="Columbus",
|
city="Columbus",
|
||||||
state_territory="Oh",
|
state_territory="Oh",
|
||||||
zipcode="43268",
|
zipcode="43268",
|
||||||
authorizing_official=expected_ao,
|
senior_official=expected_so,
|
||||||
domain=_domain,
|
domain=_domain,
|
||||||
)
|
)
|
||||||
# Given that these are different objects, this needs to be set
|
# Given that these are different objects, this needs to be set
|
||||||
|
@ -454,7 +454,7 @@ class TestOrganizationMigration(TestCase):
|
||||||
federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
|
federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
|
||||||
|
|
||||||
expected_creator = User.objects.filter(username="System").get()
|
expected_creator = User.objects.filter(username="System").get()
|
||||||
expected_ao = Contact.objects.filter(
|
expected_so = Contact.objects.filter(
|
||||||
first_name="Seline", middle_name="testmiddle2", last_name="Tower"
|
first_name="Seline", middle_name="testmiddle2", last_name="Tower"
|
||||||
).get()
|
).get()
|
||||||
expected_domain_information = DomainInformation(
|
expected_domain_information = DomainInformation(
|
||||||
|
@ -467,7 +467,7 @@ class TestOrganizationMigration(TestCase):
|
||||||
city="Olympus",
|
city="Olympus",
|
||||||
state_territory="MA",
|
state_territory="MA",
|
||||||
zipcode="12345",
|
zipcode="12345",
|
||||||
authorizing_official=expected_ao,
|
senior_official=expected_so,
|
||||||
domain=_domain,
|
domain=_domain,
|
||||||
)
|
)
|
||||||
# Given that these are different objects, this needs to be set
|
# Given that these are different objects, this needs to be set
|
||||||
|
|
|
@ -381,7 +381,7 @@ class HomeTests(TestWithUser):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site,
|
requested_domain=site,
|
||||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||||
authorizing_official=contact,
|
senior_official=contact,
|
||||||
submitter=contact_user,
|
submitter=contact_user,
|
||||||
)
|
)
|
||||||
domain_request.other_contacts.set([contact_2])
|
domain_request.other_contacts.set([contact_2])
|
||||||
|
@ -392,7 +392,7 @@ class HomeTests(TestWithUser):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site_2,
|
requested_domain=site_2,
|
||||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||||
authorizing_official=contact_2,
|
senior_official=contact_2,
|
||||||
submitter=contact_shared,
|
submitter=contact_shared,
|
||||||
)
|
)
|
||||||
domain_request_2.other_contacts.set([contact_shared])
|
domain_request_2.other_contacts.set([contact_shared])
|
||||||
|
@ -453,7 +453,7 @@ class HomeTests(TestWithUser):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site,
|
requested_domain=site,
|
||||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||||
authorizing_official=contact,
|
senior_official=contact,
|
||||||
submitter=contact_user,
|
submitter=contact_user,
|
||||||
)
|
)
|
||||||
domain_request.other_contacts.set([contact_2])
|
domain_request.other_contacts.set([contact_2])
|
||||||
|
@ -464,7 +464,7 @@ class HomeTests(TestWithUser):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site_2,
|
requested_domain=site_2,
|
||||||
status=DomainRequest.DomainRequestStatus.STARTED,
|
status=DomainRequest.DomainRequestStatus.STARTED,
|
||||||
authorizing_official=contact_2,
|
senior_official=contact_2,
|
||||||
submitter=contact_shared,
|
submitter=contact_shared,
|
||||||
)
|
)
|
||||||
domain_request_2.other_contacts.set([contact_shared])
|
domain_request_2.other_contacts.set([contact_shared])
|
||||||
|
@ -871,7 +871,7 @@ class UserProfileTests(TestWithUser, WebTest):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site,
|
requested_domain=site,
|
||||||
status=DomainRequest.DomainRequestStatus.SUBMITTED,
|
status=DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||||
authorizing_official=contact_user,
|
senior_official=contact_user,
|
||||||
submitter=contact_user,
|
submitter=contact_user,
|
||||||
)
|
)
|
||||||
with override_flag("profile_feature", active=True):
|
with override_flag("profile_feature", active=True):
|
||||||
|
@ -890,7 +890,7 @@ class UserProfileTests(TestWithUser, WebTest):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site,
|
requested_domain=site,
|
||||||
status=DomainRequest.DomainRequestStatus.SUBMITTED,
|
status=DomainRequest.DomainRequestStatus.SUBMITTED,
|
||||||
authorizing_official=contact_user,
|
senior_official=contact_user,
|
||||||
submitter=contact_user,
|
submitter=contact_user,
|
||||||
)
|
)
|
||||||
with override_flag("profile_feature", active=False):
|
with override_flag("profile_feature", active=False):
|
||||||
|
|
|
@ -150,7 +150,7 @@ class TestDomainPermissions(TestWithDomainPermissions):
|
||||||
"domain-users-add",
|
"domain-users-add",
|
||||||
"domain-dns-nameservers",
|
"domain-dns-nameservers",
|
||||||
"domain-org-name-address",
|
"domain-org-name-address",
|
||||||
"domain-authorizing-official",
|
"domain-senior-official",
|
||||||
"domain-your-contact-information",
|
"domain-your-contact-information",
|
||||||
"domain-security-email",
|
"domain-security-email",
|
||||||
]:
|
]:
|
||||||
|
@ -169,7 +169,7 @@ class TestDomainPermissions(TestWithDomainPermissions):
|
||||||
"domain-users-add",
|
"domain-users-add",
|
||||||
"domain-dns-nameservers",
|
"domain-dns-nameservers",
|
||||||
"domain-org-name-address",
|
"domain-org-name-address",
|
||||||
"domain-authorizing-official",
|
"domain-senior-official",
|
||||||
"domain-your-contact-information",
|
"domain-your-contact-information",
|
||||||
"domain-security-email",
|
"domain-security-email",
|
||||||
]:
|
]:
|
||||||
|
@ -190,7 +190,7 @@ class TestDomainPermissions(TestWithDomainPermissions):
|
||||||
"domain-dns-dnssec",
|
"domain-dns-dnssec",
|
||||||
"domain-dns-dnssec-dsdata",
|
"domain-dns-dnssec-dsdata",
|
||||||
"domain-org-name-address",
|
"domain-org-name-address",
|
||||||
"domain-authorizing-official",
|
"domain-senior-official",
|
||||||
"domain-your-contact-information",
|
"domain-your-contact-information",
|
||||||
"domain-security-email",
|
"domain-security-email",
|
||||||
]:
|
]:
|
||||||
|
@ -1082,44 +1082,43 @@ class TestDomainNameservers(TestDomainOverview, MockEppLib):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDomainAuthorizingOfficial(TestDomainOverview):
|
class TestDomainSeniorOfficial(TestDomainOverview):
|
||||||
def test_domain_authorizing_official(self):
|
def test_domain_senior_official(self):
|
||||||
"""Can load domain's authorizing official page."""
|
"""Can load domain's senior official page."""
|
||||||
page = self.client.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
page = self.client.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
# once on the sidebar, once in the title
|
self.assertContains(page, "Senior official", count=13)
|
||||||
self.assertContains(page, "Authorizing official", count=3)
|
|
||||||
|
|
||||||
def test_domain_authorizing_official_content(self):
|
def test_domain_senior_official_content(self):
|
||||||
"""Authorizing official information appears on the page."""
|
"""Senior official information appears on the page."""
|
||||||
self.domain_information.authorizing_official = Contact(first_name="Testy")
|
self.domain_information.senior_official = Contact(first_name="Testy")
|
||||||
self.domain_information.authorizing_official.save()
|
self.domain_information.senior_official.save()
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
page = self.app.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
page = self.app.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
self.assertContains(page, "Testy")
|
self.assertContains(page, "Testy")
|
||||||
|
|
||||||
def test_domain_edit_authorizing_official_in_place(self):
|
def test_domain_edit_senior_official_in_place(self):
|
||||||
"""When editing an authorizing official for domain information and AO is not
|
"""When editing a senior official for domain information and SO is not
|
||||||
joined to any other objects"""
|
joined to any other objects"""
|
||||||
self.domain_information.authorizing_official = Contact(
|
self.domain_information.senior_official = Contact(
|
||||||
first_name="Testy", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
first_name="Testy", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
||||||
)
|
)
|
||||||
self.domain_information.authorizing_official.save()
|
self.domain_information.senior_official.save()
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
ao_page = self.app.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
so_page = self.app.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
self.assertEqual(ao_form["first_name"].value, "Testy")
|
self.assertEqual(so_form["first_name"].value, "Testy")
|
||||||
ao_form["first_name"] = "Testy2"
|
so_form["first_name"] = "Testy2"
|
||||||
# ao_pk is the initial pk of the authorizing official. set it before update
|
# so_pk is the initial pk of the senior official. set it before update
|
||||||
# to be able to verify after update that the same contact object is in place
|
# to be able to verify after update that the same contact object is in place
|
||||||
ao_pk = self.domain_information.authorizing_official.id
|
so_pk = self.domain_information.senior_official.id
|
||||||
ao_form.submit()
|
so_form.submit()
|
||||||
|
|
||||||
# refresh domain information
|
# refresh domain information
|
||||||
self.domain_information.refresh_from_db()
|
self.domain_information.refresh_from_db()
|
||||||
self.assertEqual("Testy2", self.domain_information.authorizing_official.first_name)
|
self.assertEqual("Testy2", self.domain_information.senior_official.first_name)
|
||||||
self.assertEqual(ao_pk, self.domain_information.authorizing_official.id)
|
self.assertEqual(so_pk, self.domain_information.senior_official.id)
|
||||||
|
|
||||||
def assert_all_form_fields_have_expected_values(self, form, test_cases, test_for_disabled=False):
|
def assert_all_form_fields_have_expected_values(self, form, test_cases, test_for_disabled=False):
|
||||||
"""
|
"""
|
||||||
|
@ -1147,26 +1146,26 @@ class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
# Test for disabled on each field
|
# Test for disabled on each field
|
||||||
self.assertTrue("disabled" in form[field_name].attrs)
|
self.assertTrue("disabled" in form[field_name].attrs)
|
||||||
|
|
||||||
def test_domain_edit_authorizing_official_federal(self):
|
def test_domain_edit_senior_official_federal(self):
|
||||||
"""Tests that no edit can occur when the underlying domain is federal"""
|
"""Tests that no edit can occur when the underlying domain is federal"""
|
||||||
|
|
||||||
# Set the org type to federal
|
# Set the org type to federal
|
||||||
self.domain_information.generic_org_type = DomainInformation.OrganizationChoices.FEDERAL
|
self.domain_information.generic_org_type = DomainInformation.OrganizationChoices.FEDERAL
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
|
|
||||||
# Add an AO. We can do this at the model level, just not the form level.
|
# Add an SO. We can do this at the model level, just not the form level.
|
||||||
self.domain_information.authorizing_official = Contact(
|
self.domain_information.senior_official = Contact(
|
||||||
first_name="Apple", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
first_name="Apple", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
||||||
)
|
)
|
||||||
self.domain_information.authorizing_official.save()
|
self.domain_information.senior_official.save()
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
|
|
||||||
ao_page = self.app.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
so_page = self.app.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
# Test if the form is populating data correctly
|
# Test if the form is populating data correctly
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
|
|
||||||
test_cases = [
|
test_cases = [
|
||||||
("first_name", "Apple"),
|
("first_name", "Apple"),
|
||||||
|
@ -1174,16 +1173,16 @@ class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
("title", "CIO"),
|
("title", "CIO"),
|
||||||
("email", "nobody@igorville.gov"),
|
("email", "nobody@igorville.gov"),
|
||||||
]
|
]
|
||||||
self.assert_all_form_fields_have_expected_values(ao_form, test_cases, test_for_disabled=True)
|
self.assert_all_form_fields_have_expected_values(so_form, test_cases, test_for_disabled=True)
|
||||||
|
|
||||||
# Attempt to change data on each field. Because this domain is federal,
|
# Attempt to change data on each field. Because this domain is federal,
|
||||||
# this should not succeed.
|
# this should not succeed.
|
||||||
ao_form["first_name"] = "Orange"
|
so_form["first_name"] = "Orange"
|
||||||
ao_form["last_name"] = "Smoothie"
|
so_form["last_name"] = "Smoothie"
|
||||||
ao_form["title"] = "Cat"
|
so_form["title"] = "Cat"
|
||||||
ao_form["email"] = "somebody@igorville.gov"
|
so_form["email"] = "somebody@igorville.gov"
|
||||||
|
|
||||||
submission = ao_form.submit()
|
submission = so_form.submit()
|
||||||
|
|
||||||
# A 302 indicates this page underwent a redirect.
|
# A 302 indicates this page underwent a redirect.
|
||||||
self.assertEqual(submission.status_code, 302)
|
self.assertEqual(submission.status_code, 302)
|
||||||
|
@ -1198,31 +1197,31 @@ class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
self.domain_information.refresh_from_db()
|
self.domain_information.refresh_from_db()
|
||||||
|
|
||||||
# All values should be unchanged. These are defined manually for code clarity.
|
# All values should be unchanged. These are defined manually for code clarity.
|
||||||
self.assertEqual("Apple", self.domain_information.authorizing_official.first_name)
|
self.assertEqual("Apple", self.domain_information.senior_official.first_name)
|
||||||
self.assertEqual("Tester", self.domain_information.authorizing_official.last_name)
|
self.assertEqual("Tester", self.domain_information.senior_official.last_name)
|
||||||
self.assertEqual("CIO", self.domain_information.authorizing_official.title)
|
self.assertEqual("CIO", self.domain_information.senior_official.title)
|
||||||
self.assertEqual("nobody@igorville.gov", self.domain_information.authorizing_official.email)
|
self.assertEqual("nobody@igorville.gov", self.domain_information.senior_official.email)
|
||||||
|
|
||||||
def test_domain_edit_authorizing_official_tribal(self):
|
def test_domain_edit_senior_official_tribal(self):
|
||||||
"""Tests that no edit can occur when the underlying domain is tribal"""
|
"""Tests that no edit can occur when the underlying domain is tribal"""
|
||||||
|
|
||||||
# Set the org type to federal
|
# Set the org type to federal
|
||||||
self.domain_information.generic_org_type = DomainInformation.OrganizationChoices.TRIBAL
|
self.domain_information.generic_org_type = DomainInformation.OrganizationChoices.TRIBAL
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
|
|
||||||
# Add an AO. We can do this at the model level, just not the form level.
|
# Add an SO. We can do this at the model level, just not the form level.
|
||||||
self.domain_information.authorizing_official = Contact(
|
self.domain_information.senior_official = Contact(
|
||||||
first_name="Apple", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
first_name="Apple", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
||||||
)
|
)
|
||||||
self.domain_information.authorizing_official.save()
|
self.domain_information.senior_official.save()
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
|
|
||||||
ao_page = self.app.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
so_page = self.app.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
# Test if the form is populating data correctly
|
# Test if the form is populating data correctly
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
|
|
||||||
test_cases = [
|
test_cases = [
|
||||||
("first_name", "Apple"),
|
("first_name", "Apple"),
|
||||||
|
@ -1230,16 +1229,16 @@ class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
("title", "CIO"),
|
("title", "CIO"),
|
||||||
("email", "nobody@igorville.gov"),
|
("email", "nobody@igorville.gov"),
|
||||||
]
|
]
|
||||||
self.assert_all_form_fields_have_expected_values(ao_form, test_cases, test_for_disabled=True)
|
self.assert_all_form_fields_have_expected_values(so_form, test_cases, test_for_disabled=True)
|
||||||
|
|
||||||
# Attempt to change data on each field. Because this domain is federal,
|
# Attempt to change data on each field. Because this domain is federal,
|
||||||
# this should not succeed.
|
# this should not succeed.
|
||||||
ao_form["first_name"] = "Orange"
|
so_form["first_name"] = "Orange"
|
||||||
ao_form["last_name"] = "Smoothie"
|
so_form["last_name"] = "Smoothie"
|
||||||
ao_form["title"] = "Cat"
|
so_form["title"] = "Cat"
|
||||||
ao_form["email"] = "somebody@igorville.gov"
|
so_form["email"] = "somebody@igorville.gov"
|
||||||
|
|
||||||
submission = ao_form.submit()
|
submission = so_form.submit()
|
||||||
|
|
||||||
# A 302 indicates this page underwent a redirect.
|
# A 302 indicates this page underwent a redirect.
|
||||||
self.assertEqual(submission.status_code, 302)
|
self.assertEqual(submission.status_code, 302)
|
||||||
|
@ -1254,45 +1253,45 @@ class TestDomainAuthorizingOfficial(TestDomainOverview):
|
||||||
self.domain_information.refresh_from_db()
|
self.domain_information.refresh_from_db()
|
||||||
|
|
||||||
# All values should be unchanged. These are defined manually for code clarity.
|
# All values should be unchanged. These are defined manually for code clarity.
|
||||||
self.assertEqual("Apple", self.domain_information.authorizing_official.first_name)
|
self.assertEqual("Apple", self.domain_information.senior_official.first_name)
|
||||||
self.assertEqual("Tester", self.domain_information.authorizing_official.last_name)
|
self.assertEqual("Tester", self.domain_information.senior_official.last_name)
|
||||||
self.assertEqual("CIO", self.domain_information.authorizing_official.title)
|
self.assertEqual("CIO", self.domain_information.senior_official.title)
|
||||||
self.assertEqual("nobody@igorville.gov", self.domain_information.authorizing_official.email)
|
self.assertEqual("nobody@igorville.gov", self.domain_information.senior_official.email)
|
||||||
|
|
||||||
def test_domain_edit_authorizing_official_creates_new(self):
|
def test_domain_edit_senior_official_creates_new(self):
|
||||||
"""When editing an authorizing official for domain information and AO IS
|
"""When editing a senior official for domain information and SO IS
|
||||||
joined to another object"""
|
joined to another object"""
|
||||||
# set AO and Other Contact to the same Contact object
|
# set SO and Other Contact to the same Contact object
|
||||||
self.domain_information.authorizing_official = Contact(
|
self.domain_information.senior_official = Contact(
|
||||||
first_name="Testy", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
first_name="Testy", last_name="Tester", title="CIO", email="nobody@igorville.gov"
|
||||||
)
|
)
|
||||||
self.domain_information.authorizing_official.save()
|
self.domain_information.senior_official.save()
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
self.domain_information.other_contacts.add(self.domain_information.authorizing_official)
|
self.domain_information.other_contacts.add(self.domain_information.senior_official)
|
||||||
self.domain_information.save()
|
self.domain_information.save()
|
||||||
# load the Authorizing Official in the web form
|
# load the Senior Official in the web form
|
||||||
ao_page = self.app.get(reverse("domain-authorizing-official", kwargs={"pk": self.domain.id}))
|
so_page = self.app.get(reverse("domain-senior-official", kwargs={"pk": self.domain.id}))
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
# verify the first name is "Testy" and then change it to "Testy2"
|
# verify the first name is "Testy" and then change it to "Testy2"
|
||||||
self.assertEqual(ao_form["first_name"].value, "Testy")
|
self.assertEqual(so_form["first_name"].value, "Testy")
|
||||||
ao_form["first_name"] = "Testy2"
|
so_form["first_name"] = "Testy2"
|
||||||
# ao_pk is the initial pk of the authorizing official. set it before update
|
# so_pk is the initial pk of the senior official. set it before update
|
||||||
# to be able to verify after update that the same contact object is in place
|
# to be able to verify after update that the same contact object is in place
|
||||||
ao_pk = self.domain_information.authorizing_official.id
|
so_pk = self.domain_information.senior_official.id
|
||||||
ao_form.submit()
|
so_form.submit()
|
||||||
|
|
||||||
# refresh domain information
|
# refresh domain information
|
||||||
self.domain_information.refresh_from_db()
|
self.domain_information.refresh_from_db()
|
||||||
# assert that AO information is updated, and that the AO is a new Contact
|
# assert that SO information is updated, and that the SO is a new Contact
|
||||||
self.assertEqual("Testy2", self.domain_information.authorizing_official.first_name)
|
self.assertEqual("Testy2", self.domain_information.senior_official.first_name)
|
||||||
self.assertNotEqual(ao_pk, self.domain_information.authorizing_official.id)
|
self.assertNotEqual(so_pk, self.domain_information.senior_official.id)
|
||||||
# assert that the Other Contact information is not updated and that the Other Contact
|
# assert that the Other Contact information is not updated and that the Other Contact
|
||||||
# is the original Contact object
|
# is the original Contact object
|
||||||
other_contact = self.domain_information.other_contacts.all()[0]
|
other_contact = self.domain_information.other_contacts.all()[0]
|
||||||
self.assertEqual("Testy", other_contact.first_name)
|
self.assertEqual("Testy", other_contact.first_name)
|
||||||
self.assertEqual(ao_pk, other_contact.id)
|
self.assertEqual(so_pk, other_contact.id)
|
||||||
|
|
||||||
|
|
||||||
class TestDomainOrganization(TestDomainOverview):
|
class TestDomainOrganization(TestDomainOverview):
|
||||||
|
|
|
@ -253,38 +253,38 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# the post request should return a redirect to the next form in
|
# the post request should return a redirect to the next form in
|
||||||
# the domain request page
|
# the domain request page
|
||||||
self.assertEqual(org_contact_result.status_code, 302)
|
self.assertEqual(org_contact_result.status_code, 302)
|
||||||
self.assertEqual(org_contact_result["Location"], "/request/authorizing_official/")
|
self.assertEqual(org_contact_result["Location"], "/request/senior_official/")
|
||||||
num_pages_tested += 1
|
num_pages_tested += 1
|
||||||
|
|
||||||
# ---- AUTHORIZING OFFICIAL PAGE ----
|
# ---- SENIOR OFFICIAL PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = org_contact_result.follow()
|
so_page = org_contact_result.follow()
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
ao_form["authorizing_official-first_name"] = "Testy ATO"
|
so_form["senior_official-first_name"] = "Testy ATO"
|
||||||
ao_form["authorizing_official-last_name"] = "Tester ATO"
|
so_form["senior_official-last_name"] = "Tester ATO"
|
||||||
ao_form["authorizing_official-title"] = "Chief Tester"
|
so_form["senior_official-title"] = "Chief Tester"
|
||||||
ao_form["authorizing_official-email"] = "testy@town.com"
|
so_form["senior_official-email"] = "testy@town.com"
|
||||||
|
|
||||||
# test next button
|
# test next button
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_result = ao_form.submit()
|
so_result = so_form.submit()
|
||||||
# validate that data from this step are being saved
|
# validate that data from this step are being saved
|
||||||
domain_request = DomainRequest.objects.get() # there's only one
|
domain_request = DomainRequest.objects.get() # there's only one
|
||||||
self.assertEqual(domain_request.authorizing_official.first_name, "Testy ATO")
|
self.assertEqual(domain_request.senior_official.first_name, "Testy ATO")
|
||||||
self.assertEqual(domain_request.authorizing_official.last_name, "Tester ATO")
|
self.assertEqual(domain_request.senior_official.last_name, "Tester ATO")
|
||||||
self.assertEqual(domain_request.authorizing_official.title, "Chief Tester")
|
self.assertEqual(domain_request.senior_official.title, "Chief Tester")
|
||||||
self.assertEqual(domain_request.authorizing_official.email, "testy@town.com")
|
self.assertEqual(domain_request.senior_official.email, "testy@town.com")
|
||||||
# the post request should return a redirect to the next form in
|
# the post request should return a redirect to the next form in
|
||||||
# the domain request page
|
# the domain request page
|
||||||
self.assertEqual(ao_result.status_code, 302)
|
self.assertEqual(so_result.status_code, 302)
|
||||||
self.assertEqual(ao_result["Location"], "/request/current_sites/")
|
self.assertEqual(so_result["Location"], "/request/current_sites/")
|
||||||
num_pages_tested += 1
|
num_pages_tested += 1
|
||||||
|
|
||||||
# ---- CURRENT SITES PAGE ----
|
# ---- CURRENT SITES PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
current_sites_page = ao_result.follow()
|
current_sites_page = so_result.follow()
|
||||||
current_sites_form = current_sites_page.forms[0]
|
current_sites_form = current_sites_page.forms[0]
|
||||||
current_sites_form["current_sites-0-website"] = "www.city.com"
|
current_sites_form["current_sites-0-website"] = "www.city.com"
|
||||||
|
|
||||||
|
@ -610,38 +610,38 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# the post request should return a redirect to the next form in
|
# the post request should return a redirect to the next form in
|
||||||
# the domain request page
|
# the domain request page
|
||||||
self.assertEqual(org_contact_result.status_code, 302)
|
self.assertEqual(org_contact_result.status_code, 302)
|
||||||
self.assertEqual(org_contact_result["Location"], "/request/authorizing_official/")
|
self.assertEqual(org_contact_result["Location"], "/request/senior_official/")
|
||||||
num_pages_tested += 1
|
num_pages_tested += 1
|
||||||
|
|
||||||
# ---- AUTHORIZING OFFICIAL PAGE ----
|
# ---- SENIOR OFFICIAL PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = org_contact_result.follow()
|
so_page = org_contact_result.follow()
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
ao_form["authorizing_official-first_name"] = "Testy ATO"
|
so_form["senior_official-first_name"] = "Testy ATO"
|
||||||
ao_form["authorizing_official-last_name"] = "Tester ATO"
|
so_form["senior_official-last_name"] = "Tester ATO"
|
||||||
ao_form["authorizing_official-title"] = "Chief Tester"
|
so_form["senior_official-title"] = "Chief Tester"
|
||||||
ao_form["authorizing_official-email"] = "testy@town.com"
|
so_form["senior_official-email"] = "testy@town.com"
|
||||||
|
|
||||||
# test next button
|
# test next button
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_result = ao_form.submit()
|
so_result = so_form.submit()
|
||||||
# validate that data from this step are being saved
|
# validate that data from this step are being saved
|
||||||
domain_request = DomainRequest.objects.get() # there's only one
|
domain_request = DomainRequest.objects.get() # there's only one
|
||||||
self.assertEqual(domain_request.authorizing_official.first_name, "Testy ATO")
|
self.assertEqual(domain_request.senior_official.first_name, "Testy ATO")
|
||||||
self.assertEqual(domain_request.authorizing_official.last_name, "Tester ATO")
|
self.assertEqual(domain_request.senior_official.last_name, "Tester ATO")
|
||||||
self.assertEqual(domain_request.authorizing_official.title, "Chief Tester")
|
self.assertEqual(domain_request.senior_official.title, "Chief Tester")
|
||||||
self.assertEqual(domain_request.authorizing_official.email, "testy@town.com")
|
self.assertEqual(domain_request.senior_official.email, "testy@town.com")
|
||||||
# the post request should return a redirect to the next form in
|
# the post request should return a redirect to the next form in
|
||||||
# the domain request page
|
# the domain request page
|
||||||
self.assertEqual(ao_result.status_code, 302)
|
self.assertEqual(so_result.status_code, 302)
|
||||||
self.assertEqual(ao_result["Location"], "/request/current_sites/")
|
self.assertEqual(so_result["Location"], "/request/current_sites/")
|
||||||
num_pages_tested += 1
|
num_pages_tested += 1
|
||||||
|
|
||||||
# ---- CURRENT SITES PAGE ----
|
# ---- CURRENT SITES PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
current_sites_page = ao_result.follow()
|
current_sites_page = so_result.follow()
|
||||||
current_sites_form = current_sites_page.forms[0]
|
current_sites_form = current_sites_page.forms[0]
|
||||||
current_sites_form["current_sites-0-website"] = "www.city.com"
|
current_sites_form["current_sites-0-website"] = "www.city.com"
|
||||||
|
|
||||||
|
@ -1576,7 +1576,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 1 "other contact" assigned to it
|
# has 1 "other contact" assigned to it
|
||||||
# We'll do it from scratch so we can reuse the other contact
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -1607,7 +1607,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
|
@ -1703,7 +1703,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 2 "other contact" assigned to it
|
# has 2 "other contact" assigned to it
|
||||||
# We'll do it from scratch so we can reuse the other contact
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -1741,7 +1741,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
|
@ -1784,7 +1784,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 1 "other contact" assigned to it
|
# has 1 "other contact" assigned to it
|
||||||
# We'll do it from scratch so we can reuse the other contact
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -1815,7 +1815,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
|
@ -1861,7 +1861,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 1 "other contact" assigned to it
|
# has 1 "other contact" assigned to it
|
||||||
# We'll do it from scratch so we can reuse the other contact
|
# We'll do it from scratch so we can reuse the other contact
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -1892,7 +1892,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
|
@ -1937,7 +1937,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 1 "other contact" assigned to it
|
# has 1 "other contact" assigned to it
|
||||||
# We'll do it from scratch
|
# We'll do it from scratch
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -1968,7 +1968,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
|
@ -2017,9 +2017,9 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
|
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has 1 "other contact" assigned to it, the other contact is also
|
# has 1 "other contact" assigned to it, the other contact is also
|
||||||
# the authorizing official initially
|
# the senior official initially
|
||||||
# We'll do it from scratch
|
# We'll do it from scratch
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -2043,17 +2043,17 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
)
|
)
|
||||||
domain_request.other_contacts.add(ao)
|
domain_request.other_contacts.add(so)
|
||||||
|
|
||||||
# other_contact_pk is the initial pk of the other contact. set it before update
|
# other_contact_pk is the initial pk of the other contact. set it before update
|
||||||
# to be able to verify after update that the ao contact is still in place
|
# to be able to verify after update that the so contact is still in place
|
||||||
# and not updated, and that the new contact has a new id
|
# and not updated, and that the new contact has a new id
|
||||||
other_contact_pk = ao.id
|
other_contact_pk = so.id
|
||||||
|
|
||||||
# prime the form by visiting /edit
|
# prime the form by visiting /edit
|
||||||
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
||||||
|
@ -2085,20 +2085,20 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
other_contact = domain_request.other_contacts.all()[0]
|
other_contact = domain_request.other_contacts.all()[0]
|
||||||
self.assertNotEquals(other_contact_pk, other_contact.id)
|
self.assertNotEquals(other_contact_pk, other_contact.id)
|
||||||
self.assertEquals("Testy2", other_contact.first_name)
|
self.assertEquals("Testy2", other_contact.first_name)
|
||||||
# assert that the authorizing official is not updated
|
# assert that the senior official is not updated
|
||||||
authorizing_official = domain_request.authorizing_official
|
senior_official = domain_request.senior_official
|
||||||
self.assertEquals("Testy", authorizing_official.first_name)
|
self.assertEquals("Testy", senior_official.first_name)
|
||||||
|
|
||||||
def test_edit_authorizing_official_in_place(self):
|
def test_edit_senior_official_in_place(self):
|
||||||
"""When you:
|
"""When you:
|
||||||
1. edit an authorizing official which is not joined to another model,
|
1. edit a senior official which is not joined to another model,
|
||||||
2. then submit,
|
2. then submit,
|
||||||
the domain request is linked to the existing ao, and the ao updated."""
|
the domain request is linked to the existing so, and the so updated."""
|
||||||
|
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has an authorizing_official (ao)
|
# has a senior_official (so)
|
||||||
# We'll do it from scratch
|
# We'll do it from scratch
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -2115,14 +2115,14 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
)
|
)
|
||||||
|
|
||||||
# ao_pk is the initial pk of the Authorizing Official. set it before update
|
# so_pk is the initial pk of the Senior Official. set it before update
|
||||||
# to be able to verify after update that the same Contact object is in place
|
# to be able to verify after update that the same Contact object is in place
|
||||||
ao_pk = ao.id
|
so_pk = so.id
|
||||||
|
|
||||||
# prime the form by visiting /edit
|
# prime the form by visiting /edit
|
||||||
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
||||||
|
@ -2133,38 +2133,38 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
ao_page = self.app.get(reverse("domain-request:authorizing_official"))
|
so_page = self.app.get(reverse("domain-request:senior_official"))
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
|
|
||||||
# Minimal check to ensure the form is loaded
|
# Minimal check to ensure the form is loaded
|
||||||
self.assertEqual(ao_form["authorizing_official-first_name"].value, "Testy")
|
self.assertEqual(so_form["senior_official-first_name"].value, "Testy")
|
||||||
|
|
||||||
# update the first name of the contact
|
# update the first name of the contact
|
||||||
ao_form["authorizing_official-first_name"] = "Testy2"
|
so_form["senior_official-first_name"] = "Testy2"
|
||||||
|
|
||||||
# Submit the updated form
|
# Submit the updated form
|
||||||
ao_form.submit()
|
so_form.submit()
|
||||||
|
|
||||||
domain_request.refresh_from_db()
|
domain_request.refresh_from_db()
|
||||||
|
|
||||||
# assert AO is updated "in place"
|
# assert SO is updated "in place"
|
||||||
updated_ao = domain_request.authorizing_official
|
updated_so = domain_request.senior_official
|
||||||
self.assertEquals(ao_pk, updated_ao.id)
|
self.assertEquals(so_pk, updated_so.id)
|
||||||
self.assertEquals("Testy2", updated_ao.first_name)
|
self.assertEquals("Testy2", updated_so.first_name)
|
||||||
|
|
||||||
def test_edit_authorizing_official_creates_new(self):
|
def test_edit_senior_official_creates_new(self):
|
||||||
"""When you:
|
"""When you:
|
||||||
1. edit an existing authorizing official which IS joined to another model,
|
1. edit an existing senior official which IS joined to another model,
|
||||||
2. then submit,
|
2. then submit,
|
||||||
the domain request is linked to a new Contact, and the new Contact is updated."""
|
the domain request is linked to a new Contact, and the new Contact is updated."""
|
||||||
|
|
||||||
# Populate the database with a domain request that
|
# Populate the database with a domain request that
|
||||||
# has authorizing official assigned to it, the authorizing offical is also
|
# has senior official assigned to it, the senior offical is also
|
||||||
# an other contact initially
|
# an other contact initially
|
||||||
# We'll do it from scratch
|
# We'll do it from scratch
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -2181,16 +2181,16 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
status="started",
|
status="started",
|
||||||
)
|
)
|
||||||
domain_request.other_contacts.add(ao)
|
domain_request.other_contacts.add(so)
|
||||||
|
|
||||||
# ao_pk is the initial pk of the authorizing official. set it before update
|
# so_pk is the initial pk of the senior official. set it before update
|
||||||
# to be able to verify after update that the other contact is still in place
|
# to be able to verify after update that the other contact is still in place
|
||||||
# and not updated, and that the new ao has a new id
|
# and not updated, and that the new so has a new id
|
||||||
ao_pk = ao.id
|
so_pk = so.id
|
||||||
|
|
||||||
# prime the form by visiting /edit
|
# prime the form by visiting /edit
|
||||||
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
self.app.get(reverse("edit-domain-request", kwargs={"id": domain_request.pk}))
|
||||||
|
@ -2201,30 +2201,30 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
ao_page = self.app.get(reverse("domain-request:authorizing_official"))
|
so_page = self.app.get(reverse("domain-request:senior_official"))
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
|
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
|
|
||||||
# Minimal check to ensure the form is loaded
|
# Minimal check to ensure the form is loaded
|
||||||
self.assertEqual(ao_form["authorizing_official-first_name"].value, "Testy")
|
self.assertEqual(so_form["senior_official-first_name"].value, "Testy")
|
||||||
|
|
||||||
# update the first name of the contact
|
# update the first name of the contact
|
||||||
ao_form["authorizing_official-first_name"] = "Testy2"
|
so_form["senior_official-first_name"] = "Testy2"
|
||||||
|
|
||||||
# Submit the updated form
|
# Submit the updated form
|
||||||
ao_form.submit()
|
so_form.submit()
|
||||||
|
|
||||||
domain_request.refresh_from_db()
|
domain_request.refresh_from_db()
|
||||||
|
|
||||||
# assert that the other contact is not updated
|
# assert that the other contact is not updated
|
||||||
other_contacts = domain_request.other_contacts.all()
|
other_contacts = domain_request.other_contacts.all()
|
||||||
other_contact = other_contacts[0]
|
other_contact = other_contacts[0]
|
||||||
self.assertEquals(ao_pk, other_contact.id)
|
self.assertEquals(so_pk, other_contact.id)
|
||||||
self.assertEquals("Testy", other_contact.first_name)
|
self.assertEquals("Testy", other_contact.first_name)
|
||||||
# assert that the authorizing official is updated
|
# assert that the senior official is updated
|
||||||
authorizing_official = domain_request.authorizing_official
|
senior_official = domain_request.senior_official
|
||||||
self.assertEquals("Testy2", authorizing_official.first_name)
|
self.assertEquals("Testy2", senior_official.first_name)
|
||||||
|
|
||||||
def test_edit_submitter_in_place(self):
|
def test_edit_submitter_in_place(self):
|
||||||
"""When you:
|
"""When you:
|
||||||
|
@ -2421,7 +2421,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# and the step is on the sidebar list.
|
# and the step is on the sidebar list.
|
||||||
self.assertContains(tribal_government_page, self.TITLES[Step.TRIBAL_GOVERNMENT])
|
self.assertContains(tribal_government_page, self.TITLES[Step.TRIBAL_GOVERNMENT])
|
||||||
|
|
||||||
def test_domain_request_ao_dynamic_text(self):
|
def test_domain_request_so_dynamic_text(self):
|
||||||
intro_page = self.app.get(reverse("domain-request:"))
|
intro_page = self.app.get(reverse("domain-request:"))
|
||||||
# django-webtest does not handle cookie-based sessions well because it keeps
|
# django-webtest does not handle cookie-based sessions well because it keeps
|
||||||
# resetting the session key on each new request, thus destroying the concept
|
# resetting the session key on each new request, thus destroying the concept
|
||||||
|
@ -2474,24 +2474,24 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
org_contact_result = org_contact_form.submit()
|
org_contact_result = org_contact_form.submit()
|
||||||
|
|
||||||
# ---- AO CONTACT PAGE ----
|
# ---- SO CONTACT PAGE ----
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = org_contact_result.follow()
|
so_page = org_contact_result.follow()
|
||||||
self.assertContains(ao_page, "Executive branch federal agencies")
|
self.assertContains(so_page, "Executive branch federal agencies")
|
||||||
|
|
||||||
# Go back to organization type page and change type
|
# Go back to organization type page and change type
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page.click(str(self.TITLES["generic_org_type"]), index=0)
|
so_page.click(str(self.TITLES["generic_org_type"]), index=0)
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
type_form["generic_org_type-generic_org_type"] = "city"
|
type_form["generic_org_type-generic_org_type"] = "city"
|
||||||
type_result = type_form.submit()
|
type_result = type_form.submit()
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
election_page = type_result.follow()
|
election_page = type_result.follow()
|
||||||
|
|
||||||
# Go back to AO page and test the dynamic text changed
|
# Go back to SO page and test the dynamic text changed
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = election_page.click(str(self.TITLES["authorizing_official"]), index=0)
|
so_page = election_page.click(str(self.TITLES["senior_official"]), index=0)
|
||||||
self.assertContains(ao_page, "Domain requests from cities")
|
self.assertContains(so_page, "Domain requests from cities")
|
||||||
|
|
||||||
def test_domain_request_dotgov_domain_dynamic_text(self):
|
def test_domain_request_dotgov_domain_dynamic_text(self):
|
||||||
intro_page = self.app.get(reverse("domain-request:"))
|
intro_page = self.app.get(reverse("domain-request:"))
|
||||||
|
@ -2546,27 +2546,27 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
org_contact_result = org_contact_form.submit()
|
org_contact_result = org_contact_form.submit()
|
||||||
|
|
||||||
# ---- AO CONTACT PAGE ----
|
# ---- SO CONTACT PAGE ----
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = org_contact_result.follow()
|
so_page = org_contact_result.follow()
|
||||||
|
|
||||||
# ---- AUTHORIZING OFFICIAL PAGE ----
|
# ---- senior OFFICIAL PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_page = org_contact_result.follow()
|
so_page = org_contact_result.follow()
|
||||||
ao_form = ao_page.forms[0]
|
so_form = so_page.forms[0]
|
||||||
ao_form["authorizing_official-first_name"] = "Testy ATO"
|
so_form["senior_official-first_name"] = "Testy ATO"
|
||||||
ao_form["authorizing_official-last_name"] = "Tester ATO"
|
so_form["senior_official-last_name"] = "Tester ATO"
|
||||||
ao_form["authorizing_official-title"] = "Chief Tester"
|
so_form["senior_official-title"] = "Chief Tester"
|
||||||
ao_form["authorizing_official-email"] = "testy@town.com"
|
so_form["senior_official-email"] = "testy@town.com"
|
||||||
|
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
ao_result = ao_form.submit()
|
so_result = so_form.submit()
|
||||||
|
|
||||||
# ---- CURRENT SITES PAGE ----
|
# ---- CURRENT SITES PAGE ----
|
||||||
# Follow the redirect to the next form page
|
# Follow the redirect to the next form page
|
||||||
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
current_sites_page = ao_result.follow()
|
current_sites_page = so_result.follow()
|
||||||
current_sites_form = current_sites_page.forms[0]
|
current_sites_form = current_sites_page.forms[0]
|
||||||
current_sites_form["current_sites-0-website"] = "www.city.com"
|
current_sites_form["current_sites-0-website"] = "www.city.com"
|
||||||
|
|
||||||
|
@ -2627,7 +2627,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
"""
|
"""
|
||||||
Test that a previously saved domain request is available at the /edit endpoint.
|
Test that a previously saved domain request is available at the /edit endpoint.
|
||||||
"""
|
"""
|
||||||
ao, _ = Contact.objects.get_or_create(
|
so, _ = Contact.objects.get_or_create(
|
||||||
first_name="Testy",
|
first_name="Testy",
|
||||||
last_name="Tester",
|
last_name="Tester",
|
||||||
title="Chief Tester",
|
title="Chief Tester",
|
||||||
|
@ -2661,7 +2661,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
address_line1="address 1",
|
address_line1="address 1",
|
||||||
state_territory="NY",
|
state_territory="NY",
|
||||||
zipcode="10002",
|
zipcode="10002",
|
||||||
authorizing_official=ao,
|
senior_official=so,
|
||||||
requested_domain=domain,
|
requested_domain=domain,
|
||||||
submitter=you,
|
submitter=you,
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
|
@ -2699,7 +2699,7 @@ class DomainRequestTests(TestWithUser, WebTest):
|
||||||
# page = self.app.get(url)
|
# page = self.app.get(url)
|
||||||
# self.assertNotContains(page, "VALUE")
|
# self.assertNotContains(page, "VALUE")
|
||||||
|
|
||||||
# url = reverse("domain-request:authorizing_official")
|
# url = reverse("domain-request:senior_official")
|
||||||
# self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
# self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
|
||||||
# page = self.app.get(url)
|
# page = self.app.get(url)
|
||||||
# self.assertNotContains(page, "VALUE")
|
# self.assertNotContains(page, "VALUE")
|
||||||
|
@ -2981,7 +2981,7 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
|
||||||
creator=self.user,
|
creator=self.user,
|
||||||
requested_domain=site,
|
requested_domain=site,
|
||||||
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
status=DomainRequest.DomainRequestStatus.WITHDRAWN,
|
||||||
authorizing_official=contact,
|
senior_official=contact,
|
||||||
submitter=contact_user,
|
submitter=contact_user,
|
||||||
)
|
)
|
||||||
domain_request.other_contacts.set([contact_2])
|
domain_request.other_contacts.set([contact_2])
|
||||||
|
@ -3008,7 +3008,7 @@ class TestWizardUnlockingSteps(TestWithUser, WebTest):
|
||||||
# Now 'detail_page' contains the response after following the redirect
|
# Now 'detail_page' contains the response after following the redirect
|
||||||
self.assertEqual(detail_page.status_code, 200)
|
self.assertEqual(detail_page.status_code, 200)
|
||||||
|
|
||||||
# 5 unlocked steps (ao, domain, submitter, other contacts, and current sites
|
# 5 unlocked steps (so, domain, submitter, other contacts, and current sites
|
||||||
# which unlocks if domain exists), one active step, the review step is locked
|
# which unlocks if domain exists), one active step, the review step is locked
|
||||||
self.assertContains(detail_page, "#check_circle", count=5)
|
self.assertContains(detail_page, "#check_circle", count=5)
|
||||||
# Type of organization
|
# Type of organization
|
||||||
|
|
|
@ -40,20 +40,20 @@ def get_domain_infos(filter_condition, sort_fields):
|
||||||
returns: A queryset of DomainInformation objects
|
returns: A queryset of DomainInformation objects
|
||||||
"""
|
"""
|
||||||
domain_infos = (
|
domain_infos = (
|
||||||
DomainInformation.objects.select_related("domain", "authorizing_official")
|
DomainInformation.objects.select_related("domain", "senior_official")
|
||||||
.filter(**filter_condition)
|
.filter(**filter_condition)
|
||||||
.order_by(*sort_fields)
|
.order_by(*sort_fields)
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
|
|
||||||
# Do a mass concat of the first and last name fields for authorizing_official.
|
# Do a mass concat of the first and last name fields for senior_official.
|
||||||
# The old operation was computationally heavy for some reason, so if we precompute
|
# The old operation was computationally heavy for some reason, so if we precompute
|
||||||
# this here, it is vastly more efficient.
|
# this here, it is vastly more efficient.
|
||||||
domain_infos_cleaned = domain_infos.annotate(
|
domain_infos_cleaned = domain_infos.annotate(
|
||||||
ao=Concat(
|
so=Concat(
|
||||||
Coalesce(F("authorizing_official__first_name"), Value("")),
|
Coalesce(F("senior_official__first_name"), Value("")),
|
||||||
Value(" "),
|
Value(" "),
|
||||||
Coalesce(F("authorizing_official__last_name"), Value("")),
|
Coalesce(F("senior_official__last_name"), Value("")),
|
||||||
output_field=CharField(),
|
output_field=CharField(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -110,8 +110,8 @@ def parse_row_for_domain(
|
||||||
"Organization name": domain_info.organization_name,
|
"Organization name": domain_info.organization_name,
|
||||||
"City": domain_info.city,
|
"City": domain_info.city,
|
||||||
"State": domain_info.state_territory,
|
"State": domain_info.state_territory,
|
||||||
"AO": domain_info.ao, # type: ignore
|
"SO": domain_info.so, # type: ignore
|
||||||
"AO email": domain_info.authorizing_official.email if domain_info.authorizing_official else " ",
|
"SO email": domain_info.senior_official.email if domain_info.senior_official else " ",
|
||||||
"Security contact email": security_email,
|
"Security contact email": security_email,
|
||||||
"Created at": domain.created_at,
|
"Created at": domain.created_at,
|
||||||
"Deleted": domain.deleted,
|
"Deleted": domain.deleted,
|
||||||
|
@ -325,8 +325,8 @@ def export_data_type_to_csv(csv_file):
|
||||||
"Organization name",
|
"Organization name",
|
||||||
"City",
|
"City",
|
||||||
"State",
|
"State",
|
||||||
"AO",
|
"SO",
|
||||||
"AO email",
|
"SO email",
|
||||||
"Security contact email",
|
"Security contact email",
|
||||||
# For domain manager we are pass it in as a parameter below in write_body
|
# For domain manager we are pass it in as a parameter below in write_body
|
||||||
]
|
]
|
||||||
|
@ -728,10 +728,10 @@ class DomainRequestExport:
|
||||||
"Creator approved domains count",
|
"Creator approved domains count",
|
||||||
"Creator active requests count",
|
"Creator active requests count",
|
||||||
"Alternative domains",
|
"Alternative domains",
|
||||||
"AO first name",
|
"SO first name",
|
||||||
"AO last name",
|
"SO last name",
|
||||||
"AO email",
|
"SO email",
|
||||||
"AO title/role",
|
"SO title/role",
|
||||||
"Request purpose",
|
"Request purpose",
|
||||||
"Request additional details",
|
"Request additional details",
|
||||||
"Other contacts",
|
"Other contacts",
|
||||||
|
@ -798,7 +798,7 @@ class DomainRequestExport:
|
||||||
|
|
||||||
requests = (
|
requests = (
|
||||||
DomainRequest.objects.select_related(
|
DomainRequest.objects.select_related(
|
||||||
"creator", "authorizing_official", "federal_agency", "investigator", "requested_domain"
|
"creator", "senior_official", "federal_agency", "investigator", "requested_domain"
|
||||||
)
|
)
|
||||||
.prefetch_related("current_websites", "other_contacts", "alternative_domains")
|
.prefetch_related("current_websites", "other_contacts", "alternative_domains")
|
||||||
.exclude(status__in=[DomainRequest.DomainRequestStatus.STARTED])
|
.exclude(status__in=[DomainRequest.DomainRequestStatus.STARTED])
|
||||||
|
@ -817,10 +817,10 @@ class DomainRequestExport:
|
||||||
additional_values = [
|
additional_values = [
|
||||||
"requested_domain__name",
|
"requested_domain__name",
|
||||||
"federal_agency__agency",
|
"federal_agency__agency",
|
||||||
"authorizing_official__first_name",
|
"senior_official__first_name",
|
||||||
"authorizing_official__last_name",
|
"senior_official__last_name",
|
||||||
"authorizing_official__email",
|
"senior_official__email",
|
||||||
"authorizing_official__title",
|
"senior_official__title",
|
||||||
"creator__first_name",
|
"creator__first_name",
|
||||||
"creator__last_name",
|
"creator__last_name",
|
||||||
"creator__email",
|
"creator__email",
|
||||||
|
@ -940,10 +940,10 @@ class DomainRequestExport:
|
||||||
"Current websites": request.get("all_current_websites"),
|
"Current websites": request.get("all_current_websites"),
|
||||||
# Untouched FK fields - passed into the request dict.
|
# Untouched FK fields - passed into the request dict.
|
||||||
"Federal agency": request.get("federal_agency__agency"),
|
"Federal agency": request.get("federal_agency__agency"),
|
||||||
"AO first name": request.get("authorizing_official__first_name"),
|
"SO first name": request.get("senior_official__first_name"),
|
||||||
"AO last name": request.get("authorizing_official__last_name"),
|
"SO last name": request.get("senior_official__last_name"),
|
||||||
"AO email": request.get("authorizing_official__email"),
|
"SO email": request.get("senior_official__email"),
|
||||||
"AO title/role": request.get("authorizing_official__title"),
|
"SO title/role": request.get("senior_official__title"),
|
||||||
"Creator first name": request.get("creator__first_name"),
|
"Creator first name": request.get("creator__first_name"),
|
||||||
"Creator last name": request.get("creator__last_name"),
|
"Creator last name": request.get("creator__last_name"),
|
||||||
"Creator email": request.get("creator__email"),
|
"Creator email": request.get("creator__email"),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from .domain_request import *
|
from .domain_request import *
|
||||||
from .domain import (
|
from .domain import (
|
||||||
DomainView,
|
DomainView,
|
||||||
DomainAuthorizingOfficialView,
|
DomainSeniorOfficialView,
|
||||||
DomainOrgNameAddressView,
|
DomainOrgNameAddressView,
|
||||||
DomainDNSView,
|
DomainDNSView,
|
||||||
DomainNameserversView,
|
DomainNameserversView,
|
||||||
|
|
|
@ -41,7 +41,7 @@ from registrar.views.utility.permission_views import UserDomainRolePermissionDel
|
||||||
|
|
||||||
from ..forms import (
|
from ..forms import (
|
||||||
ContactForm,
|
ContactForm,
|
||||||
AuthorizingOfficialContactForm,
|
SeniorOfficialContactForm,
|
||||||
DomainOrgNameAddressForm,
|
DomainOrgNameAddressForm,
|
||||||
DomainAddUserForm,
|
DomainAddUserForm,
|
||||||
DomainSecurityEmailForm,
|
DomainSecurityEmailForm,
|
||||||
|
@ -228,18 +228,18 @@ class DomainOrgNameAddressView(DomainFormBaseView):
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class DomainAuthorizingOfficialView(DomainFormBaseView):
|
class DomainSeniorOfficialView(DomainFormBaseView):
|
||||||
"""Domain authorizing official editing view."""
|
"""Domain senior official editing view."""
|
||||||
|
|
||||||
model = Domain
|
model = Domain
|
||||||
template_name = "domain_authorizing_official.html"
|
template_name = "domain_senior_official.html"
|
||||||
context_object_name = "domain"
|
context_object_name = "domain"
|
||||||
form_class = AuthorizingOfficialContactForm
|
form_class = SeniorOfficialContactForm
|
||||||
|
|
||||||
def get_form_kwargs(self, *args, **kwargs):
|
def get_form_kwargs(self, *args, **kwargs):
|
||||||
"""Add domain_info.authorizing_official instance to make a bound form."""
|
"""Add domain_info.senior_official instance to make a bound form."""
|
||||||
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
||||||
form_kwargs["instance"] = self.object.domain_info.authorizing_official
|
form_kwargs["instance"] = self.object.domain_info.senior_official
|
||||||
|
|
||||||
domain_info = self.get_domain_info_from_domain()
|
domain_info = self.get_domain_info_from_domain()
|
||||||
invalid_fields = [DomainRequest.OrganizationChoices.FEDERAL, DomainRequest.OrganizationChoices.TRIBAL]
|
invalid_fields = [DomainRequest.OrganizationChoices.FEDERAL, DomainRequest.OrganizationChoices.TRIBAL]
|
||||||
|
@ -256,10 +256,10 @@ class DomainAuthorizingOfficialView(DomainFormBaseView):
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
"""Redirect to the overview page for the domain."""
|
"""Redirect to the overview page for the domain."""
|
||||||
return reverse("domain-authorizing-official", kwargs={"pk": self.object.pk})
|
return reverse("domain-senior-official", kwargs={"pk": self.object.pk})
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
"""The form is valid, save the authorizing official."""
|
"""The form is valid, save the senior official."""
|
||||||
|
|
||||||
# Set the domain information in the form so that it can be accessible
|
# Set the domain information in the form so that it can be accessible
|
||||||
# to associate a new Contact, if a new Contact is needed
|
# to associate a new Contact, if a new Contact is needed
|
||||||
|
@ -267,7 +267,7 @@ class DomainAuthorizingOfficialView(DomainFormBaseView):
|
||||||
form.set_domain_info(self.object.domain_info)
|
form.set_domain_info(self.object.domain_info)
|
||||||
form.save()
|
form.save()
|
||||||
|
|
||||||
messages.success(self.request, "The authorizing official for this domain has been updated.")
|
messages.success(self.request, "The senior official for this domain has been updated.")
|
||||||
|
|
||||||
# superclass has the redirect
|
# superclass has the redirect
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Step(StrEnum):
|
||||||
ORGANIZATION_ELECTION = "organization_election"
|
ORGANIZATION_ELECTION = "organization_election"
|
||||||
ORGANIZATION_CONTACT = "organization_contact"
|
ORGANIZATION_CONTACT = "organization_contact"
|
||||||
ABOUT_YOUR_ORGANIZATION = "about_your_organization"
|
ABOUT_YOUR_ORGANIZATION = "about_your_organization"
|
||||||
AUTHORIZING_OFFICIAL = "authorizing_official"
|
SENIOR_OFFICIAL = "senior_official"
|
||||||
CURRENT_SITES = "current_sites"
|
CURRENT_SITES = "current_sites"
|
||||||
DOTGOV_DOMAIN = "dotgov_domain"
|
DOTGOV_DOMAIN = "dotgov_domain"
|
||||||
PURPOSE = "purpose"
|
PURPOSE = "purpose"
|
||||||
|
@ -87,7 +87,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
||||||
Step.ORGANIZATION_ELECTION: _("Election office"),
|
Step.ORGANIZATION_ELECTION: _("Election office"),
|
||||||
Step.ORGANIZATION_CONTACT: _("Organization name and mailing address"),
|
Step.ORGANIZATION_CONTACT: _("Organization name and mailing address"),
|
||||||
Step.ABOUT_YOUR_ORGANIZATION: _("About your organization"),
|
Step.ABOUT_YOUR_ORGANIZATION: _("About your organization"),
|
||||||
Step.AUTHORIZING_OFFICIAL: _("Authorizing official"),
|
Step.SENIOR_OFFICIAL: _("Senior official"),
|
||||||
Step.CURRENT_SITES: _("Current websites"),
|
Step.CURRENT_SITES: _("Current websites"),
|
||||||
Step.DOTGOV_DOMAIN: _(".gov domain"),
|
Step.DOTGOV_DOMAIN: _(".gov domain"),
|
||||||
Step.PURPOSE: _("Purpose of your domain"),
|
Step.PURPOSE: _("Purpose of your domain"),
|
||||||
|
@ -358,7 +358,7 @@ class DomainRequestWizard(DomainRequestWizardPermissionView, TemplateView):
|
||||||
or self.domain_request.urbanization is not None
|
or self.domain_request.urbanization is not None
|
||||||
),
|
),
|
||||||
"about_your_organization": self.domain_request.about_your_organization 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,
|
"senior_official": self.domain_request.senior_official is not None,
|
||||||
"current_sites": (
|
"current_sites": (
|
||||||
self.domain_request.current_websites.exists() or self.domain_request.requested_domain is not None
|
self.domain_request.current_websites.exists() or self.domain_request.requested_domain is not None
|
||||||
),
|
),
|
||||||
|
@ -540,9 +540,9 @@ class AboutYourOrganization(DomainRequestWizard):
|
||||||
forms = [forms.AboutYourOrganizationForm]
|
forms = [forms.AboutYourOrganizationForm]
|
||||||
|
|
||||||
|
|
||||||
class AuthorizingOfficial(DomainRequestWizard):
|
class SeniorOfficial(DomainRequestWizard):
|
||||||
template_name = "domain_request_authorizing_official.html"
|
template_name = "domain_request_senior_official.html"
|
||||||
forms = [forms.AuthorizingOfficialForm]
|
forms = [forms.SeniorOfficialForm]
|
||||||
|
|
||||||
def get_context_data(self):
|
def get_context_data(self):
|
||||||
context = super().get_context_data()
|
context = super().get_context_data()
|
||||||
|
@ -817,7 +817,7 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
||||||
|
|
||||||
# After a delete occurs, do a second sweep on any returned duplicates.
|
# After a delete occurs, do a second sweep on any returned duplicates.
|
||||||
# This determines if any of these three fields share a contact, which is used for
|
# This determines if any of these three fields share a contact, which is used for
|
||||||
# the edge case where the same user may be an AO, and a submitter, for example.
|
# the edge case where the same user may be an SO, and a submitter, for example.
|
||||||
if len(duplicates) > 0:
|
if len(duplicates) > 0:
|
||||||
duplicates_to_delete, _ = self._get_orphaned_contacts(domain_request, check_db=True)
|
duplicates_to_delete, _ = self._get_orphaned_contacts(domain_request, check_db=True)
|
||||||
Contact.objects.filter(id__in=duplicates_to_delete, user=None).delete()
|
Contact.objects.filter(id__in=duplicates_to_delete, user=None).delete()
|
||||||
|
@ -830,7 +830,7 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
||||||
Collects all orphaned contacts associated with a given DomainRequest object.
|
Collects all orphaned contacts associated with a given DomainRequest object.
|
||||||
|
|
||||||
An orphaned contact is defined as a contact that is associated with the domain request,
|
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,
|
but not with any other domain_request. This includes the senior official, the submitter,
|
||||||
and any other contacts linked to the domain_request.
|
and any other contacts linked to the domain_request.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
@ -845,19 +845,19 @@ class DomainRequestDeleteView(DomainRequestPermissionDeleteView):
|
||||||
contacts_to_delete = []
|
contacts_to_delete = []
|
||||||
|
|
||||||
# Get each contact object on the DomainRequest object
|
# Get each contact object on the DomainRequest object
|
||||||
ao = domain_request.authorizing_official
|
so = domain_request.senior_official
|
||||||
submitter = domain_request.submitter
|
submitter = domain_request.submitter
|
||||||
other_contacts = list(domain_request.other_contacts.all())
|
other_contacts = list(domain_request.other_contacts.all())
|
||||||
other_contact_ids = domain_request.other_contacts.all().values_list("id", flat=True)
|
other_contact_ids = domain_request.other_contacts.all().values_list("id", flat=True)
|
||||||
|
|
||||||
# Check if the desired item still exists in the DB
|
# Check if the desired item still exists in the DB
|
||||||
if check_db:
|
if check_db:
|
||||||
ao = self._get_contacts_by_id([ao.id]).first() if ao is not None else None
|
so = self._get_contacts_by_id([so.id]).first() if so is not None else None
|
||||||
submitter = self._get_contacts_by_id([submitter.id]).first() if submitter is not None else None
|
submitter = self._get_contacts_by_id([submitter.id]).first() if submitter is not None else None
|
||||||
other_contacts = self._get_contacts_by_id(other_contact_ids)
|
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
|
# Pair each contact with its db related name for use in checking if it has joins
|
||||||
checked_contacts = [(ao, "authorizing_official"), (submitter, "submitted_domain_requests")]
|
checked_contacts = [(so, "senior_official"), (submitter, "submitted_domain_requests")]
|
||||||
checked_contacts.extend((contact, "contact_domain_requests") for contact in other_contacts)
|
checked_contacts.extend((contact, "contact_domain_requests") for contact in other_contacts)
|
||||||
|
|
||||||
for contact, related_name in checked_contacts:
|
for contact, related_name in checked_contacts:
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
10038 OUTOFSCOPE http://app:8080/users/add
|
10038 OUTOFSCOPE http://app:8080/users/add
|
||||||
10038 OUTOFSCOPE http://app:8080/nameservers
|
10038 OUTOFSCOPE http://app:8080/nameservers
|
||||||
10038 OUTOFSCOPE http://app:8080/your-contact-information
|
10038 OUTOFSCOPE http://app:8080/your-contact-information
|
||||||
10038 OUTOFSCOPE http://app:8080/authorizing-official
|
10038 OUTOFSCOPE http://app:8080/senior-official
|
||||||
10038 OUTOFSCOPE http://app:8080/security-email
|
10038 OUTOFSCOPE http://app:8080/security-email
|
||||||
10038 OUTOFSCOPE http://app:8080/delete
|
10038 OUTOFSCOPE http://app:8080/delete
|
||||||
10038 OUTOFSCOPE http://app:8080/withdraw
|
10038 OUTOFSCOPE http://app:8080/withdraw
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue