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

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# 

12 

13 

14from __future__ import annotations 

15 

16from typing import TYPE_CHECKING, override 

17 

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 

22 

23if TYPE_CHECKING: 

24 

25 from flipdare.search.db.app_friend_search import AppFriendSearch 

26 

27__all__ = ["ComplexGeneralFilter", "GeneralFilterDict"] 

28 

29type GeneralFilterDict = dict[GeneralDocumentKey, FilterType] 

30 

31 

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) 

40 

41 

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) 

51 

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} 

61 

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 

67 

68 relatinship = self.relationship 

69 if not relatinship.relation_type.is_friends: 

70 return 

71 

72 # Fetch friend IDs from the friend collection 

73 friend_uids = friend_search.get_friend_uids(self.relationship.uid) 

74 

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__")