diff --git a/frontends/api/src/generated/v1/api.ts b/frontends/api/src/generated/v1/api.ts index cf9b817ed5..62385b9658 100644 --- a/frontends/api/src/generated/v1/api.ts +++ b/frontends/api/src/generated/v1/api.ts @@ -3638,6 +3638,12 @@ export interface PercolateQuery { * @memberof PercolateQuery */ source_type: SourceTypeEnum + /** + * Friendly display label for the query + * @type {string} + * @memberof PercolateQuery + */ + display_label?: string } /** diff --git a/learning_resources_search/admin.py b/learning_resources_search/admin.py index c0a6b23160..cf839aae59 100644 --- a/learning_resources_search/admin.py +++ b/learning_resources_search/admin.py @@ -9,8 +9,8 @@ class PercolateQueryAdmin(admin.ModelAdmin): """PercolateQuery Admin""" model = models.PercolateQuery - list_display = ("original_query", "query") - search_fields = ("original_query", "query") + list_display = ("original_query", "query", "display_label") + search_fields = ("original_query", "query", "display_label") admin.site.register(models.PercolateQuery, PercolateQueryAdmin) diff --git a/learning_resources_search/migrations/0005_percolatequery_display_label.py b/learning_resources_search/migrations/0005_percolatequery_display_label.py new file mode 100644 index 0000000000..a2c2814fc0 --- /dev/null +++ b/learning_resources_search/migrations/0005_percolatequery_display_label.py @@ -0,0 +1,21 @@ +# Generated by Django 4.2.16 on 2024-09-25 18:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("learning_resources_search", "0004_alter_percolatequery_source_type"), + ] + + operations = [ + migrations.AddField( + model_name="percolatequery", + name="display_label", + field=models.CharField( + blank=True, + help_text="Friendly display label for the query", + max_length=255, + ), + ), + ] diff --git a/learning_resources_search/models.py b/learning_resources_search/models.py index 058381b2af..8b10a69981 100644 --- a/learning_resources_search/models.py +++ b/learning_resources_search/models.py @@ -26,6 +26,12 @@ class PercolateQuery(TimestampedModel): source_type = models.CharField( max_length=255, choices=[(choice, choice) for choice in SOURCE_TYPES] ) + + display_label = models.CharField( + max_length=255, + blank=True, + help_text="Friendly display label for the query", + ) users = models.ManyToManyField(User, related_name="percolate_queries") def source_label(self): @@ -37,6 +43,8 @@ def source_label(self): def source_description(self): channel = self.source_channel() + if self.display_label: + return self.display_label if channel: return channel.title return self.original_url_params() diff --git a/learning_resources_search/models_test.py b/learning_resources_search/models_test.py index fa070c6fe7..3a6058e2ea 100644 --- a/learning_resources_search/models_test.py +++ b/learning_resources_search/models_test.py @@ -1,4 +1,5 @@ from types import SimpleNamespace +from urllib.parse import urlencode import pytest @@ -152,3 +153,57 @@ def test_percolate_query_search_labels(mocker, mocked_es): == "q=testing+search+filter&department=physics&topic=math" ) assert query.source_label() == "saved_search" + + +@pytest.mark.django_db +@pytest.mark.parametrize("is_channel_query", [True, False]) +@pytest.mark.parametrize("test_label", ["new courses about cats", ""]) +def test_percolate_query_display_labels( + mocker, mocked_es, test_label, is_channel_query +): + """ + Test that makes sure we display the display label for a percolate query if it is defined + """ + + def encode_params(oparams): + ignore_params = ["endpoint"] + query = oparams + defined_params = { + key: query[key] for key in query if query[key] and key not in ignore_params + } + return urlencode(defined_params, doseq=True) + + mocker.patch( + "learning_resources_search.indexing_api.index_percolators", autospec=True + ) + mocker.patch( + "learning_resources_search.indexing_api._update_document_by_id", autospec=True + ) + + if is_channel_query: + original_query = {"department": ["physics"]} + channel = ChannelFactory.create( + search_filter=encode_params(original_query), channel_type="unit" + ) + else: + original_query = { + "q": "testing search filter", + "certification": None, + "yearly_decay_percent": None, + } + + query = PercolateQueryFactory.create( + original_query=original_query, + query=original_query, + display_label=test_label, + ) + assert query.original_url_params() == encode_params(original_query) + if not is_channel_query: + assert query.source_label() == "saved_search" + assert query.source_description() == ( + test_label + if test_label + else channel.title + if is_channel_query + else query.original_url_params() + ) diff --git a/openapi/specs/v1.yaml b/openapi/specs/v1.yaml index af71655a91..1fe6d76a0e 100644 --- a/openapi/specs/v1.yaml +++ b/openapi/specs/v1.yaml @@ -10106,6 +10106,10 @@ components: query: {} source_type: $ref: '#/components/schemas/SourceTypeEnum' + display_label: + type: string + description: Friendly display label for the query + maxLength: 255 required: - id - original_query