2020-05-26 07:16:25 +02:00
|
|
|
from unittest import mock
|
2018-03-11 18:55:20 +01:00
|
|
|
|
2022-04-14 23:58:15 +02:00
|
|
|
from zerver.actions.create_realm import do_create_realm
|
2022-04-14 23:53:15 +02:00
|
|
|
from zerver.actions.create_user import do_create_user
|
2022-04-14 23:40:49 +02:00
|
|
|
from zerver.actions.realm_emoji import check_add_realm_emoji
|
2022-04-14 23:57:15 +02:00
|
|
|
from zerver.actions.realm_settings import do_set_realm_property
|
2022-04-14 23:48:28 +02:00
|
|
|
from zerver.actions.users import do_change_user_role
|
2021-12-03 03:11:54 +01:00
|
|
|
from zerver.lib.exceptions import JsonableError
|
2016-11-10 19:30:09 +01:00
|
|
|
from zerver.lib.test_classes import ZulipTestCase
|
2019-02-02 23:53:44 +01:00
|
|
|
from zerver.lib.test_helpers import get_test_image_file
|
2022-12-14 21:51:37 +01:00
|
|
|
from zerver.lib.upload.base import BadImageError
|
2019-05-04 04:47:44 +02:00
|
|
|
from zerver.models import Realm, RealmEmoji, UserProfile, get_realm
|
2016-06-03 02:46:57 +02:00
|
|
|
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2016-08-23 02:08:42 +02:00
|
|
|
class RealmEmojiTest(ZulipTestCase):
|
2018-03-11 18:55:20 +01:00
|
|
|
def create_test_emoji(self, name: str, author: UserProfile) -> RealmEmoji:
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as img_file:
|
2021-02-12 08:19:30 +01:00
|
|
|
realm_emoji = check_add_realm_emoji(
|
|
|
|
realm=author.realm, name=name, author=author, image_file=img_file
|
|
|
|
)
|
2018-03-11 18:55:20 +01:00
|
|
|
if realm_emoji is None:
|
2021-02-12 08:19:30 +01:00
|
|
|
raise Exception("Error creating test emoji.") # nocoverage
|
2018-03-11 18:55:20 +01:00
|
|
|
return realm_emoji
|
|
|
|
|
|
|
|
def create_test_emoji_with_no_author(self, name: str, realm: Realm) -> RealmEmoji:
|
2022-08-05 23:10:04 +02:00
|
|
|
realm_emoji = RealmEmoji.objects.create(realm=realm, name=name, file_name=name)
|
2018-03-11 18:55:20 +01:00
|
|
|
return realm_emoji
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_list(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author = self.example_user("iago")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.create_test_emoji("my_emoji", emoji_author)
|
2018-03-11 18:55:20 +01:00
|
|
|
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
response_dict = self.assert_json_success(result)
|
|
|
|
self.assert_length(response_dict["emoji"], 2)
|
2016-06-03 02:46:57 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_list_no_author(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
realm = get_realm("zulip")
|
|
|
|
realm_emoji = self.create_test_emoji_with_no_author("my_emoji", realm)
|
2018-03-11 18:55:20 +01:00
|
|
|
|
2016-12-20 15:41:30 +01:00
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
content = self.assert_json_success(result)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(content["emoji"], 2)
|
2018-03-11 18:55:20 +01:00
|
|
|
test_emoji = content["emoji"][str(realm_emoji.id)]
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertIsNone(test_emoji["author_id"])
|
2016-12-20 15:41:30 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_list_admins_only(self) -> None:
|
2018-03-11 18:55:20 +01:00
|
|
|
# Test that realm emoji list is public and realm emojis
|
|
|
|
# having no author are also there in the list.
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("othello")
|
|
|
|
realm = get_realm("zulip")
|
2021-05-17 15:40:28 +02:00
|
|
|
realm.add_custom_emoji_policy = Realm.POLICY_ADMINS_ONLY
|
2016-12-20 15:41:30 +01:00
|
|
|
realm.save()
|
2021-02-12 08:20:45 +01:00
|
|
|
realm_emoji = self.create_test_emoji_with_no_author("my_emoji", realm)
|
2018-03-11 18:55:20 +01:00
|
|
|
|
2016-12-20 15:41:30 +01:00
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
content = self.assert_json_success(result)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(content["emoji"], 2)
|
2018-03-11 18:55:20 +01:00
|
|
|
test_emoji = content["emoji"][str(realm_emoji.id)]
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertIsNone(test_emoji["author_id"])
|
2016-12-20 15:41:30 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_upload(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
user = self.example_user("iago")
|
2020-03-06 18:40:46 +01:00
|
|
|
email = user.email
|
|
|
|
self.login_user(user)
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", info=emoji_data)
|
2016-06-03 02:46:57 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(200, result.status_code)
|
2018-03-11 18:55:20 +01:00
|
|
|
realm_emoji = RealmEmoji.objects.get(name="my_emoji")
|
2021-07-24 16:56:39 +02:00
|
|
|
assert realm_emoji.author is not None
|
2018-03-11 18:55:20 +01:00
|
|
|
self.assertEqual(realm_emoji.author.email, email)
|
2016-06-03 02:46:57 +02:00
|
|
|
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
content = self.assert_json_success(result)
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(content["emoji"], 2)
|
2018-03-11 18:55:20 +01:00
|
|
|
test_emoji = content["emoji"][str(realm_emoji.id)]
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assertIn("author_id", test_emoji)
|
|
|
|
author = UserProfile.objects.get(id=test_emoji["author_id"])
|
2020-05-29 11:11:48 +02:00
|
|
|
self.assertEqual(author.email, email)
|
2016-06-03 02:46:57 +02:00
|
|
|
|
2021-06-16 20:49:41 +02:00
|
|
|
def test_override_built_in_emoji_by_admin(self) -> None:
|
|
|
|
# Test that only administrators can override built-in emoji.
|
|
|
|
self.login("othello")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/laughing", info=emoji_data)
|
|
|
|
self.assert_json_error(
|
|
|
|
result,
|
2023-01-25 16:47:51 +01:00
|
|
|
"Only administrators can override default emoji.",
|
2021-06-16 20:49:41 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
user = self.example_user("iago")
|
|
|
|
email = user.email
|
|
|
|
self.login_user(user)
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/smile", info=emoji_data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
self.assertEqual(200, result.status_code)
|
|
|
|
realm_emoji = RealmEmoji.objects.get(name="smile")
|
2022-07-19 17:41:02 +02:00
|
|
|
assert realm_emoji.author is not None
|
2021-06-16 20:49:41 +02:00
|
|
|
self.assertEqual(realm_emoji.author.email, email)
|
|
|
|
|
2018-03-11 18:55:20 +01:00
|
|
|
def test_realm_emoji_repr(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
realm_emoji = RealmEmoji.objects.get(name="green_tick")
|
|
|
|
file_name = str(realm_emoji.id) + ".png"
|
2016-09-19 23:20:15 +02:00
|
|
|
self.assertEqual(
|
2023-03-08 22:18:59 +01:00
|
|
|
repr(realm_emoji),
|
|
|
|
f"<RealmEmoji: zulip: {realm_emoji.id} green_tick False {file_name}>",
|
2016-09-19 23:20:15 +02:00
|
|
|
)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_upload_exception(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_em*oji", info=emoji_data)
|
2022-07-02 05:16:18 +02:00
|
|
|
self.assert_json_error(
|
|
|
|
result,
|
2023-02-01 02:28:33 +01:00
|
|
|
"Emoji names must contain only lowercase English letters, digits, spaces, dashes, and underscores.",
|
2022-07-14 08:42:05 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_forward_slash_exception(self) -> None:
|
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post(
|
|
|
|
"/json/realm/emoji/my/emoji/with/forward/slash/", info=emoji_data
|
|
|
|
)
|
|
|
|
self.assert_json_error(
|
|
|
|
result,
|
2023-02-01 02:28:33 +01:00
|
|
|
"Emoji names must contain only lowercase English letters, digits, spaces, dashes, and underscores.",
|
2022-07-02 05:16:18 +02:00
|
|
|
)
|
2017-05-02 23:13:40 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_upload_uppercase_exception(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_EMoji", info=emoji_data)
|
2022-07-02 05:16:18 +02:00
|
|
|
self.assert_json_error(
|
|
|
|
result,
|
2023-02-01 02:28:33 +01:00
|
|
|
"Emoji names must contain only lowercase English letters, digits, spaces, dashes, and underscores.",
|
2022-07-02 05:16:18 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_upload_end_character_exception(self) -> None:
|
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_", info=emoji_data)
|
2023-02-01 02:28:33 +01:00
|
|
|
self.assert_json_error(result, "Emoji names must end with either a letter or digit.")
|
2016-06-03 02:46:57 +02:00
|
|
|
|
2020-04-08 21:49:55 +02:00
|
|
|
def test_missing_name_exception(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/%20", info=emoji_data)
|
|
|
|
self.assert_json_error(result, "Emoji name is missing")
|
2020-04-08 21:49:55 +02:00
|
|
|
|
2021-05-17 14:29:26 +02:00
|
|
|
def test_can_add_custom_emoji(self) -> None:
|
|
|
|
def validation_func(user_profile: UserProfile) -> bool:
|
|
|
|
return user_profile.can_add_custom_emoji()
|
|
|
|
|
|
|
|
self.check_has_permission_policies("add_custom_emoji_policy", validation_func)
|
|
|
|
|
2021-05-17 15:40:28 +02:00
|
|
|
def test_user_settings_for_adding_custom_emoji(self) -> None:
|
|
|
|
othello = self.example_user("othello")
|
|
|
|
self.login_user(othello)
|
|
|
|
|
|
|
|
do_change_user_role(othello, UserProfile.ROLE_MODERATOR, acting_user=None)
|
|
|
|
do_set_realm_property(
|
|
|
|
othello.realm, "add_custom_emoji_policy", Realm.POLICY_ADMINS_ONLY, acting_user=None
|
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
2021-05-17 15:40:28 +02:00
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_1", info=emoji_data)
|
|
|
|
self.assert_json_error(result, "Insufficient permission")
|
2016-12-20 15:41:30 +01:00
|
|
|
|
2021-05-17 15:40:28 +02:00
|
|
|
do_change_user_role(othello, UserProfile.ROLE_REALM_ADMINISTRATOR, acting_user=None)
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
2021-05-17 15:40:28 +02:00
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_1", info=emoji_data)
|
2017-07-22 23:26:38 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2021-05-17 15:40:28 +02:00
|
|
|
do_set_realm_property(
|
|
|
|
othello.realm, "add_custom_emoji_policy", Realm.POLICY_MODERATORS_ONLY, acting_user=None
|
|
|
|
)
|
|
|
|
do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
2021-05-17 15:40:28 +02:00
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_2", info=emoji_data)
|
|
|
|
self.assert_json_error(result, "Insufficient permission")
|
|
|
|
|
|
|
|
do_change_user_role(othello, UserProfile.ROLE_MODERATOR, acting_user=None)
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_2", info=emoji_data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
do_set_realm_property(
|
|
|
|
othello.realm,
|
|
|
|
"add_custom_emoji_policy",
|
|
|
|
Realm.POLICY_FULL_MEMBERS_ONLY,
|
|
|
|
acting_user=None,
|
|
|
|
)
|
|
|
|
do_set_realm_property(othello.realm, "waiting_period_threshold", 100000, acting_user=None)
|
|
|
|
do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)
|
|
|
|
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_3", info=emoji_data)
|
|
|
|
self.assert_json_error(result, "Insufficient permission")
|
|
|
|
|
|
|
|
do_set_realm_property(othello.realm, "waiting_period_threshold", 0, acting_user=None)
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_3", info=emoji_data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
do_set_realm_property(
|
|
|
|
othello.realm, "add_custom_emoji_policy", Realm.POLICY_MEMBERS_ONLY, acting_user=None
|
|
|
|
)
|
|
|
|
do_change_user_role(othello, UserProfile.ROLE_GUEST, acting_user=None)
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_4", info=emoji_data)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Not allowed for guest users")
|
2018-06-08 15:30:44 +02:00
|
|
|
|
2021-05-17 15:40:28 +02:00
|
|
|
do_change_user_role(othello, UserProfile.ROLE_MEMBER, acting_user=None)
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji_4", info=emoji_data)
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_delete(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author = self.example_user("iago")
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author)
|
2021-02-12 08:20:45 +01:00
|
|
|
realm_emoji = self.create_test_emoji("my_emoji", emoji_author)
|
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji")
|
2016-06-03 02:46:57 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2016-07-28 00:38:45 +02:00
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
emojis = self.assert_json_success(result)["emoji"]
|
2017-05-22 17:08:37 +02:00
|
|
|
# We only mark an emoji as deactivated instead of
|
|
|
|
# removing it from the database.
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(emojis, 2)
|
2018-03-11 18:55:20 +01:00
|
|
|
test_emoji = emojis[str(realm_emoji.id)]
|
|
|
|
self.assertEqual(test_emoji["deactivated"], True)
|
2016-12-20 15:41:30 +01:00
|
|
|
|
2018-03-11 18:55:20 +01:00
|
|
|
def test_delete_no_author(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
realm = get_realm("zulip")
|
|
|
|
self.create_test_emoji_with_no_author("my_emoji", realm)
|
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji")
|
2018-03-11 18:55:20 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_delete_admin_or_author(self) -> None:
|
2021-05-04 19:47:10 +02:00
|
|
|
# Admins can delete emoji added by others also.
|
|
|
|
# Non-admins can only delete emoji they added themselves.
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author = self.example_user("othello")
|
2018-03-11 18:55:20 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.create_test_emoji("my_emoji_1", emoji_author)
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author)
|
2017-05-22 17:08:37 +02:00
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji_1")
|
2017-05-18 21:53:33 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.logout()
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.create_test_emoji("my_emoji_2", emoji_author)
|
|
|
|
self.login("iago")
|
2017-05-22 17:08:37 +02:00
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji_2")
|
2017-05-18 21:53:33 +02:00
|
|
|
self.assert_json_success(result)
|
|
|
|
self.logout()
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
self.create_test_emoji("my_emoji_3", emoji_author)
|
|
|
|
self.login("cordelia")
|
2017-05-22 17:08:37 +02:00
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji_3")
|
2021-02-12 08:20:45 +01:00
|
|
|
self.assert_json_error(result, "Must be an organization administrator or emoji author")
|
2017-05-18 21:53:33 +02:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_delete_exception(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
2017-01-17 08:48:07 +01:00
|
|
|
result = self.client_delete("/json/realm/emoji/invalid_emoji")
|
2023-01-25 08:29:51 +01:00
|
|
|
self.assert_json_error(result, "Emoji 'invalid_emoji' does not exist", status_code=404)
|
2017-03-13 05:45:50 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_multiple_upload(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1, get_test_image_file("img.png") as fp2:
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", {"f1": fp1, "f2": fp2})
|
|
|
|
self.assert_json_error(result, "You must upload exactly one file.")
|
2017-03-13 05:45:50 +01:00
|
|
|
|
upload: Fix resizing non-animated images.
5dab6e9d31be began honoring the list of disposals for every frame.
Unfortunately, passing a list of disposals for a non-animated image
raises an exception:
```
File "zerver/lib/upload.py", line 212, in resize_emoji
image_data = resize_gif(im, size)
File "zerver/lib/upload.py", line 165, in resize_gif
frames[0].save(
File "[...]/PIL/Image.py", line 2212, in save
save_handler(self, fp, filename)
File "[...]/PIL/GifImagePlugin.py", line 605, in _save
_write_single_frame(im, fp, palette)
File "[...]/PIL/GifImagePlugin.py", line 506, in _write_single_frame
_write_local_header(fp, im, (0, 0), flags)
File "[...]/PIL/GifImagePlugin.py", line 647, in _write_local_header
disposal = int(im.encoderinfo.get("disposal", 0))
TypeError: int() argument must be a string, a bytes-like object or a
number, not 'list'
```
`check_add_realm_emoji` calls this as:
```
try:
is_animated = upload_emoji_image(image_file, emoji_file_name, a
uthor)
emoji_uploaded_successfully = True
finally:
if not emoji_uploaded_successfully:
realm_emoji.delete()
return None
# ...
```
This is equivalent to dropping _all_ exceptions silently. As such,
Zulip has silently rejected all non-animated images larger than 64x64
since 5dab6e9d31be.
Adjust to only pass a single disposal if there are no additional
frames. Add a test for non-animated images, which requires also
fixing the incidental bug that all GIF images were being recorded as
animated, regardless of if they had more than 1 frame or not.
2022-02-16 23:26:31 +01:00
|
|
|
def test_emoji_upload_success(self) -> None:
|
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.gif") as fp:
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", {"file": fp})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
def test_emoji_upload_resize_success(self) -> None:
|
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("still_large_img.gif") as fp:
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", {"file": fp})
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_emoji_upload_file_size_error(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp:
|
2021-05-29 09:04:19 +02:00
|
|
|
with self.settings(MAX_EMOJI_FILE_SIZE_MIB=0):
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", {"file": fp})
|
|
|
|
self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MiB")
|
2017-03-13 05:45:50 +01:00
|
|
|
|
2017-11-05 10:51:25 +01:00
|
|
|
def test_upload_already_existed_emoji(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/green_tick", info=emoji_data)
|
|
|
|
self.assert_json_error(result, "A custom emoji with this name already exists.")
|
2018-03-11 18:55:20 +01:00
|
|
|
|
|
|
|
def test_reupload(self) -> None:
|
2022-02-08 00:13:33 +01:00
|
|
|
# A user should be able to reupload an emoji with same name.
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", info=emoji_data)
|
2018-03-11 18:55:20 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_delete("/json/realm/emoji/my_emoji")
|
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", info=emoji_data)
|
2018-03-11 18:55:20 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
result = self.client_get("/json/realm/emoji")
|
2022-06-07 01:37:01 +02:00
|
|
|
emojis = self.assert_json_success(result)["emoji"]
|
2021-05-17 05:41:32 +02:00
|
|
|
self.assert_length(emojis, 3)
|
2018-03-11 18:55:20 +01:00
|
|
|
|
|
|
|
def test_failed_file_upload(self) -> None:
|
2021-02-12 08:20:45 +01:00
|
|
|
self.login("iago")
|
2022-02-17 00:01:27 +01:00
|
|
|
with mock.patch(
|
2022-12-14 21:51:37 +01:00
|
|
|
"zerver.lib.upload.local.write_local_file", side_effect=BadImageError(msg="Broken")
|
2022-02-17 00:01:27 +01:00
|
|
|
):
|
2021-02-12 08:20:45 +01:00
|
|
|
with get_test_image_file("img.png") as fp1:
|
|
|
|
emoji_data = {"f1": fp1}
|
|
|
|
result = self.client_post("/json/realm/emoji/my_emoji", info=emoji_data)
|
2022-02-17 00:01:27 +01:00
|
|
|
self.assert_json_error(result, "Broken")
|
2018-03-18 17:33:10 +01:00
|
|
|
|
|
|
|
def test_check_admin_realm_emoji(self) -> None:
|
2023-10-09 21:28:43 +02:00
|
|
|
# Test that a user A is able to remove a realm emoji uploaded by him
|
2018-03-18 17:33:10 +01:00
|
|
|
# and having same name as a deactivated realm emoji uploaded by some
|
|
|
|
# other user B.
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author_1 = self.example_user("cordelia")
|
|
|
|
self.create_test_emoji("test_emoji", emoji_author_1)
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author_1)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_delete("/json/realm/emoji/test_emoji")
|
2018-03-18 17:33:10 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author_2 = self.example_user("othello")
|
|
|
|
self.create_test_emoji("test_emoji", emoji_author_2)
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author_2)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_delete("/json/realm/emoji/test_emoji")
|
2018-03-18 17:33:10 +01:00
|
|
|
self.assert_json_success(result)
|
|
|
|
|
|
|
|
def test_check_admin_different_realm_emoji(self) -> None:
|
|
|
|
# Test that two different realm emojis in two different realms but
|
|
|
|
# having same name can be administered independently.
|
2021-02-12 08:20:45 +01:00
|
|
|
realm_1 = do_create_realm("test_realm", "test_realm")
|
2020-07-16 14:10:43 +02:00
|
|
|
emoji_author_1 = do_create_user(
|
2021-02-06 14:27:06 +01:00
|
|
|
"abc@example.com", password="abc", realm=realm_1, full_name="abc", acting_user=None
|
2020-07-16 14:10:43 +02:00
|
|
|
)
|
2021-02-12 08:20:45 +01:00
|
|
|
self.create_test_emoji("test_emoji", emoji_author_1)
|
2018-03-18 17:33:10 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
emoji_author_2 = self.example_user("othello")
|
|
|
|
self.create_test_emoji("test_emoji", emoji_author_2)
|
2020-03-06 18:40:46 +01:00
|
|
|
self.login_user(emoji_author_2)
|
2021-02-12 08:20:45 +01:00
|
|
|
result = self.client_delete("/json/realm/emoji/test_emoji")
|
2018-03-18 17:33:10 +01:00
|
|
|
self.assert_json_success(result)
|
2021-12-03 03:11:54 +01:00
|
|
|
|
|
|
|
def test_upload_already_existed_emoji_in_check_add_realm_emoji(self) -> None:
|
|
|
|
realm_1 = do_create_realm("test_realm", "test_realm")
|
|
|
|
emoji_author = do_create_user(
|
|
|
|
"abc@example.com", password="abc", realm=realm_1, full_name="abc", acting_user=None
|
|
|
|
)
|
|
|
|
emoji_name = "emoji_test"
|
|
|
|
with get_test_image_file("img.png") as img_file:
|
|
|
|
# Because we want to verify the IntegrityError handling
|
|
|
|
# logic in check_add_realm_emoji rather than the primary
|
|
|
|
# check in upload_emoji, we need to make this request via
|
|
|
|
# that helper rather than via the API.
|
|
|
|
check_add_realm_emoji(
|
|
|
|
realm=emoji_author.realm, name=emoji_name, author=emoji_author, image_file=img_file
|
|
|
|
)
|
|
|
|
with self.assertRaises(JsonableError):
|
|
|
|
check_add_realm_emoji(
|
|
|
|
realm=emoji_author.realm,
|
|
|
|
name=emoji_name,
|
|
|
|
author=emoji_author,
|
|
|
|
image_file=img_file,
|
|
|
|
)
|