From 646372db6eb21e718c7ff2f6879d27cc98ea97f3 Mon Sep 17 00:00:00 2001 From: Nazmus Samir Date: Wed, 22 Jul 2026 20:52:21 -0400 Subject: [PATCH] fix: search contacts by first or last name --- backend/contacts/tests/test_contacts_api.py | 28 +++++++++++++++++++++ backend/contacts/views.py | 5 +++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/backend/contacts/tests/test_contacts_api.py b/backend/contacts/tests/test_contacts_api.py index c6c1ad02..56d60a0c 100644 --- a/backend/contacts/tests/test_contacts_api.py +++ b/backend/contacts/tests/test_contacts_api.py @@ -739,6 +739,34 @@ class TestContactAttachmentView: class TestContactListViewFilters: """Tests targeting uncovered filter lines in ContactsListView.get_context_data.""" + def test_filter_by_name_matches_first_or_last_name( + self, admin_client, admin_user, org_a + ): + """The name filter matches a partial first or last name.""" + _set_rls(org_a) + first_name_match = Contact.objects.create( + first_name="John", + last_name="Smith", + email="john.smith@example.com", + org=org_a, + created_by=admin_user, + ) + last_name_match = Contact.objects.create( + first_name="Jane", + last_name="Johnson", + email="jane.johnson@example.com", + org=org_a, + created_by=admin_user, + ) + + response = admin_client.get(CONTACTS_LIST_URL, {"name": "john"}) + + assert response.status_code == status.HTTP_200_OK + returned_ids = { + contact["id"] for contact in response.data["contact_obj_list"] + } + assert returned_ids == {str(first_name_match.id), str(last_name_match.id)} + def test_filter_by_city(self, admin_client, admin_user, org_a): """Filter by city (line 52). Note: The view uses address__city__icontains but the model has flat 'city' field. diff --git a/backend/contacts/views.py b/backend/contacts/views.py index 7908f772..e4b90429 100644 --- a/backend/contacts/views.py +++ b/backend/contacts/views.py @@ -59,7 +59,10 @@ class ContactsListView(APIView, LimitOffsetPagination): if params: if params.get("name"): - queryset = queryset.filter(first_name__icontains=params.get("name")) + name = params.get("name") + queryset = queryset.filter( + Q(first_name__icontains=name) | Q(last_name__icontains=name) + ) if params.get("city"): queryset = queryset.filter(address__city__icontains=params.get("city")) if params.get("phone"):