user-status: Send `away=True` if `!presence_enabled` for user status.

We stop sending the `away=True` based on the user's `UserStatus`
object having `status=AWAY`, and instead send that value if
`!presence_enabled` for the user.

Third step in making user status `away` a deprecated way to access
`presence_enabled` for clients supporting older servers.

Part of transitioning from 'unavailable' user status feature to
'invisible mode' user presence feature.
This commit is contained in:
Lauryn Menard 2022-09-22 12:12:08 +02:00 committed by Tim Abbott
parent 7b128d6b1b
commit e36cfdb0a7
2 changed files with 19 additions and 8 deletions

View File

@ -17,7 +17,7 @@ class UserInfoDict(TypedDict, total=False):
class RawUserInfoDict(TypedDict):
user_profile_id: int
status: int
user_profile__presence_enabled: bool
status_text: str
emoji_name: str
emoji_code: str
@ -25,7 +25,10 @@ class RawUserInfoDict(TypedDict):
def format_user_status(row: RawUserInfoDict) -> UserInfoDict:
away = row["status"] == UserStatus.AWAY
# Deprecated way for clients to access the user's `presence_enabled`
# setting, with away != presence_enabled.
presence_enabled = row["user_profile__presence_enabled"]
away = not presence_enabled
status_text = row["status_text"]
emoji_name = row["emoji_name"]
emoji_code = row["emoji_code"]
@ -51,7 +54,7 @@ def get_user_status_dict(realm_id: int) -> Dict[str, UserInfoDict]:
user_profile__is_active=True,
)
.exclude(
Q(status=UserStatus.NORMAL)
Q(user_profile__presence_enabled=True)
& Q(status_text="")
& Q(emoji_name="")
& Q(emoji_code="")
@ -59,7 +62,7 @@ def get_user_status_dict(realm_id: int) -> Dict[str, UserInfoDict]:
)
.values(
"user_profile_id",
"status",
"user_profile__presence_enabled",
"status_text",
"emoji_name",
"emoji_code",

View File

@ -6,11 +6,16 @@ from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.user_status import UserInfoDict, get_user_status_dict, update_user_status
from zerver.models import UserProfile, UserStatus, get_client
AWAY = 1
def get_away_user_ids(realm_id: int) -> Set[int]:
user_dict = get_user_status_dict(realm_id)
return {int(user_id) for user_id in user_dict if user_dict[user_id].get("away")}
away_ids = set(
UserStatus.objects.filter(status=AWAY, user_profile__realm__id=realm_id).values_list(
"user_profile_id", flat=True
)
)
return away_ids
def user_status_info(user: UserProfile) -> UserInfoDict:
@ -61,10 +66,13 @@ class UserStatusTest(ZulipTestCase):
client_id=client2.id,
)
# The user's presence_enabled setting is not updated by
# update_user_status, so the away changes are no longer
# reflected in the object returned by get_user_status_dict.
# We test this below in test_endpoints.
self.assertEqual(
user_status_info(hamlet),
dict(
away=True,
status_text="out to lunch",
emoji_name="car",
emoji_code="1f697",