diff --git a/.vscode/settings.json b/.vscode/settings.json index 650e65b0f..b3ff8e30d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,12 +1,10 @@ { - "djlint.guessProfile": false, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, - "[html]": { - "editor.defaultFormatter": "monosans.djlint" - }, - "[django-html]": { - "editor.defaultFormatter": "monosans.djlint" + "[django-html][html]": { + "editor.defaultFormatter": "monosans.djlint", + "djlint.enableLinting": true, + "djlint.profile": "django" }, "files.encoding": "utf8", "files.eol": "\n", diff --git a/benefits/core/migrations/0001_initial.py b/benefits/core/migrations/0001_initial.py index ccbf07160..ee5978058 100644 --- a/benefits/core/migrations/0001_initial.py +++ b/benefits/core/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.3 on 2023-07-08 02:54 +# Generated by Django 4.2.3 on 2023-07-11 17:22 from django.db import migrations, models import django.db.models.deletion @@ -109,7 +109,7 @@ class Migration(migrations.Migration): ("phone", models.TextField()), ("active", models.BooleanField(default=False)), ("jws_signing_alg", models.TextField()), - ("eligibility_index_intro", models.TextField()), + ("eligibility_index_template", models.TextField()), ("transit_type", models.TextField()), ("eligibility_types", models.ManyToManyField(to="core.eligibilitytype")), ("eligibility_verifiers", models.ManyToManyField(to="core.eligibilityverifier")), diff --git a/benefits/core/migrations/0002_data.py b/benefits/core/migrations/0002_data.py index 49a6e66cb..0c883978d 100644 --- a/benefits/core/migrations/0002_data.py +++ b/benefits/core/migrations/0002_data.py @@ -263,7 +263,7 @@ def load_data(app, *args, **kwargs): public_key=client_public_key, jws_signing_alg=os.environ.get("MST_AGENCY_JWS_SIGNING_ALG", "RS256"), payment_processor=mst_payment_processor, - eligibility_index_intro=_("eligibility.pages.index.p[0].mst"), + eligibility_index_template="eligibility/index--mst.html", transit_type=_("agency.variables.mst.transit_type"), ) mst_agency.eligibility_types.set([mst_senior_type, mst_veteran_type, mst_courtesy_card_type]) @@ -282,7 +282,7 @@ def load_data(app, *args, **kwargs): public_key=client_public_key, jws_signing_alg=os.environ.get("SACRT_AGENCY_JWS_SIGNING_ALG", "RS256"), payment_processor=sacrt_payment_processor, - eligibility_index_intro=_("eligibility.pages.index.p[0].sacrt"), + eligibility_index_template="eligibility/index--sacrt.html", transit_type=_("agency.variables.sacrt.transit_type"), ) sacrt_agency.eligibility_types.set([sacrt_senior_type]) diff --git a/benefits/core/models.py b/benefits/core/models.py index ded6b80f3..eee1962af 100644 --- a/benefits/core/models.py +++ b/benefits/core/models.py @@ -198,7 +198,7 @@ class TransitAgency(models.Model): public_key = models.ForeignKey(PemData, related_name="+", on_delete=models.PROTECT) # The JWS-compatible signing algorithm jws_signing_alg = models.TextField() - eligibility_index_intro = models.TextField() + eligibility_index_template = models.TextField() transit_type = models.TextField() def __str__(self): diff --git a/benefits/core/templates/core/includes/button__previous_page.html b/benefits/core/templates/core/includes/button--previous-page.html similarity index 100% rename from benefits/core/templates/core/includes/button__previous_page.html rename to benefits/core/templates/core/includes/button--previous-page.html diff --git a/benefits/eligibility/templates/eligibility/index--mst.html b/benefits/eligibility/templates/eligibility/index--mst.html new file mode 100644 index 000000000..c8100345b --- /dev/null +++ b/benefits/eligibility/templates/eligibility/index--mst.html @@ -0,0 +1,7 @@ +{% extends "eligibility/index.html" %} + +{% load i18n %} + +{% block explanatory-text %} +

{% translate "eligibility.pages.index.intro.mst" %}

+{% endblock explanatory-text %} diff --git a/benefits/eligibility/templates/eligibility/index--sacrt.html b/benefits/eligibility/templates/eligibility/index--sacrt.html new file mode 100644 index 000000000..fb75a577c --- /dev/null +++ b/benefits/eligibility/templates/eligibility/index--sacrt.html @@ -0,0 +1,7 @@ +{% extends "eligibility/index.html" %} + +{% load i18n %} + +{% block explanatory-text %} +

{% translate "eligibility.pages.index.intro.sacrt" %}

+{% endblock explanatory-text %} diff --git a/benefits/eligibility/templates/eligibility/index.html b/benefits/eligibility/templates/eligibility/index.html index a6330e9dc..835c114d2 100644 --- a/benefits/eligibility/templates/eligibility/index.html +++ b/benefits/eligibility/templates/eligibility/index.html @@ -1,25 +1,30 @@ {% extends "core/base.html" %} +{% load i18n %} {% block classes %} {{ block.super | add:" eligibility-index" }} {% endblock classes %} +{% block page_title %} + {% translate "eligibility.pages.index.title" %} |  +{% endblock page_title %} + {% block nav-buttons %} - {% include "core/includes/previous-page-link.html" %} + {% url "core:index" as url %} + {% include "core/includes/button--previous-page.html" with url=url %} {% endblock nav-buttons %} +{% block headline %} +
+

{% translate "eligibility.pages.index.headline" %}

+
+{% endblock headline %} + {% block explanatory-text %} - {% for p in page.paragraphs %}

{{ p }}

{% endfor %} {% endblock explanatory-text %} {% block inner-content %}
-
- {% block forms %} - {% for f in page.forms %} - {% include "core/includes/form.html" with form=f %} - {% endfor %} - {% endblock forms %} -
+
{% include "core/includes/form.html" with form=form %}
{% endblock inner-content %} diff --git a/benefits/eligibility/templates/eligibility/start.html b/benefits/eligibility/templates/eligibility/start.html index 0985b8810..e9e965940 100644 --- a/benefits/eligibility/templates/eligibility/start.html +++ b/benefits/eligibility/templates/eligibility/start.html @@ -7,7 +7,7 @@ {% block nav-buttons %} {% url "eligibility:index" as url %} - {% include "core/includes/button__previous_page.html" with url=url %} + {% include "core/includes/button--previous-page.html" with url=url %} {% endblock nav-buttons %} {% block inner-content %} diff --git a/benefits/eligibility/views.py b/benefits/eligibility/views.py index ced9f3164..7c302f8fc 100644 --- a/benefits/eligibility/views.py +++ b/benefits/eligibility/views.py @@ -6,13 +6,11 @@ from django.template.response import TemplateResponse from django.urls import reverse from django.utils.decorators import decorator_from_middleware -from django.utils.html import format_html from django.utils.translation import pgettext, gettext as _ from benefits.core import recaptcha, session, viewmodels from benefits.core.middleware import AgencySessionRequired, LoginRequired, RecaptchaEnabled, VerifierSessionRequired from benefits.core.models import EligibilityVerifier -from benefits.core.views import ROUTE_HELP from . import analytics, forms, verify @@ -24,7 +22,6 @@ ROUTE_UNVERIFIED = "eligibility:unverified" ROUTE_ENROLLMENT = "enrollment:index" -TEMPLATE_INDEX = "eligibility/index.html" TEMPLATE_START = "eligibility/start.html" TEMPLATE_CONFIRM = "eligibility/confirm.html" TEMPLATE_UNVERIFIED = "eligibility/unverified.html" @@ -50,28 +47,7 @@ def index(request, agency=None): # this may or may not require OAuth, with a different set of scope/claims than what is already stored session.logout(request) - eligibility_start = reverse(ROUTE_START) - - help_page = reverse(ROUTE_HELP) - - agency_intro = _(agency.eligibility_index_intro) if isinstance(agency.eligibility_index_intro, str) else "" - common_intro = _("eligibility.pages.index.p[0]%(info_link)s") % {"info_link": f"{help_page}#what-is-cal-itp"} - intro = format_html(agency_intro + common_intro) - page = viewmodels.Page( - title=_("eligibility.pages.index.title"), - headline=_("eligibility.pages.index.headline"), - paragraphs=[intro], - forms=forms.EligibilityVerifierSelectionForm(agency=agency), - ) - - ctx = page.context_dict() - - origin = session.origin(request) - if origin == reverse(ROUTE_CORE_INDEX): - ctx["previous_page_button"] = viewmodels.Button.previous_page(url=origin) - - ctx["help_page"] = help_page - ctx["help_text"] = format_html(_("eligibility.pages.index.help_text%(help_link)s") % {"help_link": help_page}) + context = {"form": forms.EligibilityVerifierSelectionForm(agency=agency)} if request.method == "POST": form = forms.EligibilityVerifierSelectionForm(data=request.POST, agency=agency) @@ -84,15 +60,16 @@ def index(request, agency=None): types_to_verify = agency.type_names_to_verify(verifier) analytics.selected_verifier(request, types_to_verify) + eligibility_start = reverse(ROUTE_START) response = redirect(eligibility_start) else: # form was not valid, allow for correction/resubmission if recaptcha.has_error(form): messages.error(request, "Recaptcha failed. Please try again.") - page.forms = [form] - response = TemplateResponse(request, TEMPLATE_INDEX, ctx) + context["form"] = form + response = TemplateResponse(request, agency.eligibility_index_template, context) else: - response = TemplateResponse(request, TEMPLATE_INDEX, ctx) + response = TemplateResponse(request, agency.eligibility_index_template, context) return response diff --git a/benefits/locale/en/LC_MESSAGES/django.po b/benefits/locale/en/LC_MESSAGES/django.po index a387aea78..f1b314374 100644 --- a/benefits/locale/en/LC_MESSAGES/django.po +++ b/benefits/locale/en/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: https://github.com/cal-itp/benefits/issues \n" -"POT-Creation-Date: 2023-07-12 05:34+0000\n" +"POT-Creation-Date: 2023-07-13 16:41+0000\n" "Language: English\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -55,20 +55,9 @@ msgstr "" "That’s okay! You may still be eligible for our program. Please reach out to " "Monterey-Salinas Transit for assistance." -msgid "eligibility.pages.index.p[0].mst" -msgstr "" -"You can tap your credit or debit card when you board an MST bus, and your " -"discounted fare will automatically apply every time you ride. " - msgid "agency.variables.mst.transit_type" msgstr "bus" -msgid "eligibility.pages.index.p[0].sacrt" -msgstr "" -"You can tap your credit or debit card when you board SacRT public " -"transportation, and your discounted fare will automatically apply every time " -"you ride. " - msgid "agency.variables.sacrt.transit_type" msgstr "light rail" @@ -275,33 +264,6 @@ msgstr "" "To function properly, this website requires a browser that supports " "JavaScript. Please enable JavaScript for this website and" -msgid "eligibility.pages.index.mst_courtesy_card.label" -msgstr "I have an MST Courtesy Card" - -msgid "eligibility.pages.index.mst_courtesy_card.description" -msgstr "" -"This option is for people who have a current Courtesy Card or an MST RIDES " -"Eligibility card. This benefit may need to be renewed in the future. Using " -"this benefit means your new transit fare is half of the standard fare." - -msgid "eligibility.pages.index.senior.label" -msgstr "Older Adult" - -msgid "eligibility.pages.index.senior.description" -msgstr "" -"You must be 65 years or older. You will need to verify your identity with" - -msgid "eligibility.pages.index.veteran.label" -msgstr "US Veteran" - -msgid "eligibility.pages.index.veteran.description" -msgstr "" -"This option is for people who have served in the active military, naval, or " -"air service, and who were discharged or released therefrom under conditions " -"other than dishonorable. You will need to verify your identity through VA.gov" - msgid "core.pages.index.button" msgstr "Choose your Provider" @@ -316,7 +278,7 @@ msgid "core.pages.logged_out.headline[1]" msgstr "Thank you for using Cal-ITP Benefits!" msgid "eligibility.pages.index.label" -msgstr "Select the option that best applies to you:" +msgstr "Which transit benefit would you like to enroll in?" msgid "core.pages.error.title" msgstr "Error" @@ -501,6 +463,48 @@ msgstr "" "gov/help/' target=\"_blank\" rel=\"noopener noreferrer\">Login.gov Help " "Center" +msgid "eligibility.pages.index.mst_courtesy_card.label" +msgstr "MST Courtesy Card" + +msgid "eligibility.pages.index.mst_courtesy_card.description" +msgstr "" +"This option is for people who have a current Courtesy Card [optional " +"qualifier]." + +msgid "eligibility.pages.index.senior.label" +msgstr "Older Adult" + +msgid "eligibility.pages.index.senior.description" +msgstr "" +"You must be 65 years or older. You will need to verify your identity with" + +msgid "eligibility.pages.index.veteran.label" +msgstr "US Veteran" + +msgid "eligibility.pages.index.veteran.description" +msgstr "" +"This option is for people who have served in the active military, naval, or " +"air service, and who were discharged or released therefrom under conditions " +"other than dishonorable. You will need to verify your identity through VA.gov" + +msgid "eligibility.pages.index.intro.mst" +msgstr "" +"Cal-ITP doesn’t save any of your information. All MST transit benefits " +"[action] by [rate of discount] for [affected service] on [transit options]." + +msgid "eligibility.pages.index.intro.sacrt" +msgstr "" +"Cal-ITP doesn’t save any of your information. All SacRT transit benefits " +"[action] by [rate of discount] for [affected service] on [transit options]." + +msgid "eligibility.pages.index.title" +msgstr "Choose benefit option" + +msgid "eligibility.pages.index.headline" +msgstr "Choose the transit benefit you would like to enroll in" + msgid "eligibility.pages.start.sub_headline" msgstr "You will need a few items to connect your benefit:" @@ -537,27 +541,6 @@ msgstr "You selected a Veteran transit benefit." msgid "eligibility.buttons.veteran.signin" msgstr "Continue to VA.gov" -#, python-format -msgid "eligibility.pages.index.p[0]%(info_link)s" -msgstr "" -"Cal-ITP doesn’t save any of your information, and you don’t need to create " -"an account. Verify to get your benefit, and connect your bank card today. " -"Learn more about Cal-ITP " -"Benefits." - -msgid "eligibility.pages.index.title" -msgstr "Select a benefit option" - -msgid "eligibility.pages.index.headline" -msgstr "" -"Connect your bank card to your public transit discount with Cal-ITP Benefits." - -#, python-format -msgid "eligibility.pages.index.help_text%(help_link)s" -msgstr "" -"Not sure which option is right for you? Please visit our Help Page." - msgid "eligibility.pages.unverified.headline" msgstr "Your eligibility could not be verified." diff --git a/benefits/locale/es/LC_MESSAGES/django.po b/benefits/locale/es/LC_MESSAGES/django.po index 737cfed92..18f6e1ac8 100644 --- a/benefits/locale/es/LC_MESSAGES/django.po +++ b/benefits/locale/es/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: https://github.com/cal-itp/benefits/issues \n" -"POT-Creation-Date: 2023-07-12 05:34+0000\n" +"POT-Creation-Date: 2023-07-13 16:41+0000\n" "Language: Español\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -55,20 +55,9 @@ msgstr "" "¡Esta bien! Aún puede ser elegible para nuestro programa. Comuníquese con " "Monterey-Salinas Transit para obtener asistencia." -msgid "eligibility.pages.index.p[0].mst" -msgstr "" -"Puede acercar su tarjeta de crédito o débito cuando aborde un autobús de MST " -"y su tarifa con descuento se aplicará automáticamente cada vez que viaje. " - msgid "agency.variables.mst.transit_type" msgstr "TODO: bus" -msgid "eligibility.pages.index.p[0].sacrt" -msgstr "" -"Puede acercar su tarjeta de crédito o débito cuando aborde el transporte " -"público SacRT y su tarifa con descuento se aplicará automáticamente cada vez " -"que viaje. " - msgid "agency.variables.sacrt.transit_type" msgstr "TODO: light rail" @@ -283,33 +272,6 @@ msgstr "" "Para funcionar correctamente, este sitio web requiere un navegador que " "admita JavaScript. Por favor, active JavaScript por este sitio web y" -msgid "eligibility.pages.index.mst_courtesy_card.label" -msgstr "Tengo una Tarjeta de Cortesía de MST" - -msgid "eligibility.pages.index.mst_courtesy_card.description" -msgstr "" -"Esta opción es para personas que tienen una Tarjeta de Cortesía actual o una " -"tarjeta de elegibilidad de Paratránsito de MST RIDES. Es posible que este " -"beneficio deba renovarse en el futuro. Usar este beneficio significa que su " -"nueva tarifa de tránsito es la mitad de la tarifa estándar." - -msgid "eligibility.pages.index.senior.label" -msgstr "Adulto mayor" - -msgid "eligibility.pages.index.senior.description" -msgstr "Debe tener 65 años o más. Deberá verificar su identidad con" - -msgid "eligibility.pages.index.veteran.label" -msgstr "TODO: US Veteran" - -msgid "eligibility.pages.index.veteran.description" -msgstr "" -"TODO: This option is for people who have served in the active military, " -"naval, or air service, and who were discharged or released therefrom under " -"conditions other than dishonorable. You will need to verify your identity through VA.gov" - msgid "core.pages.index.button" msgstr "Elija su Proveedor" @@ -323,7 +285,7 @@ msgid "core.pages.logged_out.headline[1]" msgstr "¡Gracias por usar los Beneficios de Cal-ITP!" msgid "eligibility.pages.index.label" -msgstr "Seleccione la opción que mejor se adapte a usted:" +msgstr "TODO: Which transit benefit would you like to enroll in?" msgid "core.pages.error.title" msgstr "Error" @@ -511,6 +473,48 @@ msgstr "" "login.gov/help/' target=\"_blank\" rel=\"noopener noreferrer\">Login.gov " "Help Center" +msgid "eligibility.pages.index.mst_courtesy_card.label" +msgstr "TODO: MST Courtesy Card" + +msgid "eligibility.pages.index.mst_courtesy_card.description" +msgstr "" +"TODO: This option is for people who have a current Courtesy Card [optional " +"qualifier]." + +msgid "eligibility.pages.index.senior.label" +msgstr "Adulto mayor" + +msgid "eligibility.pages.index.senior.description" +msgstr "Debe tener 65 años o más. Deberá verificar su identidad con" + +msgid "eligibility.pages.index.veteran.label" +msgstr "TODO: US Veteran" + +msgid "eligibility.pages.index.veteran.description" +msgstr "" +"TODO: This option is for people who have served in the active military, " +"naval, or air service, and who were discharged or released therefrom under " +"conditions other than dishonorable. You will need to verify your identity through VA.gov" + +msgid "eligibility.pages.index.intro.mst" +msgstr "" +"TODO: Cal-ITP doesn’t save any of your information. All MST transit benefits " +"[action] by [rate of discount] for [affected service] on [transit options]." + +msgid "eligibility.pages.index.intro.sacrt" +msgstr "" +"TODO: Cal-ITP doesn’t save any of your information. All SacRT transit " +"benefits [action] by [rate of discount] for [affected service] on [transit " +"options]." + +msgid "eligibility.pages.index.title" +msgstr "TODO: Choose benefit option" + +msgid "eligibility.pages.index.headline" +msgstr "TODO: Choose the transit benefit you would like to enroll in" + msgid "eligibility.pages.start.sub_headline" msgstr "Necesitará algunos artículos para conectar su beneficio:" @@ -547,28 +551,6 @@ msgstr "TODO: You selected a Veteran transit benefit." msgid "eligibility.buttons.veteran.signin" msgstr "TODO: Continue with VA.gov" -#, python-format -msgid "eligibility.pages.index.p[0]%(info_link)s" -msgstr "" -"Cal-ITP no guarda su información y no necesita crear una cuenta. Verifique " -"para obtener su beneficio y conecte su tarjeta bancaria hoy. Obtenga más información sobre los " -"Beneficios de Cal-ITP." - -msgid "eligibility.pages.index.title" -msgstr "Seleccione una opción de beneficio" - -msgid "eligibility.pages.index.headline" -msgstr "" -"Conecté su tarjeta bancaria a su descuento de transporte público con los " -"Beneficios de Cal-ITP" - -#, python-format -msgid "eligibility.pages.index.help_text%(help_link)s" -msgstr "" -"¿No está seguro de qué opción es la adecuada para usted? Visite nuestro Página de Ayuda." - msgid "eligibility.pages.unverified.headline" msgstr "No se pudo verificar su elegibilidad." diff --git a/tests/pytest/conftest.py b/tests/pytest/conftest.py index e775fa322..e3625d90f 100644 --- a/tests/pytest/conftest.py +++ b/tests/pytest/conftest.py @@ -169,7 +169,7 @@ def model_TransitAgency(model_PemData, model_EligibilityType, model_EligibilityV private_key=model_PemData, public_key=model_PemData, jws_signing_alg="alg", - eligibility_index_intro="", + eligibility_index_template="eligibility/index.html", ) # add many-to-many relationships after creation, need ID on both sides diff --git a/tests/pytest/eligibility/test_views.py b/tests/pytest/eligibility/test_views.py index 03d0de7f7..ff54bbb5f 100644 --- a/tests/pytest/eligibility/test_views.py +++ b/tests/pytest/eligibility/test_views.py @@ -11,7 +11,6 @@ ROUTE_CONFIRM, ROUTE_ENROLLMENT, ROUTE_UNVERIFIED, - TEMPLATE_INDEX, TEMPLATE_CONFIRM, TEMPLATE_UNVERIFIED, ) @@ -63,16 +62,17 @@ def test_index_get_agency_multiple_verifiers( mock_agency = mocker.Mock(spec=model_TransitAgency) mock_agency.eligibility_verifiers.all.return_value = [model_EligibilityVerifier, model_EligibilityVerifier] mock_agency.eligibility_verifiers.count.return_value = 2 + mock_agency.index_url = "/agency" + mock_agency.eligibility_index_template = "eligibility/index.html" mocked_session_agency.return_value = mock_agency path = reverse(ROUTE_INDEX) response = client.get(path) assert response.status_code == 200 - assert response.template_name == TEMPLATE_INDEX - assert "page" in response.context_data - assert len(response.context_data["page"].forms) > 0 - assert isinstance(response.context_data["page"].forms[0], EligibilityVerifierSelectionForm) + assert response.template_name == mock_agency.eligibility_index_template + assert "form" in response.context_data + assert isinstance(response.context_data["form"], EligibilityVerifierSelectionForm) @pytest.mark.django_db @@ -84,16 +84,17 @@ def test_index_get_agency_single_verifier( mock_agency = mocker.Mock(spec=model_TransitAgency) mock_agency.eligibility_verifiers.all.return_value = [model_EligibilityVerifier] mock_agency.eligibility_verifiers.count.return_value = 1 + mock_agency.index_url = "/agency" + mock_agency.eligibility_index_template = "eligibility/index.html" mocked_session_agency.return_value = mock_agency path = reverse(ROUTE_INDEX) response = client.get(path) assert response.status_code == 200 - assert response.template_name == TEMPLATE_INDEX - assert "page" in response.context_data - assert len(response.context_data["page"].forms) > 0 - assert isinstance(response.context_data["page"].forms[0], EligibilityVerifierSelectionForm) + assert response.template_name == mock_agency.eligibility_index_template + assert "form" in response.context_data + assert isinstance(response.context_data["form"], EligibilityVerifierSelectionForm) @pytest.mark.django_db @@ -114,7 +115,6 @@ def test_index_post_invalid_form(client): response = client.post(path, {"invalid": "data"}) assert response.status_code == 200 - assert response.template_name == TEMPLATE_INDEX @pytest.mark.django_db