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 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_success_stream(self): # type: () -> 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_receive_stream_email_messages_empty_body(self): # build dummy messages for stream # test message with empty body is not sent self.login("*****@*****.**") user_profile = get_user_profile_by_email("*****@*****.**") self.subscribe_to_stream(user_profile.email, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) headers = {} headers['Reply-To'] = '*****@*****.**' # empty body incoming_valid_message = MIMEText('') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = "*****@*****.**" incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = "*****@*****.**" exception_message = "" debug_info = {} # process_message eats the exception & logs an error which can't be parsed here # so calling process_stream_message directly try: process_stream_message(incoming_valid_message['To'], incoming_valid_message['Subject'], incoming_valid_message, debug_info) except ZulipEmailForwardError, e: # empty body throws exception exception_message = e.message
def test_receive_stream_email_messages_success(self): # build dummy messages for stream # test valid incoming stream message is processed properly self.login("*****@*****.**") user_profile = get_user_profile_by_email("*****@*****.**") self.subscribe_to_stream(user_profile.email, "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'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = "*****@*****.**" incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = "*****@*****.**" 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.subject, 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_receive_stream_email_messages_empty_body(self): # build dummy messages for stream # test message with empty body is not sent self.login("*****@*****.**") user_profile = get_user_profile_by_email("*****@*****.**") self.subscribe_to_stream(user_profile.email, "Denmark") stream = get_stream("Denmark", user_profile.realm) stream_to_address = encode_email_address(stream) headers = {} headers['Reply-To'] = '*****@*****.**' # empty body incoming_valid_message = MIMEText('') incoming_valid_message['Subject'] = 'TestStreamEmailMessages Subject' incoming_valid_message['From'] = "*****@*****.**" incoming_valid_message['To'] = stream_to_address incoming_valid_message['Reply-to'] = "*****@*****.**" exception_message = "" debug_info = {} # process_message eats the exception & logs an error which can't be parsed here # so calling process_stream_message directly try: process_stream_message(incoming_valid_message['To'], incoming_valid_message['Subject'], incoming_valid_message, debug_info) except ZulipEmailForwardError as e: # empty body throws exception exception_message = e.message self.assertEqual(exception_message, "Unable to find plaintext or HTML message body")
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%0046%0032help')) self.assertTrue(email_address.endswith('@testserver')) tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) email_address = email_address.replace('+', '.') tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) email_address = email_address.replace('@testserver', '@zulip.org') self.assertEqual(decode_email_address(email_address), None) with self.settings(EMAIL_GATEWAY_EXTRA_PATTERN_HACK='@zulip.org'): tup = decode_email_address(email_address) assert tup is not None (decoded_stream_name, token) = tup self.assertEqual(decoded_stream_name, stream_name) self.assertEqual(token, stream.email_token) self.assertEqual(decode_email_address('bogus'), None)
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_receive_stream_email_messages_success(self) -> None: # build dummy messages for stream # test valid incoming stream message is processed properly 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') # type: Any # https://github.com/python/typeshed/issues/275 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_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_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_encode_email_addr(self): # type: () -> None stream = get_stream("Denmark", get_realm("zulip")) with self.settings(EMAIL_GATEWAY_PATTERN=''): test_address = encode_email_address(stream) self.assertEqual(test_address, '')
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) template_path = os.path.join(MAILS_DIR, "simple.txt") with open(template_path) as template_file: mail_template = template_file.read() 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_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) # type: Any # https://github.com/python/typeshed/issues/275 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")
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) template_path = os.path.join(MAILS_DIR, "simple.txt") with open(template_path) as template_file: mail_template = template_file.read() 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_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() # type: Any # https://github.com/python/typeshed/issues/275 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(incoming_valid_message['To'], incoming_valid_message['Subject'], 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_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('') # type: Any # https://github.com/python/typeshed/issues/275 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(incoming_valid_message['To'], incoming_valid_message['Subject'], 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_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('') # type: Any # https://github.com/python/typeshed/issues/275 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(incoming_valid_message['To'], incoming_valid_message['Subject'], 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_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') # type: Any # https://github.com/python/typeshed/issues/275 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_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_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')) tup = decode_email_address(email_address) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) parts = email_address.split('@') parts[0] += "+show-sender" email_address_show = '@'.join(parts) tup = decode_email_address(email_address_show) assert tup is not None token, show_sender = tup self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) email_address_dots = email_address.replace('+', '.') tup = decode_email_address(email_address_dots) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) email_address_dots_show = email_address_show.replace('+', '.') tup = decode_email_address(email_address_dots_show) assert tup is not None token, show_sender = tup 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') self.assertEqual(decode_email_address(email_address), None) self.assertEqual(decode_email_address(email_address_show), None) with self.settings(EMAIL_GATEWAY_EXTRA_PATTERN_HACK='@zulip.org'): tup = decode_email_address(email_address) assert tup is not None token, show_sender = tup self.assertFalse(show_sender) self.assertEqual(token, stream.email_token) tup = decode_email_address(email_address_show) assert tup is not None token, show_sender = tup self.assertTrue(show_sender) self.assertEqual(token, stream.email_token) self.assertEqual(decode_email_address('bogus'), None)
def test_error_to_stream_with_wrong_address(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_stream") 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_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: tup = decode_email_address(stream_to_address) assert tup is not None token = tup[0] self.assertEqual(token, stream.email_token)
def test_mirror_worker_rate_limiting(self, mock_mirror_email: MagicMock) -> None: fake_client = self.FakeClient() realm = get_realm('zulip') clear_history(RateLimitedRealmMirror(realm)) stream = get_stream('Denmark', realm) stream_to_address = encode_email_address(stream) data = [ dict( message=u'\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=u'\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.email_mirror.incr_ratelimit', side_effect=RateLimiterLockingException): fake_client.queue.append(('email_mirror', data[0])) worker.start() self.assertEqual(mock_mirror_email.call_count, 4)
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 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 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_reply_is_extracted_from_html(self): # type: () -> 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' ) # type: Any # https://github.com/python/typeshed/issues/275 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')
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) template_path = os.path.join(MAILS_DIR, "simple.txt") with open(template_path) as template_file: mail_template = template_file.read() 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', force_str(stream_to_address), '-s', settings.SHARED_SECRET, '-t'], stdin=read_pipe)
def test_reply_is_extracted_from_html(self): # type: () -> 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') # type: Any # https://github.com/python/typeshed/issues/275 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')
def test_success(self): # type: () -> 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) template_path = os.path.join(MAILS_DIR, "simple.txt") with open(template_path) as template_file: mail_template = template_file.read() 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', force_str(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_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_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_blank_subject_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) incoming_valid_message = MIMEText('TestStreamEmailMessages Body') incoming_valid_message['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(), "(no topic)")
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_email_subject_stripping(self) -> None: subject_list = ujson.loads(self.fixture_data('subjects.json', type='email')) for subject in subject_list: 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'] = subject['original_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) if subject['stripped_subject'] is not "": expected_topic = subject['stripped_subject'] else: expected_topic = "(no topic)" self.assertEqual(expected_topic, message.topic_name())
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_email_subject_stripping(self) -> None: subject_list = ujson.loads(self.fixture_data('subjects.json', type='email')) for subject in subject_list: 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'] = subject['original_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) if subject['stripped_subject'] != "": expected_topic = subject['stripped_subject'] else: expected_topic = "(no topic)" self.assertEqual(expected_topic, message.topic_name())
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)