diff --git a/.github/workflows/deploy-sandbox.yaml b/.github/workflows/deploy-sandbox.yaml
index d9d7cbe14..1c486bdf7 100644
--- a/.github/workflows/deploy-sandbox.yaml
+++ b/.github/workflows/deploy-sandbox.yaml
@@ -24,6 +24,7 @@ jobs:
|| startsWith(github.head_ref, 'backup/')
|| startsWith(github.head_ref, 'meoward/')
|| startsWith(github.head_ref, 'bob/')
+ || startsWith(github.head_ref, 'cb/')
outputs:
environment: ${{ steps.var.outputs.environment}}
runs-on: "ubuntu-latest"
diff --git a/.github/workflows/migrate.yaml b/.github/workflows/migrate.yaml
index 825ab04d7..f5815012c 100644
--- a/.github/workflows/migrate.yaml
+++ b/.github/workflows/migrate.yaml
@@ -16,6 +16,7 @@ on:
- stable
- staging
- development
+ - cb
- bob
- meoward
- backup
diff --git a/.github/workflows/reset-db.yaml b/.github/workflows/reset-db.yaml
index 05eb963c3..06638aa05 100644
--- a/.github/workflows/reset-db.yaml
+++ b/.github/workflows/reset-db.yaml
@@ -16,6 +16,7 @@ on:
options:
- staging
- development
+ - cb
- bob
- meoward
- backup
diff --git a/ops/manifests/manifest-cb.yaml b/ops/manifests/manifest-cb.yaml
new file mode 100644
index 000000000..b9be98d27
--- /dev/null
+++ b/ops/manifests/manifest-cb.yaml
@@ -0,0 +1,32 @@
+---
+applications:
+- name: getgov-cb
+ buildpacks:
+ - python_buildpack
+ path: ../../src
+ instances: 1
+ memory: 512M
+ stack: cflinuxfs4
+ timeout: 180
+ command: ./run.sh
+ health-check-type: http
+ health-check-http-endpoint: /health
+ health-check-invocation-timeout: 40
+ env:
+ # Send stdout and stderr straight to the terminal without buffering
+ PYTHONUNBUFFERED: yup
+ # Tell Django where to find its configuration
+ DJANGO_SETTINGS_MODULE: registrar.config.settings
+ # Tell Django where it is being hosted
+ DJANGO_BASE_URL: https://getgov-cb.app.cloud.gov
+ # Tell Django how much stuff to log
+ DJANGO_LOG_LEVEL: INFO
+ # default public site location
+ GETGOV_PUBLIC_SITE_URL: https://get.gov
+ # Flag to disable/enable features in prod environments
+ IS_PRODUCTION: False
+ routes:
+ - route: getgov-cb.app.cloud.gov
+ services:
+ - getgov-credentials
+ - getgov-cb-database
diff --git a/src/registrar/admin.py b/src/registrar/admin.py
index efafbcfc4..d8b9ff9f9 100644
--- a/src/registrar/admin.py
+++ b/src/registrar/admin.py
@@ -1020,9 +1020,7 @@ class DomainInformationAdmin(ListHeaderAdmin):
"description": "Extends type of organization",
"fields": [
"federal_type",
- # "updated_federal_agency",
- # Above field commented out so it won't display
- "federal_agency", # TODO: remove later
+ "federal_agency",
"tribe_name",
"federally_recognized_tribe",
"state_recognized_tribe",
@@ -1273,9 +1271,7 @@ class DomainRequestAdmin(ListHeaderAdmin):
"description": "Extends type of organization",
"fields": [
"federal_type",
- # "updated_federal_agency",
- # Above field commented out so it won't display
- "federal_agency", # TODO: remove later
+ "federal_agency",
"tribe_name",
"federally_recognized_tribe",
"state_recognized_tribe",
diff --git a/src/registrar/assets/sass/_theme/_admin.scss b/src/registrar/assets/sass/_theme/_admin.scss
index 9554f7acd..9f5ea7a97 100644
--- a/src/registrar/assets/sass/_theme/_admin.scss
+++ b/src/registrar/assets/sass/_theme/_admin.scss
@@ -395,7 +395,6 @@ details.dja-detail-table {
border-top: none;
border-bottom: none;
}
-
}
@@ -643,13 +642,16 @@ address.dja-address-contact-list {
display: inline-flex;
padding-top: 4px;
line-height: 14px;
- color: var(--link-fg);
width: max-content;
font-size: unset;
text-decoration: none !important;
}
}
+button.usa-button__clipboard {
+ color: var(--link-fg);
+}
+
.no-outline-on-click:focus {
outline: none !important;
}
diff --git a/src/registrar/config/settings.py b/src/registrar/config/settings.py
index ff56f24ea..bbf06b825 100644
--- a/src/registrar/config/settings.py
+++ b/src/registrar/config/settings.py
@@ -656,6 +656,7 @@ ALLOWED_HOSTS = [
"getgov-stable.app.cloud.gov",
"getgov-staging.app.cloud.gov",
"getgov-development.app.cloud.gov",
+ "getgov-cb.app.cloud.gov",
"getgov-bob.app.cloud.gov",
"getgov-meoward.app.cloud.gov",
"getgov-backup.app.cloud.gov",
@@ -799,6 +800,6 @@ if DEBUG:
# Run:
# cf run-task getgov-<> --wait --command 'python manage.py auditlogmigratejson --traceback' --name auditlogmigratejson
# on our staging and stable, then remove these 2 variables or set to False
-AUDITLOG_TWO_STEP_MIGRATION = True
+AUDITLOG_TWO_STEP_MIGRATION = False
-AUDITLOG_USE_TEXT_CHANGES_IF_JSON_IS_NOT_PRESENT = True
+AUDITLOG_USE_TEXT_CHANGES_IF_JSON_IS_NOT_PRESENT = False
diff --git a/src/registrar/fixtures_domain_requests.py b/src/registrar/fixtures_domain_requests.py
index ece1d0f7f..1a4ab0b4a 100644
--- a/src/registrar/fixtures_domain_requests.py
+++ b/src/registrar/fixtures_domain_requests.py
@@ -3,13 +3,7 @@ import random
from faker import Faker
from django.db import transaction
-from registrar.models import (
- User,
- DomainRequest,
- DraftDomain,
- Contact,
- Website,
-)
+from registrar.models import User, DomainRequest, DraftDomain, Contact, Website, FederalAgency
fake = Faker()
logger = logging.getLogger(__name__)
@@ -101,12 +95,6 @@ class DomainRequestFixture:
# TODO for a future ticket: Allow for more than just "federal" here
da.generic_org_type = app["generic_org_type"] if "generic_org_type" in app else "federal"
- da.federal_agency = (
- app["federal_agency"]
- if "federal_agency" in app
- # Random choice of agency for selects, used as placeholders for testing.
- else random.choice(DomainRequest.AGENCIES) # nosec
- )
da.submission_date = fake.date()
da.federal_type = (
app["federal_type"]
@@ -146,6 +134,13 @@ class DomainRequestFixture:
da.requested_domain, _ = DraftDomain.objects.get_or_create(name=app["requested_domain"])
else:
da.requested_domain = DraftDomain.objects.create(name=cls.fake_dot_gov())
+ if not da.federal_agency:
+ if "federal_agency" in app and app["federal_agency"] is not None:
+ da.federal_agency, _ = FederalAgency.objects.get_or_create(name=app["federal_agency"])
+ else:
+ federal_agencies = FederalAgency.objects.all()
+ # Random choice of agency for selects, used as placeholders for testing.
+ da.federal_agency = random.choice(federal_agencies) # nosec
@classmethod
def _set_many_to_many_relations(cls, da: DomainRequest, app: dict):
diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py
index 8d74f6f35..9d16a30de 100644
--- a/src/registrar/forms/domain_request_wizard.py
+++ b/src/registrar/forms/domain_request_wizard.py
@@ -13,7 +13,7 @@ from registrar.forms.utility.wizard_form_helper import (
BaseYesNoForm,
BaseDeletableRegistrarForm,
)
-from registrar.models import Contact, DomainRequest, DraftDomain, Domain
+from registrar.models import Contact, DomainRequest, DraftDomain, Domain, FederalAgency
from registrar.templatetags.url_helpers import public_site_url
from registrar.utility.enums import ValidationReturnType
@@ -97,13 +97,16 @@ class OrganizationElectionForm(RegistrarForm):
class OrganizationContactForm(RegistrarForm):
# for federal agencies we also want to know the top-level agency.
- federal_agency = forms.ChoiceField(
+ federal_agency = forms.ModelChoiceField(
label="Federal agency",
# not required because this field won't be filled out unless
# it is a federal agency. Use clean to check programatically
# if it has been filled in when required.
+ # uncomment to see if modelChoiceField can be an arg later
required=False,
- choices=[("", "--Select--")] + DomainRequest.AGENCY_CHOICES,
+ queryset=FederalAgency.objects.all(),
+ empty_label="--Select--",
+ # choices=[("", "--Select--")] + DomainRequest.AGENCY_CHOICES,
)
organization_name = forms.CharField(
label="Organization name",
diff --git a/src/registrar/management/commands/transfer_transition_domains_to_domains.py b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
index 4ea74e335..4e05235d4 100644
--- a/src/registrar/management/commands/transfer_transition_domains_to_domains.py
+++ b/src/registrar/management/commands/transfer_transition_domains_to_domains.py
@@ -18,6 +18,7 @@ from registrar.models.contact import Contact
from registrar.models.domain_request import DomainRequest
from registrar.models.domain_information import DomainInformation
from registrar.models.user import User
+from registrar.models.federal_agency import FederalAgency
logger = logging.getLogger(__name__)
@@ -819,7 +820,7 @@ class Command(BaseCommand):
valid_org_choices = [(name, value) for name, value in DomainRequest.OrganizationChoices.choices]
valid_fed_choices = [value for name, value in DomainRequest.BranchChoices.choices]
- valid_agency_choices = DomainRequest.AGENCIES
+ valid_agency_choices = FederalAgency.objects.all()
# ======================================================
# ================= DOMAIN INFORMATION =================
logger.info(
diff --git a/src/registrar/migrations/0091_remove_domaininformation_federal_agency_and_more.py b/src/registrar/migrations/0091_remove_domaininformation_federal_agency_and_more.py
new file mode 100644
index 000000000..9b5f7f9d6
--- /dev/null
+++ b/src/registrar/migrations/0091_remove_domaininformation_federal_agency_and_more.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.2.10 on 2024-05-02 17:19
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("registrar", "0090_waffleflag"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="domaininformation",
+ name="federal_agency",
+ ),
+ migrations.RemoveField(
+ model_name="domainrequest",
+ name="federal_agency",
+ ),
+ ]
diff --git a/src/registrar/migrations/0092_rename_updated_federal_agency_domaininformation_federal_agency_and_more.py b/src/registrar/migrations/0092_rename_updated_federal_agency_domaininformation_federal_agency_and_more.py
new file mode 100644
index 000000000..70793b00e
--- /dev/null
+++ b/src/registrar/migrations/0092_rename_updated_federal_agency_domaininformation_federal_agency_and_more.py
@@ -0,0 +1,23 @@
+# Generated by Django 4.2.10 on 2024-05-02 17:22
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("registrar", "0091_remove_domaininformation_federal_agency_and_more"),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name="domaininformation",
+ old_name="updated_federal_agency",
+ new_name="federal_agency",
+ ),
+ migrations.RenameField(
+ model_name="domainrequest",
+ old_name="updated_federal_agency",
+ new_name="federal_agency",
+ ),
+ ]
diff --git a/src/registrar/models/domain_information.py b/src/registrar/models/domain_information.py
index 21fc27a0d..e0b5ad237 100644
--- a/src/registrar/models/domain_information.py
+++ b/src/registrar/models/domain_information.py
@@ -37,10 +37,7 @@ class DomainInformation(TimeStampedModel):
BranchChoices = DomainRequest.BranchChoices
- # TODO for #1975: Delete this after we run the new migration
- AGENCY_CHOICES = DomainRequest.AGENCY_CHOICES
-
- updated_federal_agency = models.ForeignKey(
+ federal_agency = models.ForeignKey(
"registrar.FederalAgency",
on_delete=models.PROTECT,
help_text="Associated federal agency",
@@ -106,12 +103,6 @@ class DomainInformation(TimeStampedModel):
blank=True,
)
- federal_agency = models.CharField(
- choices=AGENCY_CHOICES,
- null=True,
- blank=True,
- )
-
federal_type = models.CharField(
max_length=50,
choices=BranchChoices.choices,
diff --git a/src/registrar/models/domain_request.py b/src/registrar/models/domain_request.py
index 19f1a66c1..a947aba2f 100644
--- a/src/registrar/models/domain_request.py
+++ b/src/registrar/models/domain_request.py
@@ -238,207 +238,6 @@ class DomainRequest(TimeStampedModel):
JUDICIAL = "judicial", "Judicial"
LEGISLATIVE = "legislative", "Legislative"
- AGENCIES = [
- "Administrative Conference of the United States",
- "Advisory Council on Historic Preservation",
- "American Battle Monuments Commission",
- "AMTRAK",
- "Appalachian Regional Commission",
- ("Appraisal Subcommittee of the Federal Financial " "Institutions Examination Council"),
- "Appraisal Subcommittee",
- "Architect of the Capitol",
- "Armed Forces Retirement Home",
- "Barry Goldwater Scholarship and Excellence in Education Foundation",
- "Barry Goldwater Scholarship and Excellence in Education Program",
- "Central Intelligence Agency",
- "Chemical Safety Board",
- "Christopher Columbus Fellowship Foundation",
- "Civil Rights Cold Case Records Review Board",
- "Commission for the Preservation of America's Heritage Abroad",
- "Commission of Fine Arts",
- "Committee for Purchase From People Who Are Blind or Severely Disabled",
- "Commodity Futures Trading Commission",
- "Congressional Budget Office",
- "Consumer Financial Protection Bureau",
- "Consumer Product Safety Commission",
- "Corporation for National & Community Service",
- "Corporation for National and Community Service",
- "Council of Inspectors General on Integrity and Efficiency",
- "Court Services and Offender Supervision",
- "Cyberspace Solarium Commission",
- "DC Court Services and Offender Supervision Agency",
- "DC Pre-trial Services",
- "Defense Nuclear Facilities Safety Board",
- "Delta Regional Authority",
- "Denali Commission",
- "Department of Agriculture",
- "Department of Commerce",
- "Department of Defense",
- "Department of Education",
- "Department of Energy",
- "Department of Health and Human Services",
- "Department of Homeland Security",
- "Department of Housing and Urban Development",
- "Department of Justice",
- "Department of Labor",
- "Department of State",
- "Department of the Interior",
- "Department of the Treasury",
- "Department of Transportation",
- "Department of Veterans Affairs",
- "Director of National Intelligence",
- "Dwight D. Eisenhower Memorial Commission",
- "Election Assistance Commission",
- "Environmental Protection Agency",
- "Equal Employment Opportunity Commission",
- "Executive Office of the President",
- "Export-Import Bank of the United States",
- "Export/Import Bank of the U.S.",
- "Farm Credit Administration",
- "Farm Credit System Insurance Corporation",
- "Federal Communications Commission",
- "Federal Deposit Insurance Corporation",
- "Federal Election Commission",
- "Federal Energy Regulatory Commission",
- "Federal Financial Institutions Examination Council",
- "Federal Housing Finance Agency",
- "Federal Judiciary",
- "Federal Labor Relations Authority",
- "Federal Maritime Commission",
- "Federal Mediation and Conciliation Service",
- "Federal Mine Safety and Health Review Commission",
- "Federal Permitting Improvement Steering Council",
- "Federal Reserve Board of Governors",
- "Federal Reserve System",
- "Federal Trade Commission",
- "General Services Administration",
- "gov Administration",
- "Government Accountability Office",
- "Government Publishing Office",
- "Gulf Coast Ecosystem Restoration Council",
- "Harry S Truman Scholarship Foundation",
- "Harry S. Truman Scholarship Foundation",
- "Institute of Museum and Library Services",
- "Institute of Peace",
- "Inter-American Foundation",
- "International Boundary and Water Commission: United States and Mexico",
- "International Boundary Commission: United States and Canada",
- "International Joint Commission: United States and Canada",
- "James Madison Memorial Fellowship Foundation",
- "Japan-United States Friendship Commission",
- "Japan-US Friendship Commission",
- "John F. Kennedy Center for Performing Arts",
- "John F. Kennedy Center for the Performing Arts",
- "Legal Services Corporation",
- "Legislative Branch",
- "Library of Congress",
- "Marine Mammal Commission",
- "Medicaid and CHIP Payment and Access Commission",
- "Medical Payment Advisory Commission",
- "Medicare Payment Advisory Commission",
- "Merit Systems Protection Board",
- "Millennium Challenge Corporation",
- "Morris K. Udall and Stewart L. Udall Foundation",
- "National Aeronautics and Space Administration",
- "National Archives and Records Administration",
- "National Capital Planning Commission",
- "National Council on Disability",
- "National Credit Union Administration",
- "National Endowment for the Arts",
- "National Endowment for the Humanities",
- "National Foundation on the Arts and the Humanities",
- "National Gallery of Art",
- "National Indian Gaming Commission",
- "National Labor Relations Board",
- "National Mediation Board",
- "National Science Foundation",
- "National Security Commission on Artificial Intelligence",
- "National Transportation Safety Board",
- "Networking Information Technology Research and Development",
- "Non-Federal Agency",
- "Northern Border Regional Commission",
- "Nuclear Regulatory Commission",
- "Nuclear Safety Oversight Committee",
- "Nuclear Waste Technical Review Board",
- "Occupational Safety & Health Review Commission",
- "Occupational Safety and Health Review Commission",
- "Office of Compliance",
- "Office of Congressional Workplace Rights",
- "Office of Government Ethics",
- "Office of Navajo and Hopi Indian Relocation",
- "Office of Personnel Management",
- "Open World Leadership Center",
- "Overseas Private Investment Corporation",
- "Peace Corps",
- "Pension Benefit Guaranty Corporation",
- "Postal Regulatory Commission",
- "Presidio Trust",
- "Privacy and Civil Liberties Oversight Board",
- "Public Buildings Reform Board",
- "Public Defender Service for the District of Columbia",
- "Railroad Retirement Board",
- "Securities and Exchange Commission",
- "Selective Service System",
- "Small Business Administration",
- "Smithsonian Institution",
- "Social Security Administration",
- "Social Security Advisory Board",
- "Southeast Crescent Regional Commission",
- "Southwest Border Regional Commission",
- "State Justice Institute",
- "State, Local, and Tribal Government",
- "Stennis Center for Public Service",
- "Surface Transportation Board",
- "Tennessee Valley Authority",
- "The Executive Office of the President",
- "The Intelligence Community",
- "The Legislative Branch",
- "The Supreme Court",
- "The United States World War One Centennial Commission",
- "U.S. Access Board",
- "U.S. Agency for Global Media",
- "U.S. Agency for International Development",
- "U.S. Capitol Police",
- "U.S. Chemical Safety Board",
- "U.S. China Economic and Security Review Commission",
- "U.S. Commission for the Preservation of Americas Heritage Abroad",
- "U.S. Commission of Fine Arts",
- "U.S. Commission on Civil Rights",
- "U.S. Commission on International Religious Freedom",
- "U.S. Courts",
- "U.S. Department of Agriculture",
- "U.S. Interagency Council on Homelessness",
- "U.S. International Trade Commission",
- "U.S. Nuclear Waste Technical Review Board",
- "U.S. Office of Special Counsel",
- "U.S. Peace Corps",
- "U.S. Postal Service",
- "U.S. Semiquincentennial Commission",
- "U.S. Trade and Development Agency",
- "U.S.-China Economic and Security Review Commission",
- "Udall Foundation",
- "United States AbilityOne",
- "United States Access Board",
- "United States African Development Foundation",
- "United States Agency for Global Media",
- "United States Arctic Research Commission",
- "United States Global Change Research Program",
- "United States Holocaust Memorial Museum",
- "United States Institute of Peace",
- "United States Interagency Council on Homelessness",
- "United States International Development Finance Corporation",
- "United States International Trade Commission",
- "United States Postal Service",
- "United States Senate",
- "United States Trade and Development Agency",
- "Utah Reclamation Mitigation and Conservation Commission",
- "Vietnam Education Foundation",
- "Western Hemisphere Drug Policy Commission",
- "Woodrow Wilson International Center for Scholars",
- "World War I Centennial Commission",
- ]
- AGENCY_CHOICES = [(v, v) for v in AGENCIES]
-
class RejectionReasons(models.TextChoices):
DOMAIN_PURPOSE = "purpose_not_met", "Purpose requirements not met"
REQUESTOR = "requestor_not_eligible", "Requestor not eligible to make request"
@@ -467,7 +266,7 @@ class DomainRequest(TimeStampedModel):
blank=True,
)
- updated_federal_agency = models.ForeignKey(
+ federal_agency = models.ForeignKey(
"registrar.FederalAgency",
on_delete=models.PROTECT,
help_text="Associated federal agency",
@@ -530,12 +329,6 @@ class DomainRequest(TimeStampedModel):
blank=True,
)
- federal_agency = models.CharField(
- choices=AGENCY_CHOICES,
- null=True,
- blank=True,
- )
-
federal_type = models.CharField(
max_length=50,
choices=BranchChoices.choices,
diff --git a/src/registrar/templates/domain_request_requirements.html b/src/registrar/templates/domain_request_requirements.html
index d0da7818b..c2581fad6 100644
--- a/src/registrar/templates/domain_request_requirements.html
+++ b/src/registrar/templates/domain_request_requirements.html
@@ -1,5 +1,6 @@
{% extends 'domain_request_form.html' %}
{% load field_helpers %}
+{% load url_helpers %}
{% block form_instructions %}
Please read this page. Check the box at the bottom to show that you agree to the requirements for operating a .gov domain.
@@ -10,7 +11,7 @@
Commercial purposes
- A .gov domain must not be used for commercial purposes, such as advertising that benefits private individuals or entities.
+ A .gov domain must not be used for commercial purposes, such as advertising that benefits private individuals or entities.
Political campaigns
diff --git a/src/registrar/tests/common.py b/src/registrar/tests/common.py
index f1c77fb8e..3d9a147a2 100644
--- a/src/registrar/tests/common.py
+++ b/src/registrar/tests/common.py
@@ -26,6 +26,7 @@ from registrar.models import (
DomainInformation,
PublicContact,
Domain,
+ FederalAgency,
)
from epplibwrapper import (
commands,
@@ -539,6 +540,9 @@ class MockDb(TestCase):
self.end_date = current_date + timedelta(days=2)
self.start_date = current_date - timedelta(days=2)
+ self.federal_agency_1, _ = FederalAgency.objects.get_or_create(agency="World War I Centennial Commission")
+ self.federal_agency_2, _ = FederalAgency.objects.get_or_create(agency="Armed Forces Retirement Home")
+
self.domain_1, _ = Domain.objects.get_or_create(
name="cdomain1.gov", state=Domain.State.READY, first_ready=timezone.now()
)
@@ -582,7 +586,7 @@ class MockDb(TestCase):
creator=self.user,
domain=self.domain_1,
generic_org_type="federal",
- federal_agency="World War I Centennial Commission",
+ federal_agency=self.federal_agency_1,
federal_type="executive",
is_election_board=False,
)
@@ -593,63 +597,63 @@ class MockDb(TestCase):
creator=self.user,
domain=self.domain_3,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_4, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_4,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_5, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_5,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_6, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_6,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_7, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_7,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_8, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_8,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_9, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_9,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_10, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_10,
generic_org_type="federal",
- federal_agency="Armed Forces Retirement Home",
+ federal_agency=self.federal_agency_2,
is_election_board=False,
)
self.domain_information_11, _ = DomainInformation.objects.get_or_create(
creator=self.user,
domain=self.domain_11,
generic_org_type="federal",
- federal_agency="World War I Centennial Commission",
+ federal_agency=self.federal_agency_1,
federal_type="executive",
is_election_board=False,
)
@@ -740,6 +744,7 @@ class MockDb(TestCase):
User.objects.all().delete()
UserDomainRole.objects.all().delete()
DomainInvitation.objects.all().delete()
+ FederalAgency.objects.all().delete()
def mock_user():
@@ -805,7 +810,6 @@ def completed_domain_request(
is_election_board=False,
organization_type=None,
federal_agency=None,
- updated_federal_agency=None,
):
"""A completed domain request."""
if not user:
@@ -861,7 +865,6 @@ def completed_domain_request(
status=status,
investigator=investigator,
federal_agency=federal_agency,
- updated_federal_agency=updated_federal_agency,
)
if has_about_your_organization:
domain_request_kwargs["about_your_organization"] = "e-Government"
diff --git a/src/registrar/tests/test_admin.py b/src/registrar/tests/test_admin.py
index 4c09f6472..98c5df0ac 100644
--- a/src/registrar/tests/test_admin.py
+++ b/src/registrar/tests/test_admin.py
@@ -2187,8 +2187,7 @@ class TestDomainRequestAdmin(MockEppLib):
"updated_at",
"status",
"rejection_reason",
- "updated_federal_agency",
- # TODO: once approved, we'll have to remove above from test
+ "federal_agency",
"creator",
"investigator",
"generic_org_type",
@@ -2197,7 +2196,6 @@ class TestDomainRequestAdmin(MockEppLib):
"federally_recognized_tribe",
"state_recognized_tribe",
"tribe_name",
- "federal_agency",
"federal_type",
"organization_name",
"address_line1",
diff --git a/src/registrar/tests/test_management_scripts.py b/src/registrar/tests/test_management_scripts.py
index 86ea1847f..791c1eb1f 100644
--- a/src/registrar/tests/test_management_scripts.py
+++ b/src/registrar/tests/test_management_scripts.py
@@ -16,6 +16,7 @@ from registrar.models import (
UserDomainRole,
VerifiedByStaff,
PublicContact,
+ FederalAgency,
)
from django.core.management import call_command
@@ -534,8 +535,9 @@ class TestPatchAgencyInfo(TestCase):
self.user, _ = User.objects.get_or_create(username="testuser")
self.domain, _ = Domain.objects.get_or_create(name="testdomain.gov")
self.domain_info, _ = DomainInformation.objects.get_or_create(domain=self.domain, creator=self.user)
+ self.federal_agency, _ = FederalAgency.objects.get_or_create(agency="test agency")
self.transition_domain, _ = TransitionDomain.objects.get_or_create(
- domain_name="testdomain.gov", federal_agency="test agency"
+ domain_name="testdomain.gov", federal_agency=self.federal_agency
)
def tearDown(self):
@@ -550,82 +552,6 @@ class TestPatchAgencyInfo(TestCase):
with less_console_noise():
call_command("patch_federal_agency_info", "registrar/tests/data/fake_current_full.csv", debug=True)
- def test_patch_agency_info(self):
- """
- Tests that the `patch_federal_agency_info` command successfully
- updates the `federal_agency` field
- of a `DomainInformation` object when the corresponding
- `TransitionDomain` object has a valid `federal_agency`.
- """
- with less_console_noise():
- # Ensure that the federal_agency is None
- self.assertEqual(self.domain_info.federal_agency, None)
- self.call_patch_federal_agency_info()
- # Reload the domain_info object from the database
- self.domain_info.refresh_from_db()
- # Check that the federal_agency field was updated
- self.assertEqual(self.domain_info.federal_agency, "test agency")
-
- def test_patch_agency_info_skip(self):
- """
- Tests that the `patch_federal_agency_info` command logs a warning and
- does not update the `federal_agency` field
- of a `DomainInformation` object when the corresponding
- `TransitionDomain` object does not exist.
- """
- with less_console_noise():
- # Set federal_agency to None to simulate a skip
- self.transition_domain.federal_agency = None
- self.transition_domain.save()
- with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context:
- self.call_patch_federal_agency_info()
- # Check that the correct log message was output
- self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0])
- # Reload the domain_info object from the database
- self.domain_info.refresh_from_db()
- # Check that the federal_agency field was not updated
- self.assertIsNone(self.domain_info.federal_agency)
-
- def test_patch_agency_info_skip_updates_data(self):
- """
- Tests that the `patch_federal_agency_info` command logs a warning but
- updates the DomainInformation object, because a record exists in the
- provided current-full.csv file.
- """
- with less_console_noise():
- # Set federal_agency to None to simulate a skip
- self.transition_domain.federal_agency = None
- self.transition_domain.save()
- # Change the domain name to something parsable in the .csv
- self.domain.name = "cdomain1.gov"
- self.domain.save()
- with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="WARNING") as context:
- self.call_patch_federal_agency_info()
- # Check that the correct log message was output
- self.assertIn("SOME AGENCY DATA WAS NONE", context.output[0])
- # Reload the domain_info object from the database
- self.domain_info.refresh_from_db()
- # Check that the federal_agency field was not updated
- self.assertEqual(self.domain_info.federal_agency, "World War I Centennial Commission")
-
- def test_patch_agency_info_skips_valid_domains(self):
- """
- Tests that the `patch_federal_agency_info` command logs INFO and
- does not update the `federal_agency` field
- of a `DomainInformation` object
- """
- with less_console_noise():
- self.domain_info.federal_agency = "unchanged"
- self.domain_info.save()
- with self.assertLogs("registrar.management.commands.patch_federal_agency_info", level="INFO") as context:
- self.call_patch_federal_agency_info()
- # Check that the correct log message was output
- self.assertIn("FINISHED", context.output[1])
- # Reload the domain_info object from the database
- self.domain_info.refresh_from_db()
- # Check that the federal_agency field was not updated
- self.assertEqual(self.domain_info.federal_agency, "unchanged")
-
class TestExtendExpirationDates(MockEppLib):
def setUp(self):
@@ -841,120 +767,3 @@ class TestDiscloseEmails(MockEppLib):
)
]
)
-
-
-# TODO in #1793: Remove this whole test class
-class TestPopulateDomainUpdatedFederalAgency(TestCase):
- def setUp(self):
- super().setUp()
-
- # Get the domain requests
- self.domain_request_1 = completed_domain_request(
- name="stitches.gov",
- generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
- is_election_board=True,
- status=DomainRequest.DomainRequestStatus.IN_REVIEW,
- federal_agency="U.S. Peace Corps",
- )
- self.domain_request_2 = completed_domain_request(
- name="fadoesntexist.gov",
- generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
- is_election_board=True,
- status=DomainRequest.DomainRequestStatus.IN_REVIEW,
- federal_agency="MEOWARDRULES",
- )
- self.domain_request_3 = completed_domain_request(
- name="nullfederalagency.gov",
- generic_org_type=DomainRequest.OrganizationChoices.FEDERAL,
- is_election_board=True,
- status=DomainRequest.DomainRequestStatus.IN_REVIEW,
- federal_agency=None,
- )
-
- # Approve all three requests
- self.domain_request_1.approve()
- self.domain_request_2.approve()
- self.domain_request_3.approve()
-
- # Get the domains
- self.domain_1 = Domain.objects.get(name="stitches.gov")
- self.domain_2 = Domain.objects.get(name="fadoesntexist.gov")
- self.domain_3 = Domain.objects.get(name="nullfederalagency.gov")
-
- # Get the domain infos
- self.domain_info_1 = DomainInformation.objects.get(domain=self.domain_1)
- self.domain_info_2 = DomainInformation.objects.get(domain=self.domain_2)
- self.domain_info_3 = DomainInformation.objects.get(domain=self.domain_3)
-
- def tearDown(self):
- super().tearDown()
- DomainInformation.objects.all().delete()
- DomainRequest.objects.all().delete()
- Domain.objects.all().delete()
-
- def run_populate_domain_updated_federal_agency(self):
- """
- This method executes the populate_domain_updated_federal_agency command.
-
- The 'call_command' function from Django's management framework is then used to
- execute the populate_domain_updated_federal_agency command.
- """
- with less_console_noise():
- call_command("populate_domain_updated_federal_agency")
-
- def test_domain_information_renaming_federal_agency_success(self):
- """
- Domain Information updates successfully for an "outdated" Federal Agency
- """
-
- self.run_populate_domain_updated_federal_agency()
-
- self.domain_info_1.refresh_from_db()
-
- previous_federal_agency_name = self.domain_info_1.federal_agency
-
- updated_federal_agency_name = self.domain_info_1.updated_federal_agency.agency
-
- self.assertEqual(previous_federal_agency_name, "U.S. Peace Corps")
- self.assertEqual(updated_federal_agency_name, "Peace Corps")
-
- def test_domain_information_does_not_exist(self):
- """
- Update a Federal Agency that doesn't exist
- (should return None bc the Federal Agency didn't exist before)
- """
-
- self.run_populate_domain_updated_federal_agency()
-
- self.domain_info_2.refresh_from_db()
-
- self.assertEqual(self.domain_info_2.updated_federal_agency, None)
-
- def test_domain_request_is_skipped(self):
- """
- Update a Domain Request that doesn't exist
- (should return None bc the Federal Agency didn't exist before)
- """
-
- # Test case #2
- self.run_populate_domain_updated_federal_agency()
-
- self.domain_request_2.refresh_from_db()
-
- self.assertEqual(self.domain_request_2.updated_federal_agency, None)
-
- def test_domain_information_updating_null_federal_agency_to_non_federal_agency(self):
- """
- Updating a Domain Information that was previously None
- to Non-Federal Agency
- """
-
- self.run_populate_domain_updated_federal_agency()
-
- self.domain_info_3.refresh_from_db()
-
- previous_federal_agency_name = self.domain_info_3.federal_agency
- updated_federal_agency_name = self.domain_info_3.updated_federal_agency.agency
-
- self.assertEqual(previous_federal_agency_name, None)
- self.assertEqual(updated_federal_agency_name, "Non-Federal Agency")
diff --git a/src/registrar/tests/test_transition_domain_migrations.py b/src/registrar/tests/test_transition_domain_migrations.py
index 9311b59f7..92b205713 100644
--- a/src/registrar/tests/test_transition_domain_migrations.py
+++ b/src/registrar/tests/test_transition_domain_migrations.py
@@ -11,6 +11,7 @@ from registrar.models import (
TransitionDomain,
DomainInformation,
UserDomainRole,
+ FederalAgency,
)
from django.core.management import call_command
@@ -42,6 +43,7 @@ class TestProcessedMigrations(TestCase):
DomainInformation.objects.all().delete()
DomainInvitation.objects.all().delete()
TransitionDomain.objects.all().delete()
+ FederalAgency.objects.all().delete()
# Delete users
User.objects.all().delete()
@@ -329,6 +331,7 @@ class TestOrganizationMigration(TestCase):
# Lets test the first one
transition = transition_domains.first()
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
expected_transition_domain = TransitionDomain(
username="alexandra.bobbitt5@test.com",
domain_name="fakewebsite2.gov",
@@ -337,7 +340,7 @@ class TestOrganizationMigration(TestCase):
generic_org_type="Federal",
organization_name="Fanoodle",
federal_type="Executive",
- federal_agency="Department of Commerce",
+ federal_agency=federal_agency,
epp_creation_date=datetime.date(2004, 5, 7),
epp_expiration_date=datetime.date(2023, 9, 30),
first_name="Seline",
@@ -392,6 +395,7 @@ class TestOrganizationMigration(TestCase):
# == Third, test that we've loaded data as we expect == #
_domain = Domain.objects.filter(name="fakewebsite2.gov").get()
domain_information = DomainInformation.objects.filter(domain=_domain).get()
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
expected_creator = User.objects.filter(username="System").get()
expected_ao = Contact.objects.filter(
@@ -400,7 +404,7 @@ class TestOrganizationMigration(TestCase):
expected_domain_information = DomainInformation(
creator=expected_creator,
generic_org_type="federal",
- federal_agency="Department of Commerce",
+ federal_agency=federal_agency,
federal_type="executive",
organization_name="Fanoodle",
address_line1="93001 Arizona Drive",
@@ -447,6 +451,7 @@ class TestOrganizationMigration(TestCase):
# == Fourth, test that no data is overwritten as we expect == #
_domain = Domain.objects.filter(name="fakewebsite2.gov").get()
domain_information = DomainInformation.objects.filter(domain=_domain).get()
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="Department of Commerce")
expected_creator = User.objects.filter(username="System").get()
expected_ao = Contact.objects.filter(
@@ -455,7 +460,7 @@ class TestOrganizationMigration(TestCase):
expected_domain_information = DomainInformation(
creator=expected_creator,
generic_org_type="federal",
- federal_agency="Department of Commerce",
+ federal_agency=federal_agency,
federal_type="executive",
organization_name="Fanoodle",
address_line1="93001 Galactic Way",
@@ -758,74 +763,6 @@ class TestMigrations(TestCase):
self.assertEqual(testdomain.name, "fakewebsite2.gov")
self.assertEqual(testdomain.state, "on hold")
- def test_load_full_domain_information(self):
- with less_console_noise():
- self.run_load_domains()
- self.run_transfer_domains()
-
- # Analyze the tables
- expected_total_transition_domains = 9
- expected_total_domains = 5
- expected_total_domain_informations = 5
- expected_total_domain_invitations = 8
-
- expected_missing_domains = 0
- expected_duplicate_domains = 0
- expected_missing_domain_informations = 0
- expected_missing_domain_invitations = 1
- self.compare_tables(
- expected_total_transition_domains,
- expected_total_domains,
- expected_total_domain_informations,
- expected_total_domain_invitations,
- expected_missing_domains,
- expected_duplicate_domains,
- expected_missing_domain_informations,
- expected_missing_domain_invitations,
- )
-
- # Test created Domain Information objects
- domain = Domain.objects.filter(name="anomaly.gov").get()
- anomaly_domain_infos = DomainInformation.objects.filter(domain=domain)
-
- self.assertEqual(anomaly_domain_infos.count(), 1)
-
- # This domain should be pretty barebones. Something isnt
- # parsing right if we get a lot of data.
- anomaly = anomaly_domain_infos.get()
- self.assertEqual(anomaly.organization_name, "Flashdog")
- self.assertEqual(anomaly.generic_org_type, None)
- self.assertEqual(anomaly.federal_agency, None)
- self.assertEqual(anomaly.federal_type, None)
-
- # Check for the "system" creator user
- Users = User.objects.filter(username="System")
- self.assertEqual(Users.count(), 1)
- self.assertEqual(anomaly.creator, Users.get())
-
- domain = Domain.objects.filter(name="fakewebsite2.gov").get()
- fakewebsite_domain_infos = DomainInformation.objects.filter(domain=domain)
- self.assertEqual(fakewebsite_domain_infos.count(), 1)
-
- fakewebsite = fakewebsite_domain_infos.get()
- self.assertEqual(fakewebsite.organization_name, "Fanoodle")
- self.assertEqual(fakewebsite.generic_org_type, "federal")
- self.assertEqual(fakewebsite.federal_agency, "Department of Commerce")
- self.assertEqual(fakewebsite.federal_type, "executive")
-
- ao = fakewebsite.authorizing_official
-
- self.assertEqual(ao.first_name, "Seline")
- self.assertEqual(ao.middle_name, "testmiddle2")
- self.assertEqual(ao.last_name, "Tower")
- self.assertEqual(ao.email, "stower3@answers.com")
- self.assertEqual(ao.phone, "151-539-6028")
-
- # Check for the "system" creator user
- Users = User.objects.filter(username="System")
- self.assertEqual(Users.count(), 1)
- self.assertEqual(anomaly.creator, Users.get())
-
def test_transfer_transition_domains_to_domains(self):
with less_console_noise():
self.run_load_domains()
diff --git a/src/registrar/tests/test_views_domain.py b/src/registrar/tests/test_views_domain.py
index 6448e91e1..1d9fbb2a8 100644
--- a/src/registrar/tests/test_views_domain.py
+++ b/src/registrar/tests/test_views_domain.py
@@ -31,6 +31,7 @@ from registrar.models import (
HostIP,
UserDomainRole,
User,
+ FederalAgency,
)
from datetime import date, datetime, timedelta
from django.utils import timezone
@@ -1420,13 +1421,13 @@ class TestDomainOrganization(TestDomainOverview):
"""
Submitting a change to federal_agency is blocked for federal domains
"""
- # Set the current domain to a tribal organization with a preset value.
- # Save first, so we can test if saving is unaffected (it should be).
+
fed_org_type = DomainInformation.OrganizationChoices.FEDERAL
self.domain_information.generic_org_type = fed_org_type
self.domain_information.save()
try:
- self.domain_information.federal_agency = "AMTRAK"
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="AMTRAK")
+ self.domain_information.federal_agency = federal_agency
self.domain_information.save()
except ValueError as err:
self.fail(f"A ValueError was caught during the test: {err}")
@@ -1438,7 +1439,7 @@ class TestDomainOrganization(TestDomainOverview):
form = org_name_page.forms[0]
# Check the value of the input field
agency_input = form.fields["federal_agency"][0]
- self.assertEqual(agency_input.value, "AMTRAK")
+ self.assertEqual(agency_input.value, str(federal_agency.id))
# Check if the input field is disabled
self.assertTrue("disabled" in agency_input.attrs)
@@ -1456,14 +1457,14 @@ class TestDomainOrganization(TestDomainOverview):
self.assertEqual(success_result_page.status_code, 200)
# Check for the old and new value
- self.assertContains(success_result_page, "AMTRAK")
+ self.assertContains(success_result_page, federal_agency.id)
self.assertNotContains(success_result_page, "Department of State")
# Do another check on the form itself
form = success_result_page.forms[0]
# Check the value of the input field
organization_name_input = form.fields["federal_agency"][0]
- self.assertEqual(organization_name_input.value, "AMTRAK")
+ self.assertEqual(organization_name_input.value, str(federal_agency.id))
# Check if the input field is disabled
self.assertTrue("disabled" in organization_name_input.attrs)
@@ -1482,7 +1483,8 @@ class TestDomainOrganization(TestDomainOverview):
self.domain_information.generic_org_type = federal_org_type
self.domain_information.save()
- old_federal_agency_value = ("AMTRAK", "AMTRAK")
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="AMTRAK")
+ old_federal_agency_value = federal_agency
try:
# Add a federal agency. Defined as a tuple since this list may change order.
self.domain_information.federal_agency = old_federal_agency_value
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
index 22ad56646..272464133 100644
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -16,6 +16,7 @@ from registrar.models import (
Contact,
User,
Website,
+ FederalAgency,
)
from registrar.views.domain_request import DomainRequestWizard, Step
@@ -178,7 +179,8 @@ class DomainRequestTests(TestWithUser, WebTest):
org_contact_page = federal_result.follow()
org_contact_form = org_contact_page.forms[0]
# federal agency so we have to fill in federal_agency
- org_contact_form["organization_contact-federal_agency"] = "General Services Administration"
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="General Services Administration")
+ org_contact_form["organization_contact-federal_agency"] = federal_agency.id
org_contact_form["organization_contact-organization_name"] = "Testorg"
org_contact_form["organization_contact-address_line1"] = "address 1"
org_contact_form["organization_contact-address_line2"] = "address 2"
@@ -688,7 +690,6 @@ class DomainRequestTests(TestWithUser, WebTest):
self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
contact_result = org_contact_form.submit()
-
# the post request should return a redirect to the
# about your organization page if it was successful.
self.assertEqual(contact_result.status_code, 302)
@@ -2020,7 +2021,8 @@ class DomainRequestTests(TestWithUser, WebTest):
org_contact_page = federal_result.follow()
org_contact_form = org_contact_page.forms[0]
# federal agency so we have to fill in federal_agency
- org_contact_form["organization_contact-federal_agency"] = "General Services Administration"
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="General Services Administration")
+ org_contact_form["organization_contact-federal_agency"] = federal_agency.id
org_contact_form["organization_contact-organization_name"] = "Testorg"
org_contact_form["organization_contact-address_line1"] = "address 1"
org_contact_form["organization_contact-address_line2"] = "address 2"
@@ -2091,7 +2093,8 @@ class DomainRequestTests(TestWithUser, WebTest):
org_contact_page = federal_result.follow()
org_contact_form = org_contact_page.forms[0]
# federal agency so we have to fill in federal_agency
- org_contact_form["organization_contact-federal_agency"] = "General Services Administration"
+ federal_agency, _ = FederalAgency.objects.get_or_create(agency="General Services Administration")
+ org_contact_form["organization_contact-federal_agency"] = federal_agency.id
org_contact_form["organization_contact-organization_name"] = "Testorg"
org_contact_form["organization_contact-address_line1"] = "address 1"
org_contact_form["organization_contact-address_line2"] = "address 2"