internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: cal-itp/benefits

Issue:
Refactor Agency dynamic headline into model prop
Right now we are hardcoding the [Agency index headline PO key](https://github.com/cal-itp/benefits/blob/dev/benefits/core/views.py#L62):

```python
page = viewmodels.Page(
      title=_("core.pages.agency_index.title"),
      headline=_("core.pages.agency_index.mst_cc.headline"),
      button=button,
      classes="home",
  )
```

This is fine for MST. We need to make this a dynamic key coming from an `agency` prop for the future.

## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [ ] `agency_index` gets its headline from the selected `agency`



Discussion:
Let's wait to see what happens with #1090 and how much of the headline is/can be reused. Maybe we can fill in e.g. the agency slug dynamically.
Based on the designs, the headline / agency index page doesn't change too drastically between agencies:

| **`MST`** | **`SacRT`** |
| ----- | ------ |
| ![image](https://user-images.githubusercontent.com/1783439/212400081-06e0cb02-68e4-46d6-9df4-ebd080c519bc.png) | ![image](https://user-images.githubusercontent.com/1783439/212400120-cc6bceab-6862-43dc-b493-3d8e9dfd7836.png) |

So let's parameterize the headline with the agency short name (similar to #1196), but otherwise leave the model alone.

Resolving patch:
diff --git a/benefits/core/views.py b/benefits/core/views.py
--- a/benefits/core/views.py
+++ b/benefits/core/views.py
@@ -49,7 +49,8 @@ def agency_index(request, agency):
 
     page = viewmodels.Page(
         title=_("core.pages.agency_index.title"),
-        headline=_("core.pages.agency_index.mst_cc.headline"),
+        headline=_("core.pages.agency_index.headline%(transit_agency_short_name)s")
+        % {"transit_agency_short_name": agency.short_name},
         button=button,
     )
 


Test patch:
Repository: cal-itp/benefits

Issue:
Configure a Sentry denylist
Looks like we can configure a `denylist` on `EventScrubber` when calling `sentry_sdk.init`: https://docs.sentry.io/platforms/python/data-management/sensitive-data/

Another more general approach to modifying events is to configure a `before_send` function: https://docs.sentry.io/platforms/python/configuration/filtering/

_Originally posted by @angela-tran in https://github.com/cal-itp/benefits/issues/1334#issuecomment-1490416579_
            


Discussion:

Resolving patch:
diff --git a/benefits/sentry.py b/benefits/sentry.py
--- a/benefits/sentry.py
+++ b/benefits/sentry.py
@@ -1,10 +1,13 @@
-from benefits import VERSION
-import sentry_sdk
-from sentry_sdk.integrations.django import DjangoIntegration
 import shutil
 import os
 import subprocess
 
+import sentry_sdk
+from sentry_sdk.integrations.django import DjangoIntegration
+from sentry_sdk.scrubber import EventScrubber, DEFAULT_DENYLIST
+
+from benefits import VERSION
+
 
 SENTRY_ENVIRONMENT = os.environ.get("SENTRY_ENVIRONMENT", "local")
 
@@ -52,6 +55,12 @@ def get_release() -> str:
             return VERSION
 
 
+def get_denylist():
+    # custom denylist
+    denylist = DEFAULT_DENYLIST + ["sub", "name"]
+    return denylist
+
+
 def configure():
     SENTRY_DSN = os.environ.get("SENTRY_DSN")
     if SENTRY_DSN:
@@ -68,6 +77,10 @@ def configure():
             environment=SENTRY_ENVIRONMENT,
             release=release,
             in_app_include=["benefits"],
+            # send_default_pii must be False (the default) for a custom EventScrubber/denylist
+            # https://docs.sentry.io/platforms/python/data-management/sensitive-data/#event_scrubber
+            send_default_pii=False,
+            event_scrubber=EventScrubber(denylist=get_denylist()),
         )
     else:
         print("SENTRY_DSN not set, so won't send events")


Test patch:
Repository: cal-itp/benefits

Issue:
Consider strict Content Security Policy
In #203/#211/#216 we implemented a basic Content Security Policy, mainly aimed at supplementing the now deprecated `X-Frame-Options` header to prevent Cross Site Framing / Clickjacking type attacks.

Google recommends going further with a **strict** Content Security Policy, see more here: https://csp.withgoogle.com/docs/strict-csp.html

The main change for us would be inclusion of the `nonce` attribute in `<script>` and `<style>` elements. Read more about how this is done in `django-csp` here: https://django-csp.readthedocs.io/en/latest/nonce.html


Discussion:

Resolving patch:
diff --git a/benefits/sentry.py b/benefits/sentry.py
--- a/benefits/sentry.py
+++ b/benefits/sentry.py
@@ -10,6 +10,7 @@
 
 
 SENTRY_ENVIRONMENT = os.environ.get("SENTRY_ENVIRONMENT", "local")
+SENTRY_CSP_REPORT_URI = None
 
 
 def git_available():
@@ -82,5 +83,9 @@ def configure():
             send_default_pii=False,
             event_scrubber=EventScrubber(denylist=get_denylist()),
         )
+
+        # override the module-level variable when configuration happens, if set
+        global SENTRY_CSP_REPORT_URI
+        SENTRY_CSP_REPORT_URI = os.environ.get("SENTRY_REPORT_URI", "")
     else:
         print("SENTRY_DSN not set, so won't send events")
diff --git a/benefits/settings.py b/benefits/settings.py
--- a/benefits/settings.py
+++ b/benefits/settings.py
@@ -271,9 +271,9 @@ def _filter_empty(ls):
 # In particular, note that the inner single-quotes are required!
 # https://django-csp.readthedocs.io/en/latest/configuration.html#policy-settings
 
-CSP_DEFAULT_SRC = ["'self'"]
+CSP_BASE_URI = ["'none'"]
 
-CSP_IMG_SRC = ["'self'", "data:"]
+CSP_DEFAULT_SRC = ["'self'"]
 
 CSP_CONNECT_SRC = ["'self'", "https://api.amplitude.com/"]
 env_connect_src = _filter_empty(os.environ.get("DJANGO_CSP_CONNECT_SRC", "").split(","))
@@ -292,8 +292,18 @@ def _filter_empty(ls):
 if len(env_frame_src) > 0:
     CSP_FRAME_SRC = env_frame_src
 
+CSP_IMG_SRC = ["'self'", "data:"]
+
+# Configuring strict Content Security Policy
+# https://django-csp.readthedocs.io/en/latest/nonce.html
+CSP_INCLUDE_NONCE_IN = ["script-src"]
+
+CSP_OBJECT_SRC = ["'none'"]
+
+if sentry.SENTRY_CSP_REPORT_URI:
+    CSP_REPORT_URI = [sentry.SENTRY_CSP_REPORT_URI]
+
 CSP_SCRIPT_SRC = [
-    "'unsafe-inline'",
     "https://cdn.amplitude.com/libs/",
     "https://cdn.jsdelivr.net/",
     "*.littlepay.com",
@@ -305,7 +315,6 @@ def _filter_empty(ls):
 
 CSP_STYLE_SRC = [
     "'self'",
-    "'unsafe-inline'",
     "https://california.azureedge.net/",
     "https://fonts.googleapis.com/css",
 ]


Test patch:
Repository: cal-itp/benefits

Issue:
Veterans: Enrollment Success - Add correct msgid
Issue: `EligibilityVerifier` for Veterans has wrong copy/pointing to a Login.gov msgid on Enrollment Success page.

## Acceptance Criteria

- [x] `EligibilityVerifier` for Veterans has its own `enrollment_success_confirm_item_details` 
- [x] `enrollment_success_confirm_item_details` can be this copy for the time being. This is NOT what is on Figma / Google Spreadsheets right now for the updated Enrollment Success.
```
msgid "enrollment.pages.success.login_gov.confirm_item.details"
msgstr ""
"You were not charged anything today. When boarding transit, pay with this "
"same physical card and you will automatically receive your new reduced fare. "
"You will need to reapply if you choose to change the bank card you use to "
"pay for transit service."
```

Currently on Dev:
<img width="1512" alt="image" src="https://github.com/cal-itp/benefits/assets/3673236/2f9e79f7-5883-45e1-9567-94d9fa21726a">


The PR for this issue should change the above to look like this:
<img width="1512" alt="image" src="https://github.com/cal-itp/benefits/assets/3673236/e47ed623-eeea-4ae2-9c70-8795bf79d882">




Discussion:

Resolving patch:
diff --git a/benefits/core/migrations/0002_data.py b/benefits/core/migrations/0002_data.py
--- a/benefits/core/migrations/0002_data.py
+++ b/benefits/core/migrations/0002_data.py
@@ -185,9 +185,7 @@ def load_data(app, *args, **kwargs):
         start_item_secondary_details=_("eligibility.pages.start.veteran.start_item.secondary_details"),
         unverified_title=_("eligibility.pages.unverified.title"),
         unverified_blurb=_("eligibility.pages.unverified.p[0]"),
-        enrollment_success_confirm_item_details=_(
-            "enrollment.pages.index.login_gov.eligibility_confirmed_item.details%(transit_agency_short_name)s"
-        ),
+        enrollment_success_confirm_item_details=_("enrollment.pages.success.veteran.confirm_item.details"),
         enrollment_success_expiry_item_heading=None,
         enrollment_success_expiry_item_details=None,
     )


Test patch:
Repository: cal-itp/benefits

Issue:
Bug: Grid-width issue
Related to #1545 

Almost all instances of `col-lg-10` app should now be `col-lg-8`.


Discussion:

Resolving patch:
diff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py
--- a/benefits/eligibility/forms.py
+++ b/benefits/eligibility/forms.py
@@ -27,7 +27,7 @@ def __init__(self, agency: models.TransitAgency, *args, **kwargs):
         super().__init__(*args, **kwargs)
         verifiers = agency.eligibility_verifiers.all()
 
-        self.classes = "offset-lg-1 col-lg-9"
+        self.classes = "col-lg-8"
         # second element is not used since we render the whole label using selection_label_template,
         # therefore set to None
         self.fields["verifier"].choices = [(v.id, None) for v in verifiers]
@@ -56,7 +56,7 @@ class EligibilityVerificationForm(forms.Form):
     def __init__(self, verifier: models.EligibilityVerifier, *args, **kwargs):
         super().__init__(*args, **kwargs)
 
-        self.classes = "offset-lg-3 col-lg-6"
+        self.classes = "col-lg-6"
         sub_widget = widgets.FormControlTextInput(placeholder=verifier.form_sub_placeholder)
         if verifier.form_sub_pattern:
             sub_widget.attrs.update({"pattern": verifier.form_sub_pattern})


Test patch:
Repository: cal-itp/benefits

Issue:
Bug: Help Page - MST/CC answer is different
<img width="1512" alt="image" src="https://github.com/cal-itp/benefits/assets/3673236/6de8ded2-1141-4878-a077-891ce7177786">

font size should be changed to match the rest of the page too
Bug: Enrollment Index - Copy bug
<img width="1512" alt="image" src="https://github.com/cal-itp/benefits/assets/3673236/a386ae94-e45b-4c3e-ae42-b9c782174823">

The LittlePay link is in the wrong spot.


Discussion:

Resolving patch:
diff --git a/benefits/core/migrations/0002_data.py b/benefits/core/migrations/0002_data.py
--- a/benefits/core/migrations/0002_data.py
+++ b/benefits/core/migrations/0002_data.py
@@ -177,7 +177,7 @@ def load_data(app, *args, **kwargs):
         auth_provider=None,
         selection_label_template="eligibility/includes/selection-label--mst-courtesy-card.html",
         start_template="eligibility/start--mst-courtesy-card.html",
-        form_title=_("Confirm your Courtesy Card"),
+        form_title=_("Agency card information"),
         form_headline=_("Let’s see if we can confirm your eligibility."),
         form_blurb=_("Please input your Courtesy Card number and last name below to confirm your eligibility."),
         form_sub_label=_("MST Courtesy Card number"),
@@ -186,7 +186,7 @@ def load_data(app, *args, **kwargs):
         form_sub_pattern=r"\d{5}",
         form_input_mode="numeric",
         form_max_length=5,
-        form_name_label=_("last name (as it appears on Courtesy Card)"),
+        form_name_label=_("Last name (as it appears on Courtesy Card)"),
         form_name_help_text=_("We use this to help confirm your Courtesy Card."),
         form_name_placeholder="Garcia",
         form_name_max_length=255,


Test patch:
Repository: cal-itp/benefits

Issue:
Veteran enrollment pathway: display Login.gov sign-out button views following identity verification
When a rider chooses the US Veteran option for Benefits enrollment, they will utilize Login.gov (see #1691 for context). After a veteran completes identity verification, they will see a series views in the Benefits app depending on the verification response. (See the the [login flow](https://www.figma.com/file/SeSd3LaLd6WkbEYhmtKpO3/Benefits-(Full-Application)?type=design&node-id=5766%3A22626&mode=design&t=cLR0Gycsisf0pNvS-1) in Figma.) The app needs to present the option to sign out of Login.gov once identity verification is complete.

## Acceptance Criteria

- [ ] Display _Sign out of Login_ button on `Enrollment` view
- [ ] Display _Sign out of Login_ button on `Eligibility Error` view
- [ ] Display _Sign out of Login_ button on `Payment Error` view
- [ ] Display _Sign out of Login_ button on `Success` view



Discussion:

Resolving patch:
diff --git a/benefits/core/migrations/0002_data.py b/benefits/core/migrations/0002_data.py
--- a/benefits/core/migrations/0002_data.py
+++ b/benefits/core/migrations/0002_data.py
@@ -144,8 +144,8 @@ def load_data(app, *args, **kwargs):
     AuthProvider = app.get_model("core", "AuthProvider")
 
     senior_auth_provider = AuthProvider.objects.create(
-        sign_out_button_template="core/includes/button--sign-out--senior.html",
-        sign_out_link_template="core/includes/link--sign-out--senior.html",
+        sign_out_button_template="core/includes/button--sign-out--login-gov.html",
+        sign_out_link_template="core/includes/link--sign-out--login-gov.html",
         client_name=os.environ.get("SENIOR_AUTH_PROVIDER_CLIENT_NAME", "senior-benefits-oauth-client-name"),
         client_id=os.environ.get("AUTH_PROVIDER_CLIENT_ID", "benefits-oauth-client-id"),
         authority=os.environ.get("AUTH_PROVIDER_AUTHORITY", "https://example.com"),
@@ -155,6 +155,8 @@ def load_data(app, *args, **kwargs):
     )
 
     veteran_auth_provider = AuthProvider.objects.create(
+        sign_out_button_template="core/includes/button--sign-out--login-gov.html",
+        sign_out_link_template="core/includes/link--sign-out--login-gov.html",
         client_name=os.environ.get("VETERAN_AUTH_PROVIDER_CLIENT_NAME", "veteran-benefits-oauth-client-name"),
         client_id=os.environ.get("AUTH_PROVIDER_CLIENT_ID", "benefits-oauth-client-id"),
         authority=os.environ.get("AUTH_PROVIDER_AUTHORITY", "https://example.com"),


Test patch:
Repository: cal-itp/benefits

Issue:
Parameterize database path and deletion
## Background

Currently, the `bin/init.sh` script deletes and then recreates (via Django's `manage.py` helpers) the Sqlite database file every time it is called. This happens both during local development and in the Azure app service -- `bin/init.sh` is called during the [app image's startup](https://github.com/cal-itp/benefits/blob/dev/bin/start.sh#L6).

The [Django app settings](https://github.com/cal-itp/benefits/blob/dev/benefits/settings.py#L153) put the Sqlite database file in the same directory as the source code within the running app (or dev) container. In the Azure app service, this is an ephemeral directory that is lost on app service restarts / redeploys, so it is "good" that the database file is recreated each app service restart.

However, our "data" is encoded in a large [data migration file](https://github.com/cal-itp/benefits/blob/dev/benefits/core/migrations/0002_data.py) that can read from the environment. We want to move away from configuring the app as code, and the first step is being able to maintain our database file between app service restarts.

## Acceptance Criteria

- [x] database is deleted if environment variable e.g. `DATABASE_RESET` if set and `true`
- [x] database stored in a location determined by an environment variable e.g. `DATABASE_DIR`; default to the current directory to maintain existing behavior if unset
- [x] local devcontainer workflow is unaffected / still works OOTB
- [x] ~`DATABASE_DIR` set to `/home/site/wwwroot` for Azure app service; https://github.com/cal-itp/benefits/issues/1673#issuecomment-1779933175~ Reverted to `.` for more research
- [x] `DATABASE_RESET` set to `true` for Azure app service _for now to maintain existing behavior while we migrate to an Admin interface_

## Additional context

- #1312
- #1673




Discussion:

Resolving patch:
diff --git a/benefits/settings.py b/benefits/settings.py
--- a/benefits/settings.py
+++ b/benefits/settings.py
@@ -2,6 +2,7 @@
 Django settings for benefits project.
 """
 import os
+
 from benefits import sentry
 
 
@@ -147,10 +148,11 @@ def _filter_empty(ls):
 
 WSGI_APPLICATION = "benefits.wsgi.application"
 
+DATABASE_DIR = os.environ.get("DJANGO_DB_DIR", BASE_DIR)
 DATABASES = {
     "default": {
         "ENGINE": "django.db.backends.sqlite3",
-        "NAME": "django.db",
+        "NAME": os.path.join(DATABASE_DIR, "django.db"),
     }
 }
 


Test patch:
Repository: cal-itp/benefits

Issue:
SBMTD Mobility Pass Enrollment: Small adjustments to application copy
Incorporating suggested feedback from the engineering team to improve application copy for the SBMTD Mobility Pass enrollment pathway.

A couple notes:
- We will leave "Mobility Pass" untranslated and capitalized in the Spanish copy, as this is the proper name of the product in English at SBMTD. 
- In some places, we used "four-digit" rather than "4-digit" when referring to the Mobility Pass number. We will standardize on "4-digit" everywhere. This style is more concise and consistent with the implementation for MST's Courtesy Card.

## Acceptance Criteria

- [x] English Copy and Spanish Copy in the Mobility Pass pathway in the Benefits app matches the copy in the SBMTD tab of the [copy source spreadsheet](https://docs.google.com/spreadsheets/d/1_Gi_YbJr4ZuXCOsnOWaewvHqUO1nC1nKqiVDHvw0118/edit?usp=sharing). 




Discussion:
@machikoyasuda tagging you for awareness.

Resolving patch:
diff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py
--- a/benefits/eligibility/forms.py
+++ b/benefits/eligibility/forms.py
@@ -166,11 +166,11 @@ def __init__(self, *args, **kwargs):
             title=_("Agency card information"),
             headline=_("Let’s see if we can confirm your eligibility."),
             blurb=_("Please input your Mobility Pass number and last name below to confirm your eligibility."),
-            name_label=_("Last name (as it appears on Mobility Pass)"),
+            name_label=_("Last name (as it appears on Mobility Pass card)"),
             name_placeholder="Garcia",
             name_help_text=_("We use this to help confirm your Mobility Pass."),
             sub_label=_("SBMTD Mobility Pass number"),
-            sub_help_text=_("This is a 4-digit number on the front and back of your card."),
+            sub_help_text=_("This is a 4-digit number on the back of your card."),
             sub_placeholder="1234",
             name_max_length=255,
             sub_input_mode="numeric",


Test patch:
Repository: cal-itp/benefits

Issue:
`Eligibility index`: update copy to be more consistent and provide context for user
| Desktop (showing MST) | Mobile (showing SBMTD) |
| --- | --- |
| ![image](https://github.com/cal-itp/benefits/assets/25497886/fc0aea1c-832f-4375-b1ba-ea77f1f9f306) | ![image](https://github.com/cal-itp/benefits/assets/25497886/1e78192e-7852-46f3-91c4-1324e48d8238) |


## Figma links
- [Desktop_Eligibility](https://www.figma.com/file/SeSd3LaLd6WkbEYhmtKpO3/Benefits-(Full-Application)?type=design&node-id=14387-12551&mode=design&t=11PIPi0dRtWNuQmK-4)
- [Mobile_Eligibility](https://www.figma.com/file/SeSd3LaLd6WkbEYhmtKpO3/Benefits-(Full-Application)?type=design&node-id=14646-18505&mode=design&t=11PIPi0dRtWNuQmK-4)


## Acceptance Criteria

<!-- Remember to consider edge cases -->

- [x] Body copy: first body sentence was updated
- [x] Remove agency name in the copy for the radio buttons subheaders
   - [x] “MST Courtesy Card” is now “Courtesy Card”
   - [x] "SBMTD Reduced Fare Mobility ID" is now "Reduced Fare Mobility ID"
- [x] Radio button descriptions were updated and for SBMTD, mentions the previous name
- [x] CTA copy is updated



Discussion:

Resolving patch:
diff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py
--- a/benefits/eligibility/forms.py
+++ b/benefits/eligibility/forms.py
@@ -21,7 +21,7 @@ class EligibilityVerifierSelectionForm(forms.Form):
 
     verifier = forms.ChoiceField(label="", widget=widgets.VerifierRadioSelect)
     # sets label to empty string so the radio_select template can override the label style
-    submit_value = _("Choose this Benefit")
+    submit_value = _("Choose this benefit")
 
     def __init__(self, agency: models.TransitAgency, *args, **kwargs):
         super().__init__(*args, **kwargs)


Test patch:
diff --git a/tests/cypress/plugins/helpers.js b/tests/cypress/plugins/helpers.js
--- a/tests/cypress/plugins/helpers.js
+++ b/tests/cypress/plugins/helpers.js
@@ -26,6 +26,6 @@ export const selectCourtesyCard = () => {
   cy.location("pathname").should("eq", `/eligibility/${agency.slug}`);
 
   cy.contains("MST Courtesy Card").click();
-  cy.contains("Choose this Benefit").click();
+  cy.contains("Choose this benefit").click();
   cy.contains("Continue").click();
 };
Repository: cal-itp/benefits

Issue:
EligibilityVerifier.api_auth_key_secret_name required in the Admin
When trying to edit an existing or add a new `EligibilityVerifier` model in the Admin, the following error message is displayed:

![image](https://github.com/cal-itp/benefits/assets/1783439/156125a8-f092-4fb8-8104-18e9184ea26a)

This is despite the [field in the model being marked with `null=True, blank=True`](https://github.com/cal-itp/benefits/blob/dev/benefits/core/models.py#L170)

It looks like the bug is in this [override of the `blank` kwarg in `SecretNameField`](https://github.com/cal-itp/benefits/blob/dev/benefits/core/models.py#L41):

```python
# similar to max_length, enforce at the field (form) validation level to not allow blanks
kwargs["blank"] = False
```

We want `blank = True` to allow the form to pass validation in the Admin.

## To Reproduce

Steps to reproduce the behavior:

1. Open the Admin
2. Click on `Eligibility verifiers`
3. Click an existing one and click the `Save` button (no changes necessary)
4. See error

## Expected behavior

This is an optional field. It should not be required to save an `EligibilityVerifier` in the Admin.


Discussion:

Resolving patch:
diff --git a/benefits/core/models.py b/benefits/core/models.py
--- a/benefits/core/models.py
+++ b/benefits/core/models.py
@@ -37,8 +37,6 @@ def __init__(self, *args, **kwargs):
         # although the validator also checks for a max length of 127
         # this setting enforces the length at the database column level as well
         kwargs["max_length"] = 127
-        # similar to max_length, enforce at the field (form) validation level to not allow blanks
-        kwargs["blank"] = False
         # the default is False, but this is more explicit
         kwargs["allow_unicode"] = False
         super().__init__(*args, **kwargs)
@@ -102,6 +100,9 @@ def supports_sign_out(self):
     def client_id(self):
         return get_secret_by_name(self.client_id_secret_name)
 
+    def __str__(self) -> str:
+        return self.client_name
+
 
 class EligibilityType(models.Model):
     """A single conditional eligibility type."""


Test patch:
diff --git a/tests/pytest/core/test_models.py b/tests/pytest/core/test_models.py
--- a/tests/pytest/core/test_models.py
+++ b/tests/pytest/core/test_models.py
@@ -25,6 +25,13 @@ def test_SecretNameField_init():
     assert field.description != ""
 
 
+def test_SecretNameField_init_null_blank():
+    field = SecretNameField(blank=True, null=True)
+
+    assert field.blank is True
+    assert field.null is True
+
+
 @pytest.mark.django_db
 def test_PemData_str(model_PemData):
     assert str(model_PemData) == model_PemData.label
@@ -89,6 +96,7 @@ def test_PemData_data_text_secret_name_and_remote__uses_remote(
 def test_model_AuthProvider(model_AuthProvider):
     assert not model_AuthProvider.supports_claims_verification
     assert model_AuthProvider.supports_sign_out
+    assert str(model_AuthProvider) == model_AuthProvider.client_name
 
 
 @pytest.mark.django_db