def _setup_export_files(self) -> Tuple[str, str, str, bytes]: realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() return attachment_path_id, emoji_path, original_avatar_path_id, test_image
def test_multiple_upload(self): # type: () -> None email = self.example_email('iago') self.login(email) 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.')
def test_upload_avatar_image(self) -> None: conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY) bucket = conn.create_bucket(settings.S3_AVATAR_BUCKET) user_profile = self.example_user('hamlet') path_id = user_avatar_path(user_profile) original_image_path_id = path_id + ".original" medium_path_id = path_id + "-medium.png" with get_test_image_file('img.png') as image_file: zerver.lib.upload.upload_backend.upload_avatar_image(image_file, user_profile, user_profile) test_image_data = open(get_test_image_file('img.png').name, 'rb').read() test_medium_image_data = resize_avatar(test_image_data, MEDIUM_AVATAR_SIZE) original_image_key = bucket.get_key(original_image_path_id) self.assertEqual(original_image_key.key, original_image_path_id) image_data = original_image_key.get_contents_as_string() self.assertEqual(image_data, test_image_data) medium_image_key = bucket.get_key(medium_path_id) self.assertEqual(medium_image_key.key, medium_path_id) medium_image_data = medium_image_key.get_contents_as_string() self.assertEqual(medium_image_data, test_medium_image_data) bucket.delete_key(medium_image_key) zerver.lib.upload.upload_backend.ensure_medium_avatar_image(user_profile) medium_image_key = bucket.get_key(medium_path_id) self.assertEqual(medium_image_key.key, medium_path_id)
def test_multiple_upload_failure(self) -> None: """ Attempting to upload two files should fail. """ self.login(self.example_email("hamlet")) with get_test_image_file('img.png') as fp1, \ get_test_image_file('img.png') as fp2: result = self.client_post("/json/users/me/avatar", {'f1': fp1, 'f2': fp2}) self.assert_json_error(result, "You must upload exactly one avatar.")
def test_multiple_upload_failure(self) -> None: """ Attempting to upload two files should fail. """ # Log in as admin self.login(self.example_email("iago")) with get_test_image_file('img.png') as fp1, \ get_test_image_file('img.png') as fp2: result = self.client_post("/json/realm/icon", {'f1': fp1, 'f2': fp2}) self.assert_json_error(result, "You must upload exactly one icon.")
def test_export_files_from_s3(self) -> None: conn = S3Connection(settings.S3_KEY, settings.S3_SECRET_KEY) conn.create_bucket(settings.S3_AUTH_UPLOADS_BUCKET) conn.create_bucket(settings.S3_AVATAR_BUCKET) realm = Realm.objects.get(string_id='zulip') message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) attachment_path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=attachment_path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=realm.id, emoji_file_name='1.png', ) with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], attachment_path_id) # Test uploads fields = attachment_path_id.split('/') fn = os.path.join(full_data['uploads_dir'], os.path.join(fields[1], fields[2])) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join(full_data['emoji_dir'], emoji_path) fn = fn.replace('1.png', '') self.assertIn('1.png', os.listdir(fn)) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def test_add_bot_with_too_many_files(self) -> None: self.login(self.example_email('hamlet')) self.assert_num_bots_equal(0) with get_test_image_file('img.png') as fp1, \ get_test_image_file('img.gif') as fp2: bot_info = dict( full_name='whatever', short_name='whatever', file1=fp1, file2=fp2, ) result = self.client_post("/json/bots", bot_info) self.assert_json_error(result, 'You may only upload one file at a time') self.assert_num_bots_equal(0)
def test_realm_icon_upload_file_size_error(self): # type: () -> None self.login(self.example_email("iago")) with get_test_image_file(self.correct_files[0][0]) as fp: with self.settings(MAX_ICON_FILE_SIZE=0): result = self.client_post("/json/realm/icon", {'file': fp}) self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
def test_avatar_upload_file_size_error(self): # type: () -> None self.login(self.example_email("hamlet")) with get_test_image_file(self.correct_files[0][0]) as fp: with self.settings(MAX_AVATAR_FILE_SIZE=0): result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
def test_emoji_upload_by_guest_user(self) -> None: email = self.example_email('polonius') self.login(email) 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) self.assert_json_error(result, 'Not allowed for guest users')
def test_transfer_emoji_to_s3(self) -> None: bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0] othello = self.example_user('othello') RealmEmoji.objects.all().delete() emoji_name = "emoji.png" image_file = get_test_image_file("img.png") emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file) if not emoji: raise AssertionError("Unable to add emoji.") emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=othello.realm_id, emoji_file_name=emoji.file_name, ) transfer_emoji_to_s3(1) self.assertEqual(len(bucket.get_all_keys()), 2) original_key = bucket.get_key(emoji_path + ".original") resized_key = bucket.get_key(emoji_path) image_file.seek(0) image_data = image_file.read() resized_image_data = resize_emoji(image_data) self.assertEqual(image_data, original_key.get_contents_as_string()) self.assertEqual(resized_image_data, resized_key.get_contents_as_string())
def test_emoji_upload_file_size_error(self) -> None: email = self.example_email('iago') self.login(email) with get_test_image_file('img.png') as fp: with self.settings(MAX_EMOJI_FILE_SIZE=0): 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 MB')
def test_upload_already_existed_emoji(self) -> None: email = self.example_email('iago') self.login(email) 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, 'Realm emoji with this Realm and Name already exists.')
def test_upload(self) -> None: email = self.example_email('iago') self.login(email) 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) self.assert_json_success(result) self.assertEqual(200, result.status_code) emoji = RealmEmoji.objects.get(name="my_emoji") self.assertEqual(emoji.author.email, email) result = self.client_get("/json/realm/emoji") content = result.json() self.assert_json_success(result) self.assertEqual(len(content["emoji"]), 2) self.assertIn('author', content["emoji"]['my_emoji']) self.assertEqual( content["emoji"]['my_emoji']['author']['email'], email) realm_emoji = RealmEmoji.objects.get(name='my_emoji') file_name = realm_emoji.name + '.png' self.assertEqual( str(realm_emoji), '<RealmEmoji(zulip): %s my_emoji False %s>' % (realm_emoji.id, file_name) )
def test_upload_uppercase_exception(self) -> None: email = self.example_email('iago') self.login(email) 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) self.assert_json_error(result, 'Invalid characters in emoji name')
def test_failed_file_upload(self) -> None: email = self.example_email('iago') self.login(email) with mock.patch('zerver.lib.upload.write_local_file', side_effect=Exception()): 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) self.assert_json_error(result, "Image file upload failed.")
def test_export_files_from_local(self) -> None: message = Message.objects.all()[0] user_profile = message.sender url = upload_message_file(u'dummy.txt', len(b'zulip!'), u'text/plain', b'zulip!', user_profile) path_id = url.replace('/user_uploads/', '') claim_attachment( user_profile=user_profile, path_id=path_id, message=message, is_message_realm_public=True ) avatar_path_id = user_avatar_path(user_profile) original_avatar_path_id = avatar_path_id + ".original" realm = Realm.objects.get(string_id='zulip') with get_test_image_file('img.png') as img_file: upload_emoji_image(img_file, '1.png', user_profile) with get_test_image_file('img.png') as img_file: upload_avatar_image(img_file, user_profile, user_profile) test_image = open(get_test_image_file('img.png').name, 'rb').read() message.sender.avatar_source = 'U' message.sender.save() full_data = self._export_realm(realm) data = full_data['attachment'] self.assertEqual(len(data['zerver_attachment']), 1) record = data['zerver_attachment'][0] self.assertEqual(record['path_id'], path_id) # Test uploads fn = os.path.join(full_data['uploads_dir'], path_id) with open(fn) as f: self.assertEqual(f.read(), 'zulip!') # Test emojis fn = os.path.join(full_data['emoji_dir'], RealmEmoji.PATH_ID_TEMPLATE.format(realm_id=realm.id, emoji_file_name='1.png')) fn = fn.replace('1.png', '') self.assertEqual('1.png', os.listdir(fn)[0]) # Test avatars fn = os.path.join(full_data['avatar_dir'], original_avatar_path_id) fn_data = open(fn, 'rb').read() self.assertEqual(fn_data, test_image)
def test_realm_icon_version(self) -> None: self.login(self.example_email("iago")) realm = get_realm('zulip') icon_version = realm.icon_version self.assertEqual(icon_version, 1) with get_test_image_file(self.correct_files[0][0]) as fp: self.client_post("/json/realm/icon", {'file': fp}) realm = get_realm('zulip') self.assertEqual(realm.icon_version, icon_version + 1)
def create_test_emoji(self, name: str, author: UserProfile) -> RealmEmoji: with get_test_image_file('img.png') as img_file: realm_emoji = check_add_realm_emoji(realm=author.realm, name=name, author=author, image_file=img_file) if realm_emoji is None: raise Exception("Error creating test emoji.") # nocoverage return realm_emoji
def test_upload_anyone(self) -> None: email = self.example_email('othello') self.login(email) realm = get_realm('zulip') realm.add_emoji_by_admins_only = False realm.save() 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) self.assert_json_success(result)
def test_upload_admins_only(self) -> None: email = self.example_email('othello') self.login(email) realm = get_realm('zulip') realm.add_emoji_by_admins_only = True realm.save() 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) self.assert_json_error(result, 'Must be an organization administrator')
def test_invalid_icons(self) -> None: """ A PUT request to /json/realm/icon with an invalid file should fail. """ for fname in self.corrupt_files: # with self.subTest(fname=fname): self.login(self.example_email("iago")) with get_test_image_file(fname) as fp: result = self.client_post("/json/realm/icon", {'file': fp}) self.assert_json_error(result, "Could not decode image; did you upload an image file?")
def test_reupload(self) -> None: # An user should be able to reupload an emoji with same name. email = self.example_email('iago') self.login(email) 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) self.assert_json_success(result) result = self.client_delete("/json/realm/emoji/my_emoji") self.assert_json_success(result) 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) self.assert_json_success(result) result = self.client_get("/json/realm/emoji") emojis = result.json()["emoji"] self.assert_json_success(result) self.assertEqual(len(emojis), 3)
def test_patch_bot_avatar(self) -> None: self.login(self.example_email('hamlet')) bot_info = { 'full_name': 'The Bot of Hamlet', 'short_name': 'hambot', } result = self.client_post("/json/bots", bot_info) self.assert_json_success(result) bot_email = '*****@*****.**' bot_realm = get_realm('zulip') profile = get_user(bot_email, bot_realm) self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_GRAVATAR) # Try error case first (too many files): with get_test_image_file('img.png') as fp1, \ get_test_image_file('img.gif') as fp2: result = self.client_patch_multipart( '/json/bots/[email protected]', dict(file1=fp1, file2=fp2)) self.assert_json_error(result, 'You may only upload one file at a time') profile = get_user(bot_email, bot_realm) self.assertEqual(profile.avatar_version, 1) # HAPPY PATH with get_test_image_file('img.png') as fp: result = self.client_patch_multipart( '/json/bots/[email protected]', dict(file=fp)) profile = get_user(bot_email, bot_realm) self.assertEqual(profile.avatar_version, 2) # Make sure that avatar image that we've uploaded is same with avatar image in the server self.assertTrue(filecmp.cmp(fp.name, os.path.splitext(avatar_disk_path(profile))[0] + ".original")) self.assert_json_success(result) self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_USER) self.assertTrue(os.path.exists(avatar_disk_path(profile)))
def test_invalid_avatars(self) -> None: """ A PUT request to /json/users/me/avatar with an invalid file should fail. """ for fname in self.corrupt_files: # with self.subTest(fname=fname): self.login(self.example_email("hamlet")) with get_test_image_file(fname) as fp: result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_error(result, "Could not decode image; did you upload an image file?") user_profile = self.example_user('hamlet') self.assertEqual(user_profile.avatar_version, 1)
def test_invalid_icons(self): # type: () -> None """ A PUT request to /json/realm/icon with an invalid file should fail. """ for fname in self.corrupt_files: # with self.subTest(fname=fname): self.login(self.example_email("iago")) with get_test_image_file(fname) as fp: result = self.client_post("/json/realm/icon", {'file': fp}) self.assert_json_error( result, "Could not decode image; did you upload an image file?")
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, "Only administrators can override built-in emoji.", ) 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") self.assertEqual(realm_emoji.author.email, email)
def test_invalid_avatars(self): # type: () -> None """ A PUT request to /json/users/me/avatar with an invalid file should fail. """ for fname in self.corrupt_files: # with self.subTest(fname=fname): self.login(self.example_email("hamlet")) with get_test_image_file(fname) as fp: result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_error(result, "Could not decode image; did you upload an image file?") user_profile = self.example_user('hamlet') self.assertEqual(user_profile.avatar_version, 1)
def test_avatar_changes_disabled(self) -> None: self.login("hamlet") with self.settings(AVATAR_CHANGES_DISABLED=True): result = self.client_delete("/json/users/me/avatar") self.assert_json_error( result, "Avatar changes are disabled in this organization.", 400) with self.settings(AVATAR_CHANGES_DISABLED=True): with get_test_image_file("img.png") as fp1: result = self.client_post("/json/users/me/avatar", {"f1": fp1}) self.assert_json_error( result, "Avatar changes are disabled in this organization.", 400)
def test_add_bot_with_user_avatar(self) -> None: email = '*****@*****.**' realm = get_realm('zulip') self.login(self.example_email('hamlet')) self.assert_num_bots_equal(0) with get_test_image_file('img.png') as fp: self.create_bot(file=fp) profile = get_user(email, realm) # Make sure that avatar image that we've uploaded is same with avatar image in the server self.assertTrue(filecmp.cmp(fp.name, os.path.splitext(avatar_disk_path(profile))[0] + ".original")) self.assert_num_bots_equal(1) self.assertEqual(profile.avatar_source, UserProfile.AVATAR_FROM_USER) self.assertTrue(os.path.exists(avatar_disk_path(profile)))
def test_avatar_changes_disabled(self) -> None: user = self.example_user('hamlet') email = user.email self.login(email) with self.settings(AVATAR_CHANGES_DISABLED=True): result = self.client_delete("/json/users/me/avatar") self.assert_json_error( result, "Avatar changes are disabled in this organization.", 400) with self.settings(AVATAR_CHANGES_DISABLED=True): with get_test_image_file('img.png') as fp1: result = self.client_post("/json/users/me/avatar", {'f1': fp1}) self.assert_json_error( result, "Avatar changes are disabled in this organization.", 400)
def test_upload(self) -> None: email = self.example_email('iago') self.login(email) 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) self.assert_json_success(result) self.assertEqual(200, result.status_code) realm_emoji = RealmEmoji.objects.get(name="my_emoji") self.assertEqual(realm_emoji.author.email, email) result = self.client_get("/json/realm/emoji") content = result.json() self.assert_json_success(result) self.assertEqual(len(content["emoji"]), 2) test_emoji = content["emoji"][str(realm_emoji.id)] self.assertIn('author', test_emoji) self.assertEqual(test_emoji['author']['email'], email)
def test_import_files_from_s3(self) -> None: uploads_bucket, avatar_bucket = create_s3_buckets( settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) realm = Realm.objects.get(string_id='zulip') self._setup_export_files() self._export_realm(realm) with patch('logging.info'): do_import_realm( os.path.join(settings.TEST_WORKER_DIR, 'test-export'), 'test-zulip') imported_realm = Realm.objects.get(string_id='test-zulip') with open(get_test_image_file('img.png').name, 'rb') as f: test_image_data = f.read() # Test attachments uploaded_file = Attachment.objects.get(realm=imported_realm) self.assertEqual(len(b'zulip!'), uploaded_file.size) attachment_content = uploads_bucket.get_key( uploaded_file.path_id).get_contents_as_string() self.assertEqual(b"zulip!", attachment_content) # Test emojis realm_emoji = RealmEmoji.objects.get(realm=imported_realm) emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=imported_realm.id, emoji_file_name=realm_emoji.file_name, ) emoji_key = avatar_bucket.get_key(emoji_path) self.assertIsNotNone(emoji_key) self.assertEqual(emoji_key.key, emoji_path) # Test avatars user_email = Message.objects.all()[0].sender.email user_profile = UserProfile.objects.get(email=user_email, realm=imported_realm) avatar_path_id = user_avatar_path(user_profile) + ".original" original_image_key = avatar_bucket.get_key(avatar_path_id) self.assertEqual(original_image_key.key, avatar_path_id) image_data = original_image_key.get_contents_as_string() self.assertEqual(image_data, test_image_data)
def test_valid_avatars(self): # type: () -> None """ A PUT request to /json/users/me/avatar with a valid file should return a url and actually create an avatar. """ version = 2 for fname, rfname in self.correct_files: # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below. # with self.subTest(fname=fname): self.login(self.example_email("hamlet")) with get_test_image_file(fname) as fp: result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_success(result) self.assertIn("avatar_url", result.json()) base = '/user_avatars/' url = result.json()['avatar_url'] self.assertEqual(base, url[:len(base)]) if rfname is not None: response = self.client_get(url) data = b"".join(response.streaming_content) self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100)) # Verify that the medium-size avatar was created user_profile = self.example_user('hamlet') medium_avatar_disk_path = avatar_disk_path(user_profile, medium=True) self.assertTrue(os.path.exists(medium_avatar_disk_path)) # Confirm that ensure_medium_avatar_url works to recreate # medium size avatars from the original if needed os.remove(medium_avatar_disk_path) self.assertFalse(os.path.exists(medium_avatar_disk_path)) zerver.lib.upload.upload_backend.ensure_medium_avatar_image( user_profile) self.assertTrue(os.path.exists(medium_avatar_disk_path)) # Verify whether the avatar_version gets incremented with every new upload self.assertEqual(user_profile.avatar_version, version) version += 1
def test_transfer_avatars_to_s3(self) -> None: bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0] self.login('hamlet') with get_test_image_file('img.png') as image_file: self.client_post("/json/users/me/avatar", {'file': image_file}) user = self.example_user("hamlet") transfer_avatars_to_s3(1) path_id = user_avatar_path(user) image_key = bucket.get_key(path_id) original_image_key = bucket.get_key(path_id + ".original") medium_image_key = bucket.get_key(path_id + "-medium.png") self.assertEqual(len(bucket.get_all_keys()), 3) self.assertEqual(image_key.get_contents_as_string(), open(avatar_disk_path(user), "rb").read()) self.assertEqual(original_image_key.get_contents_as_string(), open(avatar_disk_path(user, original=True), "rb").read()) self.assertEqual(medium_image_key.get_contents_as_string(), open(avatar_disk_path(user, medium=True), "rb").read())
def test_transfer_avatars_to_s3(self) -> None: bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0] self.login(self.example_email("hamlet")) with get_test_image_file('img.png') as image_file: self.client_post("/json/users/me/avatar", {'file': image_file}) user = self.example_user("hamlet") transfer_avatars_to_s3(1) path_id = user_avatar_path(user) image_key = bucket.get_key(path_id) original_image_key = bucket.get_key(path_id + ".original") medium_image_key = bucket.get_key(path_id + "-medium.png") self.assertEqual(len(bucket.get_all_keys()), 3) self.assertEqual(image_key.get_contents_as_string(), open(avatar_disk_path(user), "rb").read()) self.assertEqual(original_image_key.get_contents_as_string(), open(avatar_disk_path(user, original=True), "rb").read()) self.assertEqual(medium_image_key.get_contents_as_string(), open(avatar_disk_path(user, medium=True), "rb").read())
def test_upload(self) -> None: 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/my_emoji", info=emoji_data) self.assert_json_success(result) self.assertEqual(200, result.status_code) realm_emoji = RealmEmoji.objects.get(name="my_emoji") self.assertEqual(realm_emoji.author.email, email) result = self.client_get("/json/realm/emoji") content = result.json() self.assert_json_success(result) self.assert_length(content["emoji"], 2) test_emoji = content["emoji"][str(realm_emoji.id)] self.assertIn("author_id", test_emoji) author = UserProfile.objects.get(id=test_emoji["author_id"]) self.assertEqual(author.email, email)
def test_valid_avatars(self): # type: () -> None """ A PUT request to /json/users/me/avatar with a valid file should return a url and actually create an avatar. """ version = 2 for fname, rfname in self.correct_files: # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below. # with self.subTest(fname=fname): self.login(self.example_email("hamlet")) with get_test_image_file(fname) as fp: result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_success(result) self.assertIn("avatar_url", result.json()) base = '/user_avatars/' url = result.json()['avatar_url'] self.assertEqual(base, url[:len(base)]) if rfname is not None: response = self.client_get(url) data = b"".join(response.streaming_content) self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100)) # Verify that the medium-size avatar was created user_profile = self.example_user('hamlet') medium_avatar_disk_path = avatar_disk_path(user_profile, medium=True) self.assertTrue(os.path.exists(medium_avatar_disk_path)) # Confirm that ensure_medium_avatar_url works to recreate # medium size avatars from the original if needed os.remove(medium_avatar_disk_path) self.assertFalse(os.path.exists(medium_avatar_disk_path)) zerver.lib.upload.upload_backend.ensure_medium_avatar_image(user_profile) self.assertTrue(os.path.exists(medium_avatar_disk_path)) # Verify whether the avatar_version gets incremented with every new upload self.assertEqual(user_profile.avatar_version, version) version += 1
def test_valid_icons(self) -> None: """ A PUT request to /json/realm/icon with a valid file should return a url and actually create an realm icon. """ for fname, rfname in self.correct_files: # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below. # with self.subTest(fname=fname): self.login(self.example_email("iago")) with get_test_image_file(fname) as fp: result = self.client_post("/json/realm/icon", {'file': fp}) realm = get_realm('zulip') self.assert_json_success(result) self.assertIn("icon_url", result.json()) base = '/user_avatars/%s/realm/icon.png' % (realm.id, ) url = result.json()['icon_url'] self.assertEqual(base, url[:len(base)]) if rfname is not None: response = self.client_get(url) data = b"".join(response.streaming_content) self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))
def test_valid_icons(self) -> None: """ A PUT request to /json/realm/icon with a valid file should return a url and actually create an realm icon. """ for fname, rfname in self.correct_files: # TODO: use self.subTest once we're exclusively on python 3 by uncommenting the line below. # with self.subTest(fname=fname): self.login(self.example_email("iago")) with get_test_image_file(fname) as fp: result = self.client_post("/json/realm/icon", {'file': fp}) realm = get_realm('zulip') self.assert_json_success(result) self.assertIn("icon_url", result.json()) base = '/user_avatars/%s/realm/icon.png' % (realm.id,) url = result.json()['icon_url'] self.assertEqual(base, url[:len(base)]) if rfname is not None: response = self.client_get(url) data = b"".join(response.streaming_content) self.assertEqual(Image.open(io.BytesIO(data)).size, (100, 100))
def test_transfer_avatars_to_s3(self) -> None: bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0] self.login("hamlet") with get_test_image_file("img.png") as image_file: self.client_post("/json/users/me/avatar", {"file": image_file}) user = self.example_user("hamlet") with self.assertLogs(level="INFO"): transfer_avatars_to_s3(1) path_id = user_avatar_path(user) image_key = bucket.Object(path_id) original_image_key = bucket.Object(path_id + ".original") medium_image_key = bucket.Object(path_id + "-medium.png") self.assert_length(list(bucket.objects.all()), 3) with open(avatar_disk_path(user), "rb") as f: self.assertEqual(image_key.get()["Body"].read(), f.read()) with open(avatar_disk_path(user, original=True), "rb") as f: self.assertEqual(original_image_key.get()["Body"].read(), f.read()) with open(avatar_disk_path(user, medium=True), "rb") as f: self.assertEqual(medium_image_key.get()["Body"].read(), f.read())
def test_upload_already_existed_emoji(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/green_tick', info=emoji_data) self.assert_json_error(result, 'A custom emoji with this name already exists.')
def test_upload_uppercase_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) self.assert_json_error(result, 'Invalid characters in emoji name')
def test_s3_source_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = "") -> str: url_in_result = "smart/filters:no_upscale()%s/%s/source_type/s3" sharpen_filter = "" if size: url_in_result = f"/{size}/{url_in_result}" sharpen_filter = ":sharpen(0.5,0.2,true)" hex_uri = base64.urlsafe_b64encode(uri.encode()).decode("utf-8") return url_in_result % (sharpen_filter, hex_uri) create_s3_buckets(settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) hamlet = self.example_user("hamlet") self.login_user(hamlet) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {"file": fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = "/user_uploads/" self.assertEqual(base, uri[:len(base)]) # Test full size image. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "thumbnail" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, "0x300") self.assertIn(expected_part_url, result.url) # Test custom emoji URLs in Zulip messages. user_profile = self.example_user("hamlet") file_name = "emoji.png" with get_test_image_file("img.png") as image_file: upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = "/user_avatars/" self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail", { "url": custom_emoji_url[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail API endpoint with standard API auth self.logout() result = self.api_get(hamlet, "/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login("iago") result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_avatar_upload_file_size_error(self) -> None: self.login(self.example_email("hamlet")) with get_test_image_file(self.correct_files[0][0]) as fp: with self.settings(MAX_AVATAR_FILE_SIZE=0): result = self.client_post("/json/users/me/avatar", {'file': fp}) self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
def test_multiple_upload(self) -> None: email = self.example_email('iago') self.login(email) 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.')
def test_no_admin_user_upload(self) -> None: self.login(self.example_email("hamlet")) with get_test_image_file(self.correct_files[0][0]) as fp: result = self.client_post("/json/realm/icon", {'file': fp}) self.assert_json_error(result, 'Must be a realm administrator')
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)
def test_local_file_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale()%s/%s/source_type/local_file' sharpen_filter = '' if size: url_in_result = f'/{size}/{url_in_result}' sharpen_filter = ':sharpen(0.5,0.2,true)' hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (sharpen_filter, hex_uri) self.login('hamlet') fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) # Test full size image. # We remove the forward slash infront of the `/user_uploads/` to match # Markdown behaviour. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "thumbnail" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test with a Unicode filename. fp = StringIO("zulip!") fp.name = "μένει.jpg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = orjson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] # We remove the forward slash infront of the `/user_uploads/` to match # Markdown behaviour. result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") file_name = "emoji.png" with get_test_image_file("img.png") as image_file: upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail", { "url": custom_emoji_url[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail API endpoint with HTTP basic auth. self.logout() user_profile = self.example_user("hamlet") result = self.api_get(user_profile, "/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail API endpoint with ?api_key # auth. user_profile = self.example_user("hamlet") result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full", "api_key": get_api_key(user_profile) }) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login('iago') result = self.client_get("/thumbnail", { "url": uri[1:], "size": "full" }) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_local_file_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale():sharpen(2.2,0.8,false)/%s/source_type/local_file' if size: url_in_result = '/%s/%s' % (size, url_in_result) hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (hex_uri) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) # Test full size image. # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test with a unicode filename. fp = StringIO("zulip!") fp.name = "μένει.jpg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] # We remove the forward slash infront of the `/user_uploads/` to match # bugdown behaviour. quoted_uri = urllib.parse.quote(uri[1:], safe='') result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(custom_emoji_url) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail api endpoint with HTTP basic auth. self.logout() user_profile = self.example_user("hamlet") result = self.api_get(self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri, )) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Tests the /api/v1/thumbnail api endpoint with ?api_key # auth. user_profile = self.example_user("hamlet") result = self.client_get('/thumbnail?url=%s&size=full&api_key=%s' % (quoted_uri, get_api_key(user_profile))) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
def test_missing_name_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/%20", info=emoji_data) self.assert_json_error(result, "Emoji name is missing")
def test_transfer_emoji_to_s3(self) -> None: bucket = create_s3_buckets(settings.S3_AVATAR_BUCKET)[0] othello = self.example_user("othello") RealmEmoji.objects.all().delete() emoji_name = "emoji.png" with get_test_image_file("img.png") as image_file: emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file) if not emoji: raise AssertionError("Unable to add emoji.") emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=othello.realm_id, emoji_file_name=emoji.file_name, ) with self.assertLogs(level="INFO"): transfer_emoji_to_s3(1) self.assert_length(list(bucket.objects.all()), 2) original_key = bucket.Object(emoji_path + ".original") resized_key = bucket.Object(emoji_path) image_data = read_test_image_file("img.png") resized_image_data, is_animated, still_image_data = resize_emoji(image_data) self.assertEqual(is_animated, False) self.assertEqual(still_image_data, None) self.assertEqual(image_data, original_key.get()["Body"].read()) self.assertEqual(resized_image_data, resized_key.get()["Body"].read()) emoji_name = "emoji2.png" with get_test_image_file("animated_img.gif") as image_file: emoji = check_add_realm_emoji(othello.realm, emoji_name, othello, image_file) if not emoji: raise AssertionError("Unable to add emoji.") emoji_path = RealmEmoji.PATH_ID_TEMPLATE.format( realm_id=othello.realm_id, emoji_file_name=emoji.file_name, ) with self.assertLogs(level="INFO"): transfer_emoji_to_s3(1) self.assert_length(list(bucket.objects.all()), 5) original_key = bucket.Object(emoji_path + ".original") resized_key = bucket.Object(emoji_path) assert emoji.file_name still_key = bucket.Object( RealmEmoji.STILL_PATH_ID_TEMPLATE.format( realm_id=othello.realm_id, emoji_filename_without_extension=os.path.splitext(emoji.file_name)[0], ) ) image_data = read_test_image_file("animated_img.gif") resized_image_data, is_animated, still_image_data = resize_emoji(image_data) self.assertEqual(is_animated, True) self.assertEqual(type(still_image_data), bytes) self.assertEqual(image_data, original_key.get()["Body"].read()) self.assertEqual(resized_image_data, resized_key.get()["Body"].read()) self.assertEqual(still_image_data, still_key.get()["Body"].read())
def test_slack_import_to_existing_database( self, mock_get_slack_api_data: mock.Mock, mock_build_avatar_url: mock.Mock, mock_build_avatar: mock.Mock, mock_process_uploads: mock.Mock, mock_attachment: mock.Mock, mock_requests_get: mock.Mock) -> None: test_slack_dir = os.path.join(settings.DEPLOY_ROOT, "zerver", "tests", "fixtures", "slack_fixtures") test_slack_zip_file = os.path.join(test_slack_dir, "test_slack_importer.zip") test_slack_unzipped_file = os.path.join(test_slack_dir, "test_slack_importer") test_realm_subdomain = 'test-slack-import' output_dir = os.path.join(settings.DEPLOY_ROOT, "var", "test-slack-importer-data") token = 'valid-token' # If the test fails, the 'output_dir' would not be deleted and hence it would give an # error when we run the tests next time, as 'do_convert_data' expects an empty 'output_dir' # hence we remove it before running 'do_convert_data' self.rm_tree(output_dir) # Also the unzipped data file should be removed if the test fails at 'do_convert_data' self.rm_tree(test_slack_unzipped_file) user_data_fixture = ujson.loads( self.fixture_data('user_data.json', type='slack_fixtures')) team_info_fixture = ujson.loads( self.fixture_data('team_info.json', type='slack_fixtures')) mock_get_slack_api_data.side_effect = [ user_data_fixture['members'], {}, team_info_fixture["team"] ] mock_requests_get.return_value.raw = get_test_image_file("img.png") do_convert_data(test_slack_zip_file, output_dir, token) self.assertTrue(os.path.exists(output_dir)) self.assertTrue(os.path.exists(output_dir + '/realm.json')) realm_icons_path = os.path.join(output_dir, 'realm_icons') realm_icon_records_path = os.path.join(realm_icons_path, 'records.json') self.assertTrue(os.path.exists(realm_icon_records_path)) with open(realm_icon_records_path) as f: records = ujson.load(f) self.assertEqual(len(records), 2) self.assertEqual(records[0]["path"], "0/icon.original") self.assertTrue( os.path.exists( os.path.join(realm_icons_path, records[0]["path"]))) self.assertEqual(records[1]["path"], "0/icon.png") self.assertTrue( os.path.exists( os.path.join(realm_icons_path, records[1]["path"]))) # test import of the converted slack data into an existing database with self.settings(BILLING_ENABLED=False): do_import_realm(output_dir, test_realm_subdomain) realm = get_realm(test_realm_subdomain) self.assertTrue(realm.name, test_realm_subdomain) self.assertEqual(realm.icon_source, Realm.ICON_UPLOADED) # test RealmAuditLog realmauditlog = RealmAuditLog.objects.filter(realm=realm) realmauditlog_event_type = {log.event_type for log in realmauditlog} self.assertEqual( realmauditlog_event_type, { RealmAuditLog.SUBSCRIPTION_CREATED, RealmAuditLog.REALM_PLAN_TYPE_CHANGED }) Realm.objects.filter(name=test_realm_subdomain).delete() remove_folder(output_dir) # remove tar file created in 'do_convert_data' function os.remove(output_dir + '.tar.gz') self.assertFalse(os.path.exists(output_dir))
def test_s3_source_type(self) -> None: def get_file_path_urlpart(uri: str, size: str = '') -> str: url_in_result = 'smart/filters:no_upscale()%s/%s/source_type/s3' sharpen_filter = '' if size: url_in_result = '/%s/%s' % (size, url_in_result) sharpen_filter = ':sharpen(0.5,0.2,true)' hex_uri = base64.urlsafe_b64encode(uri.encode()).decode('utf-8') return url_in_result % (sharpen_filter, hex_uri) create_s3_buckets(settings.S3_AUTH_UPLOADS_BUCKET, settings.S3_AVATAR_BUCKET) self.login(self.example_email("hamlet")) fp = StringIO("zulip!") fp.name = "zulip.jpeg" result = self.client_post("/json/user_uploads", {'file': fp}) self.assert_json_success(result) json = ujson.loads(result.content) self.assertIn("uri", json) uri = json["uri"] base = '/user_uploads/' self.assertEqual(base, uri[:len(base)]) quoted_uri = urllib.parse.quote(uri[1:], safe='') # Test full size image. result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test thumbnail size. result = self.client_get("/thumbnail?url=%s&size=thumbnail" % (quoted_uri)) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri, '0x300') self.assertIn(expected_part_url, result.url) # Test custom emoji urls in Zulip messages. user_profile = self.example_user("hamlet") image_file = get_test_image_file("img.png") file_name = "emoji.png" upload_emoji_image(image_file, file_name, user_profile) custom_emoji_url = upload_backend.get_emoji_url( file_name, user_profile.realm_id) emoji_url_base = '/user_avatars/' self.assertEqual(emoji_url_base, custom_emoji_url[:len(emoji_url_base)]) quoted_emoji_url = urllib.parse.quote(custom_emoji_url[1:], safe='') # Test full size custom emoji image (for emoji link in messages case). result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_emoji_url)) self.assertEqual(result.status_code, 302, result) self.assertIn(custom_emoji_url, result.url) # Tests the /api/v1/thumbnail api endpoint with standard API auth self.logout() result = self.api_get(self.example_email("hamlet"), '/thumbnail?url=%s&size=full' % (quoted_uri, )) self.assertEqual(result.status_code, 302, result) expected_part_url = get_file_path_urlpart(uri) self.assertIn(expected_part_url, result.url) # Test with another user trying to access image using thumbor. self.login(self.example_email("iago")) result = self.client_get("/thumbnail?url=%s&size=full" % (quoted_uri)) self.assertEqual(result.status_code, 403, result) self.assert_in_response("You are not authorized to view this file.", result)
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) with get_test_image_file("img.png") as fp1: emoji_data = {"f1": fp1} result = self.client_post("/json/realm/emoji/my_emoji_1", info=emoji_data) self.assert_json_error(result, "Insufficient permission") do_change_user_role(othello, UserProfile.ROLE_REALM_ADMINISTRATOR, 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_1", info=emoji_data) self.assert_json_success(result) 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) 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_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) self.assert_json_error(result, "Not allowed for guest users") 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)
def test_realm_icon_upload_file_size_error(self) -> None: self.login(self.example_email("iago")) with get_test_image_file(self.correct_files[0][0]) as fp: with self.settings(MAX_ICON_FILE_SIZE=0): result = self.client_post("/json/realm/icon", {'file': fp}) self.assert_json_error(result, "Uploaded file is larger than the allowed limit of 0 MB")
def test_missing_name_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/', info=emoji_data) self.assert_json_error(result, 'Emoji name is missing')