diff --git a/server/szurubooru/search/base_search_config.py b/server/szurubooru/search/base_search_config.py index 6df7eb5..9b4d06f 100644 --- a/server/szurubooru/search/base_search_config.py +++ b/server/szurubooru/search/base_search_config.py @@ -38,22 +38,26 @@ class BaseSearchConfig(object): ''' Decorate SQLAlchemy filter on given column using supplied criterion. ''' - if isinstance(criterion, criteria.PlainSearchCriterion): - expr = column == int(criterion.value) - elif isinstance(criterion, criteria.ArraySearchCriterion): - expr = column.in_(int(value) for value in criterion.values) - elif isinstance(criterion, criteria.RangedSearchCriterion): - assert criterion.min_value != '' \ - or criterion.max_value != '' - if criterion.min_value != '' and criterion.max_value != '': - expr = column.between( - int(criterion.min_value), int(criterion.max_value)) - elif criterion.min_value != '': - expr = column >= int(criterion.min_value) - elif criterion.max_value != '': - expr = column <= int(criterion.max_value) - else: - assert False + try: + if isinstance(criterion, criteria.PlainSearchCriterion): + expr = column == int(criterion.value) + elif isinstance(criterion, criteria.ArraySearchCriterion): + expr = column.in_(int(value) for value in criterion.values) + elif isinstance(criterion, criteria.RangedSearchCriterion): + assert criterion.min_value != '' \ + or criterion.max_value != '' + if criterion.min_value != '' and criterion.max_value != '': + expr = column.between( + int(criterion.min_value), int(criterion.max_value)) + elif criterion.min_value != '': + expr = column >= int(criterion.min_value) + elif criterion.max_value != '': + expr = column <= int(criterion.max_value) + else: + assert False + except ValueError as e: + raise errors.SearchError( + 'Criterion value %r must be a number.' % (criterion,)) if criterion.negated: expr = ~expr return expr diff --git a/server/szurubooru/tests/search/test_tag_search_config.py b/server/szurubooru/tests/search/test_tag_search_config.py index a3c4899..7582a57 100644 --- a/server/szurubooru/tests/search/test_tag_search_config.py +++ b/server/szurubooru/tests/search/test_tag_search_config.py @@ -134,7 +134,9 @@ def test_filter_by_edit_time( ('post-count:2', ['t1']), ('post-count:1', ['t2']), ('post-count:1..', ['t1', 't2']), + ('post-count-min:1', ['t1', 't2']), ('post-count:..1', ['t2']), + ('post-count-max:1', ['t2']), ('usage-count:2', ['t1']), ('usage-count:1', ['t2']), ('usages:2', ['t1']), @@ -153,6 +155,19 @@ def test_filter_by_post_count( post2.tags.append(tag1) verify_unpaged(input, expected_tag_names) +@pytest.mark.parametrize('input', [ + 'post-count:..', + 'post-count:asd', + 'post-count:asd,1', + 'post-count:1,asd', + 'post-count:asd..1', + 'post-count:1..asd', +]) +def test_filter_by_invalid_input(executor, input): + with pytest.raises(errors.SearchError): + actual_count, actual_posts = executor.execute( + input, page=1, page_size=100) + @pytest.mark.parametrize('input,expected_tag_names', [ ('suggestion-count:2', ['t1']), ('suggestion-count:1', ['t2']),