def _prepare_message(self, message: Message, realm: Realm, stream_name: str) -> None: stream = get_stream(stream_name, realm) recipient_headers = [ "X-Gm-Original-To", "Delivered-To", "Resent-To", "Resent-CC", "To", "CC" ] for header in recipient_headers: if header in message: del message[header] message[header] = encode_email_address(stream) return message['To'] = encode_email_address(stream)
def _prepare_message(self, message: Message, realm: Realm, stream_name: str) -> None: stream = get_stream(stream_name, realm) # The block below ensures that the imported email message doesn't have any recipient-like # headers that are inconsistent with the recipient we want (the stream address). recipient_headers = ["X-Gm-Original-To", "Delivered-To", "Resent-To", "Resent-CC", "CC"] for header in recipient_headers: if header in message: del message[header] message[header] = encode_email_address(stream) if 'To' in message: del message['To'] message['To'] = encode_email_address(stream)
def test_log_and_report(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "errors") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) address_parts = stream_to_address.split('@') scrubbed_address = 'X'*len(address_parts[0]) + '@' + address_parts[1] incoming_valid_message = MIMEText('Test Body') incoming_valid_message['Subject'] = "Test Subject" incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address log_and_report(incoming_valid_message, "test error message", stream_to_address) message = most_recent_message(user_profile) self.assertEqual("email mirror error", message.topic_name()) msg_content = message.content.strip('~').strip() expected_content = "Sender: {}\nTo: {} <Address to stream id: {}>\ntest error message" expected_content = expected_content.format(self.example_email('hamlet'), scrubbed_address, stream.id) self.assertEqual(msg_content, expected_content) log_and_report(incoming_valid_message, "test error message", None) message = most_recent_message(user_profile) self.assertEqual("email mirror error", message.topic_name()) msg_content = message.content.strip('~').strip() expected_content = "Sender: {}\nTo: No recipient found\ntest error message" expected_content = expected_content.format(self.example_email('hamlet')) self.assertEqual(msg_content, expected_content)
def test_receive_private_stream_email_messages_success(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.make_stream("private_stream", invite_only=True) self.subscribe(user_profile, "private_stream") stream = get_stream("private_stream", user_profile.realm) stream_to_address = encode_email_address(stream) incoming_valid_message = MIMEText('TestStreamEmailMessages Body') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) # Hamlet is subscribed to this stream so should see the email message from Othello. message = most_recent_message(user_profile) self.assertEqual(message.content, "TestStreamEmailMessages Body") self.assertEqual(get_display_recipient(message.recipient), stream.name) self.assertEqual(message.topic_name(), incoming_valid_message['Subject'])
def test_receive_stream_email_multiple_recipient_success(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) # stream address is angle-addr within multiple addresses stream_to_addresses = [ "A.N. Other <*****@*****.**>", "Denmark <{}>".format(encode_email_address(stream)) ] incoming_valid_message = MIMEText('TestStreamEmailMessages Body') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = ", ".join(stream_to_addresses) incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) # Hamlet is subscribed to this stream so should see the email message from Othello. message = most_recent_message(user_profile) self.assertEqual(message.content, "TestStreamEmailMessages Body") self.assertEqual(get_display_recipient(message.recipient), stream.name) self.assertEqual(message.topic_name(), incoming_valid_message['Subject'])
def test_receive_stream_email_show_sender_success(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) parts = stream_to_address.split('@') parts[0] += "+show-sender" stream_to_address = '@'.join(parts) incoming_valid_message = MIMEText('TestStreamEmailMessages Body') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual( message.content, "From: %s\n%s" % (self.example_email('hamlet'), "TestStreamEmailMessages Body")) self.assertEqual(get_display_recipient(message.recipient), stream.name) self.assertEqual(message.topic_name(), incoming_valid_message['Subject'])
def test_message_with_valid_attachment(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) incoming_valid_message = MIMEMultipart() text_msg = MIMEText("Test body") incoming_valid_message.attach(text_msg) with open(os.path.join(settings.DEPLOY_ROOT, "static/images/default-avatar.png"), 'rb') as f: image_bytes = f.read() attachment_msg = MIMEImage(image_bytes) attachment_msg.add_header('Content-Disposition', 'attachment', filename="image.png") incoming_valid_message.attach(attachment_msg) incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') with mock.patch('zerver.lib.email_mirror.upload_message_file', return_value='https://test_url') as upload_message_file: process_message(incoming_valid_message) upload_message_file.assert_called_with('image.png', len(image_bytes), 'image/png', image_bytes, get_system_bot(settings.EMAIL_GATEWAY_BOT), target_realm=user_profile.realm) message = most_recent_message(user_profile) self.assertEqual(message.content, "Test body[image.png](https://test_url)")
def test_error_no_recipient(self) -> None: script = os.path.join(os.path.dirname(__file__), '../../scripts/lib/email-mirror-postfix') sender = self.example_email('hamlet') stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) mail_template = self.fixture_data('simple.txt', type='email') mail = mail_template.format(stream_to_address=stream_to_address, sender=sender) read_pipe, write_pipe = os.pipe() os.write(write_pipe, mail.encode()) os.close(write_pipe) success_call = True try: subprocess.check_output( [script, '-s', settings.SHARED_SECRET, '-t'], stdin=read_pipe) except subprocess.CalledProcessError as e: self.assertEqual( e.output, b'5.1.1 Bad destination mailbox address: No missed message email address.\n' ) self.assertEqual(e.returncode, 67) success_call = False self.assertFalse(success_call)
def test_mirror_worker_rate_limiting(self, mock_mirror_email: MagicMock, mock_warn: MagicMock) -> None: fake_client = self.FakeClient() realm = get_realm('zulip') RateLimitedRealmMirror(realm).clear_history() stream = get_stream('Denmark', realm) stream_to_address = encode_email_address(stream) data = [ dict( message='\xf3test', time=time.time(), rcpt_to=stream_to_address ) ] * 5 for element in data: fake_client.queue.append(('email_mirror', element)) with simulated_queue_client(lambda: fake_client): start_time = time.time() with patch('time.time', return_value=start_time): worker = queue_processors.MirrorWorker() worker.setup() worker.start() # Of the first 5 messages, only 2 should be processed # (the rest being rate-limited): self.assertEqual(mock_mirror_email.call_count, 2) # If a new message is sent into the stream mirror, it will get rejected: fake_client.queue.append(('email_mirror', data[0])) worker.start() self.assertEqual(mock_mirror_email.call_count, 2) # However, missed message emails don't get rate limited: with self.settings(EMAIL_GATEWAY_PATTERN="*****@*****.**"): address = 'mm' + ('x' * 32) + '@example.com' event = dict( message='\xf3test', time=time.time(), rcpt_to=address ) fake_client.queue.append(('email_mirror', event)) worker.start() self.assertEqual(mock_mirror_email.call_count, 3) # After some times passes, emails get accepted again: with patch('time.time', return_value=(start_time + 11.0)): fake_client.queue.append(('email_mirror', data[0])) worker.start() self.assertEqual(mock_mirror_email.call_count, 4) # If RateLimiterLockingException is thrown, we rate-limit the new message: with patch('zerver.lib.rate_limiter.RedisRateLimiterBackend.incr_ratelimit', side_effect=RateLimiterLockingException): fake_client.queue.append(('email_mirror', data[0])) worker.start() self.assertEqual(mock_mirror_email.call_count, 4) mock_warn.assert_called_with( "Deadlock trying to incr_ratelimit for %s", "RateLimitedRealmMirror:%s" % (realm.string_id,), )
def test_success_to_stream_with_good_token_wrong_stream_name(self) -> None: stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) stream_to_address = stream_to_address.replace("denmark", "Wrong_name") result = self.send_offline_message(stream_to_address, self.example_email('hamlet')) self.assert_json_success(result)
def test_decode_ignores_stream_name(self) -> None: stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) stream_to_address = stream_to_address.replace("denmark", "Some_name") # get the email_token: token = decode_email_address(stream_to_address)[0] self.assertEqual(token, stream.email_token)
def test_encode_decode_nonlatin_alphabet_stream_name(self) -> None: realm = get_realm('zulip') stream_name = 'Тестовы some ascii letters' stream = ensure_stream(realm, stream_name) email_address = encode_email_address(stream) msg_string = get_email_gateway_message_string_from_address(email_address) parts = msg_string.split('+') # Stream name should be completely stripped to '', so msg_string # should only have the email_token in it. self.assertEqual(len(parts), 1) # Correctly decode the resulting address that doesn't have the stream name: token, show_sender = decode_email_address(email_address) self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) asciiable_stream_name = "ąężć" stream = ensure_stream(realm, asciiable_stream_name) email_address = encode_email_address(stream) self.assertTrue(email_address.startswith("aezc+"))
def test_error_to_stream_with_wrong_address(self) -> None: stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) # get the email_token: token = decode_email_address(stream_to_address)[0] stream_to_address = stream_to_address.replace(token, "Wrong_token") result = self.send_offline_message(stream_to_address, self.example_email('hamlet')) self.assert_json_error( result, "5.1.1 Bad destination mailbox address: " "Please use the address specified in your Streams page.")
def test_reply_is_extracted_from_html(self) -> None: # build dummy messages for stream # test valid incoming stream message is processed properly email = self.example_email('hamlet') self.login(email) user_profile = self.example_user('hamlet') self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) html = """ <html> <body> <p>Reply</p> <blockquote> <div> On 11-Apr-2011, at 6:54 PM, Bob <[email protected]> wrote: </div> <div> Quote </div> </blockquote> </body> </html> """ incoming_valid_message = MIMEText(html, 'html') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) # Hamlet is subscribed to this stream so should see the email message from Othello. message = most_recent_message(user_profile) self.assertEqual(message.content, 'Reply') # Don't extract if Subject indicates the email has been forwarded into the mirror: del incoming_valid_message['Subject'] incoming_valid_message[ 'Subject'] = 'FWD: TestStreamEmailMessages Subject' process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual(message.content, convert_html_to_markdown(html))
def send_subscription_add_events( realm: Realm, sub_info_list: List[SubInfo], subscriber_dict: Dict[int, Set[int]], ) -> None: info_by_user: Dict[int, List[SubInfo]] = defaultdict(list) for sub_info in sub_info_list: info_by_user[sub_info.user.id].append(sub_info) stream_ids = {sub_info.stream.id for sub_info in sub_info_list} recent_traffic = get_streams_traffic(stream_ids=stream_ids) # We generally only have a few streams, so we compute stream # data in its own loop. stream_info_dict: Dict[int, StreamInfo] = {} for sub_info in sub_info_list: stream = sub_info.stream if stream.id not in stream_info_dict: email_address = encode_email_address(stream, show_sender=True) stream_weekly_traffic = get_average_weekly_stream_traffic( stream.id, stream.date_created, recent_traffic ) if stream.is_in_zephyr_realm and not stream.invite_only: subscribers = [] else: subscribers = list(subscriber_dict[stream.id]) stream_info_dict[stream.id] = StreamInfo( email_address=email_address, stream_weekly_traffic=stream_weekly_traffic, subscribers=subscribers, ) for user_id, sub_infos in info_by_user.items(): sub_dicts = [] for sub_info in sub_infos: stream = sub_info.stream stream_info = stream_info_dict[stream.id] subscription = sub_info.sub sub_dict = stream.to_dict() for field_name in Subscription.API_FIELDS: sub_dict[field_name] = getattr(subscription, field_name) sub_dict["in_home_view"] = not subscription.is_muted sub_dict["email_address"] = stream_info.email_address sub_dict["stream_weekly_traffic"] = stream_info.stream_weekly_traffic sub_dict["subscribers"] = stream_info.subscribers sub_dicts.append(sub_dict) # Send a notification to the user who subscribed. event = dict(type="subscription", op="add", subscriptions=sub_dicts) send_event(realm, event, [user_id])
def test_encode_decode(self) -> None: realm = get_realm('zulip') stream_name = 'dev. help' stream = ensure_stream(realm, stream_name) email_address = encode_email_address(stream) self.assertTrue(email_address.startswith('dev-help')) self.assertTrue(email_address.endswith('@testserver')) token, show_sender = decode_email_address(email_address) self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) parts = email_address.split('@') parts[0] += "+show-sender" email_address_show = '@'.join(parts) token, show_sender = decode_email_address(email_address_show) self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) email_address_dots = email_address.replace('+', '.') token, show_sender = decode_email_address(email_address_dots) self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) email_address_dots_show = email_address_show.replace('+', '.') token, show_sender = decode_email_address(email_address_dots_show) self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) email_address = email_address.replace('@testserver', '@zulip.org') email_address_show = email_address_show.replace( '@testserver', '@zulip.org') with self.assertRaises(ZulipEmailForwardError): decode_email_address(email_address) with self.assertRaises(ZulipEmailForwardError): decode_email_address(email_address_show) with self.settings(EMAIL_GATEWAY_EXTRA_PATTERN_HACK='@zulip.org'): token, show_sender = decode_email_address(email_address) self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) token, show_sender = decode_email_address(email_address_show) self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) with self.assertRaises(ZulipEmailForwardError): decode_email_address('bogus')
def test_success(self) -> None: script = os.path.join(os.path.dirname(__file__), '../../scripts/lib/email-mirror-postfix') sender = self.example_email('hamlet') stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) mail_template = self.fixture_data('simple.txt', type='email') mail = mail_template.format(stream_to_address=stream_to_address, sender=sender) read_pipe, write_pipe = os.pipe() os.write(write_pipe, mail.encode()) os.close(write_pipe) subprocess.check_call( [script, '-r', stream_to_address, '-s', settings.SHARED_SECRET, '-t'], stdin=read_pipe)
def test_mirror_worker(self, mock_mirror_email: MagicMock) -> None: fake_client = self.FakeClient() stream = get_stream('Denmark', get_realm('zulip')) stream_to_address = encode_email_address(stream) data = [ dict(message=u'\xf3test', time=time.time(), rcpt_to=stream_to_address) ] * 3 for element in data: fake_client.queue.append(('email_mirror', element)) with simulated_queue_client(lambda: fake_client): worker = queue_processors.MirrorWorker() worker.setup() worker.start() self.assertEqual(mock_mirror_email.call_count, 3)
def test_charset_not_specified(self) -> None: message_as_string = self.fixture_data('1.txt', type='email') message_as_string = message_as_string.replace("Content-Type: text/plain; charset=\"us-ascii\"", "Content-Type: text/plain") incoming_message = message_from_string(message_as_string) user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) del incoming_message['To'] incoming_message['To'] = stream_to_address process_message(incoming_message) message = most_recent_message(user_profile) self.assertEqual(message.content, "Email fixture 1.txt body")
def test_receive_stream_email_messages_no_textual_body(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) # No textual body incoming_valid_message = MIMEMultipart() with open(os.path.join(settings.DEPLOY_ROOT, "static/images/default-avatar.png"), 'rb') as f: incoming_valid_message.attach(MIMEImage(f.read())) incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') with mock.patch('zerver.lib.email_mirror.logging.warning') as mock_warn: process_message(incoming_valid_message) mock_warn.assert_called_with("Unable to find plaintext or HTML message body")
def test_mirror_worker(self, mock_mirror_email: MagicMock) -> None: fake_client = self.FakeClient() stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) data = [ dict( msg_base64=base64.b64encode(b"\xf3test").decode(), time=time.time(), rcpt_to=stream_to_address, ), ] * 3 for element in data: fake_client.enqueue("email_mirror", element) with simulated_queue_client(lambda: fake_client): worker = queue_processors.MirrorWorker() worker.setup() worker.start() self.assertEqual(mock_mirror_email.call_count, 3)
def test_receive_stream_email_messages_empty_body(self) -> None: # build dummy messages for stream # test message with empty body is not sent user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) # empty body incoming_valid_message = MIMEText('') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') with mock.patch('zerver.lib.email_mirror.logging.warning') as mock_warn: process_message(incoming_valid_message) mock_warn.assert_called_with("Email has no nonempty body sections; ignoring.")
def test_receive_stream_email_messages_no_textual_body(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) headers = {} headers['Reply-To'] = self.example_email('othello') # No textual body incoming_valid_message = MIMEMultipart() with open( os.path.join(settings.DEPLOY_ROOT, "static/images/default-avatar.png"), 'rb') as f: incoming_valid_message.attach(MIMEImage(f.read())) incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') exception_message = "" debug_info = {} # type: Dict[str, Any] # process_message eats the exception & logs an error which can't be parsed here # so calling process_stream_message directly try: with mock.patch('logging.warning'): process_stream_message( str(incoming_valid_message['To'] ), # need to insert str() or mypy throws type error incoming_valid_message, debug_info) except ZulipEmailForwardError as e: # empty body throws exception exception_message = str(e) self.assertEqual(exception_message, "Unable to find plaintext or HTML message body")
def test_process_message_strips_subject(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) incoming_valid_message = MIMEText('TestStreamEmailMessages Body') incoming_valid_message['Subject'] = "Re: Fwd: Re: Test" incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual("Test", message.topic_name()) # If after stripping we get an empty subject, it should get set to (no topic) del incoming_valid_message['Subject'] incoming_valid_message['Subject'] = "Re: Fwd: Re: " process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual("(no topic)", message.topic_name())
def test_receive_stream_email_messages_empty_body_after_stripping(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) headers = {} headers['Reply-To'] = self.example_email('othello') # empty body incoming_valid_message = MIMEText('-- \nFooter') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual(message.content, "(No email body)")
def test_reply_is_extracted_from_plain(self) -> None: # build dummy messages for stream # test valid incoming stream message is processed properly email = self.example_email('hamlet') self.login(email) user_profile = self.example_user('hamlet') self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) text = """Reply -----Original Message----- Quote""" incoming_valid_message = MIMEText(text) incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') process_message(incoming_valid_message) # Hamlet is subscribed to this stream so should see the email message from Othello. message = most_recent_message(user_profile) self.assertEqual(message.content, "Reply") # Don't extract if Subject indicates the email has been forwarded into the mirror: del incoming_valid_message['Subject'] incoming_valid_message[ 'Subject'] = 'FWD: TestStreamEmailMessages Subject' process_message(incoming_valid_message) message = most_recent_message(user_profile) self.assertEqual(message.content, text)
def test_receive_stream_email_messages_empty_body(self) -> None: # build dummy messages for stream # test message with empty body is not sent user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) headers = {} headers['Reply-To'] = self.example_email('othello') # empty body incoming_valid_message = MIMEText('') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') exception_message = "" debug_info = {} # type: Dict[str, Any] # process_message eats the exception & logs an error which can't be parsed here # so calling process_stream_message directly try: process_stream_message( str(incoming_valid_message['To'] ), # need to insert str() or mypy throws type error incoming_valid_message, debug_info) except ZulipEmailForwardError as e: # empty body throws exception exception_message = str(e) self.assertEqual(exception_message, "Email has no nonempty body sections; ignoring.")
def test_message_with_invalid_attachment(self) -> None: user_profile = self.example_user('hamlet') self.login(user_profile.email) self.subscribe(user_profile, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) incoming_valid_message = MIMEMultipart() text_msg = MIMEText("Test body") incoming_valid_message.attach(text_msg) # Create an invalid attachment: attachment_msg = MIMEMultipart() attachment_msg.add_header('Content-Disposition', 'attachment', filename="some_attachment") incoming_valid_message.attach(attachment_msg) incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = self.example_email('hamlet') incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = self.example_email('othello') with mock.patch('zerver.lib.email_mirror.logger.warning') as mock_warn: process_message(incoming_valid_message) mock_warn.assert_called_with("Payload is not bytes (invalid attachment %s in message from %s)." % ('some_attachment', self.example_email('hamlet')))
def test_success_stream(self) -> None: stream = get_stream("Denmark", get_realm("zulip")) stream_to_address = encode_email_address(stream) result = self.send_offline_message(stream_to_address, self.example_email('hamlet')) self.assert_json_success(result)
def test_encode_email_addr(self) -> None: stream = get_stream("Denmark", get_realm("zulip")) with self.settings(EMAIL_GATEWAY_PATTERN=''): test_address = encode_email_address(stream) self.assertEqual(test_address, '')