Coverage for functions \ flipdare \ firestore \ context \ group_member_context.py: 45%
77 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#
13from __future__ import annotations
15from typing import TYPE_CHECKING, Any, override
16from flipdare.app_types import DatabaseDict
17from flipdare.firestore.context._model_context import ModelContext
18from flipdare.firestore.context._model_context_factory import ModelContextFactory
19from flipdare.wrapper import (
20 GroupMemberWrapper,
21 GroupWrapper,
22 UserWrapper,
23)
25if TYPE_CHECKING:
26 from flipdare.manager.db_manager import DbManager
28__all__ = ["GroupMemberContextFactory", "GroupMemberContext"]
31class GroupMemberContextFactory(ModelContextFactory[GroupMemberWrapper, "GroupMemberContext"]):
33 def __init__(self, db_manager: DbManager | None = None) -> None:
34 super().__init__(db_manager=db_manager)
36 @override
37 def create(self, obj: Any) -> GroupMemberContext | None:
38 if isinstance(obj, GroupMemberContext):
39 return obj
40 if isinstance(obj, GroupMemberWrapper):
41 return self._from_model(obj)
42 if isinstance(obj, str):
43 return self._from_id(obj)
44 obj_data: DatabaseDict = obj # set explicity type for type checkers.
45 return self._from_data(obj_data)
47 @override
48 def _from_id(self, doc_id: str) -> GroupMemberContext | None:
49 # NOTE: from_id is inherited and does not support sub-collections
50 raise RuntimeError(
51 f"GroupMemberContextFactory does not support from_id for doc_id: {doc_id}",
52 )
54 @override
55 def _from_data(self, data: DatabaseDict) -> GroupMemberContext | None:
56 try:
57 # from_dict returns PersistedWrapper[GroupMemberWrapper]
58 member: GroupMemberWrapper = GroupMemberWrapper.from_dict(data)
59 return self._from_model(member)
60 except Exception:
61 return None
63 @override
64 def _from_model(
65 self,
66 model: GroupMemberWrapper,
67 ) -> GroupMemberContext | None:
69 group = self.get_group(model.gid) # Returns GroupWrapper | None
70 user = self.get_user(model.uid) # Returns UserWrapper | None
71 owner: UserWrapper | None = None
72 if group is not None:
73 owner = self.get_user(group.model.uid)
75 return GroupMemberContext(group=group, user=user, owner=owner)
78class GroupMemberContext(ModelContext):
80 def __init__(
81 self,
82 group: GroupWrapper | None = None,
83 user: UserWrapper | None = None,
84 owner: UserWrapper | None = None,
85 ) -> None:
86 self._group = group
87 self._user = user
88 self._owner = owner
90 # Call super().__init__() LAST - it calls validate()
91 super().__init__()
93 @property
94 def group(self) -> GroupWrapper:
95 self._require_valid("access group")
96 return self._group # type: ignore
98 @property
99 def user(self) -> UserWrapper:
100 self._require_valid("access user")
101 return self._user # type: ignore
103 @property
104 def owner(self) -> UserWrapper:
105 self._require_valid("access owner")
106 return self._owner # type: ignore
108 @property
109 def group_id(self) -> str:
110 self._require_valid("access group_id")
111 assert self._group is not None # for mypy
112 return self._group.doc_id
114 @property
115 @override
116 def doc_id(self) -> str:
117 return self.group.doc_id
119 @override
120 def validate(self) -> bool:
121 """Validate that all required models exist and have doc_ids."""
122 return self._is_model_valid(self._group) and self._is_model_valid(self._owner)
124 @property
125 @override
126 def _error_messages(self) -> list[str]:
127 """Build list of validation errors."""
128 errors: list[str] = []
129 if err := self._validate_model(self._group, "group"):
130 errors.append(err)
131 if err := self._validate_model(self._owner, "owner"):
132 errors.append(err)
133 return errors