Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion udata/core/dataservices/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class DataserviceSearch(ModelSearchAdapter):
model = Dataservice
service_class = DataserviceService
consumer_class = DataserviceConsumer
configurable_size_facets = ["organization_id_with_name"]

sorts = {"created": "created_at", "views": "views", "followers": "followers"}

Expand Down
1 change: 0 additions & 1 deletion udata/core/dataset/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class DatasetSearch(ModelSearchAdapter):
model = Dataset
service_class = DatasetService
consumer_class = DatasetConsumer
configurable_size_facets = ["organization_id_with_name"]

sorts = {
"created": "created_at_internal",
Expand Down
1 change: 0 additions & 1 deletion udata/core/reuse/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class ReuseSearch(ModelSearchAdapter):
model = Reuse
service_class = ReuseService
consumer_class = ReuseConsumer
configurable_size_facets = ["organization_id_with_name"]

sorts = {
"created": "created_at",
Expand Down
1 change: 0 additions & 1 deletion udata/core/topic/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ class TopicSearch(ModelSearchAdapter):
model = Topic
service_class = TopicService
consumer_class = TopicConsumer
configurable_size_facets = ["organization_id_with_name"]

sorts = {
"name": "name",
Expand Down
19 changes: 11 additions & 8 deletions udata/search/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from flask_restx.reqparse import RequestParser

from udata.search.query import SearchQuery
from udata_search_service.search_clients import TermsFacet

log = logging.getLogger(__name__)

Expand All @@ -13,7 +14,6 @@ class ModelSearchAdapter:
model = None
sorts = None
filters = {}
configurable_size_facets = []
service_class = None
consumer_class = None

Expand Down Expand Up @@ -58,13 +58,16 @@ def as_request_parser(cls, paginate=True, store_missing: bool = True):
parser.add_argument(
"page_size", type=int, location="args", default=20, help="The page size"
)
for facet_name in cls.configurable_size_facets:
parser.add_argument(
f"facet_size__{facet_name}",
type=int,
location="args",
help=f"Number of {facet_name} facet values to return",
)
if cls.service_class:
for facet in cls.service_class.facets:
if isinstance(facet, TermsFacet):
parser.add_argument(
f"facet_size__{facet.name}",
type=int,
location="args",
store_missing=store_missing,
help=f"Number of {facet.name} facet values to return",
)
return parser

@classmethod
Expand Down
4 changes: 3 additions & 1 deletion udata/search/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ def __init__(self, params):
self._facet_sizes = {}
for key in [k for k in list(params.keys()) if k.startswith("facet_size__")]:
facet_name = key[len("facet_size__") :]
self._facet_sizes[facet_name] = parse_facet_size(key, params.pop(key), max_facet_size)
raw = params.pop(key)
if raw is not None:
self._facet_sizes[facet_name] = parse_facet_size(key, raw, max_facet_size)
self._filters = {}
self.extract_filters(params)

Expand Down
23 changes: 13 additions & 10 deletions udata/tests/search/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from flask_restx.reqparse import RequestParser

from udata import search
from udata.core.access_type.constants import AccessType
from udata.core.dataservices.factories import DataserviceFactory
from udata.core.dataservices.search import DataserviceSearch
from udata.core.dataset.factories import (
Expand All @@ -17,6 +18,7 @@
from udata.core.dataset.search import DatasetSearch
from udata.core.organization.constants import (
ASSOCIATION,
CERTIFIED,
COMPANY,
LOCAL_AUTHORITY,
NOT_SPECIFIED,
Expand All @@ -33,6 +35,7 @@
from udata.search.commands import finalize_reindex, index_model
from udata.tests.api import APITestCase
from udata.utils import clean_string
from udata_search_service.search_clients import TermsFacet

from . import FakeSearch

Expand Down Expand Up @@ -365,8 +368,6 @@ def test_serialize_deduplicates_topic_ids(self):

def test_serialize_includes_access_type(self):
"""Test that DatasetSearch.serialize includes access_type in the serialized document"""
from udata.core.access_type.constants import AccessType

dataset = DatasetFactory(access_type=AccessType.OPEN)
serialized = DatasetSearch.serialize(dataset)

Expand Down Expand Up @@ -501,8 +502,6 @@ def test_serialize_includes_producer_type_user(self):

def test_serialize_excludes_certified_from_producer_type(self):
"""Test that certified badge is excluded from producer_type"""
from udata.core.organization.constants import CERTIFIED

org = OrganizationFactory()
org.add_badge(PUBLIC_SERVICE)
org.add_badge(CERTIFIED)
Expand Down Expand Up @@ -565,10 +564,16 @@ def test_facet_size_params_in_request_parser(self):
for adapter in [DatasetSearch, ReuseSearch, DataserviceSearch]:
parser = adapter.as_request_parser()
arg_names = [arg.name for arg in parser.args]
assert "facet_size__organization_id_with_name" in arg_names, (
f"{adapter.__name__} parser is missing facet_size__organization_id_with_name — "
f"it would be silently dropped from API requests"
)
expected = [
f"facet_size__{f.name}"
for f in adapter.service_class.facets
if isinstance(f, TermsFacet)
]
for expected_arg in expected:
assert expected_arg in arg_names, (
f"{adapter.__name__} parser is missing {expected_arg} — "
f"it would be silently dropped from API requests"
)

def test_facet_size_param_is_int(self):
parser = DatasetSearch.as_request_parser()
Expand All @@ -579,8 +584,6 @@ def test_facet_size_param_is_int(self):
class DataserviceSearchAdapterTest(APITestCase):
def test_serialize_includes_access_type(self):
"""Test that DataserviceSearch.serialize includes access_type in the serialized document"""
from udata.core.access_type.constants import AccessType

dataservice = DataserviceFactory(access_type=AccessType.OPEN)
serialized = DataserviceSearch.serialize(dataservice)

Expand Down
7 changes: 7 additions & 0 deletions udata/tests/search/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ def test_empty_facet_sizes_when_not_provided():
assert kwargs["facet_sizes"] == {}


def test_facets_list_passed_to_client_query():
service, mock_client = make_service()
service.search(base_filters())
_, kwargs = mock_client.query_datasets.call_args
assert kwargs["facets"] == DatasetService.facets


def test_facet_sizes_not_passed_as_filter():
service, mock_client = make_service()
filters = {**base_filters(), "facet_sizes": {"tag": 100}}
Expand Down
Loading