2020-06-11 00:54:34 +02:00
|
|
|
import datetime
|
2018-05-16 03:35:48 +02:00
|
|
|
from datetime import timedelta
|
2020-06-11 00:54:34 +02:00
|
|
|
from typing import Any, Dict
|
2020-05-26 07:16:25 +02:00
|
|
|
from unittest import mock
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2020-06-11 00:54:34 +02:00
|
|
|
from django.utils.timezone import now as timezone_now
|
|
|
|
|
2022-04-14 23:48:28 +02:00
|
|
|
from zerver.actions.users import do_deactivate_user
|
2022-09-16 18:12:20 +02:00
|
|
|
from zerver.lib.presence import get_presence_dict_by_realm
|
2020-06-11 00:54:34 +02:00
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
2023-03-01 07:34:25 +01:00
|
|
|
from zerver.lib.test_helpers import make_client, reset_email_visibility_to_everyone_in_zulip_realm
|
2017-03-02 09:52:17 +01:00
|
|
|
from zerver.lib.timestamp import datetime_to_timestamp
|
2016-09-13 23:45:39 +02:00
|
|
|
from zerver.models import (
|
2017-09-08 17:55:46 +02:00
|
|
|
PushDeviceToken,
|
2016-09-13 23:45:39 +02:00
|
|
|
UserActivity,
|
2018-05-10 01:54:45 +02:00
|
|
|
UserActivityInterval,
|
2017-02-19 16:43:32 +01:00
|
|
|
UserPresence,
|
2020-06-11 00:54:34 +02:00
|
|
|
UserProfile,
|
2016-09-13 23:45:39 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2017-03-08 12:53:26 +01:00
|
|
|
class TestClientModel(ZulipTestCase):
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_client_stringification(self) -> None:
|
2021-02-12 08:19:30 +01:00
|
|
|
"""
|
2017-10-27 09:06:40 +02:00
|
|
|
This test is designed to cover __str__ method for Client.
|
2021-02-12 08:19:30 +01:00
|
|
|
"""
|
2021-02-12 08:20:45 +01:00
|
|
|
client = make_client("some_client")
|
2023-03-08 22:18:59 +01:00
|
|
|
self.assertEqual(repr(client), "<Client: some_client>")
|
2017-03-08 12:53:26 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2017-02-19 16:43:32 +01:00
|
|
|
class UserPresenceModelTests(ZulipTestCase):
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_date_logic(self) -> None:
|
2017-02-19 16:43:32 +01:00
|
|
|
UserPresence.objects.all().delete()
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.example_user("hamlet")
|
2017-05-07 19:39:30 +02:00
|
|
|
email = user_profile.email
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 0)
|
2017-02-19 16:43:32 +01:00
|
|
|
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user_profile)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "active"})
|
2017-02-19 16:43:32 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2020-02-02 18:22:19 +01:00
|
|
|
slim_presence = False
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id, slim_presence)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 1)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(presence_dct[email]["website"]["status"], "active")
|
2017-02-19 16:43:32 +01:00
|
|
|
|
2020-02-02 18:22:19 +01:00
|
|
|
slim_presence = True
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id, slim_presence)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 1)
|
2020-02-07 14:50:30 +01:00
|
|
|
info = presence_dct[str(user_profile.id)]
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(info.keys()), {"active_timestamp"})
|
2020-02-02 18:22:19 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def back_date(num_weeks: int) -> None:
|
2017-02-19 16:43:32 +01:00
|
|
|
user_presence = UserPresence.objects.filter(user_profile=user_profile)[0]
|
2017-04-15 04:03:56 +02:00
|
|
|
user_presence.timestamp = timezone_now() - datetime.timedelta(weeks=num_weeks)
|
2017-02-19 16:43:32 +01:00
|
|
|
user_presence.save()
|
|
|
|
|
|
|
|
# Simulate the presence being a week old first. Nothing should change.
|
|
|
|
back_date(num_weeks=1)
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 1)
|
2017-02-19 16:43:32 +01:00
|
|
|
|
|
|
|
# If the UserPresence row is three weeks old, we ignore it.
|
|
|
|
back_date(num_weeks=3)
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 0)
|
2017-02-19 16:43:32 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_push_tokens(self) -> None:
|
2017-09-08 17:55:46 +02:00
|
|
|
UserPresence.objects.all().delete()
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.example_user("hamlet")
|
2017-09-08 17:55:46 +02:00
|
|
|
email = user_profile.email
|
|
|
|
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user_profile)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "active"})
|
2017-09-08 17:55:46 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def pushable() -> bool:
|
2022-09-16 18:12:20 +02:00
|
|
|
presence_dct = get_presence_dict_by_realm(user_profile.realm_id)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(presence_dct, 1)
|
2021-02-12 08:20:45 +01:00
|
|
|
return presence_dct[email]["website"]["pushable"]
|
2017-09-08 17:55:46 +02:00
|
|
|
|
|
|
|
self.assertFalse(pushable())
|
|
|
|
|
|
|
|
user_profile.enable_offline_push_notifications = True
|
|
|
|
user_profile.save()
|
|
|
|
|
|
|
|
self.assertFalse(pushable())
|
|
|
|
|
|
|
|
PushDeviceToken.objects.create(
|
|
|
|
user=user_profile,
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
kind=PushDeviceToken.APNS,
|
2017-09-08 17:55:46 +02:00
|
|
|
)
|
|
|
|
self.assertTrue(pushable())
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2016-09-13 23:45:39 +02:00
|
|
|
class UserPresenceTests(ZulipTestCase):
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_invalid_presence(self) -> None:
|
2020-03-06 18:40:46 +01:00
|
|
|
user = self.example_user("hamlet")
|
|
|
|
self.login_user(user)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "foo"})
|
|
|
|
self.assert_json_error(result, "Invalid status: foo")
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_set_idle(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
client = "website"
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
othello = self.example_user("othello")
|
2020-03-12 14:17:25 +01:00
|
|
|
|
|
|
|
self.login_user(hamlet)
|
2020-03-06 18:40:46 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
params = dict(status="idle")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["presences"][hamlet.email][client]["status"], "idle")
|
|
|
|
self.assertIn("timestamp", json["presences"][hamlet.email][client])
|
|
|
|
self.assertIsInstance(json["presences"][hamlet.email][client]["timestamp"], int)
|
|
|
|
self.assertEqual(set(json["presences"].keys()), {hamlet.email})
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2020-03-12 14:17:25 +01:00
|
|
|
self.login_user(othello)
|
2021-02-12 08:20:45 +01:00
|
|
|
params = dict(status="idle", slim_presence="true")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
presences = json["presences"]
|
2020-02-07 14:50:30 +01:00
|
|
|
self.assertEqual(
|
|
|
|
set(presences.keys()),
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
{str(hamlet.id), str(othello.id)},
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
|
|
|
hamlet_info = presences[str(hamlet.id)]
|
|
|
|
othello_info = presences[str(othello.id)]
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(hamlet_info.keys()), {"idle_timestamp"})
|
|
|
|
self.assertEqual(set(othello_info.keys()), {"idle_timestamp"})
|
2020-02-07 14:50:30 +01:00
|
|
|
|
|
|
|
self.assertGreaterEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
othello_info["idle_timestamp"],
|
|
|
|
hamlet_info["idle_timestamp"],
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_set_active(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
othello = self.example_user("othello")
|
2020-03-12 14:17:25 +01:00
|
|
|
|
|
|
|
self.login_user(hamlet)
|
2021-02-12 08:20:45 +01:00
|
|
|
client = "website"
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
params = dict(status="idle")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
response_dict = self.assert_json_success(result)
|
2020-02-07 14:50:30 +01:00
|
|
|
|
2022-06-07 01:37:01 +02:00
|
|
|
self.assertEqual(response_dict["presences"][hamlet.email][client]["status"], "idle")
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("othello")
|
|
|
|
params = dict(status="idle")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2020-02-07 14:50:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["presences"][othello.email][client]["status"], "idle")
|
|
|
|
self.assertEqual(json["presences"][hamlet.email][client]["status"], "idle")
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
params = dict(status="active")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2020-02-07 14:50:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["presences"][othello.email][client]["status"], "active")
|
|
|
|
self.assertEqual(json["presences"][hamlet.email][client]["status"], "idle")
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2020-02-07 14:50:30 +01:00
|
|
|
self.login_user(hamlet)
|
2021-02-12 08:20:45 +01:00
|
|
|
params = dict(status="active", slim_presence="true")
|
2020-02-07 14:50:30 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", params)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2020-02-07 14:50:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
presences = json["presences"]
|
2020-02-07 14:50:30 +01:00
|
|
|
self.assertEqual(
|
|
|
|
set(presences.keys()),
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
{str(hamlet.id), str(othello.id)},
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
|
|
|
othello_info = presences[str(othello.id)]
|
|
|
|
hamlet_info = presences[str(hamlet.id)]
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
set(othello_info.keys()),
|
2021-02-12 08:20:45 +01:00
|
|
|
{"active_timestamp"},
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
set(hamlet_info.keys()),
|
2021-02-12 08:20:45 +01:00
|
|
|
{"active_timestamp"},
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
self.assertGreaterEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
hamlet_info["active_timestamp"],
|
|
|
|
othello_info["active_timestamp"],
|
2020-02-07 14:50:30 +01:00
|
|
|
)
|
|
|
|
|
2018-11-16 17:08:09 +01:00
|
|
|
@mock.patch("stripe.Customer.list", return_value=[])
|
|
|
|
def test_new_user_input(self, unused_mock: mock.Mock) -> None:
|
2018-05-10 01:54:45 +02:00
|
|
|
"""Mostly a test for UserActivityInterval"""
|
|
|
|
user_profile = self.example_user("hamlet")
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("hamlet")
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assertEqual(UserActivityInterval.objects.filter(user_profile=user_profile).count(), 0)
|
|
|
|
time_zero = timezone_now().replace(microsecond=0)
|
2021-02-12 08:20:45 +01:00
|
|
|
with mock.patch("zerver.views.presence.timezone_now", return_value=time_zero):
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "active", "new_user_input": "true"}
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(UserActivityInterval.objects.filter(user_profile=user_profile).count(), 1)
|
|
|
|
interval = UserActivityInterval.objects.get(user_profile=user_profile)
|
|
|
|
self.assertEqual(interval.start, time_zero)
|
|
|
|
self.assertEqual(interval.end, time_zero + UserActivityInterval.MIN_INTERVAL_LENGTH)
|
|
|
|
|
|
|
|
second_time = time_zero + timedelta(seconds=600)
|
|
|
|
# Extent the interval
|
2021-02-12 08:20:45 +01:00
|
|
|
with mock.patch("zerver.views.presence.timezone_now", return_value=second_time):
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "active", "new_user_input": "true"}
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(UserActivityInterval.objects.filter(user_profile=user_profile).count(), 1)
|
|
|
|
interval = UserActivityInterval.objects.get(user_profile=user_profile)
|
|
|
|
self.assertEqual(interval.start, time_zero)
|
|
|
|
self.assertEqual(interval.end, second_time + UserActivityInterval.MIN_INTERVAL_LENGTH)
|
|
|
|
|
|
|
|
third_time = time_zero + timedelta(seconds=6000)
|
2021-02-12 08:20:45 +01:00
|
|
|
with mock.patch("zerver.views.presence.timezone_now", return_value=third_time):
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "active", "new_user_input": "true"}
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(UserActivityInterval.objects.filter(user_profile=user_profile).count(), 2)
|
2021-02-12 08:20:45 +01:00
|
|
|
interval = UserActivityInterval.objects.filter(user_profile=user_profile).order_by("start")[
|
2021-02-12 08:19:30 +01:00
|
|
|
0
|
|
|
|
]
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assertEqual(interval.start, time_zero)
|
|
|
|
self.assertEqual(interval.end, second_time + UserActivityInterval.MIN_INTERVAL_LENGTH)
|
2021-02-12 08:20:45 +01:00
|
|
|
interval = UserActivityInterval.objects.filter(user_profile=user_profile).order_by("start")[
|
2021-02-12 08:19:30 +01:00
|
|
|
1
|
|
|
|
]
|
2018-05-10 01:54:45 +02:00
|
|
|
self.assertEqual(interval.start, third_time)
|
|
|
|
self.assertEqual(interval.end, third_time + UserActivityInterval.MIN_INTERVAL_LENGTH)
|
|
|
|
|
2018-05-16 03:52:18 +02:00
|
|
|
# Now test /activity with actual data
|
|
|
|
user_profile.is_staff = True
|
|
|
|
user_profile.save()
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_get("/activity")
|
2018-05-16 03:52:18 +02:00
|
|
|
self.assertEqual(result.status_code, 200)
|
|
|
|
|
2018-03-17 00:23:38 +01:00
|
|
|
def test_filter_presence_idle_user_ids(self) -> None:
|
|
|
|
user_profile = self.example_user("hamlet")
|
2022-04-14 23:50:10 +02:00
|
|
|
from zerver.actions.message_send import filter_presence_idle_user_ids
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("hamlet")
|
2018-03-17 00:23:38 +01:00
|
|
|
|
|
|
|
self.assertEqual(filter_presence_idle_user_ids({user_profile.id}), [user_profile.id])
|
2021-02-12 08:20:45 +01:00
|
|
|
self.client_post("/json/users/me/presence", {"status": "idle"})
|
2018-03-17 00:23:38 +01:00
|
|
|
self.assertEqual(filter_presence_idle_user_ids({user_profile.id}), [user_profile.id])
|
2019-12-11 01:58:44 +01:00
|
|
|
|
|
|
|
# Active presence from the mobile app doesn't count
|
2021-02-12 08:19:30 +01:00
|
|
|
self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "active"}, HTTP_USER_AGENT="ZulipMobile/1.0"
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2019-12-11 01:58:44 +01:00
|
|
|
self.assertEqual(filter_presence_idle_user_ids({user_profile.id}), [user_profile.id])
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.client_post("/json/users/me/presence", {"status": "active"})
|
2018-03-17 00:23:38 +01:00
|
|
|
self.assertEqual(filter_presence_idle_user_ids({user_profile.id}), [])
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_no_mit(self) -> None:
|
2016-09-13 23:45:39 +02:00
|
|
|
"""Zephyr mirror realms such as MIT never get a list of users"""
|
2021-02-12 08:20:45 +01:00
|
|
|
user = self.mit_user("espuser")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "idle"}, subdomain="zephyr")
|
2022-06-07 01:37:01 +02:00
|
|
|
response_dict = self.assert_json_success(result)
|
|
|
|
self.assertEqual(response_dict["presences"], {})
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_mirror_presence(self) -> None:
|
2016-09-13 23:45:39 +02:00
|
|
|
"""Zephyr mirror realms find out the status of their mirror bot"""
|
2021-02-12 08:20:45 +01:00
|
|
|
user_profile = self.mit_user("espuser")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user_profile)
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def post_presence() -> Dict[str, Any]:
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "idle"}, subdomain="zephyr"
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2016-09-13 23:45:39 +02:00
|
|
|
return json
|
|
|
|
|
|
|
|
json = post_presence()
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["zephyr_mirror_active"], False)
|
2016-09-13 23:45:39 +02:00
|
|
|
|
|
|
|
self._simulate_mirror_activity_for_user(user_profile)
|
|
|
|
json = post_presence()
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["zephyr_mirror_active"], True)
|
2016-09-13 23:45:39 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def _simulate_mirror_activity_for_user(self, user_profile: UserProfile) -> None:
|
2017-04-15 04:03:56 +02:00
|
|
|
last_visit = timezone_now()
|
2021-02-12 08:20:45 +01:00
|
|
|
client = make_client("zephyr_mirror")
|
2016-09-13 23:45:39 +02:00
|
|
|
|
|
|
|
UserActivity.objects.get_or_create(
|
|
|
|
user_profile=user_profile,
|
|
|
|
client=client,
|
2021-02-12 08:20:45 +01:00
|
|
|
query="get_events",
|
2016-09-13 23:45:39 +02:00
|
|
|
count=2,
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
last_visit=last_visit,
|
2016-09-13 23:45:39 +02:00
|
|
|
)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_same_realm(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
espuser = self.mit_user("espuser")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(espuser)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.client_post("/json/users/me/presence", {"status": "idle"}, subdomain="zephyr")
|
2017-04-18 03:23:32 +02:00
|
|
|
self.logout()
|
2016-09-13 23:45:39 +02:00
|
|
|
|
|
|
|
# Ensure we don't see hamlet@zulip.com information leakage
|
2021-02-12 08:20:45 +01:00
|
|
|
hamlet = self.example_user("hamlet")
|
2020-03-12 14:17:25 +01:00
|
|
|
self.login_user(hamlet)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "idle"})
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(json["presences"][hamlet.email]["website"]["status"], "idle")
|
2020-03-12 14:17:25 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
json["presences"].keys(),
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
{hamlet.email},
|
2020-03-12 14:17:25 +01:00
|
|
|
)
|
2017-02-11 08:38:16 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2017-02-11 08:38:16 +01:00
|
|
|
class SingleUserPresenceTests(ZulipTestCase):
|
2020-03-18 15:19:03 +01:00
|
|
|
def test_email_access(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
user = self.example_user("hamlet")
|
2020-03-18 15:19:03 +01:00
|
|
|
self.login_user(user)
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
other_user = self.example_user("othello")
|
|
|
|
other_user.email = "email@zulip.com"
|
|
|
|
other_user.delivery_email = "delivery_email@zulip.com"
|
2020-03-18 15:19:03 +01:00
|
|
|
other_user.save()
|
|
|
|
|
|
|
|
# Note that we don't leak any info on delivery emails.
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_get("/json/users/delivery_email@zulip.com/presence")
|
|
|
|
self.assert_json_error(result, "No such user")
|
2020-03-18 15:19:03 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_get("/json/users/not_even_in_realm@zulip.com/presence")
|
|
|
|
self.assert_json_error(result, "No such user")
|
2020-03-18 15:19:03 +01:00
|
|
|
|
|
|
|
# For a known email, we may simply complain about lack of presence info.
|
|
|
|
result = self.client_get("/json/users/email@zulip.com/presence")
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "No presence data for email@zulip.com")
|
2020-03-18 15:19:03 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_single_user_get(self) -> None:
|
2023-03-01 07:34:25 +01:00
|
|
|
reset_email_visibility_to_everyone_in_zulip_realm()
|
2017-02-11 08:38:16 +01:00
|
|
|
|
docs: Add missing space to compound verbs “log in”, “set up”, etc.
Noun: backup, checkout, cleanup, login, logout, setup, shutdown, signup,
timeout.
Verb: back up, check out, clean up, log in, log out, set up, shut
down, sign up, time out.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-25 23:05:38 +02:00
|
|
|
# First, we set up the test with some data
|
2020-03-10 11:48:26 +01:00
|
|
|
user = self.example_user("othello")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/users/me/presence", {"status": "active"})
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_post(
|
2021-02-12 08:20:45 +01:00
|
|
|
"/json/users/me/presence", {"status": "active"}, HTTP_USER_AGENT="ZulipDesktop/1.0"
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
|
|
|
result = self.api_post(
|
|
|
|
user,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
{"status": "idle"},
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipAndroid/1.0",
|
|
|
|
)
|
2017-02-11 08:38:16 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
# Check some error conditions
|
|
|
|
result = self.client_get("/json/users/nonexistence@zulip.com/presence")
|
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
|
|
|
result = self.client_get("/json/users/cordelia@zulip.com/presence")
|
|
|
|
self.assert_json_error(result, "No presence data for cordelia@zulip.com")
|
|
|
|
|
2021-01-04 19:36:00 +01:00
|
|
|
cordelia = self.example_user("cordelia")
|
|
|
|
result = self.client_get(f"/json/users/{cordelia.id}/presence")
|
|
|
|
self.assert_json_error(result, f"No presence data for {cordelia.id}")
|
|
|
|
|
2021-03-27 06:02:12 +01:00
|
|
|
do_deactivate_user(self.example_user("cordelia"), acting_user=None)
|
2017-02-11 08:38:16 +01:00
|
|
|
result = self.client_get("/json/users/cordelia@zulip.com/presence")
|
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
2021-01-04 19:36:00 +01:00
|
|
|
result = self.client_get(f"/json/users/{cordelia.id}/presence")
|
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
2019-07-20 23:38:05 +02:00
|
|
|
result = self.client_get("/json/users/default-bot@zulip.com/presence")
|
2017-04-12 20:50:23 +02:00
|
|
|
self.assert_json_error(result, "Presence is not supported for bot users.")
|
2017-02-11 08:38:16 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
sipbtest = self.mit_user("sipbtest")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(sipbtest)
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.client_get("/json/users/othello@zulip.com/presence", subdomain="zephyr")
|
2017-02-11 08:38:16 +01:00
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
2021-01-04 19:36:00 +01:00
|
|
|
othello = self.example_user("othello")
|
|
|
|
result = self.client_get(f"/json/users/{othello.id}/presence", subdomain="zephyr")
|
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
2017-02-11 08:38:16 +01:00
|
|
|
# Then, we check everything works
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("hamlet")
|
2017-02-11 08:38:16 +01:00
|
|
|
result = self.client_get("/json/users/othello@zulip.com/presence")
|
2022-06-07 01:37:01 +02:00
|
|
|
result_dict = self.assert_json_success(result)
|
2017-03-02 09:52:17 +01:00
|
|
|
self.assertEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
set(result_dict["presence"].keys()), {"ZulipAndroid", "website", "aggregated"}
|
2021-01-04 19:36:00 +01:00
|
|
|
)
|
|
|
|
self.assertEqual(set(result_dict["presence"]["website"].keys()), {"status", "timestamp"})
|
|
|
|
|
|
|
|
result = self.client_get(f"/json/users/{othello.id}/presence")
|
2022-06-07 01:37:01 +02:00
|
|
|
result_dict = self.assert_json_success(result)
|
2021-01-04 19:36:00 +01:00
|
|
|
self.assertEqual(
|
|
|
|
set(result_dict["presence"].keys()), {"ZulipAndroid", "website", "aggregated"}
|
2021-02-12 08:19:30 +01:00
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(result_dict["presence"]["website"].keys()), {"status", "timestamp"})
|
2017-03-02 09:52:17 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_ping_only(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("othello")
|
2017-03-31 01:46:45 +02:00
|
|
|
req = dict(
|
2021-02-12 08:20:45 +01:00
|
|
|
status="active",
|
|
|
|
ping_only="true",
|
2017-03-31 01:46:45 +02:00
|
|
|
)
|
|
|
|
result = self.client_post("/json/users/me/presence", req)
|
2022-06-07 01:37:01 +02:00
|
|
|
self.assertEqual(self.assert_json_success(result)["msg"], "")
|
2017-03-02 09:52:17 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2017-03-02 09:52:17 +01:00
|
|
|
class UserPresenceAggregationTests(ZulipTestCase):
|
2021-02-12 08:19:30 +01:00
|
|
|
def _send_presence_for_aggregated_tests(
|
|
|
|
self, user: UserProfile, status: str, validate_time: datetime.datetime
|
|
|
|
) -> Dict[str, Dict[str, Any]]:
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user)
|
2021-02-12 08:20:45 +01:00
|
|
|
timezone_util = "zerver.views.presence.timezone_now"
|
2017-03-02 09:52:17 +01:00
|
|
|
with mock.patch(timezone_util, return_value=validate_time - datetime.timedelta(seconds=5)):
|
2021-02-12 08:20:45 +01:00
|
|
|
self.client_post("/json/users/me/presence", {"status": status})
|
2017-03-02 09:52:17 +01:00
|
|
|
with mock.patch(timezone_util, return_value=validate_time - datetime.timedelta(seconds=2)):
|
2021-02-12 08:19:30 +01:00
|
|
|
self.api_post(
|
|
|
|
user,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
{"status": status},
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipAndroid/1.0",
|
|
|
|
)
|
2017-03-02 09:52:17 +01:00
|
|
|
with mock.patch(timezone_util, return_value=validate_time - datetime.timedelta(seconds=7)):
|
2021-02-12 08:19:30 +01:00
|
|
|
latest_result = self.api_post(
|
|
|
|
user,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
{"status": status},
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipIOS/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
latest_result_dict = self.assert_json_success(latest_result)
|
2017-03-18 10:41:57 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
latest_result_dict["presences"][user.email]["aggregated"],
|
2017-03-18 10:41:57 +01:00
|
|
|
{
|
2021-02-12 08:20:45 +01:00
|
|
|
"status": status,
|
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=2)),
|
|
|
|
"client": "ZulipAndroid",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
},
|
2017-03-18 10:41:57 +01:00
|
|
|
)
|
2020-03-12 14:17:25 +01:00
|
|
|
|
2020-06-09 00:25:09 +02:00
|
|
|
result = self.client_get(f"/json/users/{user.email}/presence")
|
2022-06-07 01:37:01 +02:00
|
|
|
return self.assert_json_success(result)
|
2017-03-02 09:52:17 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_aggregated_info(self) -> None:
|
2020-03-10 11:48:26 +01:00
|
|
|
user = self.example_user("othello")
|
2017-04-15 04:03:56 +02:00
|
|
|
validate_time = timezone_now()
|
2021-02-12 08:20:45 +01:00
|
|
|
self._send_presence_for_aggregated_tests(user, "active", validate_time)
|
2021-02-12 08:19:30 +01:00
|
|
|
with mock.patch(
|
2021-02-12 08:20:45 +01:00
|
|
|
"zerver.views.presence.timezone_now",
|
2021-02-12 08:19:30 +01:00
|
|
|
return_value=validate_time - datetime.timedelta(seconds=1),
|
|
|
|
):
|
|
|
|
result = self.api_post(
|
|
|
|
user,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
{"status": "active"},
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipTestDev/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
result_dict = self.assert_json_success(result)
|
2017-03-18 10:41:57 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict["presences"][user.email]["aggregated"],
|
2017-03-18 10:41:57 +01:00
|
|
|
{
|
2021-02-12 08:20:45 +01:00
|
|
|
"status": "active",
|
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=1)),
|
|
|
|
"client": "ZulipTestDev",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
},
|
2017-03-18 10:41:57 +01:00
|
|
|
)
|
|
|
|
|
2023-01-02 20:50:23 +01:00
|
|
|
def test_aggregated_presence_active(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
user = self.example_user("othello")
|
2017-04-15 04:03:56 +02:00
|
|
|
validate_time = timezone_now()
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict = self._send_presence_for_aggregated_tests(user, "active", validate_time)
|
2017-03-02 09:52:17 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict["presence"]["aggregated"],
|
2017-03-02 09:52:17 +01:00
|
|
|
{
|
|
|
|
"status": "active",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=2)),
|
|
|
|
},
|
2017-03-02 09:52:17 +01:00
|
|
|
)
|
|
|
|
|
2023-01-02 20:50:23 +01:00
|
|
|
def test_aggregated_presence_idle(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
user = self.example_user("othello")
|
2017-04-15 04:03:56 +02:00
|
|
|
validate_time = timezone_now()
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict = self._send_presence_for_aggregated_tests(user, "idle", validate_time)
|
2017-03-02 09:52:17 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict["presence"]["aggregated"],
|
2017-03-02 09:52:17 +01:00
|
|
|
{
|
|
|
|
"status": "idle",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=2)),
|
|
|
|
},
|
2017-03-02 09:52:17 +01:00
|
|
|
)
|
|
|
|
|
2023-01-02 20:50:23 +01:00
|
|
|
def test_aggregated_presence_mixed(self) -> None:
|
2020-03-10 11:48:26 +01:00
|
|
|
user = self.example_user("othello")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user)
|
2017-04-15 04:03:56 +02:00
|
|
|
validate_time = timezone_now()
|
2021-02-12 08:19:30 +01:00
|
|
|
with mock.patch(
|
2021-02-12 08:20:45 +01:00
|
|
|
"zerver.views.presence.timezone_now",
|
2021-02-12 08:19:30 +01:00
|
|
|
return_value=validate_time - datetime.timedelta(seconds=3),
|
|
|
|
):
|
|
|
|
self.api_post(
|
|
|
|
user,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
{"status": "active"},
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipTestDev/1.0",
|
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict = self._send_presence_for_aggregated_tests(user, "idle", validate_time)
|
2017-03-02 09:52:17 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict["presence"]["aggregated"],
|
2017-03-02 09:52:17 +01:00
|
|
|
{
|
|
|
|
"status": "idle",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=2)),
|
|
|
|
},
|
2017-03-02 09:52:17 +01:00
|
|
|
)
|
2017-03-06 12:25:37 +01:00
|
|
|
|
2023-01-02 20:50:23 +01:00
|
|
|
def test_aggregated_presence_offline(self) -> None:
|
2020-03-10 11:48:26 +01:00
|
|
|
user = self.example_user("othello")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(user)
|
2017-04-15 04:03:56 +02:00
|
|
|
validate_time = timezone_now()
|
2017-03-06 12:25:37 +01:00
|
|
|
with self.settings(OFFLINE_THRESHOLD_SECS=1):
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict = self._send_presence_for_aggregated_tests(user, "idle", validate_time)
|
2017-03-06 12:25:37 +01:00
|
|
|
self.assertDictEqual(
|
2021-02-12 08:20:45 +01:00
|
|
|
result_dict["presence"]["aggregated"],
|
2017-03-06 12:25:37 +01:00
|
|
|
{
|
|
|
|
"status": "offline",
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
"timestamp": datetime_to_timestamp(validate_time - datetime.timedelta(seconds=2)),
|
|
|
|
},
|
2017-03-06 12:25:37 +01:00
|
|
|
)
|
2018-10-14 19:22:04 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2018-10-14 19:22:04 +02:00
|
|
|
class GetRealmStatusesTest(ZulipTestCase):
|
|
|
|
def test_get_statuses(self) -> None:
|
docs: Add missing space to compound verbs “log in”, “set up”, etc.
Noun: backup, checkout, cleanup, login, logout, setup, shutdown, signup,
timeout.
Verb: back up, check out, clean up, log in, log out, set up, shut
down, sign up, time out.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2021-04-25 23:05:38 +02:00
|
|
|
# Set up the test by simulating users reporting their presence data.
|
2020-02-02 17:29:05 +01:00
|
|
|
othello = self.example_user("othello")
|
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
othello,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="active"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipAndroid/1.0",
|
|
|
|
)
|
2018-10-14 19:22:04 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
hamlet,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="idle"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipDesktop/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(json["presences"].keys()), {hamlet.email, othello.email})
|
2020-02-02 17:29:05 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
hamlet,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="active", slim_presence="true"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipDesktop/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(json["presences"].keys()), {str(hamlet.id), str(othello.id)})
|
2018-10-14 19:22:04 +02:00
|
|
|
|
|
|
|
# Check that a bot can fetch the presence data for the realm.
|
2020-03-10 11:48:26 +01:00
|
|
|
result = self.api_get(self.example_user("default_bot"), "/api/v1/realm/presence")
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(json["presences"].keys()), {hamlet.email, othello.email})
|
2020-05-01 20:39:26 +02:00
|
|
|
|
|
|
|
def test_presence_disabled(self) -> None:
|
|
|
|
# Disable presence status and test whether the presence
|
|
|
|
# is reported or not.
|
|
|
|
othello = self.example_user("othello")
|
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
othello.presence_enabled = False
|
|
|
|
hamlet.presence_enabled = True
|
2021-02-12 08:20:45 +01:00
|
|
|
othello.save(update_fields=["presence_enabled"])
|
|
|
|
hamlet.save(update_fields=["presence_enabled"])
|
2020-05-01 20:39:26 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
othello,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="active"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipAndroid/1.0",
|
|
|
|
)
|
2020-05-01 20:39:26 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
hamlet,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="idle"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipDesktop/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2020-05-01 20:39:26 +02:00
|
|
|
|
|
|
|
# Othello's presence status is disabled so it won't be reported.
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(json["presences"].keys()), {hamlet.email})
|
2020-05-01 20:39:26 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
result = self.api_post(
|
|
|
|
hamlet,
|
|
|
|
"/api/v1/users/me/presence",
|
2021-02-12 08:20:45 +01:00
|
|
|
dict(status="active", slim_presence="true"),
|
2021-02-12 08:19:30 +01:00
|
|
|
HTTP_USER_AGENT="ZulipDesktop/1.0",
|
|
|
|
)
|
2022-06-07 01:37:01 +02:00
|
|
|
json = self.assert_json_success(result)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertEqual(set(json["presences"].keys()), {str(hamlet.id)})
|