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"