From 536be0c097224773089573a011854cd2024967c2 Mon Sep 17 00:00:00 2001 From: Murdo Moyse Date: Tue, 20 Feb 2024 10:37:02 +0000 Subject: [PATCH] Added tests for text highlighting --- home/service/search.py | 47 ++++++++++++++++++++++-------------------- tests/conftest.py | 13 +++++++----- tests/test_services.py | 38 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/home/service/search.py b/home/service/search.py index 71adcbd2..ae513218 100644 --- a/home/service/search.py +++ b/home/service/search.py @@ -1,5 +1,5 @@ from typing import Any - +from copy import deepcopy from data_platform_catalogue.search_types import MultiSelectFilter, SortOption from django.core.paginator import Paginator @@ -14,6 +14,7 @@ def __init__(self, form: SearchForm, page: str, items_per_page: int = 20): self.page = page self.client = self._get_catalogue_client() self.results = self._get_search_results(page, items_per_page) + self.highlighted_results = self._highlight_results() self.paginator = self._get_paginator(items_per_page) self.context = self._get_context() @@ -42,13 +43,8 @@ def _get_search_results(self, page: str, items_per_page: int): sort=sort_option, count=items_per_page, ) - highlighted_results = ( - self._highlight_results(results, query) - if query != "" - else results - ) - return highlighted_results + return results def _get_paginator(self, items_per_page: int) -> Paginator: pages_list = list(range(self.results.total_results)) @@ -85,22 +81,29 @@ def _get_context(self) -> dict[str, Any]: return context - def _highlight_results(self, results, string_to_highlight): - "Take a SearchResponse and add bold markdown where a string appears" - for result in results.page_results: - metadata = getattr(result, "metadata") - highlighted_search_summary = metadata.get("search_summary", "").replace( - string_to_highlight, f"**{string_to_highlight}**" - ) - setattr(result, "metadata", metadata) - - name = getattr(result, "description") - highlighted_description = name.replace( - string_to_highlight, f"**{string_to_highlight}**" - ) - setattr(result, "description", highlighted_description) + def _highlight_results(self): + "Take a SearchResponse and add bold markdown where the query appears" + string_to_highlight = self.form.cleaned_data.get("query") if self.form.is_valid() else "" + highlighted_results = deepcopy(self.results) - return results + if string_to_highlight == "": + return highlighted_results + + else: + for result in highlighted_results.page_results: + metadata = getattr(result, "metadata") + metadata["search_summary"] = metadata.get("search_summary", "").replace( + string_to_highlight, f"**{string_to_highlight}**" + ) + setattr(result, "metadata", metadata) + + name = getattr(result, "description") + highlighted_description = name.replace( + string_to_highlight, f"**{string_to_highlight}**" + ) + setattr(result, "description", highlighted_description) + + return highlighted_results def _get_match_reason_display_names(self): return { diff --git a/tests/conftest.py b/tests/conftest.py index 68c34893..cf1af01c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -32,7 +32,8 @@ def generate_page(page_size=20): result_type=choice( (ResultType.DATA_PRODUCT, ResultType.TABLE)), name=fake.name(), - description=fake.paragraphs(), + description=fake.paragraph(), + metadata={"search_summary":"a"}, ) ) return results @@ -105,10 +106,12 @@ def valid_form(): @pytest.fixture -def search_context(valid_form): - search_service = SearchService(form=valid_form, page="1") - context = search_service._get_context() - return context +def search_service(valid_form): + return SearchService(form=valid_form, page="1") + +@pytest.fixture +def search_context(search_service): + return search_service.context @pytest.fixture diff --git a/tests/test_services.py b/tests/test_services.py index 60160f5e..416f1804 100644 --- a/tests/test_services.py +++ b/tests/test_services.py @@ -1,5 +1,6 @@ from types import GeneratorType from data_platform_catalogue.search_types import ResultType +from home.service.search import SearchService class TestSearchService: @@ -24,6 +25,43 @@ def test_get_context_label_clear_href(self, search_context): "HMCTS": "?query=test&sort=ascending&clear_filter=False&clear_label=False" } + def test_highlight_results_no_query(self, search_service): + search_service.form.cleaned_data = {"query": ""} + search_service._highlight_results() + assert ( + normal.description == highlighted.description + & normal.metadata == highlighted.metadata + for normal, highlighted in zip( + search_service.results.page_results, + search_service.highlighted_results.page_results, + ) + ) + + def test_highlight_results_with_query(self, search_service): + search_service.form.cleaned_data = {"query": "a"} + search_service._highlight_results() + + assert ( + "**a**" in highlighted.description + & "**" not in normal.description + for normal, highlighted + in zip( + search_service.results.page_results, + search_service.highlighted_results.page_results, + ) + if "a" in normal.description + ) + assert ( + "**a**" in highlighted.metadata["search_summary"] + & "**" not in normal.metadata["search_summary"] + for normal, highlighted + in zip( + search_service.results.page_results, + search_service.highlighted_results.page_results, + ) + if "a" in normal.metadata["search_summary"] + ) + class TestDetailsService: def test_get_context(self, detail_context, mock_catalogue):