Repository: cisagov/manage.get.gov

Issue:
Inform users of .gov requirements before starting a new domain request
### Issue description

This ticket is for implementing the designs for https://github.com/cisagov/manage.get.gov/issues/547, also known as the preamble.


Flow from **beta.get.gov**:
- a user clicks start a new domain requests, moves past a modal and then logs in
- they arrive at a new application (in manage.get.gov) that has  a new page is inserted before the "org type" step

This ticket is for just adding the new page and having it show conditionally based on the user arriving from beta.get.govs links/buttons

### Acceptance criteria

- [ ] The request flow displays a new, informational page (i.e. preamble) at the beginning of the form when a user arrived at the application not via the edit an existing application button (OR link on beta.get.gov see related ticket)

### Additional context

- [New text for both flows](https://docs.google.com/document/d/15FpRLKXGeeNJ5D8uCu1YtRDZSWN5ZrJPKXJV4tCY6fw/edit#heading=h.cldogb82du8p)
- [Mural with flows](https://app.mural.co/t/gsa6/m/gsa6/1701893071504/3b10ecf79684c8e3a1387d7fe5665b58f3c156fa?sender=michellerago0372)
- Figma mockup: [Flow from beta.get.gov](https://www.figma.com/proto/aJbuDLJNNikqQObTuCNKQa/GetGov_Designs_ECS-Truss?page-id=2913%3A27400&type=design&node-id=2927-42517&viewport=131%2C74%2C0.14&t=l70YtUOmnoE59X5H-1&scaling=min-zoom&starting-point-node-id=2927%3A42517&show-proto-sidebar=1&mode=design) and [flow from manage.get.gov](https://www.figma.com/proto/aJbuDLJNNikqQObTuCNKQa/GetGov_Designs_ECS-Truss?page-id=2913%3A27400&type=design&node-id=2926-28192&viewport=131%2C74%2C0.14&t=VIQ4EPkC3bwHn9Xk-1&scaling=min-zoom&starting-point-node-id=2926%3A28192&show-proto-sidebar=1&mode=design)

The related ticket needs to wait until launch to be merged, but this ticket can be merged without an issue.

Design: https://github.com/cisagov/manage.get.gov/issues/547
Related to cisagov/getgov-home#147

### Links to other issues

_No response_


Discussion:

Resolving patch:
diff --git a/src/registrar/views/application.py b/src/registrar/views/application.py
--- a/src/registrar/views/application.py
+++ b/src/registrar/views/application.py
@@ -209,16 +209,16 @@ def get(self, request, *args, **kwargs):
         # if accessing this class directly, redirect to the first step
         #     in other words, if `ApplicationWizard` is called as view
         #     directly by some redirect or url handler, we'll send users
-        #     to the first step in the processes; subclasses will NOT
-        #     be redirected. The purpose of this is to allow code to
+        #     either to an acknowledgement page or to the first step in
+        #     the processes (if an edit rather than a new request); subclasses
+        #     will NOT be redirected. The purpose of this is to allow code to
         #     send users "to the application wizard" without needing to
         #     know which view is first in the list of steps.
         if self.__class__ == ApplicationWizard:
-            # if starting a new application, clear the storage
             if request.path_info == self.NEW_URL_NAME:
-                del self.storage
-
-            return self.goto(self.steps.first)
+                return render(request, "application_intro.html")
+            else:
+                return self.goto(self.steps.first)
 
         self.steps.current = current_url
         context = self.get_context_data()
@@ -373,13 +373,20 @@ def is_valid(self, forms: list) -> bool:
 
     def post(self, request, *args, **kwargs) -> HttpResponse:
         """This method handles POST requests."""
-        # if accessing this class directly, redirect to the first step
-        if self.__class__ == ApplicationWizard:
-            return self.goto(self.steps.first)
 
         # which button did the user press?
         button: str = request.POST.get("submit_button", "")
 
+        # if user has acknowledged the intro message
+        if button == "intro_acknowledge":
+            if request.path_info == self.NEW_URL_NAME:
+                del self.storage
+            return self.goto(self.steps.first)
+
+        # if accessing this class directly, redirect to the first step
+        if self.__class__ == ApplicationWizard:
+            return self.goto(self.steps.first)
+
         forms = self.get_forms(use_post=True)
         if self.is_valid(forms):
             # always save progress


Test patch:
diff --git a/src/registrar/tests/test_views.py b/src/registrar/tests/test_views.py
--- a/src/registrar/tests/test_views.py
+++ b/src/registrar/tests/test_views.py
@@ -109,7 +109,7 @@ def test_application_form_view(self):
         response = self.client.get("/register/", follow=True)
         self.assertContains(
             response,
-            "What kind of U.S.-based government organization do you represent?",
+            "You’re about to start your .gov domain request.",
         )
 
     def test_domain_application_form_with_ineligible_user(self):
@@ -138,11 +138,44 @@ def setUp(self):
         self.app.set_user(self.user.username)
         self.TITLES = ApplicationWizard.TITLES
 
+    def test_application_form_intro_acknowledgement(self):
+        """Tests that user is presented with intro acknowledgement page"""
+        intro_page = self.app.get(reverse("application:"))
+        self.assertContains(intro_page, "You’re about to start your .gov domain request")
+
+    def test_application_form_intro_is_skipped_when_edit_access(self):
+        """Tests that user is NOT presented with intro acknowledgement page when accessed through 'edit'"""
+        completed_application(status=DomainApplication.ApplicationStatus.STARTED, user=self.user)
+        home_page = self.app.get("/")
+        self.assertContains(home_page, "city.gov")
+        # click the "Edit" link
+        detail_page = home_page.click("Edit", index=0)
+        # Check that the response is a redirect
+        self.assertEqual(detail_page.status_code, 302)
+        # You can access the 'Location' header to get the redirect URL
+        redirect_url = detail_page.url
+        self.assertEqual(redirect_url, "/register/organization_type/")
+
     def test_application_form_empty_submit(self):
-        # 302 redirect to the first form
-        page = self.app.get(reverse("application:")).follow()
+        """Tests empty submit on the first page after the acknowledgement page"""
+        intro_page = self.app.get(reverse("application:"))
+        # 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]
+
         # submitting should get back the same page if the required field is empty
-        result = page.forms[0].submit()
+        result = type_page.forms[0].submit()
         self.assertIn("What kind of U.S.-based government organization do you represent?", result)
 
     def test_application_multiple_applications_exist(self):
@@ -157,8 +190,18 @@ def test_application_multiple_applications_exist(self):
 
         # now, attempt to create another one
         with less_console_noise():
-            page = self.app.get("/register/").follow()
-            self.assertContains(page, "You cannot submit this request yet")
+            intro_page = self.app.get(reverse("application:"))
+            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]
+
+            self.assertContains(type_page, "You cannot submit this request yet")
 
     @boto3_mocking.patching
     def test_application_form_submission(self):
@@ -177,13 +220,22 @@ def test_application_form_submission(self):
         SKIPPED_PAGES = 4
         num_pages = len(self.TITLES) - SKIPPED_PAGES
 
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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["organization_type-organization_type"] = "federal"
@@ -540,13 +592,22 @@ def test_application_form_started_allsteps(self):
 
     def test_application_form_conditional_federal(self):
         """Federal branch question is shown for federal organizations."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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  ----
 
         # the conditional step titles shouldn't appear initially
@@ -586,13 +647,22 @@ def test_application_form_conditional_federal(self):
 
     def test_application_form_conditional_elections(self):
         """Election question is shown for other organizations."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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  ----
 
         # the conditional step titles shouldn't appear initially
@@ -631,13 +701,22 @@ def test_application_form_conditional_elections(self):
 
     def test_application_form_section_skipping(self):
         """Can skip forward and back in sections"""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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_form = type_page.forms[0]
         type_form["organization_type-organization_type"] = "federal"
         self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@@ -659,13 +738,22 @@ def test_application_form_section_skipping(self):
 
     def test_application_form_nonfederal(self):
         """Non-federal organizations don't have to provide their federal agency."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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_form = type_page.forms[0]
         type_form["organization_type-organization_type"] = DomainApplication.OrganizationChoices.INTERSTATE
         self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@@ -695,13 +783,22 @@ def test_application_form_nonfederal(self):
 
     def test_application_about_your_organization_special(self):
         """Special districts have to answer an additional question."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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_form = type_page.forms[0]
         type_form["organization_type-organization_type"] = DomainApplication.OrganizationChoices.SPECIAL_DISTRICT
         self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@@ -818,13 +915,22 @@ def test_application_delete_other_contact(self):
 
     def test_application_about_your_organiztion_interstate(self):
         """Special districts have to answer an additional question."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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_form = type_page.forms[0]
         type_form["organization_type-organization_type"] = DomainApplication.OrganizationChoices.INTERSTATE
         self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@@ -837,12 +943,22 @@ def test_application_about_your_organiztion_interstate(self):
 
     def test_application_tribal_government(self):
         """Tribal organizations have to answer an additional question."""
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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_form = type_page.forms[0]
         type_form["organization_type-organization_type"] = DomainApplication.OrganizationChoices.TRIBAL
         self.app.set_cookie(settings.SESSION_COOKIE_NAME, session_id)
@@ -857,13 +973,22 @@ def test_application_tribal_government(self):
         self.assertContains(tribal_government_page, self.TITLES[Step.TRIBAL_GOVERNMENT])
 
     def test_application_ao_dynamic_text(self):
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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["organization_type-organization_type"] = "federal"
@@ -919,12 +1044,22 @@ def test_application_ao_dynamic_text(self):
         self.assertContains(ao_page, "Domain requests from cities")
 
     def test_application_dotgov_domain_dynamic_text(self):
-        type_page = self.app.get(reverse("application:")).follow()
+        intro_page = self.app.get(reverse("application:"))
         # 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["organization_type-organization_type"] = "federal"
@@ -1168,8 +1303,22 @@ def test_long_org_name_in_application(self):
         Make sure the long name is displaying in the application form,
         org step
         """
-        request = self.app.get(reverse("application:")).follow()
-        self.assertContains(request, "Federal: an agency of the U.S. government")
+        intro_page = self.app.get(reverse("application:"))
+        # 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()
+
+        self.assertContains(type_page, "Federal: an agency of the U.S. government")
 
     def test_long_org_name_in_application_manage(self):
         """