Coverage for functions \ flipdare \ search \ core \ filter \ general_filter.py: 92%
36 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
« prev ^ index » next coverage.py v7.13.0, created at 2026-05-08 12:22 +1000
1#!/usr/bin/env python
2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
3#
4# This file is part of Flipdare's proprietary software and contains
5# confidential and copyrighted material. Unauthorised copying,
6# modification, distribution, or use of this file is strictly
7# prohibited without prior written permission from Flipdare Pty Ltd.
8#
9# This software includes third-party components licensed under MIT,
10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
11#
14from __future__ import annotations
16from typing import TYPE_CHECKING, override
18from flipdare.generated.schema.search.general_document_schema import GeneralDocumentKey
19from flipdare.generated.shared.search.search_obj_type import SearchObjType
20from flipdare.search.core.filter._complex_filter import ComplexFilter, Relationship
21from flipdare.search.core.filter._simple_filter import FilterType, SimpleFilter
23if TYPE_CHECKING:
25 from flipdare.search.db.app_friend_search import AppFriendSearch
27__all__ = ["ComplexGeneralFilter", "GeneralFilterDict"]
29type GeneralFilterDict = dict[GeneralDocumentKey, FilterType]
32class SimpleGeneralFilter(SimpleFilter[GeneralDocumentKey]):
33 def __init__(
34 self,
35 obj_types: list[SearchObjType] | None = None,
36 filters: GeneralFilterDict | None = None,
37 ) -> None:
38 self._obj_types = obj_types
39 super().__init__(filters=filters)
42class ComplexGeneralFilter(ComplexFilter[GeneralDocumentKey]):
43 def __init__(
44 self,
45 relationship: Relationship | None = None,
46 obj_types: list[SearchObjType] | None = None,
47 filters: GeneralFilterDict | None = None,
48 ) -> None:
49 self._obj_types = obj_types
50 super().__init__(relationship=relationship, filters=filters)
52 @override
53 def _extra_filters(self) -> dict[str, FilterType]:
54 obj_types = self._obj_types
55 if not obj_types:
56 return {}
57 if len(obj_types) == 1:
58 return {GeneralDocumentKey.OBJ_TYPE.value: obj_types[0].value}
59 obj_types_str = "[" + ", ".join(t.value for t in obj_types) + "]"
60 return {GeneralDocumentKey.OBJ_TYPE.value: obj_types_str}
62 @override
63 def _prepare(self, friend_search: AppFriendSearch) -> None:
64 """Fetch friend UIDs and inject them as a list filter."""
65 if self.relationship is None:
66 return
68 relatinship = self.relationship
69 if not relatinship.relation_type.is_friends:
70 return
72 # Fetch friend IDs from the friend collection
73 friend_uids = friend_search.get_friend_uids(self.relationship.uid)
75 if friend_uids:
76 self.add_filter(GeneralDocumentKey.UID, friend_uids)
77 else:
78 # If no friends, force 0 results by filtering for a non-existent ID
79 self.add_filter(GeneralDocumentKey.UID, "__EMPTY_FRIEND_LIST__")