Repository: cisagov/manage.get.gov

Issue:
Connect Federal Agency drop down with the federal agency table
### Current Behavior
We recently added the federal agencies table, but it is not connected to anything, we should connect it to in the "Organization name and mailing address" (for org type "Federal") request page and anywhere else the federal agency field is used. 
Note in the current state in the "Organization name and mailing address" (for org type "Federal") request page, the current "Federal agency" dropdown shows duplicate entries which do _not_ exist in the federal agency table (they were removed intentionally). There is also an invalid option in the dropdown: "State, Local, and Tribal Government" which should be just Non-Federal Agency instead.  These duplicate and incorrect values do **not** exist in the Federal Agency table; however, there is a migration script ticket (#1975)  to update any 'deprecated' values to the correct ones to use.  If you pick up this current ticket, the migration ticket is a logical choice to work at the same time. They should be merged around the same time.


There are also 2 values we should keep but not allow end users to select:
- gov Administration
- Non-Federal Agency 

### Acceptance Criteria 
- [ ] Make all occurrences of the federal_agency drop down use the new Agency field that is connected to the federal agency table see #2029 and #1896
- [ ] Hide 2 values when shown in the request form's dropdown (but keep them in the database/Django admin):
  - [ ] gov Administration
  - [ ] Non-Federal Agency
- [x] ~In the request form's Federal Agency dropdown, include an "other" field to allow users to add an agency not in our list (ignore this one)~
- [ ] Make sure federal agency on domain request and domain info are all still drop downs
- [ ] ~remove the old federal_agency field  as it is no longer needed and be sure the now linked Agency field now shows on the django admin exactly where federal_agency was showing and that the field is viewable for all users (note the goal is to make it look like nothing changed for analysts)~
- [ ] Create 2 migration files:  1: Migration file to DELETE `federal_agency` 2: Migration file to RENAME `updated_federal_agency` to `federal_agency` (updated_federal_agency now filled in at this point, so we have to delete + rename)
- [ ] Remove tests testing that updated_federal_agency duplicates the FederalAgency version of federal_agency that reference updated_federal_agency as this field will be renamed to federal_agency to replace the current federal_agency field.
- [ ] Make sure both Superuser and Analysts can view the correct new Federal Agency list without issues

### Additional Context

[Slack thread discussion](https://cisa-corp.slack.com/archives/C05BGB4L5NF/p1708109328529279)



### Issue Links
blocked by #1896 
blocked by #2029 
Relates to #1975 (do at around the same time to avoid issues)
Relates to: #337 


Discussion:
Changing epic to org model because it's preliminary to that work.
I've refined the text and struck a few things from this task. The refinement label stays to talk about "hiding" two values. 

Before we add an "other" field that prompts for a user-supplied value, let's determine how this selection would flow into the rest of the request form/DjAdmin/notification emails that are sent.  @kristinacyin 
updated language on AC 3
In refinement, we decided to take this opportunity to create a table for federal agencies and to make the domain mapping A/C its own issue. @abroddrick will take a first pass.
Moved status backed to "Planned" to "Ready" since it was moved out from sprint 43 into sprint 44.
This is Ticket #3 for Federal Agency
Removed "blocked" label since the tickets that are blocking this ticket are closed.

Resolving patch:
diff --git a/src/registrar/forms/domain_request_wizard.py b/src/registrar/forms/domain_request_wizard.py
--- a/src/registrar/forms/domain_request_wizard.py
+++ b/src/registrar/forms/domain_request_wizard.py
@@ -97,6 +97,7 @@ def clean_is_election_board(self):
 
 class OrganizationContactForm(RegistrarForm):
     # for federal agencies we also want to know the top-level agency.
+    excluded_agencies = ["gov Administration", "Non-Federal Agency"]
     federal_agency = forms.ModelChoiceField(
         label="Federal agency",
         # not required because this field won't be filled out unless
@@ -104,9 +105,8 @@ class OrganizationContactForm(RegistrarForm):
         # if it has been filled in when required.
         # uncomment to see if modelChoiceField can be an arg later
         required=False,
-        queryset=FederalAgency.objects.all(),
+        queryset=FederalAgency.objects.exclude(agency__in=excluded_agencies),
         empty_label="--Select--",
-        # choices=[("", "--Select--")] + DomainRequest.AGENCY_CHOICES,
     )
     organization_name = forms.CharField(
         label="Organization name",


Test patch:
diff --git a/src/registrar/tests/test_views_request.py b/src/registrar/tests/test_views_request.py
--- a/src/registrar/tests/test_views_request.py
+++ b/src/registrar/tests/test_views_request.py
@@ -723,6 +723,53 @@ def test_domain_request_about_your_organization_special(self):
 
         self.assertContains(contact_page, self.TITLES[Step.ABOUT_YOUR_ORGANIZATION])
 
+    def test_federal_agency_dropdown_excludes_expected_values(self):
+        """The Federal Agency dropdown on a domain request form should not
+        include options for gov Administration and Non-Federal Agency"""
+        intro_page = self.app.get(reverse("domain-request:"))
+        # django-webtest does not handle cookie-based sessions well because it keeps
+        # resetting the session key on each new request, thus destroying the concept
+        # of a "session". We are going to do it manually, saving the session ID here
+        # and then setting the cookie on each request.
+        session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+
+        intro_form = intro_page.forms[0]
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        intro_result = intro_form.submit()
+
+        # follow first redirect
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        type_page = intro_result.follow()
+        session_id = self.app.cookies[settings.SESSION_COOKIE_NAME]
+
+        # ---- TYPE PAGE  ----
+        type_form = type_page.forms[0]
+        type_form["generic_org_type-generic_org_type"] = "federal"
+
+        # test next button
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        type_result = type_form.submit()
+
+        # ---- FEDERAL BRANCH PAGE  ----
+        # Follow the redirect to the next form page
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        federal_page = type_result.follow()
+        federal_form = federal_page.forms[0]
+        federal_form["organization_federal-federal_type"] = "executive"
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        federal_result = federal_form.submit()
+
+        # ---- ORG CONTACT PAGE  ----
+        # Follow the redirect to the next form page
+        self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
+        org_contact_page = federal_result.follow()
+
+        # gov Administration and Non-Federal Agency should not be federal agency options
+        self.assertNotContains(org_contact_page, "gov Administration")
+        self.assertNotContains(org_contact_page, "Non-Federal Agency")
+        # make sure correct federal agency options still show up
+        self.assertContains(org_contact_page, "General Services Administration")
+
     def test_yes_no_contact_form_inits_blank_for_new_domain_request(self):
         """On the Other Contacts page, the yes/no form gets initialized with nothing selected for
         new domain requests"""