Fix include and exclude filters not processing "no tags" condition

This commit is contained in:
allegroai 2024-01-10 15:26:55 +02:00
parent 768c3d80ff
commit 8c347f8fa9
3 changed files with 41 additions and 3 deletions

View File

@ -1134,7 +1134,7 @@ class ProjectBLL:
for op, actions in db_query.items():
field_conditions = {}
for action, values in actions.items():
value = list(set(values))
value = list(set(values)) if isinstance(values, list) else values
for key in reversed(action.split("__")):
value = {f"${key}": value}
field_conditions.update(value)

View File

@ -617,7 +617,20 @@ class GetMixin(PropsMixin):
):
if not vals:
continue
operations[self._db_modifiers[(op, include)]] = list(set(vals))
unique = set(vals)
if None in unique:
# noinspection PyTypeChecker
unique.remove(None)
if include:
operations["size"] = 0
else:
operations["not__size"] = 0
if not unique:
continue
operations[self._db_modifiers[(op, include)]] = list(unique)
self.db_query[op] = operations
@ -655,7 +668,8 @@ class GetMixin(PropsMixin):
ops = []
for action, vals in actions.items():
if not vals:
# cannot just check vals here since 0 is acceptable value
if vals is None or vals == []:
continue
ops.append(RegexQ(**{f"{mongoengine_field}__{action}": vals}))

View File

@ -3,6 +3,30 @@ from apiserver.tests.automated import TestService
class TestGetAllExFilters(TestService):
def test_no_tags_filter(self):
task = self._temp_task(tags=["test"])
task_no_tags = self._temp_task()
tasks = [task, task_no_tags]
for cond, op, tags, expected_tasks in (
("any", "include", [None], [task_no_tags]),
("any", "include", ["test"], [task]),
("any", "include", ["test", None], [task, task_no_tags]),
("any", "exclude", [None], [task]),
("any", "exclude", ["test"], [task_no_tags]),
("any", "exclude", ["test", None], [task, task_no_tags]),
("all", "include", [None], [task_no_tags]),
("all", "include", ["test"], [task]),
("all", "include", ["test", None], []),
("all", "exclude", [None], [task]),
("all", "exclude", ["test"], [task_no_tags]),
("all", "exclude", ["test", None], []),
):
res = self.api.tasks.get_all_ex(
id=tasks, filters={"tags": {cond: {op: tags}}}
).tasks
self.assertEqual({t.id for t in res}, set(expected_tasks))
def test_list_filters(self):
tags = ["a", "b", "c", "d"]
tasks = [self._temp_task(tags=tags[:i]) for i in range(len(tags) + 1)]