From 8a8988edf469623d7c8065b0edfb496dd0a83a89 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Mon, 18 Mar 2024 17:18:19 +0000
Subject: [PATCH 1/9] feat: implement CalFresh include template for Help page
---
.../core/includes/help--calfresh.html | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 benefits/core/templates/core/includes/help--calfresh.html
diff --git a/benefits/core/templates/core/includes/help--calfresh.html b/benefits/core/templates/core/includes/help--calfresh.html
new file mode 100644
index 000000000..3a44909ff
--- /dev/null
+++ b/benefits/core/templates/core/includes/help--calfresh.html
@@ -0,0 +1,41 @@
+{% load i18n %}
+
+
+ {% translate "How do I know if I'm eligible for the transit benefit for CalFresh Cardholders?" %}
+
+
+ {% blocktranslate trimmed %}
+ We verify your eligibility as a CalFresh Cardholder by confirming you have received funds in your
+ CalFresh account at any point in the last three months. This means you are eligible for a transit
+ benefit even if you did not receive funds in your CalFresh account this month or last month.
+ {% endblocktranslate %}
+
+
+
+ {% translate "Will this transit benefit change my CalFresh account?" %}
+
+
+ {% blocktranslate trimmed %}
+ No. Your monthly CalFresh allotment will not change.
+ {% endblocktranslate %}
+
+
+
+ {% translate "Do I need my Golden State Advantage card to enroll?" %}
+
+
+ {% blocktranslate trimmed %}
+ No, you do not need your physical EBT card to enroll. We use information from Login.gov and the California
+ Department of Social Services to enroll you in the benefit.
+ {% endblocktranslate %}
+
+
+
+ {% translate "Can I use my Golden State Advantage card to pay for transit rides?" %}
+
+
+ {% blocktranslate trimmed %}
+ No. You can not use your EBT or P-EBT card to pay for public transportation. When you tap to ride, use your personal
+ contactless debit or credit card to pay for public transportation.
+ {% endblocktranslate %}
+
From b1a688362458bcdfb678d8e49a2a0ee4f01011da Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Thu, 21 Mar 2024 01:03:29 +0000
Subject: [PATCH 2/9] refactor: move help_template to EligibilityVerifier and
use unique ones
we need the templates to be specified on verifiers so that the help page
reflects configuration changes rather than being hard-coded on an
agency's template.
---
benefits/core/context_processors.py | 9 +++++++-
...ve_help_template_to_eligibilityverifier.py | 22 +++++++++++++++++++
benefits/core/migrations/local_fixtures.json | 9 ++++----
benefits/core/models.py | 2 +-
benefits/core/templates/core/help.html | 6 +++--
5 files changed, 39 insertions(+), 9 deletions(-)
create mode 100644 benefits/core/migrations/0005_move_help_template_to_eligibilityverifier.py
diff --git a/benefits/core/context_processors.py b/benefits/core/context_processors.py
index 958ac6d57..96d3879ea 100644
--- a/benefits/core/context_processors.py
+++ b/benefits/core/context_processors.py
@@ -7,10 +7,17 @@
from . import models, session
+def unique_values(original_list):
+ # dict.fromkeys gets the unique values and preserves order
+ return list(dict.fromkeys(original_list))
+
+
def _agency_context(agency):
return {
"eligibility_index_url": agency.eligibility_index_url,
- "help_template": agency.help_template,
+ "help_templates": unique_values(
+ [v.help_template for v in agency.eligibility_verifiers.all() if v.help_template is not None]
+ ),
"info_url": agency.info_url,
"long_name": agency.long_name,
"phone": agency.phone,
diff --git a/benefits/core/migrations/0005_move_help_template_to_eligibilityverifier.py b/benefits/core/migrations/0005_move_help_template_to_eligibilityverifier.py
new file mode 100644
index 000000000..8f26ac8ea
--- /dev/null
+++ b/benefits/core/migrations/0005_move_help_template_to_eligibilityverifier.py
@@ -0,0 +1,22 @@
+# Generated by Django 5.0.3 on 2024-03-21 00:31
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("core", "0004_alter_eligibilityverifier_display_order"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="transitagency",
+ name="help_template",
+ ),
+ migrations.AddField(
+ model_name="eligibilityverifier",
+ name="help_template",
+ field=models.TextField(null=True),
+ ),
+ ]
diff --git a/benefits/core/migrations/local_fixtures.json b/benefits/core/migrations/local_fixtures.json
index 511c95095..5f11f1a72 100644
--- a/benefits/core/migrations/local_fixtures.json
+++ b/benefits/core/migrations/local_fixtures.json
@@ -186,7 +186,8 @@
"auth_provider": null,
"selection_label_template": "eligibility/includes/selection-label--mst-courtesy-card.html",
"start_template": "eligibility/start--mst-courtesy-card.html",
- "form_class": "benefits.eligibility.forms.MSTCourtesyCard"
+ "form_class": "benefits.eligibility.forms.MSTCourtesyCard",
+ "help_template": "core/includes/help--mst.html"
}
},
{
@@ -249,7 +250,8 @@
"auth_provider": null,
"selection_label_template": "eligibility/includes/selection-label--sbmtd-mobility-pass.html",
"start_template": "eligibility/start--sbmtd-mobility-pass.html",
- "form_class": "benefits.eligibility.forms.SBMTDMobilityPass"
+ "form_class": "benefits.eligibility.forms.SBMTDMobilityPass",
+ "help_template": "core/includes/help--sbmtd.html"
}
},
{
@@ -334,7 +336,6 @@
"index_template": "core/index--mst.html",
"eligibility_index_template": "eligibility/index--mst.html",
"enrollment_success_template": "enrollment/success--mst.html",
- "help_template": "core/includes/help--mst.html",
"eligibility_types": [1, 7, 2, 3],
"eligibility_verifiers": [1, 7, 2, 3]
}
@@ -358,7 +359,6 @@
"index_template": "core/index--sacrt.html",
"eligibility_index_template": "eligibility/index--sacrt.html",
"enrollment_success_template": "enrollment/success--sacrt.html",
- "help_template": null,
"eligibility_types": [4],
"eligibility_verifiers": [4]
}
@@ -382,7 +382,6 @@
"index_template": "core/index--sbmtd.html",
"eligibility_index_template": "eligibility/index--sbmtd.html",
"enrollment_success_template": "enrollment/success--sbmtd.html",
- "help_template": "core/includes/help--sbmtd.html",
"eligibility_types": [5, 6],
"eligibility_verifiers": [5, 6]
}
diff --git a/benefits/core/models.py b/benefits/core/models.py
index 36010414a..b68df626d 100644
--- a/benefits/core/models.py
+++ b/benefits/core/models.py
@@ -177,6 +177,7 @@ class EligibilityVerifier(models.Model):
start_template = models.TextField(null=True)
# reference to a form class used by this Verifier, e.g. benefits.app.forms.FormClass
form_class = models.TextField(null=True)
+ help_template = models.TextField(null=True)
class Meta:
ordering = ["display_order"]
@@ -269,7 +270,6 @@ class TransitAgency(models.Model):
index_template = models.TextField()
eligibility_index_template = models.TextField()
enrollment_success_template = models.TextField()
- help_template = models.TextField(null=True)
def __str__(self):
return self.long_name
diff --git a/benefits/core/templates/core/help.html b/benefits/core/templates/core/help.html
index 53adc1569..ef3325904 100644
--- a/benefits/core/templates/core/help.html
+++ b/benefits/core/templates/core/help.html
@@ -110,8 +110,10 @@ {% translate "How do I veri
{% endblocktranslate %}
- {% if agency and agency.help_template %}
- {% include agency.help_template %}
+ {% if agency and agency.help_templates %}
+ {% for help_template in agency.help_templates %}
+ {% include help_template %}
+ {% endfor %}
{% endif %}
{% translate "What is Littlepay?" %}
From dc95f50b9d8e1807eb1928fee3ec5b8636b85e23 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Thu, 21 Mar 2024 01:19:46 +0000
Subject: [PATCH 3/9] refactor(help): rename templates to reflect their
eligibility type
---
benefits/core/migrations/local_fixtures.json | 4 ++--
.../includes/{help--mst.html => help--mst-courtesy-card.html} | 0
.../{help--sbmtd.html => help--sbmtd-mobility-pass.html} | 0
3 files changed, 2 insertions(+), 2 deletions(-)
rename benefits/core/templates/core/includes/{help--mst.html => help--mst-courtesy-card.html} (100%)
rename benefits/core/templates/core/includes/{help--sbmtd.html => help--sbmtd-mobility-pass.html} (100%)
diff --git a/benefits/core/migrations/local_fixtures.json b/benefits/core/migrations/local_fixtures.json
index 5f11f1a72..5b21ccda7 100644
--- a/benefits/core/migrations/local_fixtures.json
+++ b/benefits/core/migrations/local_fixtures.json
@@ -187,7 +187,7 @@
"selection_label_template": "eligibility/includes/selection-label--mst-courtesy-card.html",
"start_template": "eligibility/start--mst-courtesy-card.html",
"form_class": "benefits.eligibility.forms.MSTCourtesyCard",
- "help_template": "core/includes/help--mst.html"
+ "help_template": "core/includes/help--mst-courtesy-card.html"
}
},
{
@@ -251,7 +251,7 @@
"selection_label_template": "eligibility/includes/selection-label--sbmtd-mobility-pass.html",
"start_template": "eligibility/start--sbmtd-mobility-pass.html",
"form_class": "benefits.eligibility.forms.SBMTDMobilityPass",
- "help_template": "core/includes/help--sbmtd.html"
+ "help_template": "core/includes/help--sbmtd-mobility-pass.html"
}
},
{
diff --git a/benefits/core/templates/core/includes/help--mst.html b/benefits/core/templates/core/includes/help--mst-courtesy-card.html
similarity index 100%
rename from benefits/core/templates/core/includes/help--mst.html
rename to benefits/core/templates/core/includes/help--mst-courtesy-card.html
diff --git a/benefits/core/templates/core/includes/help--sbmtd.html b/benefits/core/templates/core/includes/help--sbmtd-mobility-pass.html
similarity index 100%
rename from benefits/core/templates/core/includes/help--sbmtd.html
rename to benefits/core/templates/core/includes/help--sbmtd-mobility-pass.html
From 13335a8803016c5dba2fd2d56ed807210cf736b1 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Thu, 21 Mar 2024 01:43:02 +0000
Subject: [PATCH 4/9] chore(fixture): add help template to CalFresh eligibility
verifier
---
benefits/core/migrations/local_fixtures.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/benefits/core/migrations/local_fixtures.json b/benefits/core/migrations/local_fixtures.json
index 5b21ccda7..4e047041d 100644
--- a/benefits/core/migrations/local_fixtures.json
+++ b/benefits/core/migrations/local_fixtures.json
@@ -272,7 +272,8 @@
"auth_provider": 1,
"selection_label_template": "eligibility/includes/selection-label--calfresh.html",
"start_template": "eligibility/start--calfresh.html",
- "form_class": null
+ "form_class": null,
+ "help_template": "core/includes/help--calfresh.html"
}
},
{
From ce14b73d9ff072f81f61dd69a1637dfb722fe6d8 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Thu, 21 Mar 2024 18:39:24 +0000
Subject: [PATCH 5/9] fix: context processor should use same filter as verifier
selection form
fixes failing eligibility view tests
---
benefits/core/context_processors.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/benefits/core/context_processors.py b/benefits/core/context_processors.py
index 96d3879ea..3a9ec296a 100644
--- a/benefits/core/context_processors.py
+++ b/benefits/core/context_processors.py
@@ -16,7 +16,7 @@ def _agency_context(agency):
return {
"eligibility_index_url": agency.eligibility_index_url,
"help_templates": unique_values(
- [v.help_template for v in agency.eligibility_verifiers.all() if v.help_template is not None]
+ [v.help_template for v in agency.eligibility_verifiers.filter(active=True) if v.help_template is not None]
),
"info_url": agency.info_url,
"long_name": agency.long_name,
From cc0a6d3b962197bbbc977598f30fb25e7ef98f15 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Thu, 21 Mar 2024 18:39:44 +0000
Subject: [PATCH 6/9] fix(test): update core view tests to ensure mocked value
is iterable
---
tests/pytest/core/test_views.py | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/tests/pytest/core/test_views.py b/tests/pytest/core/test_views.py
index 74b05fbe1..1a0aa9220 100644
--- a/tests/pytest/core/test_views.py
+++ b/tests/pytest/core/test_views.py
@@ -24,6 +24,11 @@ def session_reset_spy(mocker):
@pytest.fixture
def mocked_active_agency(mocker):
mock_agency = mocker.Mock()
+
+ # ensure agency.eligibility_verifiers is iterable
+ eligibility_verifiers = mocker.MagicMock()
+ mock_agency.eligibility_verifiers = eligibility_verifiers
+
mock_agency.index_url = "/agency"
mocker.patch("benefits.core.session.agency", return_value=mock_agency)
mocker.patch("benefits.core.session.active_agency", return_value=True)
From 0cd9a1e59aecf5997c043107bfc181d76a5af25b Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Fri, 22 Mar 2024 18:12:30 +0000
Subject: [PATCH 7/9] chore(conftest): move test fixtures into conftest
for consistency
---
tests/pytest/conftest.py | 39 ++++++++++++++++++++++++++++++++
tests/pytest/core/test_models.py | 39 --------------------------------
2 files changed, 39 insertions(+), 39 deletions(-)
diff --git a/tests/pytest/conftest.py b/tests/pytest/conftest.py
index 0dcf3aa8b..c10093d6d 100644
--- a/tests/pytest/conftest.py
+++ b/tests/pytest/conftest.py
@@ -105,6 +105,45 @@ def model_EligibilityType():
return eligibility
+@pytest.fixture
+def model_EligibilityType_does_not_support_expiration(model_EligibilityType):
+ model_EligibilityType.supports_expiration = False
+ model_EligibilityType.expiration_days = 0
+ model_EligibilityType.save()
+
+ return model_EligibilityType
+
+
+@pytest.fixture
+def model_EligibilityType_zero_expiration_days(model_EligibilityType):
+ model_EligibilityType.supports_expiration = True
+ model_EligibilityType.expiration_days = 0
+ model_EligibilityType.expiration_reenrollment_days = 14
+ model_EligibilityType.save()
+
+ return model_EligibilityType
+
+
+@pytest.fixture
+def model_EligibilityType_zero_expiration_reenrollment_days(model_EligibilityType):
+ model_EligibilityType.supports_expiration = True
+ model_EligibilityType.expiration_days = 14
+ model_EligibilityType.expiration_reenrollment_days = 0
+ model_EligibilityType.save()
+
+ return model_EligibilityType
+
+
+@pytest.fixture
+def model_EligibilityType_supports_expiration(model_EligibilityType):
+ model_EligibilityType.supports_expiration = True
+ model_EligibilityType.expiration_days = 365
+ model_EligibilityType.expiration_reenrollment_days = 14
+ model_EligibilityType.save()
+
+ return model_EligibilityType
+
+
@pytest.fixture
def model_EligibilityVerifier(model_PemData, model_EligibilityType):
verifier = EligibilityVerifier.objects.create(
diff --git a/tests/pytest/core/test_models.py b/tests/pytest/core/test_models.py
index dbf4f44bd..4a888a14a 100644
--- a/tests/pytest/core/test_models.py
+++ b/tests/pytest/core/test_models.py
@@ -13,45 +13,6 @@ def mock_requests_get_pem_data(mocker):
return mocker.patch("benefits.core.models.requests.get", return_value=mocker.Mock(text="PEM text"))
-@pytest.fixture
-def model_EligibilityType_does_not_support_expiration(model_EligibilityType):
- model_EligibilityType.supports_expiration = False
- model_EligibilityType.expiration_days = 0
- model_EligibilityType.save()
-
- return model_EligibilityType
-
-
-@pytest.fixture
-def model_EligibilityType_zero_expiration_days(model_EligibilityType):
- model_EligibilityType.supports_expiration = True
- model_EligibilityType.expiration_days = 0
- model_EligibilityType.expiration_reenrollment_days = 14
- model_EligibilityType.save()
-
- return model_EligibilityType
-
-
-@pytest.fixture
-def model_EligibilityType_zero_expiration_reenrollment_days(model_EligibilityType):
- model_EligibilityType.supports_expiration = True
- model_EligibilityType.expiration_days = 14
- model_EligibilityType.expiration_reenrollment_days = 0
- model_EligibilityType.save()
-
- return model_EligibilityType
-
-
-@pytest.fixture
-def model_EligibilityType_supports_expiration(model_EligibilityType):
- model_EligibilityType.supports_expiration = True
- model_EligibilityType.expiration_days = 365
- model_EligibilityType.expiration_reenrollment_days = 14
- model_EligibilityType.save()
-
- return model_EligibilityType
-
-
def test_SecretNameField_init():
field = SecretNameField()
From d79f06c186a8491f2576e3f5a8588fff3ea66740 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Fri, 22 Mar 2024 18:39:40 +0000
Subject: [PATCH 8/9] refactor(models): add property to TransitAgency to get
active verifiers
update usage in verifier selection form, context processors, and tests
---
benefits/core/context_processors.py | 4 +---
benefits/core/models.py | 5 +++++
benefits/eligibility/forms.py | 2 +-
tests/pytest/core/test_models.py | 17 +++++++++++++++++
tests/pytest/core/test_views.py | 2 +-
tests/pytest/eligibility/test_views.py | 14 ++++++++++----
6 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/benefits/core/context_processors.py b/benefits/core/context_processors.py
index 3a9ec296a..012a9a645 100644
--- a/benefits/core/context_processors.py
+++ b/benefits/core/context_processors.py
@@ -15,9 +15,7 @@ def unique_values(original_list):
def _agency_context(agency):
return {
"eligibility_index_url": agency.eligibility_index_url,
- "help_templates": unique_values(
- [v.help_template for v in agency.eligibility_verifiers.filter(active=True) if v.help_template is not None]
- ),
+ "help_templates": unique_values([v.help_template for v in agency.active_verifiers if v.help_template is not None]),
"info_url": agency.info_url,
"long_name": agency.long_name,
"phone": agency.phone,
diff --git a/benefits/core/models.py b/benefits/core/models.py
index b68df626d..58e49205c 100644
--- a/benefits/core/models.py
+++ b/benefits/core/models.py
@@ -323,6 +323,11 @@ def public_key_data(self):
"""This Agency's public key as a string."""
return self.public_key.data
+ @property
+ def active_verifiers(self):
+ """This Agency's eligibility verifiers that are active."""
+ return self.eligibility_verifiers.filter(active=True)
+
@staticmethod
def by_id(id):
"""Get a TransitAgency instance by its ID."""
diff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py
index 3d64c89cf..a088f04ff 100644
--- a/benefits/eligibility/forms.py
+++ b/benefits/eligibility/forms.py
@@ -25,7 +25,7 @@ class EligibilityVerifierSelectionForm(forms.Form):
def __init__(self, agency: models.TransitAgency, *args, **kwargs):
super().__init__(*args, **kwargs)
- verifiers = agency.eligibility_verifiers.filter(active=True)
+ verifiers = agency.active_verifiers
self.classes = "col-lg-8"
# second element is not used since we render the whole label using selection_label_template,
diff --git a/tests/pytest/core/test_models.py b/tests/pytest/core/test_models.py
index 4a888a14a..aedfdb571 100644
--- a/tests/pytest/core/test_models.py
+++ b/tests/pytest/core/test_models.py
@@ -317,6 +317,23 @@ def test_TransitAgency_str(model_TransitAgency):
assert str(model_TransitAgency) == model_TransitAgency.long_name
+@pytest.mark.django_db
+def test_TransitAgency_active_verifiers(model_TransitAgency, model_EligibilityVerifier):
+ # add another to the list of verifiers by cloning the original
+ # https://stackoverflow.com/a/48149675/453168
+ new_verifier = EligibilityVerifier.objects.get(pk=model_EligibilityVerifier.id)
+ new_verifier.pk = None
+ new_verifier.active = False
+ new_verifier.save()
+
+ model_TransitAgency.eligibility_verifiers.add(new_verifier)
+
+ assert model_TransitAgency.eligibility_verifiers.count() == 2
+ assert model_TransitAgency.active_verifiers.count() == 1
+
+ assert model_TransitAgency.active_verifiers[0] == model_EligibilityVerifier
+
+
@pytest.mark.django_db
def test_TransitAgency_get_type_id_matching(model_TransitAgency):
eligibility = model_TransitAgency.eligibility_types.first()
diff --git a/tests/pytest/core/test_views.py b/tests/pytest/core/test_views.py
index 1a0aa9220..628110bfb 100644
--- a/tests/pytest/core/test_views.py
+++ b/tests/pytest/core/test_views.py
@@ -27,7 +27,7 @@ def mocked_active_agency(mocker):
# ensure agency.eligibility_verifiers is iterable
eligibility_verifiers = mocker.MagicMock()
- mock_agency.eligibility_verifiers = eligibility_verifiers
+ mock_agency.active_verifiers = eligibility_verifiers
mock_agency.index_url = "/agency"
mocker.patch("benefits.core.session.agency", return_value=mock_agency)
diff --git a/tests/pytest/eligibility/test_views.py b/tests/pytest/eligibility/test_views.py
index 3a8a430e1..ea55ad460 100644
--- a/tests/pytest/eligibility/test_views.py
+++ b/tests/pytest/eligibility/test_views.py
@@ -85,8 +85,12 @@ def test_index_get_agency_multiple_verifiers(
):
# override the mocked session agency with a mock agency that has multiple verifiers
mock_agency = mocker.Mock(spec=model_TransitAgency)
- mock_agency.eligibility_verifiers.filter.return_value = [model_EligibilityVerifier, model_EligibilityVerifier]
- mock_agency.eligibility_verifiers.count.return_value = 2
+
+ # mock the active_verifiers property on the class - https://stackoverflow.com/a/55642462
+ type(mock_agency).active_verifiers = mocker.PropertyMock(
+ return_value=[model_EligibilityVerifier, model_EligibilityVerifier]
+ )
+
mock_agency.index_url = "/agency"
mock_agency.eligibility_index_template = "eligibility/index.html"
mocked_session_agency.return_value = mock_agency
@@ -107,8 +111,10 @@ def test_index_get_agency_single_verifier(
):
# override the mocked session agency with a mock agency that has a single verifier
mock_agency = mocker.Mock(spec=model_TransitAgency)
- mock_agency.eligibility_verifiers.filter.return_value = [model_EligibilityVerifier]
- mock_agency.eligibility_verifiers.count.return_value = 1
+
+ # mock the active_verifiers property on the class - https://stackoverflow.com/a/55642462
+ type(mock_agency).active_verifiers = mocker.PropertyMock(return_value=[model_EligibilityVerifier])
+
mock_agency.index_url = "/agency"
mock_agency.eligibility_index_template = "eligibility/index.html"
mocked_session_agency.return_value = mock_agency
From f3fe500824bd906113038a2ef0c342c1da56f2d8 Mon Sep 17 00:00:00 2001
From: Angela Tran
Date: Fri, 22 Mar 2024 18:45:02 +0000
Subject: [PATCH 9/9] test: unit test for helper function
expected behavior is to return an ordered list of the unique values
---
tests/pytest/core/test_context_processors.py | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 tests/pytest/core/test_context_processors.py
diff --git a/tests/pytest/core/test_context_processors.py b/tests/pytest/core/test_context_processors.py
new file mode 100644
index 000000000..9048ed90a
--- /dev/null
+++ b/tests/pytest/core/test_context_processors.py
@@ -0,0 +1,9 @@
+from benefits.core.context_processors import unique_values
+
+
+def test_unique_values():
+ original_list = ["a", "b", "c", "a", "a", "zzz", "b", "c", "d", "b"]
+
+ new_list = unique_values(original_list)
+
+ assert new_list == ["a", "b", "c", "zzz", "d"]