2021-03-27 12:23:32 +01:00
|
|
|
from datetime import datetime, timezone
|
|
|
|
from unittest import mock
|
|
|
|
|
2021-04-10 19:32:22 +02:00
|
|
|
import orjson
|
|
|
|
|
2021-03-27 12:23:32 +01:00
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
|
|
|
from zerver.lib.timestamp import datetime_to_timestamp
|
2021-04-08 06:20:43 +02:00
|
|
|
from zerver.lib.user_mutes import get_mute_object, get_user_mutes
|
2021-04-10 19:32:22 +02:00
|
|
|
from zerver.models import RealmAuditLog
|
2021-03-27 12:23:32 +01:00
|
|
|
|
|
|
|
|
|
|
|
class MutedUsersTests(ZulipTestCase):
|
2021-04-07 19:20:46 +02:00
|
|
|
# Hamlet does the muting/unmuting, and Cordelia gets muted/unmuted.
|
2021-03-27 12:23:32 +01:00
|
|
|
def test_get_user_mutes(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
2021-03-27 12:23:32 +01:00
|
|
|
cordelia = self.example_user("cordelia")
|
|
|
|
|
2021-04-07 19:20:46 +02:00
|
|
|
muted_users = get_user_mutes(hamlet)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assertEqual(muted_users, [])
|
|
|
|
mute_time = datetime(2021, 1, 1, tzinfo=timezone.utc)
|
|
|
|
|
2021-04-07 19:33:10 +02:00
|
|
|
with mock.patch("zerver.views.muting.timezone_now", return_value=mute_time):
|
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
|
|
|
self.assert_json_success(result)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:20:46 +02:00
|
|
|
muted_users = get_user_mutes(hamlet)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assertEqual(len(muted_users), 1)
|
|
|
|
|
|
|
|
self.assertDictEqual(
|
|
|
|
muted_users[0],
|
|
|
|
{
|
|
|
|
"id": cordelia.id,
|
|
|
|
"timestamp": datetime_to_timestamp(mute_time),
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_add_muted_user_mute_self(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:20:46 +02:00
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(hamlet.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assert_json_error(result, "Cannot mute self")
|
|
|
|
|
|
|
|
def test_add_muted_user_mute_bot(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
|
|
|
bot_info = {
|
|
|
|
"full_name": "The Bot of Hamlet",
|
|
|
|
"short_name": "hambot",
|
|
|
|
"bot_type": "1",
|
|
|
|
}
|
|
|
|
result = self.client_post("/json/bots", bot_info)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
muted_id = result.json()["user_id"]
|
|
|
|
|
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(muted_id)
|
2021-04-07 19:20:46 +02:00
|
|
|
result = self.api_post(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
# Currently we do not allow muting bots. This is the error message
|
|
|
|
# from `access_user_by_id`.
|
|
|
|
self.assert_json_error(result, "No such user")
|
|
|
|
|
|
|
|
def test_add_muted_user_mute_twice(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
|
|
|
cordelia = self.example_user("cordelia")
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:33:10 +02:00
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
|
|
|
self.assert_json_success(result)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:20:46 +02:00
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assert_json_error(result, "User already muted")
|
|
|
|
|
|
|
|
def test_add_muted_user_valid_data(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
|
|
|
cordelia = self.example_user("cordelia")
|
2021-04-07 19:03:15 +02:00
|
|
|
mute_time = datetime(2021, 1, 1, tzinfo=timezone.utc)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:03:15 +02:00
|
|
|
with mock.patch("zerver.views.muting.timezone_now", return_value=mute_time):
|
2021-04-07 19:20:46 +02:00
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2021-04-07 19:03:15 +02:00
|
|
|
self.assertIn(
|
|
|
|
{
|
2021-04-07 19:20:46 +02:00
|
|
|
"id": cordelia.id,
|
2021-04-07 19:03:15 +02:00
|
|
|
"timestamp": datetime_to_timestamp(mute_time),
|
|
|
|
},
|
2021-04-07 19:20:46 +02:00
|
|
|
get_user_mutes(hamlet),
|
2021-04-07 19:03:15 +02:00
|
|
|
)
|
2021-04-08 06:20:43 +02:00
|
|
|
self.assertIsNotNone(get_mute_object(hamlet, cordelia))
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-10 19:32:22 +02:00
|
|
|
audit_log_entries = list(
|
|
|
|
RealmAuditLog.objects.filter(acting_user=hamlet, modified_user=hamlet).values_list(
|
|
|
|
"event_type", "event_time", "extra_data"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
self.assertEqual(len(audit_log_entries), 1)
|
|
|
|
audit_log_entry = audit_log_entries[0]
|
|
|
|
self.assertEqual(
|
|
|
|
audit_log_entry,
|
|
|
|
(
|
|
|
|
RealmAuditLog.USER_MUTED,
|
|
|
|
mute_time,
|
|
|
|
orjson.dumps({"muted_user_id": cordelia.id}).decode(),
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
2021-03-27 12:23:32 +01:00
|
|
|
def test_remove_muted_user_unmute_before_muting(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
|
|
|
cordelia = self.example_user("cordelia")
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-07 19:20:46 +02:00
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_delete(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
self.assert_json_error(result, "User is not muted")
|
|
|
|
|
|
|
|
def test_remove_muted_user_valid_data(self) -> None:
|
2021-04-07 19:20:46 +02:00
|
|
|
hamlet = self.example_user("hamlet")
|
|
|
|
self.login_user(hamlet)
|
|
|
|
cordelia = self.example_user("cordelia")
|
2021-04-07 19:03:15 +02:00
|
|
|
mute_time = datetime(2021, 1, 1, tzinfo=timezone.utc)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-10 19:32:22 +02:00
|
|
|
with mock.patch("zerver.views.muting.timezone_now", return_value=mute_time):
|
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_post(hamlet, url)
|
|
|
|
self.assert_json_success(result)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
2021-04-10 19:32:22 +02:00
|
|
|
with mock.patch("zerver.lib.actions.timezone_now", return_value=mute_time):
|
|
|
|
# To test that `RealmAuditLog` entry has correct `event_time`.
|
|
|
|
url = "/api/v1/users/me/muted_users/{}".format(cordelia.id)
|
|
|
|
result = self.api_delete(hamlet, url)
|
2021-03-27 12:23:32 +01:00
|
|
|
|
|
|
|
self.assert_json_success(result)
|
2021-04-07 19:03:15 +02:00
|
|
|
self.assertNotIn(
|
|
|
|
{
|
2021-04-07 19:20:46 +02:00
|
|
|
"id": cordelia.id,
|
2021-04-07 19:03:15 +02:00
|
|
|
"timestamp": datetime_to_timestamp(mute_time),
|
|
|
|
},
|
2021-04-07 19:20:46 +02:00
|
|
|
get_user_mutes(hamlet),
|
2021-04-07 19:03:15 +02:00
|
|
|
)
|
2021-04-08 06:20:43 +02:00
|
|
|
self.assertIsNone(get_mute_object(hamlet, cordelia))
|
2021-04-10 19:32:22 +02:00
|
|
|
|
|
|
|
audit_log_entries = list(
|
|
|
|
RealmAuditLog.objects.filter(acting_user=hamlet, modified_user=hamlet)
|
|
|
|
.values_list("event_type", "event_time", "extra_data")
|
|
|
|
.order_by("id")
|
|
|
|
)
|
|
|
|
self.assertEqual(len(audit_log_entries), 2)
|
|
|
|
audit_log_entry = audit_log_entries[1]
|
|
|
|
self.assertEqual(
|
|
|
|
audit_log_entry,
|
|
|
|
(
|
|
|
|
RealmAuditLog.USER_UNMUTED,
|
|
|
|
mute_time,
|
|
|
|
orjson.dumps({"unmuted_user_id": cordelia.id}).decode(),
|
|
|
|
),
|
|
|
|
)
|