2017-03-08 12:28:24 +01:00
import random
import re
2020-06-05 23:26:35 +02:00
from email . headerregistry import Address
2020-06-13 03:34:01 +02:00
from typing import List , Sequence
2020-06-11 00:54:34 +02:00
from unittest . mock import patch
2017-03-08 12:28:24 +01:00
2020-06-11 00:54:34 +02:00
import ldap
2020-08-07 01:09:47 +02:00
import orjson
2017-03-08 12:28:24 +01:00
from django . conf import settings
from django . core import mail
from django . test import override_settings
2019-10-05 03:54:48 +02:00
from django_auth_ldap . config import LDAPSearch
2017-03-08 12:28:24 +01:00
2020-05-21 00:13:06 +02:00
from zerver . lib . actions import do_change_notification_settings , do_change_user_role
2020-06-11 00:54:34 +02:00
from zerver . lib . email_notifications import (
enqueue_welcome_emails ,
fix_emojis ,
2020-07-15 01:21:28 +02:00
fix_spoilers_in_html ,
2020-06-11 00:54:34 +02:00
handle_missedmessage_emails ,
relative_to_full_url ,
2017-05-08 17:54:11 +02:00
)
2020-06-11 00:54:34 +02:00
from zerver . lib . send_email import FromAddress , send_custom_email
from zerver . lib . test_classes import ZulipTestCase
from zerver . models import ScheduledEmail , UserProfile , get_realm , get_stream
2017-03-08 12:28:24 +01:00
2020-04-09 13:39:16 +02:00
class TestCustomEmails ( ZulipTestCase ) :
def test_send_custom_email_argument ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
email_subject = " subject_test "
reply_to = " reply_to_test "
2020-04-09 13:39:16 +02:00
from_name = " from_name_test "
markdown_template_path = " templates/zerver/emails/email_base_default.source.html "
2021-02-12 08:19:30 +01:00
send_custom_email (
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" reply_to " : reply_to ,
" subject " : email_subject ,
" from_name " : from_name ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2020-04-09 13:39:16 +02:00
msg = mail . outbox [ 0 ]
self . assertEqual ( msg . subject , email_subject )
2021-05-17 05:41:32 +02:00
self . assert_length ( msg . reply_to , 1 )
2020-04-09 13:39:16 +02:00
self . assertEqual ( msg . reply_to [ 0 ] , reply_to )
self . assertNotIn ( " { % block content % } " , msg . body )
def test_send_custom_email_headers ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2021-02-12 08:19:30 +01:00
markdown_template_path = (
" zerver/tests/fixtures/email/custom_emails/email_base_headers_test.source.html "
)
send_custom_email (
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2020-04-09 13:39:16 +02:00
msg = mail . outbox [ 0 ]
2021-05-10 07:02:14 +02:00
self . assertEqual ( msg . subject , " Test subject " )
2020-04-09 13:39:16 +02:00
self . assertFalse ( msg . reply_to )
2021-02-12 08:20:45 +01:00
self . assertEqual ( " Test body " , msg . body )
2020-04-09 13:39:16 +02:00
def test_send_custom_email_no_argument ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2020-04-09 13:39:16 +02:00
from_name = " from_name_test "
2021-02-12 08:20:45 +01:00
email_subject = " subject_test "
2020-04-09 13:39:16 +02:00
markdown_template_path = " zerver/tests/fixtures/email/custom_emails/email_base_headers_no_headers_test.source.html "
from zerver . lib . send_email import NoEmailArgumentException
2021-02-12 08:19:30 +01:00
self . assertRaises (
NoEmailArgumentException ,
send_custom_email ,
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" from_name " : from_name ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
self . assertRaises (
NoEmailArgumentException ,
send_custom_email ,
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" subject " : email_subject ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
2020-04-09 13:39:16 +02:00
def test_send_custom_email_doubled_arguments ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2020-04-09 13:39:16 +02:00
from_name = " from_name_test "
2021-02-12 08:20:45 +01:00
email_subject = " subject_test "
2021-02-12 08:19:30 +01:00
markdown_template_path = (
" zerver/tests/fixtures/email/custom_emails/email_base_headers_test.source.html "
)
2020-04-09 13:39:16 +02:00
from zerver . lib . send_email import DoubledEmailArgumentException
2021-02-12 08:19:30 +01:00
self . assertRaises (
DoubledEmailArgumentException ,
send_custom_email ,
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" subject " : email_subject ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
self . assertRaises (
DoubledEmailArgumentException ,
send_custom_email ,
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" from_name " : from_name ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
2020-04-09 13:39:16 +02:00
2020-04-18 15:51:29 +02:00
def test_send_custom_email_admins_only ( self ) - > None :
2021-02-12 08:20:45 +01:00
admin_user = self . example_user ( " hamlet " )
2021-03-27 05:13:46 +01:00
do_change_user_role ( admin_user , UserProfile . ROLE_REALM_ADMINISTRATOR , acting_user = None )
2020-04-18 15:51:29 +02:00
2021-02-12 08:20:45 +01:00
non_admin_user = self . example_user ( " cordelia " )
2020-04-18 15:51:29 +02:00
2021-02-12 08:19:30 +01:00
markdown_template_path = (
" zerver/tests/fixtures/email/custom_emails/email_base_headers_test.source.html "
)
send_custom_email (
[ admin_user , non_admin_user ] ,
{
" markdown_template_path " : markdown_template_path ,
" admins_only " : True ,
2021-04-07 01:27:02 +02:00
" dry_run " : False ,
2021-02-12 08:19:30 +01:00
} ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2020-04-18 15:51:29 +02:00
self . assertIn ( admin_user . delivery_email , mail . outbox [ 0 ] . to [ 0 ] )
2021-04-07 01:27:02 +02:00
def test_send_custom_email_dry_run ( self ) - > None :
hamlet = self . example_user ( " hamlet " )
email_subject = " subject_test "
reply_to = " reply_to_test "
from_name = " from_name_test "
markdown_template_path = " templates/zerver/tests/markdown/test_nested_code_blocks.md "
with patch ( " builtins.print " ) as _ :
send_custom_email (
[ hamlet ] ,
{
" markdown_template_path " : markdown_template_path ,
" reply_to " : reply_to ,
" subject " : email_subject ,
" from_name " : from_name ,
" dry_run " : True ,
} ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 0 )
2021-04-07 01:27:02 +02:00
2020-04-09 13:39:16 +02:00
2018-11-14 12:46:56 +01:00
class TestFollowupEmails ( ZulipTestCase ) :
def test_day1_email_context ( self ) - > None :
hamlet = self . example_user ( " hamlet " )
enqueue_welcome_emails ( hamlet )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = hamlet )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2018-11-14 12:46:56 +01:00
self . assertEqual ( email_data [ " context " ] [ " email " ] , self . example_email ( " hamlet " ) )
self . assertEqual ( email_data [ " context " ] [ " is_realm_admin " ] , False )
2020-06-08 23:04:39 +02:00
self . assertEqual ( email_data [ " context " ] [ " getting_started_link " ] , " https://zulip.com " )
2018-11-14 12:46:56 +01:00
self . assertNotIn ( " ldap_username " , email_data [ " context " ] )
ScheduledEmail . objects . all ( ) . delete ( )
iago = self . example_user ( " iago " )
enqueue_welcome_emails ( iago )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = iago )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2018-11-14 12:46:56 +01:00
self . assertEqual ( email_data [ " context " ] [ " email " ] , self . example_email ( " iago " ) )
self . assertEqual ( email_data [ " context " ] [ " is_realm_admin " ] , True )
2021-02-12 08:19:30 +01:00
self . assertEqual (
email_data [ " context " ] [ " getting_started_link " ] ,
" http://zulip.testserver/help/getting-your-organization-started-with-zulip " ,
)
2018-11-14 12:46:56 +01:00
self . assertNotIn ( " ldap_username " , email_data [ " context " ] )
2018-11-29 16:32:17 +01:00
# See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#ldap-including-active-directory
# for case details.
2021-02-12 08:19:30 +01:00
@override_settings (
AUTHENTICATION_BACKENDS = (
2021-02-12 08:20:45 +01:00
" zproject.backends.ZulipLDAPAuthBackend " ,
" zproject.backends.ZulipDummyBackend " ,
2021-02-12 08:19:30 +01:00
) ,
# configure email search for email address in the uid attribute:
AUTH_LDAP_REVERSE_EMAIL_SEARCH = LDAPSearch (
" ou=users,dc=zulip,dc=com " , ldap . SCOPE_ONELEVEL , " (uid= %(email)s ) "
) ,
)
2018-11-29 16:32:17 +01:00
def test_day1_email_ldap_case_a_login_credentials ( self ) - > None :
2019-10-16 18:27:53 +02:00
self . init_default_ldap_database ( )
2021-02-12 08:20:45 +01:00
ldap_user_attr_map = { " full_name " : " cn " }
2019-10-16 18:27:53 +02:00
with self . settings ( AUTH_LDAP_USER_ATTR_MAP = ldap_user_attr_map ) :
2021-02-12 08:19:30 +01:00
self . login_with_return (
" newuser_email_as_uid@zulip.com " ,
self . ldap_password ( " newuser_email_as_uid@zulip.com " ) ,
)
2020-03-12 14:17:25 +01:00
user = UserProfile . objects . get ( delivery_email = " newuser_email_as_uid@zulip.com " )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = user )
2018-11-29 16:32:17 +01:00
2021-05-17 05:41:32 +02:00
self . assert_length ( scheduled_emails , 2 )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2018-11-29 16:32:17 +01:00
self . assertEqual ( email_data [ " context " ] [ " ldap " ] , True )
2021-02-12 08:19:30 +01:00
self . assertEqual (
email_data [ " context " ] [ " ldap_username " ] , " newuser_email_as_uid@zulip.com "
)
@override_settings (
AUTHENTICATION_BACKENDS = (
2021-02-12 08:20:45 +01:00
" zproject.backends.ZulipLDAPAuthBackend " ,
" zproject.backends.ZulipDummyBackend " ,
2021-02-12 08:19:30 +01:00
)
)
2018-11-29 16:32:17 +01:00
def test_day1_email_ldap_case_b_login_credentials ( self ) - > None :
2019-10-16 18:27:53 +02:00
self . init_default_ldap_database ( )
2021-02-12 08:20:45 +01:00
ldap_user_attr_map = { " full_name " : " cn " }
2018-11-14 12:46:56 +01:00
with self . settings (
2021-02-12 08:20:45 +01:00
LDAP_APPEND_DOMAIN = " zulip.com " ,
2021-02-12 08:19:30 +01:00
AUTH_LDAP_USER_ATTR_MAP = ldap_user_attr_map ,
2019-10-16 18:27:53 +02:00
) :
2020-02-19 19:40:49 +01:00
self . login_with_return ( " newuser@zulip.com " , self . ldap_password ( " newuser " ) )
2018-11-29 16:32:17 +01:00
2020-03-12 14:17:25 +01:00
user = UserProfile . objects . get ( delivery_email = " newuser@zulip.com " )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = user )
2018-11-29 16:32:17 +01:00
2021-05-17 05:41:32 +02:00
self . assert_length ( scheduled_emails , 2 )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2018-11-29 16:32:17 +01:00
self . assertEqual ( email_data [ " context " ] [ " ldap " ] , True )
self . assertEqual ( email_data [ " context " ] [ " ldap_username " ] , " newuser " )
2021-02-12 08:19:30 +01:00
@override_settings (
AUTHENTICATION_BACKENDS = (
2021-02-12 08:20:45 +01:00
" zproject.backends.ZulipLDAPAuthBackend " ,
" zproject.backends.ZulipDummyBackend " ,
2021-02-12 08:19:30 +01:00
)
)
2018-11-29 16:32:17 +01:00
def test_day1_email_ldap_case_c_login_credentials ( self ) - > None :
2019-10-16 18:27:53 +02:00
self . init_default_ldap_database ( )
2021-02-12 08:20:45 +01:00
ldap_user_attr_map = { " full_name " : " cn " }
2018-11-29 16:32:17 +01:00
with self . settings (
2021-02-12 08:20:45 +01:00
LDAP_EMAIL_ATTR = " mail " ,
2021-02-12 08:19:30 +01:00
AUTH_LDAP_USER_ATTR_MAP = ldap_user_attr_map ,
2019-10-16 18:27:53 +02:00
) :
2020-02-19 19:40:49 +01:00
self . login_with_return ( " newuser_with_email " , self . ldap_password ( " newuser_with_email " ) )
2020-03-12 14:17:25 +01:00
user = UserProfile . objects . get ( delivery_email = " newuser_email@zulip.com " )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = user )
2018-11-14 12:46:56 +01:00
2021-05-17 05:41:32 +02:00
self . assert_length ( scheduled_emails , 2 )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2018-11-29 16:32:17 +01:00
self . assertEqual ( email_data [ " context " ] [ " ldap " ] , True )
2019-11-05 02:29:03 +01:00
self . assertEqual ( email_data [ " context " ] [ " ldap_username " ] , " newuser_with_email " )
2018-11-14 12:46:56 +01:00
2018-11-14 12:58:35 +01:00
def test_followup_emails_count ( self ) - > None :
hamlet = self . example_user ( " hamlet " )
cordelia = self . example_user ( " cordelia " )
enqueue_welcome_emails ( self . example_user ( " hamlet " ) )
# Hamlet has account only in Zulip realm so both day1 and day2 emails should be sent
2019-04-29 07:00:03 +02:00
scheduled_emails = ScheduledEmail . objects . filter ( users = hamlet ) . order_by (
2021-02-12 08:19:30 +01:00
" scheduled_timestamp "
)
2018-11-14 12:58:35 +01:00
self . assertEqual ( 2 , len ( scheduled_emails ) )
2021-02-12 08:19:30 +01:00
self . assertEqual (
2021-02-12 08:20:45 +01:00
orjson . loads ( scheduled_emails [ 1 ] . data ) [ " template_prefix " ] , " zerver/emails/followup_day2 "
2021-02-12 08:19:30 +01:00
)
self . assertEqual (
2021-02-12 08:20:45 +01:00
orjson . loads ( scheduled_emails [ 0 ] . data ) [ " template_prefix " ] , " zerver/emails/followup_day1 "
2021-02-12 08:19:30 +01:00
)
2018-11-14 12:58:35 +01:00
ScheduledEmail . objects . all ( ) . delete ( )
enqueue_welcome_emails ( cordelia )
2019-01-04 01:50:21 +01:00
scheduled_emails = ScheduledEmail . objects . filter ( users = cordelia )
2018-11-14 12:58:35 +01:00
# Cordelia has account in more than 1 realm so day2 email should not be sent
2021-05-17 05:41:32 +02:00
self . assert_length ( scheduled_emails , 1 )
2020-08-07 01:09:47 +02:00
email_data = orjson . loads ( scheduled_emails [ 0 ] . data )
2021-02-12 08:20:45 +01:00
self . assertEqual ( email_data [ " template_prefix " ] , " zerver/emails/followup_day1 " )
2018-11-14 12:58:35 +01:00
2021-02-12 08:19:30 +01:00
2017-03-08 12:28:24 +01:00
class TestMissedMessages ( ZulipTestCase ) :
2018-05-11 01:39:38 +02:00
def normalize_string ( self , s : str ) - > str :
2017-03-08 12:28:24 +01:00
s = s . strip ( )
2021-02-12 08:20:45 +01:00
return re . sub ( r " \ s+ " , " " , s )
2017-03-08 12:28:24 +01:00
2017-11-05 10:51:25 +01:00
def _get_tokens ( self ) - > List [ str ] :
2021-02-12 08:20:45 +01:00
return [ " mm " + str ( random . getrandbits ( 32 ) ) for _ in range ( 30 ) ]
2017-03-08 12:28:24 +01:00
2021-02-12 08:19:30 +01:00
def _test_cases (
self ,
msg_id : int ,
verify_body_include : List [ str ] ,
email_subject : str ,
send_as_user : bool ,
verify_html_body : bool = False ,
show_message_content : bool = True ,
verify_body_does_not_include : Sequence [ str ] = [ ] ,
2021-02-12 08:20:45 +01:00
trigger : str = " " ,
2021-02-12 08:19:30 +01:00
) - > None :
2021-02-12 08:20:45 +01:00
othello = self . example_user ( " othello " )
hamlet = self . example_user ( " hamlet " )
2019-12-19 18:26:44 +01:00
tokens = self . _get_tokens ( )
2021-02-12 08:20:45 +01:00
with patch ( " zerver.lib.email_mirror.generate_missed_message_token " , side_effect = tokens ) :
handle_missedmessage_emails ( hamlet . id , [ { " message_id " : msg_id , " trigger " : trigger } ] )
2017-03-08 04:46:49 +01:00
if settings . EMAIL_GATEWAY_PATTERN != " " :
2019-12-26 13:46:55 +01:00
reply_to_addresses = [ settings . EMAIL_GATEWAY_PATTERN % ( t , ) for t in tokens ]
2021-02-12 08:19:30 +01:00
reply_to_emails = [
str ( Address ( display_name = " Zulip " , addr_spec = address ) )
for address in reply_to_addresses
]
2017-03-08 04:46:49 +01:00
else :
2017-08-16 03:32:36 +02:00
reply_to_emails = [ " noreply@testserver " ]
2017-03-08 12:28:24 +01:00
msg = mail . outbox [ 0 ]
2021-04-20 22:55:31 +02:00
from_email = str ( Address ( display_name = " Zulip notifications " , addr_spec = FromAddress . NOREPLY ) )
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2017-03-08 12:28:24 +01:00
if send_as_user :
2020-06-10 06:41:04 +02:00
from_email = f ' " { othello . full_name } " < { othello . email } > '
2021-01-26 04:20:36 +01:00
self . assertEqual ( self . email_envelope_from ( msg ) , settings . NOREPLY_EMAIL_ADDRESS )
self . assertEqual ( self . email_display_from ( msg ) , from_email )
2018-11-11 16:07:05 +01:00
self . assertEqual ( msg . subject , email_subject )
2021-05-17 05:41:32 +02:00
self . assert_length ( msg . reply_to , 1 )
2017-06-26 19:43:32 +02:00
self . assertIn ( msg . reply_to [ 0 ] , reply_to_emails )
2017-07-07 22:34:22 +02:00
if verify_html_body :
2020-01-31 12:50:02 +01:00
for text in verify_body_include :
self . assertIn ( text , self . normalize_string ( msg . alternatives [ 0 ] [ 0 ] ) )
2017-07-07 22:34:22 +02:00
else :
2020-01-31 12:50:02 +01:00
for text in verify_body_include :
self . assertIn ( text , self . normalize_string ( msg . body ) )
2020-06-13 03:34:01 +02:00
for text in verify_body_does_not_include :
self . assertNotIn ( text , self . normalize_string ( msg . body ) )
2020-06-14 13:32:38 +02:00
self . assertEqual ( msg . extra_headers [ " List-Id " ] , " Zulip Dev <zulip.testserver> " )
2017-03-08 12:28:24 +01:00
2021-02-12 08:19:30 +01:00
def _realm_name_in_missed_message_email_subject (
self , realm_name_in_notifications : bool
) - > None :
2018-02-06 20:04:14 +01:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message! " ,
2018-02-06 20:04:14 +01:00
)
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Extremely personal message! " ]
email_subject = " PMs with Othello, the Moor of Venice "
2018-02-06 20:04:14 +01:00
if realm_name_in_notifications :
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Othello, the Moor of Venice [Zulip Dev] "
2020-01-31 12:50:02 +01:00
self . _test_cases ( msg_id , verify_body_include , email_subject , False )
2018-02-06 20:04:14 +01:00
2021-02-12 08:19:30 +01:00
def _extra_context_in_missed_stream_messages_mention (
self , send_as_user : bool , show_message_content : bool = True
) - > None :
2017-03-08 12:28:24 +01:00
for i in range ( 0 , 11 ) :
2021-02-12 08:20:45 +01:00
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , content = str ( i ) )
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , " 11 " , topic_name = " test2 " )
2017-10-28 17:52:15 +02:00
msg_id = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , " denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
2017-11-29 13:42:39 +01:00
if show_message_content :
2020-01-31 12:50:02 +01:00
verify_body_include = [
" Othello, the Moor of Venice: 1 2 3 4 5 6 7 8 9 10 @**King Hamlet** -- " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" You are receiving this because you were mentioned in Zulip Dev. " ,
2020-01-31 12:50:02 +01:00
]
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
python: Convert assignment type annotations to Python 3.6 style.
This commit was split by tabbott; this piece covers the vast majority
of files in Zulip, but excludes scripts/, tools/, and puppet/ to help
ensure we at least show the right error messages for Xenial systems.
We can likely further refine the remaining pieces with some testing.
Generated by com2ann, with whitespace fixes and various manual fixes
for runtime issues:
- invoiced_through: Optional[LicenseLedger] = models.ForeignKey(
+ invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
-_apns_client: Optional[APNsClient] = None
+_apns_client: Optional["APNsClient"] = None
- notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- signup_notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ signup_notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- author: Optional[UserProfile] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
+ author: Optional["UserProfile"] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
- bot_owner: Optional[UserProfile] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
+ bot_owner: Optional["UserProfile"] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
- default_sending_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
- default_events_register_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_sending_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_events_register_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
-descriptors_by_handler_id: Dict[int, ClientDescriptor] = {}
+descriptors_by_handler_id: Dict[int, "ClientDescriptor"] = {}
-worker_classes: Dict[str, Type[QueueProcessingWorker]] = {}
-queues: Dict[str, Dict[str, Type[QueueProcessingWorker]]] = {}
+worker_classes: Dict[str, Type["QueueProcessingWorker"]] = {}
+queues: Dict[str, Dict[str, Type["QueueProcessingWorker"]]] = {}
-AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional[LDAPSearch] = None
+AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional["LDAPSearch"] = None
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-22 01:09:50 +02:00
verify_body_does_not_include : List [ str ] = [ ]
2017-11-29 13:42:39 +01:00
else :
# Test in case if message content in missed email message are disabled.
2020-01-31 12:55:47 +01:00
verify_body_include = [
" This email does not include message content because you have disabled message " ,
" http://zulip.testserver/help/pm-mention-alert-notifications " ,
" View or reply in Zulip " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" Manage email preferences: http://zulip.testserver/#settings/notifications " ,
2020-01-31 12:55:47 +01:00
]
2021-04-20 23:02:19 +02:00
email_subject = " New messages "
2021-02-12 08:19:30 +01:00
verify_body_does_not_include = [
2021-02-12 08:20:45 +01:00
" Denmark > test " ,
" Othello, the Moor of Venice " ,
" 1 2 3 4 5 6 7 8 9 10 @**King Hamlet** " ,
" private " ,
" group " ,
" Reply to this email directly, or view it in Zulip " ,
2021-02-12 08:19:30 +01:00
]
self . _test_cases (
msg_id ,
verify_body_include ,
email_subject ,
send_as_user ,
show_message_content = show_message_content ,
verify_body_does_not_include = verify_body_does_not_include ,
2021-02-12 08:20:45 +01:00
trigger = " mentioned " ,
2021-02-12 08:19:30 +01:00
)
def _extra_context_in_missed_stream_messages_wildcard_mention (
self , send_as_user : bool , show_message_content : bool = True
) - > None :
2019-08-26 04:40:07 +02:00
for i in range ( 1 , 6 ) :
2021-02-12 08:20:45 +01:00
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , content = str ( i ) )
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , " 11 " , topic_name = " test2 " )
msg_id = self . send_stream_message ( self . example_user ( " othello " ) , " denmark " , " @**all** " )
2019-08-26 04:40:07 +02:00
if show_message_content :
2020-01-31 12:50:02 +01:00
verify_body_include = [
" Othello, the Moor of Venice: 1 2 3 4 5 @**all** -- " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" You are receiving this because you were mentioned in Zulip Dev. " ,
2020-01-31 12:50:02 +01:00
]
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
python: Convert assignment type annotations to Python 3.6 style.
This commit was split by tabbott; this piece covers the vast majority
of files in Zulip, but excludes scripts/, tools/, and puppet/ to help
ensure we at least show the right error messages for Xenial systems.
We can likely further refine the remaining pieces with some testing.
Generated by com2ann, with whitespace fixes and various manual fixes
for runtime issues:
- invoiced_through: Optional[LicenseLedger] = models.ForeignKey(
+ invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
-_apns_client: Optional[APNsClient] = None
+_apns_client: Optional["APNsClient"] = None
- notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- signup_notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ signup_notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- author: Optional[UserProfile] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
+ author: Optional["UserProfile"] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
- bot_owner: Optional[UserProfile] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
+ bot_owner: Optional["UserProfile"] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
- default_sending_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
- default_events_register_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_sending_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_events_register_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
-descriptors_by_handler_id: Dict[int, ClientDescriptor] = {}
+descriptors_by_handler_id: Dict[int, "ClientDescriptor"] = {}
-worker_classes: Dict[str, Type[QueueProcessingWorker]] = {}
-queues: Dict[str, Dict[str, Type[QueueProcessingWorker]]] = {}
+worker_classes: Dict[str, Type["QueueProcessingWorker"]] = {}
+queues: Dict[str, Dict[str, Type["QueueProcessingWorker"]]] = {}
-AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional[LDAPSearch] = None
+AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional["LDAPSearch"] = None
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-22 01:09:50 +02:00
verify_body_does_not_include : List [ str ] = [ ]
2019-08-26 04:40:07 +02:00
else :
# Test in case if message content in missed email message are disabled.
2020-01-31 12:55:47 +01:00
verify_body_include = [
" This email does not include message content because you have disabled message " ,
" http://zulip.testserver/help/pm-mention-alert-notifications " ,
" View or reply in Zulip " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" Manage email preferences: http://zulip.testserver/#settings/notifications " ,
2020-01-31 12:55:47 +01:00
]
2021-04-20 23:02:19 +02:00
email_subject = " New messages "
2021-02-12 08:19:30 +01:00
verify_body_does_not_include = [
2021-02-12 08:20:45 +01:00
" Denmark > test " ,
" Othello, the Moor of Venice " ,
" 1 2 3 4 5 @**all** " ,
" private " ,
" group " ,
" Reply to this email directly, or view it in Zulip " ,
2021-02-12 08:19:30 +01:00
]
self . _test_cases (
msg_id ,
verify_body_include ,
email_subject ,
send_as_user ,
show_message_content = show_message_content ,
verify_body_does_not_include = verify_body_does_not_include ,
2021-02-12 08:20:45 +01:00
trigger = " wildcard_mentioned " ,
2021-02-12 08:19:30 +01:00
)
2019-08-26 04:40:07 +02:00
2019-12-19 18:26:44 +01:00
def _extra_context_in_missed_stream_messages_email_notify ( self , send_as_user : bool ) - > None :
2017-11-21 06:11:13 +01:00
for i in range ( 0 , 11 ) :
2021-02-12 08:20:45 +01:00
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , content = str ( i ) )
self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , " 11 " , topic_name = " test2 " )
msg_id = self . send_stream_message ( self . example_user ( " othello " ) , " denmark " , " 12 " )
2020-01-31 12:50:02 +01:00
verify_body_include = [
" Othello, the Moor of Venice: 1 2 3 4 5 6 7 8 9 10 12 -- " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" You are receiving this because you have email notifications enabled for this stream. " ,
2020-01-31 12:50:02 +01:00
]
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2021-02-12 08:19:30 +01:00
self . _test_cases (
2021-02-12 08:20:45 +01:00
msg_id , verify_body_include , email_subject , send_as_user , trigger = " stream_email_notify "
2021-02-12 08:19:30 +01:00
)
2017-05-12 22:47:34 +02:00
2021-02-12 08:19:30 +01:00
def _extra_context_in_missed_stream_messages_mention_two_senders (
self , send_as_user : bool
) - > None :
2017-05-12 22:47:34 +02:00
for i in range ( 0 , 3 ) :
2021-02-12 08:20:45 +01:00
self . send_stream_message ( self . example_user ( " cordelia " ) , " Denmark " , str ( i ) )
2017-10-28 17:52:15 +02:00
msg_id = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , " Denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
2020-01-31 12:50:02 +01:00
verify_body_include = [
2021-04-11 16:26:54 +02:00
" Cordelia, Lear ' s daughter: 0 1 2 Othello, the Moor of Venice: @**King Hamlet** -- " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" You are receiving this because you were mentioned in Zulip Dev. " ,
2020-01-31 12:50:02 +01:00
]
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2021-02-12 08:19:30 +01:00
self . _test_cases (
2021-02-12 08:20:45 +01:00
msg_id , verify_body_include , email_subject , send_as_user , trigger = " mentioned "
2021-02-12 08:19:30 +01:00
)
2017-05-12 22:47:34 +02:00
2021-02-12 08:19:30 +01:00
def _extra_context_in_personal_missed_stream_messages (
self ,
send_as_user : bool ,
show_message_content : bool = True ,
message_content_disabled_by_user : bool = False ,
message_content_disabled_by_realm : bool = False ,
) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message! " ,
2017-10-28 17:52:15 +02:00
)
2017-11-29 13:42:39 +01:00
if show_message_content :
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Extremely personal message! " ]
email_subject = " PMs with Othello, the Moor of Venice "
python: Convert assignment type annotations to Python 3.6 style.
This commit was split by tabbott; this piece covers the vast majority
of files in Zulip, but excludes scripts/, tools/, and puppet/ to help
ensure we at least show the right error messages for Xenial systems.
We can likely further refine the remaining pieces with some testing.
Generated by com2ann, with whitespace fixes and various manual fixes
for runtime issues:
- invoiced_through: Optional[LicenseLedger] = models.ForeignKey(
+ invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
-_apns_client: Optional[APNsClient] = None
+_apns_client: Optional["APNsClient"] = None
- notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- signup_notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ signup_notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- author: Optional[UserProfile] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
+ author: Optional["UserProfile"] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
- bot_owner: Optional[UserProfile] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
+ bot_owner: Optional["UserProfile"] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
- default_sending_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
- default_events_register_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_sending_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_events_register_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
-descriptors_by_handler_id: Dict[int, ClientDescriptor] = {}
+descriptors_by_handler_id: Dict[int, "ClientDescriptor"] = {}
-worker_classes: Dict[str, Type[QueueProcessingWorker]] = {}
-queues: Dict[str, Dict[str, Type[QueueProcessingWorker]]] = {}
+worker_classes: Dict[str, Type["QueueProcessingWorker"]] = {}
+queues: Dict[str, Dict[str, Type["QueueProcessingWorker"]]] = {}
-AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional[LDAPSearch] = None
+AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional["LDAPSearch"] = None
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-22 01:09:50 +02:00
verify_body_does_not_include : List [ str ] = [ ]
2017-11-29 13:42:39 +01:00
else :
2020-01-31 12:55:47 +01:00
if message_content_disabled_by_realm :
verify_body_include = [
" This email does not include message content because your organization has disabled " ,
" http://zulip.testserver/help/hide-message-content-in-emails " ,
" View or reply in Zulip " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" Manage email preferences: http://zulip.testserver/#settings/notifications " ,
2020-01-31 12:55:47 +01:00
]
elif message_content_disabled_by_user :
verify_body_include = [
" This email does not include message content because you have disabled message " ,
" http://zulip.testserver/help/pm-mention-alert-notifications " ,
" View or reply in Zulip " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" Manage email preferences: http://zulip.testserver/#settings/notifications " ,
2020-01-31 12:55:47 +01:00
]
2021-04-20 23:02:19 +02:00
email_subject = " New messages "
2021-02-12 08:19:30 +01:00
verify_body_does_not_include = [
2021-02-12 08:20:45 +01:00
" Othello, the Moor of Venice " ,
" Extremely personal message! " ,
" mentioned " ,
" group " ,
" Reply to this email directly, or view it in Zulip " ,
2021-02-12 08:19:30 +01:00
]
self . _test_cases (
msg_id ,
verify_body_include ,
email_subject ,
send_as_user ,
show_message_content = show_message_content ,
verify_body_does_not_include = verify_body_does_not_include ,
)
2017-03-08 12:28:24 +01:00
2019-12-19 18:26:44 +01:00
def _reply_to_email_in_personal_missed_stream_messages ( self , send_as_user : bool ) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message! " ,
2017-10-28 17:52:15 +02:00
)
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Reply to this email directly, or view it in Zulip " ]
email_subject = " PMs with Othello, the Moor of Venice "
2020-01-31 12:50:02 +01:00
self . _test_cases ( msg_id , verify_body_include , email_subject , send_as_user )
2017-03-08 04:46:49 +01:00
2019-12-19 18:26:44 +01:00
def _reply_warning_in_personal_missed_stream_messages ( self , send_as_user : bool ) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message! " ,
2017-10-28 17:52:15 +02:00
)
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Do not reply to this email. " ]
email_subject = " PMs with Othello, the Moor of Venice "
2020-01-31 12:50:02 +01:00
self . _test_cases ( msg_id , verify_body_include , email_subject , send_as_user )
2017-03-08 04:46:49 +01:00
2021-02-12 08:19:30 +01:00
def _extra_context_in_huddle_missed_stream_messages_two_others (
self , send_as_user : bool , show_message_content : bool = True
) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_huddle_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
2017-10-28 17:52:15 +02:00
[
2021-02-12 08:20:45 +01:00
self . example_user ( " hamlet " ) ,
self . example_user ( " iago " ) ,
2017-10-28 17:52:15 +02:00
] ,
2021-02-12 08:20:45 +01:00
" Group personal message! " ,
2017-10-28 17:52:15 +02:00
)
2017-03-08 12:28:24 +01:00
2017-11-29 13:42:39 +01:00
if show_message_content :
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Othello, the Moor of Venice: Group personal message! -- Reply " ]
email_subject = " Group PMs with Iago and Othello, the Moor of Venice "
python: Convert assignment type annotations to Python 3.6 style.
This commit was split by tabbott; this piece covers the vast majority
of files in Zulip, but excludes scripts/, tools/, and puppet/ to help
ensure we at least show the right error messages for Xenial systems.
We can likely further refine the remaining pieces with some testing.
Generated by com2ann, with whitespace fixes and various manual fixes
for runtime issues:
- invoiced_through: Optional[LicenseLedger] = models.ForeignKey(
+ invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
-_apns_client: Optional[APNsClient] = None
+_apns_client: Optional["APNsClient"] = None
- notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- signup_notifications_stream: Optional[Stream] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
+ signup_notifications_stream: Optional["Stream"] = models.ForeignKey('Stream', related_name='+', null=True, blank=True, on_delete=CASCADE)
- author: Optional[UserProfile] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
+ author: Optional["UserProfile"] = models.ForeignKey('UserProfile', blank=True, null=True, on_delete=CASCADE)
- bot_owner: Optional[UserProfile] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
+ bot_owner: Optional["UserProfile"] = models.ForeignKey('self', null=True, on_delete=models.SET_NULL)
- default_sending_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
- default_events_register_stream: Optional[Stream] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_sending_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
+ default_events_register_stream: Optional["Stream"] = models.ForeignKey('zerver.Stream', null=True, related_name='+', on_delete=CASCADE)
-descriptors_by_handler_id: Dict[int, ClientDescriptor] = {}
+descriptors_by_handler_id: Dict[int, "ClientDescriptor"] = {}
-worker_classes: Dict[str, Type[QueueProcessingWorker]] = {}
-queues: Dict[str, Dict[str, Type[QueueProcessingWorker]]] = {}
+worker_classes: Dict[str, Type["QueueProcessingWorker"]] = {}
+queues: Dict[str, Dict[str, Type["QueueProcessingWorker"]]] = {}
-AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional[LDAPSearch] = None
+AUTH_LDAP_REVERSE_EMAIL_SEARCH: Optional["LDAPSearch"] = None
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-22 01:09:50 +02:00
verify_body_does_not_include : List [ str ] = [ ]
2017-11-29 13:42:39 +01:00
else :
2020-01-31 12:55:47 +01:00
verify_body_include = [
" This email does not include message content because you have disabled message " ,
" http://zulip.testserver/help/pm-mention-alert-notifications " ,
" View or reply in Zulip " ,
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
" Manage email preferences: http://zulip.testserver/#settings/notifications " ,
2020-01-31 12:55:47 +01:00
]
2021-04-20 23:02:19 +02:00
email_subject = " New messages "
2021-02-12 08:19:30 +01:00
verify_body_does_not_include = [
2021-02-12 08:20:45 +01:00
" Iago " ,
" Othello, the Moor of Venice Othello, the Moor of Venice " ,
" Group personal message! " ,
" mentioned " ,
" Reply to this email directly, or view it in Zulip " ,
2021-02-12 08:19:30 +01:00
]
self . _test_cases (
msg_id ,
verify_body_include ,
email_subject ,
send_as_user ,
show_message_content = show_message_content ,
verify_body_does_not_include = verify_body_does_not_include ,
)
def _extra_context_in_huddle_missed_stream_messages_three_others (
self , send_as_user : bool
) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_huddle_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
2017-10-28 17:52:15 +02:00
[
2021-02-12 08:20:45 +01:00
self . example_user ( " hamlet " ) ,
self . example_user ( " iago " ) ,
self . example_user ( " cordelia " ) ,
2017-10-28 17:52:15 +02:00
] ,
2021-02-12 08:20:45 +01:00
" Group personal message! " ,
2017-10-28 17:52:15 +02:00
)
2017-05-03 09:22:58 +02:00
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Othello, the Moor of Venice: Group personal message! -- Reply " ]
2021-04-11 16:26:54 +02:00
email_subject = (
" Group PMs with Cordelia, Lear ' s daughter, Iago, and Othello, the Moor of Venice "
)
2020-01-31 12:50:02 +01:00
self . _test_cases ( msg_id , verify_body_include , email_subject , send_as_user )
2017-05-03 09:22:58 +02:00
2021-02-12 08:19:30 +01:00
def _extra_context_in_huddle_missed_stream_messages_many_others (
self , send_as_user : bool
) - > None :
msg_id = self . send_huddle_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
2021-02-12 08:19:30 +01:00
[
2021-02-12 08:20:45 +01:00
self . example_user ( " hamlet " ) ,
self . example_user ( " iago " ) ,
self . example_user ( " cordelia " ) ,
self . example_user ( " prospero " ) ,
2021-02-12 08:19:30 +01:00
] ,
2021-02-12 08:20:45 +01:00
" Group personal message! " ,
2021-02-12 08:19:30 +01:00
)
2017-05-03 09:22:58 +02:00
2021-02-12 08:20:45 +01:00
verify_body_include = [ " Othello, the Moor of Venice: Group personal message! -- Reply " ]
2021-04-11 16:26:54 +02:00
email_subject = " Group PMs with Cordelia, Lear ' s daughter, Iago, and 2 others "
2020-01-31 12:50:02 +01:00
self . _test_cases ( msg_id , verify_body_include , email_subject , send_as_user )
2017-03-14 08:38:01 +01:00
2019-12-19 18:26:44 +01:00
def _deleted_message_in_missed_stream_messages ( self , send_as_user : bool ) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , " denmark " , " @**King Hamlet** to be deleted "
2021-02-12 08:19:30 +01:00
)
2017-03-14 08:38:01 +01:00
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
self . login ( " othello " )
2021-02-12 08:19:30 +01:00
result = self . client_patch (
2021-02-12 08:20:45 +01:00
" /json/messages/ " + str ( msg_id ) , { " message_id " : msg_id , " content " : " " }
2021-02-12 08:19:30 +01:00
)
2017-03-14 08:38:01 +01:00
self . assert_json_success ( result )
2021-02-12 08:20:45 +01:00
handle_missedmessage_emails ( hamlet . id , [ { " message_id " : msg_id } ] )
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 0 )
2017-03-14 08:38:01 +01:00
2019-12-19 18:26:44 +01:00
def _deleted_message_in_personal_missed_stream_messages ( self , send_as_user : bool ) - > None :
2021-02-12 08:19:30 +01:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message! to be deleted! " ,
2021-02-12 08:19:30 +01:00
)
2017-03-14 08:38:01 +01:00
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
self . login ( " othello " )
2021-02-12 08:19:30 +01:00
result = self . client_patch (
2021-02-12 08:20:45 +01:00
" /json/messages/ " + str ( msg_id ) , { " message_id " : msg_id , " content " : " " }
2021-02-12 08:19:30 +01:00
)
2017-03-14 08:38:01 +01:00
self . assert_json_success ( result )
2021-02-12 08:20:45 +01:00
handle_missedmessage_emails ( hamlet . id , [ { " message_id " : msg_id } ] )
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 0 )
2017-03-14 08:38:01 +01:00
2019-12-19 18:26:44 +01:00
def _deleted_message_in_huddle_missed_stream_messages ( self , send_as_user : bool ) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_huddle_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
2017-10-28 17:52:15 +02:00
[
2021-02-12 08:20:45 +01:00
self . example_user ( " hamlet " ) ,
self . example_user ( " iago " ) ,
2017-10-28 17:52:15 +02:00
] ,
2021-02-12 08:20:45 +01:00
" Group personal message! " ,
2017-10-28 17:52:15 +02:00
)
2017-03-14 08:38:01 +01:00
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
iago = self . example_user ( " iago " )
self . login ( " othello " )
2021-02-12 08:19:30 +01:00
result = self . client_patch (
2021-02-12 08:20:45 +01:00
" /json/messages/ " + str ( msg_id ) , { " message_id " : msg_id , " content " : " " }
2021-02-12 08:19:30 +01:00
)
2017-03-14 08:38:01 +01:00
self . assert_json_success ( result )
2021-02-12 08:20:45 +01:00
handle_missedmessage_emails ( hamlet . id , [ { " message_id " : msg_id } ] )
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 0 )
2021-02-12 08:20:45 +01:00
handle_missedmessage_emails ( iago . id , [ { " message_id " : msg_id } ] )
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 0 )
2017-03-14 08:38:01 +01:00
2018-02-06 20:04:14 +01:00
def test_realm_name_in_notifications ( self ) - > None :
# Test with realm_name_in_notifications for hamlet disabled.
self . _realm_name_in_missed_message_email_subject ( False )
# Enable realm_name_in_notifications for hamlet and test again.
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2018-02-06 20:04:14 +01:00
hamlet . realm_name_in_notifications = True
2021-02-12 08:20:45 +01:00
hamlet . save ( update_fields = [ " realm_name_in_notifications " ] )
2018-02-06 20:04:14 +01:00
# Empty the test outbox
mail . outbox = [ ]
self . _realm_name_in_missed_message_email_subject ( True )
2017-11-29 13:42:39 +01:00
def test_message_content_disabled_in_missed_message_notifications ( self ) - > None :
# Test when user disabled message content in email notifications.
2021-02-12 08:19:30 +01:00
do_change_notification_settings (
2021-04-08 11:10:34 +02:00
self . example_user ( " hamlet " ) ,
" message_content_in_email_notifications " ,
False ,
acting_user = None ,
2021-02-12 08:19:30 +01:00
)
2017-11-29 13:42:39 +01:00
self . _extra_context_in_missed_stream_messages_mention ( False , show_message_content = False )
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_missed_stream_messages_wildcard_mention (
False , show_message_content = False
)
2019-08-26 04:40:07 +02:00
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_personal_missed_stream_messages (
False , show_message_content = False , message_content_disabled_by_user = True
)
2017-11-29 13:42:39 +01:00
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_huddle_missed_stream_messages_two_others (
False , show_message_content = False
)
2017-11-29 13:42:39 +01:00
2017-03-08 12:28:24 +01:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_missed_stream_messages_as_user ( self ) - > None :
2017-05-12 22:47:34 +02:00
self . _extra_context_in_missed_stream_messages_mention ( True )
2017-03-08 12:28:24 +01:00
2017-11-05 10:51:25 +01:00
def test_extra_context_in_missed_stream_messages ( self ) - > None :
2017-05-12 22:47:34 +02:00
self . _extra_context_in_missed_stream_messages_mention ( False )
2019-08-26 04:40:07 +02:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
def test_extra_context_in_missed_stream_messages_as_user_wildcard ( self ) - > None :
self . _extra_context_in_missed_stream_messages_wildcard_mention ( True )
def test_extra_context_in_missed_stream_messages_wildcard ( self ) - > None :
self . _extra_context_in_missed_stream_messages_wildcard_mention ( False )
2017-05-12 22:47:34 +02:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_missed_stream_messages_as_user_two_senders ( self ) - > None :
2017-05-12 22:47:34 +02:00
self . _extra_context_in_missed_stream_messages_mention_two_senders ( True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_missed_stream_messages_two_senders ( self ) - > None :
2017-05-12 22:47:34 +02:00
self . _extra_context_in_missed_stream_messages_mention_two_senders ( False )
2017-03-08 12:28:24 +01:00
2017-11-05 10:51:25 +01:00
def test_reply_to_email_in_personal_missed_stream_messages ( self ) - > None :
2017-03-08 04:46:49 +01:00
self . _reply_to_email_in_personal_missed_stream_messages ( False )
2017-11-21 06:11:13 +01:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
def test_extra_context_in_missed_stream_messages_email_notify_as_user ( self ) - > None :
self . _extra_context_in_missed_stream_messages_email_notify ( True )
def test_extra_context_in_missed_stream_messages_email_notify ( self ) - > None :
self . _extra_context_in_missed_stream_messages_email_notify ( False )
2017-03-08 04:46:49 +01:00
@override_settings ( EMAIL_GATEWAY_PATTERN = " " )
2017-11-05 10:51:25 +01:00
def test_reply_warning_in_personal_missed_stream_messages ( self ) - > None :
2017-03-08 04:46:49 +01:00
self . _reply_warning_in_personal_missed_stream_messages ( False )
2017-03-08 12:28:24 +01:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_personal_missed_stream_messages_as_user ( self ) - > None :
2017-03-08 12:28:24 +01:00
self . _extra_context_in_personal_missed_stream_messages ( True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_personal_missed_stream_messages ( self ) - > None :
2017-03-08 12:28:24 +01:00
self . _extra_context_in_personal_missed_stream_messages ( False )
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_two_others_as_user ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_two_others ( True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_two_others ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_two_others ( False )
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_three_others_as_user ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_three_others ( True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_three_others ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_three_others ( False )
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_many_others_as_user ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_many_others ( True )
2017-03-08 12:28:24 +01:00
2017-11-05 10:51:25 +01:00
def test_extra_context_in_huddle_missed_stream_messages_many_others ( self ) - > None :
2017-05-03 09:22:58 +02:00
self . _extra_context_in_huddle_missed_stream_messages_many_others ( False )
2017-03-14 08:38:01 +01:00
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_missed_stream_messages_as_user ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_missed_stream_messages ( True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_missed_stream_messages ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_missed_stream_messages ( False )
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_personal_missed_stream_messages_as_user ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_personal_missed_stream_messages ( True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_personal_missed_stream_messages ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_personal_missed_stream_messages ( False )
@override_settings ( SEND_MISSED_MESSAGE_EMAILS_AS_USER = True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_huddle_missed_stream_messages_as_user ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_huddle_missed_stream_messages ( True )
2017-11-05 10:51:25 +01:00
def test_deleted_message_in_huddle_missed_stream_messages ( self ) - > None :
2017-03-14 08:38:01 +01:00
self . _deleted_message_in_huddle_missed_stream_messages ( False )
2017-07-07 22:34:22 +02:00
2019-01-14 14:04:08 +01:00
def test_realm_message_content_allowed_in_email_notifications ( self ) - > None :
user = self . example_user ( " hamlet " )
# When message content is allowed at realm level
realm = get_realm ( " zulip " )
realm . message_content_allowed_in_email_notifications = True
2021-02-12 08:20:45 +01:00
realm . save ( update_fields = [ " message_content_allowed_in_email_notifications " ] )
2019-01-14 14:04:08 +01:00
# Emails have missed message content when message content is enabled by the user
2021-04-08 11:10:34 +02:00
do_change_notification_settings (
user , " message_content_in_email_notifications " , True , acting_user = None
)
2019-01-14 14:04:08 +01:00
mail . outbox = [ ]
self . _extra_context_in_personal_missed_stream_messages ( False , show_message_content = True )
# Emails don't have missed message content when message content is disabled by the user
2021-04-08 11:10:34 +02:00
do_change_notification_settings (
user , " message_content_in_email_notifications " , False , acting_user = None
)
2019-01-14 14:04:08 +01:00
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_personal_missed_stream_messages (
False , show_message_content = False , message_content_disabled_by_user = True
)
2019-01-14 14:04:08 +01:00
# When message content is not allowed at realm level
2021-04-20 23:27:25 +02:00
# Emails don't have message content irrespective of message content setting of the user
2019-01-14 14:04:08 +01:00
realm = get_realm ( " zulip " )
realm . message_content_allowed_in_email_notifications = False
2021-02-12 08:20:45 +01:00
realm . save ( update_fields = [ " message_content_allowed_in_email_notifications " ] )
2019-01-14 14:04:08 +01:00
2021-04-08 11:10:34 +02:00
do_change_notification_settings (
user , " message_content_in_email_notifications " , True , acting_user = None
)
2019-01-14 14:04:08 +01:00
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_personal_missed_stream_messages (
False , show_message_content = False , message_content_disabled_by_realm = True
)
2019-01-14 14:04:08 +01:00
2021-04-08 11:10:34 +02:00
do_change_notification_settings (
user , " message_content_in_email_notifications " , False , acting_user = None
)
2019-01-14 14:04:08 +01:00
mail . outbox = [ ]
2021-02-12 08:19:30 +01:00
self . _extra_context_in_personal_missed_stream_messages (
False ,
show_message_content = False ,
message_content_disabled_by_user = True ,
message_content_disabled_by_realm = True ,
)
2019-01-14 14:04:08 +01:00
2019-12-19 18:26:44 +01:00
def test_realm_emoji_in_missed_message ( self ) - > None :
2019-03-15 18:56:56 +01:00
realm = get_realm ( " zulip " )
2017-07-07 22:34:22 +02:00
2017-10-28 17:52:15 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message with a realm emoji :green_tick:! " ,
2021-02-12 08:19:30 +01:00
)
2021-02-12 08:20:45 +01:00
realm_emoji_id = realm . get_active_emoji ( ) [ " green_tick " ] [ " id " ]
2021-02-12 08:19:30 +01:00
realm_emoji_url = (
f " http://zulip.testserver/user_avatars/ { realm . id } /emoji/images/ { realm_emoji_id } .png "
)
verify_body_include = [
f ' <img alt= " :green_tick: " src= " { realm_emoji_url } " title= " green tick " style= " height: 20px; " > '
]
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Othello, the Moor of Venice "
2021-02-12 08:19:30 +01:00
self . _test_cases (
msg_id , verify_body_include , email_subject , send_as_user = False , verify_html_body = True
)
2017-10-28 00:55:16 +02:00
2019-12-19 18:26:44 +01:00
def test_emojiset_in_missed_message ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
hamlet . emojiset = " twitter "
hamlet . save ( update_fields = [ " emojiset " ] )
2017-10-28 00:55:16 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Extremely personal message with a hamburger :hamburger:! " ,
2021-02-12 08:19:30 +01:00
)
verify_body_include = [
' <img alt= " :hamburger: " src= " http://zulip.testserver/static/generated/emoji/images-twitter-64/1f354.png " title= " hamburger " style= " height: 20px; " > '
]
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Othello, the Moor of Venice "
2021-02-12 08:19:30 +01:00
self . _test_cases (
msg_id , verify_body_include , email_subject , send_as_user = False , verify_html_body = True
)
2017-07-15 01:07:52 +02:00
2019-12-19 18:26:44 +01:00
def test_stream_link_in_missed_message ( self ) - > None :
2017-10-28 17:52:15 +02:00
msg_id = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) ,
self . example_user ( " hamlet " ) ,
" Come and join us in #**Verona**. " ,
2021-02-12 08:19:30 +01:00
)
2021-02-12 08:20:45 +01:00
stream_id = get_stream ( " Verona " , get_realm ( " zulip " ) ) . id
2020-06-09 00:25:09 +02:00
href = f " http://zulip.testserver/#narrow/stream/ { stream_id } -Verona "
2021-02-12 08:19:30 +01:00
verify_body_include = [
f ' <a class= " stream " data-stream-id= " { stream_id } " href= " { href } " >#Verona</a '
]
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Othello, the Moor of Venice "
2021-02-12 08:19:30 +01:00
self . _test_cases (
msg_id , verify_body_include , email_subject , send_as_user = False , verify_html_body = True
)
2019-07-11 13:04:11 +02:00
2019-12-19 18:26:44 +01:00
def test_sender_name_in_missed_message ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2021-02-12 08:19:30 +01:00
msg_id_1 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " iago " ) , " Denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
2021-02-12 08:20:45 +01:00
msg_id_2 = self . send_stream_message ( self . example_user ( " iago " ) , " Verona " , " * 1 \n *2 " )
msg_id_3 = self . send_personal_message ( self . example_user ( " iago " ) , hamlet , " Hello " )
2021-02-12 08:19:30 +01:00
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 , " trigger " : " mentioned " } ,
{ " message_id " : msg_id_2 , " trigger " : " stream_email_notify " } ,
{ " message_id " : msg_id_3 } ,
2021-02-12 08:19:30 +01:00
] ,
)
2019-07-11 13:04:11 +02:00
2021-02-12 08:20:45 +01:00
self . assertIn ( " Iago: @**King Hamlet** \n \n -- \n You are " , mail . outbox [ 0 ] . body )
2019-07-11 13:04:11 +02:00
# If message content starts with <p> tag the sender name is appended inside the <p> tag.
2021-02-12 08:19:30 +01:00
self . assertIn (
' <p><b>Iago</b>: <span class= " user-mention " ' , mail . outbox [ 0 ] . alternatives [ 0 ] [ 0 ]
)
2019-07-11 13:04:11 +02:00
2021-02-12 08:20:45 +01:00
self . assertIn ( " Iago: * 1 \n *2 \n \n -- \n You are receiving " , mail . outbox [ 1 ] . body )
2019-07-11 13:04:11 +02:00
# If message content does not starts with <p> tag sender name is appended before the <p> tag
2021-02-12 08:19:30 +01:00
self . assertIn (
2021-02-12 08:20:45 +01:00
" <b>Iago</b>: <ul> \n <li>1<br/> \n *2</li> \n </ul> \n " ,
2021-02-12 08:19:30 +01:00
mail . outbox [ 1 ] . alternatives [ 0 ] [ 0 ] ,
)
2019-07-11 13:04:11 +02:00
2021-02-12 08:20:45 +01:00
self . assertEqual ( " Hello \n \n -- \n \n Reply " , mail . outbox [ 2 ] . body [ : 16 ] )
2019-07-11 13:04:11 +02:00
# Sender name is not appended to message for PM missed messages
2021-02-12 08:19:30 +01:00
self . assertIn (
2021-02-12 08:20:45 +01:00
" > \n \n <p>Hello</p> \n " ,
2021-02-12 08:19:30 +01:00
mail . outbox [ 2 ] . alternatives [ 0 ] [ 0 ] ,
)
2019-07-11 13:04:11 +02:00
2019-12-19 18:26:44 +01:00
def test_multiple_missed_personal_messages ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2021-02-12 08:19:30 +01:00
msg_id_1 = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , hamlet , " Personal Message 1 "
2021-02-12 08:19:30 +01:00
)
msg_id_2 = self . send_personal_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " iago " ) , hamlet , " Personal Message 2 "
2021-02-12 08:19:30 +01:00
)
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 } ,
{ " message_id " : msg_id_2 } ,
2021-02-12 08:19:30 +01:00
] ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 2 )
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Othello, the Moor of Venice "
2018-11-11 16:07:05 +01:00
self . assertEqual ( mail . outbox [ 0 ] . subject , email_subject )
2021-02-12 08:20:45 +01:00
email_subject = " PMs with Iago "
2018-11-11 16:07:05 +01:00
self . assertEqual ( mail . outbox [ 1 ] . subject , email_subject )
2017-09-21 01:11:49 +02:00
2019-12-19 18:26:44 +01:00
def test_multiple_stream_messages ( self ) - > None :
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
msg_id_1 = self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , " Message1 " )
msg_id_2 = self . send_stream_message ( self . example_user ( " iago " ) , " Denmark " , " Message2 " )
2021-02-12 08:19:30 +01:00
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 , " trigger " : " stream_email_notify " } ,
{ " message_id " : msg_id_2 , " trigger " : " stream_email_notify " } ,
2021-02-12 08:19:30 +01:00
] ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2018-11-11 16:07:05 +01:00
self . assertEqual ( mail . outbox [ 0 ] . subject , email_subject )
2017-11-21 06:11:13 +01:00
2019-12-19 18:26:44 +01:00
def test_multiple_stream_messages_and_mentions ( self ) - > None :
2019-07-08 08:02:17 +02:00
""" Subject should be stream name and topic as usual. """
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
msg_id_1 = self . send_stream_message ( self . example_user ( " iago " ) , " Denmark " , " Regular message " )
2021-02-12 08:19:30 +01:00
msg_id_2 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , " Denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 , " trigger " : " stream_email_notify " } ,
{ " message_id " : msg_id_2 , " trigger " : " mentioned " } ,
2021-02-12 08:19:30 +01:00
] ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2018-11-11 16:07:05 +01:00
self . assertEqual ( mail . outbox [ 0 ] . subject , email_subject )
2017-11-21 06:11:13 +01:00
2019-12-19 18:26:44 +01:00
def test_message_access_in_emails ( self ) - > None :
2018-07-26 20:19:45 +02:00
# Messages sent to a protected history-private stream shouldn't be
# accessible/available in emails before subscribing
stream_name = " private_stream "
2021-02-12 08:19:30 +01:00
self . make_stream ( stream_name , invite_only = True , history_public_to_subscribers = False )
2021-02-12 08:20:45 +01:00
user = self . example_user ( " iago " )
2018-07-26 20:19:45 +02:00
self . subscribe ( user , stream_name )
2021-02-12 08:20:45 +01:00
late_subscribed_user = self . example_user ( " hamlet " )
2018-07-26 20:19:45 +02:00
2021-02-12 08:20:45 +01:00
self . send_stream_message ( user , stream_name , " Before subscribing " )
2018-07-26 20:19:45 +02:00
self . subscribe ( late_subscribed_user , stream_name )
2021-02-12 08:19:30 +01:00
self . send_stream_message ( user , stream_name , " After subscribing " )
2018-07-26 20:19:45 +02:00
2021-02-12 08:20:45 +01:00
mention_msg_id = self . send_stream_message ( user , stream_name , " @**King Hamlet** " )
2018-07-26 20:19:45 +02:00
2021-02-12 08:19:30 +01:00
handle_missedmessage_emails (
late_subscribed_user . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : mention_msg_id , " trigger " : " mentioned " } ,
2021-02-12 08:19:30 +01:00
] ,
)
2018-07-26 20:19:45 +02:00
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2021-02-12 08:20:45 +01:00
self . assertEqual ( mail . outbox [ 0 ] . subject , " #private_stream > test " ) # email subject
2018-07-26 20:19:45 +02:00
email_text = mail . outbox [ 0 ] . message ( ) . as_string ( )
2021-02-12 08:20:45 +01:00
self . assertNotIn ( " Before subscribing " , email_text )
self . assertIn ( " After subscribing " , email_text )
self . assertIn ( " @**King Hamlet** " , email_text )
2018-07-26 20:19:45 +02:00
2019-12-19 18:26:44 +01:00
def test_stream_mentions_multiple_people ( self ) - > None :
2019-07-08 08:02:17 +02:00
""" Subject should be stream name and topic as usual. """
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
2021-02-12 08:19:30 +01:00
msg_id_1 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " iago " ) , " Denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
msg_id_2 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " othello " ) , " Denmark " , " @**King Hamlet** "
2021-02-12 08:19:30 +01:00
)
msg_id_3 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " cordelia " ) , " Denmark " , " Regular message "
2021-02-12 08:19:30 +01:00
)
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 , " trigger " : " mentioned " } ,
{ " message_id " : msg_id_2 , " trigger " : " mentioned " } ,
{ " message_id " : msg_id_3 , " trigger " : " stream_email_notify " } ,
2021-02-12 08:19:30 +01:00
] ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 1 )
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2018-11-11 16:07:05 +01:00
self . assertEqual ( mail . outbox [ 0 ] . subject , email_subject )
2017-11-21 06:11:13 +01:00
2019-12-19 18:26:44 +01:00
def test_multiple_stream_messages_different_topics ( self ) - > None :
2017-11-21 06:11:13 +01:00
""" Should receive separate emails for each topic within a stream. """
2021-02-12 08:20:45 +01:00
hamlet = self . example_user ( " hamlet " )
msg_id_1 = self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , " Message1 " )
2021-02-12 08:19:30 +01:00
msg_id_2 = self . send_stream_message (
2021-02-12 08:20:45 +01:00
self . example_user ( " iago " ) , " Denmark " , " Message2 " , topic_name = " test2 "
2021-02-12 08:19:30 +01:00
)
handle_missedmessage_emails (
hamlet . id ,
[
2021-02-12 08:20:45 +01:00
{ " message_id " : msg_id_1 , " trigger " : " stream_email_notify " } ,
{ " message_id " : msg_id_2 , " trigger " : " stream_email_notify " } ,
2021-02-12 08:19:30 +01:00
] ,
)
2021-05-17 05:41:32 +02:00
self . assert_length ( mail . outbox , 2 )
2018-11-11 16:07:05 +01:00
email_subjects = { mail . outbox [ 0 ] . subject , mail . outbox [ 1 ] . subject }
2021-02-12 08:20:45 +01:00
valid_email_subjects = { " #Denmark > test " , " #Denmark > test2 " }
2018-11-11 16:07:05 +01:00
self . assertEqual ( email_subjects , valid_email_subjects )
2017-11-21 06:11:13 +01:00
2017-11-05 10:51:25 +01:00
def test_relative_to_full_url ( self ) - > None :
2019-07-24 07:47:04 +02:00
zulip_realm = get_realm ( " zulip " )
zephyr_realm = get_realm ( " zephyr " )
2017-09-21 01:11:49 +02:00
# Run `relative_to_full_url()` function over test fixtures present in
# 'markdown_test_cases.json' and check that it converts all the relative
# URLs to absolute URLs.
2020-08-07 01:09:47 +02:00
fixtures = orjson . loads ( self . fixture_data ( " markdown_test_cases.json " ) )
2017-09-21 01:11:49 +02:00
test_fixtures = { }
2021-02-12 08:20:45 +01:00
for test in fixtures [ " regular_tests " ] :
test_fixtures [ test [ " name " ] ] = test
2017-09-21 01:11:49 +02:00
for test_name in test_fixtures :
test_data = test_fixtures [ test_name ] [ " expected_output " ]
output_data = relative_to_full_url ( " http://example.com " , test_data )
2018-07-02 00:05:24 +02:00
if re . search ( r """ (?<= \ =[ ' " ])/(?=[^<]+>) """ , output_data ) is not None :
2021-02-12 08:19:30 +01:00
raise AssertionError (
" Relative URL present in email: "
+ output_data
+ " \n Failed test case ' s name is: "
+ test_name
+ " \n It is present in markdown_test_cases.json "
)
2017-09-21 01:11:49 +02:00
# Specific test cases.
2017-09-22 19:16:24 +02:00
# A path similar to our emoji path, but not in a link:
2017-09-21 01:11:49 +02:00
test_data = " <p>Check out the file at: ' /static/generated/emoji/images/emoji/ ' </p> "
actual_output = relative_to_full_url ( " http://example.com " , test_data )
expected_output = " <p>Check out the file at: ' /static/generated/emoji/images/emoji/ ' </p> "
self . assertEqual ( actual_output , expected_output )
2017-09-22 19:16:24 +02:00
# An uploaded file
2019-07-24 07:47:04 +02:00
test_data = ' <a href= " /user_uploads/ {realm_id} /1f/some_random_value " >/user_uploads/ {realm_id} /1f/some_random_value</a> '
test_data = test_data . format ( realm_id = zephyr_realm . id )
2017-09-21 01:11:49 +02:00
actual_output = relative_to_full_url ( " http://example.com " , test_data )
2021-02-12 08:19:30 +01:00
expected_output = (
' <a href= " http://example.com/user_uploads/ {realm_id} /1f/some_random_value " > '
2021-02-12 08:20:45 +01:00
+ " /user_uploads/ {realm_id} /1f/some_random_value</a> "
2021-02-12 08:19:30 +01:00
)
2019-07-24 07:47:04 +02:00
expected_output = expected_output . format ( realm_id = zephyr_realm . id )
2017-09-21 01:11:49 +02:00
self . assertEqual ( actual_output , expected_output )
2019-03-09 17:43:48 +01:00
# A profile picture like syntax, but not actually in an HTML tag
2017-09-21 01:11:49 +02:00
test_data = ' <p>Set src= " /avatar/username@example.com?s=30 " </p> '
actual_output = relative_to_full_url ( " http://example.com " , test_data )
expected_output = ' <p>Set src= " /avatar/username@example.com?s=30 " </p> '
self . assertEqual ( actual_output , expected_output )
2017-09-27 19:39:42 +02:00
2017-10-11 22:41:19 +02:00
# A narrow URL which begins with a '#'.
2021-02-12 08:19:30 +01:00
test_data = (
' <p><a href= " #narrow/stream/test/topic/test.20topic/near/142 " '
+ ' title= " #narrow/stream/test/topic/test.20topic/near/142 " >Conversation</a></p> '
)
2017-10-11 22:41:19 +02:00
actual_output = relative_to_full_url ( " http://example.com " , test_data )
2021-02-12 08:19:30 +01:00
expected_output = (
' <p><a href= " http://example.com/#narrow/stream/test/topic/test.20topic/near/142 " '
+ ' title= " http://example.com/#narrow/stream/test/topic/test.20topic/near/142 " >Conversation</a></p> '
)
2017-10-11 22:41:19 +02:00
self . assertEqual ( actual_output , expected_output )
2017-10-13 16:59:58 +02:00
# Scrub inline images.
2021-02-12 08:19:30 +01:00
test_data = (
' <p>See this <a href= " /user_uploads/ {realm_id} /52/fG7GM9e3afz_qsiUcSce2tl_/avatar_103.jpeg " target= " _blank " '
+ ' title= " avatar_103.jpeg " >avatar_103.jpeg</a>.</p> '
+ ' <div class= " message_inline_image " ><a href= " /user_uploads/ {realm_id} /52/fG7GM9e3afz_qsiUcSce2tl_/avatar_103.jpeg " '
+ ' target= " _blank " title= " avatar_103.jpeg " ><img src= " /user_uploads/ {realm_id} /52/fG7GM9e3afz_qsiUcSce2tl_/avatar_103.jpeg " ></a></div> '
)
2019-07-24 07:47:04 +02:00
test_data = test_data . format ( realm_id = zulip_realm . id )
2017-10-13 16:59:58 +02:00
actual_output = relative_to_full_url ( " http://example.com " , test_data )
2021-02-12 08:19:30 +01:00
expected_output = (
' <div><p>See this <a href= " http://example.com/user_uploads/ {realm_id} /52/fG7GM9e3afz_qsiUcSce2tl_/avatar_103.jpeg " target= " _blank " '
+ ' title= " avatar_103.jpeg " >avatar_103.jpeg</a>.</p></div> '
)
2019-07-24 07:47:04 +02:00
expected_output = expected_output . format ( realm_id = zulip_realm . id )
2017-10-13 16:59:58 +02:00
self . assertEqual ( actual_output , expected_output )
2018-01-24 19:23:51 +01:00
# A message containing only an inline image URL preview, we do
# somewhat more extensive surgery.
2021-02-12 08:19:30 +01:00
test_data = (
' <div class= " message_inline_image " ><a href= " https://www.google.com/images/srpr/logo4w.png " '
+ ' target= " _blank " title= " https://www.google.com/images/srpr/logo4w.png " > '
+ ' <img data-src-fullsize= " /thumbnail/https % 3A//www.google.com/images/srpr/logo4w.png?size=0x0 " '
+ ' src= " /thumbnail/https % 3A//www.google.com/images/srpr/logo4w.png?size=0x100 " ></a></div> '
)
2018-01-24 19:23:51 +01:00
actual_output = relative_to_full_url ( " http://example.com " , test_data )
2021-02-12 08:19:30 +01:00
expected_output = (
' <p><a href= " https://www.google.com/images/srpr/logo4w.png " '
+ ' target= " _blank " title= " https://www.google.com/images/srpr/logo4w.png " > '
2021-02-12 08:20:45 +01:00
+ " https://www.google.com/images/srpr/logo4w.png</a></p> "
2021-02-12 08:19:30 +01:00
)
2018-01-24 19:23:51 +01:00
self . assertEqual ( actual_output , expected_output )
2020-07-15 01:21:28 +02:00
def test_spoilers_in_html_emails ( self ) - > None :
2021-02-12 08:20:45 +01:00
test_data = ' <div class= " spoiler-block " ><div class= " spoiler-header " > \n \n <p><a>header</a> text</p> \n </div><div class= " spoiler-content " aria-hidden= " true " > \n \n <p>content</p> \n </div></div> \n \n <p>outside spoiler</p> '
actual_output = fix_spoilers_in_html ( test_data , " en " )
expected_output = ' <div><div class= " spoiler-block " > \n \n <p><a>header</a> text<span> </span><span class= " spoiler-title " title= " Open Zulip to see the spoiler content " >(Open Zulip to see the spoiler content)</span></p> \n </div> \n \n <p>outside spoiler</p></div> '
2020-07-15 01:21:28 +02:00
self . assertEqual ( actual_output , expected_output )
# test against our markdown_test_cases so these features do not get out of sync.
2020-08-07 01:09:47 +02:00
fixtures = orjson . loads ( self . fixture_data ( " markdown_test_cases.json " ) )
2020-07-15 01:21:28 +02:00
test_fixtures = { }
2021-02-12 08:20:45 +01:00
for test in fixtures [ " regular_tests " ] :
if " spoiler " in test [ " name " ] :
test_fixtures [ test [ " name " ] ] = test
2020-07-15 01:21:28 +02:00
for test_name in test_fixtures :
test_data = test_fixtures [ test_name ] [ " expected_output " ]
2021-02-12 08:20:45 +01:00
output_data = fix_spoilers_in_html ( test_data , " en " )
assert " spoiler-header " not in output_data
assert " spoiler-content " not in output_data
assert " spoiler-block " in output_data
assert " spoiler-title " in output_data
2020-07-15 01:21:28 +02:00
def test_spoilers_in_text_emails ( self ) - > None :
content = " @**King Hamlet** \n \n ```spoiler header text \n secret-text \n ``` "
2021-02-12 08:20:45 +01:00
msg_id = self . send_stream_message ( self . example_user ( " othello " ) , " Denmark " , content )
2021-02-12 08:19:30 +01:00
verify_body_include = [ " header text " , " Open Zulip to see the spoiler content " ]
2020-07-15 01:21:28 +02:00
verify_body_does_not_include = [ " secret-text " ]
2021-02-12 08:20:45 +01:00
email_subject = " #Denmark > test "
2020-07-15 01:21:28 +02:00
send_as_user = False
2021-02-12 08:19:30 +01:00
self . _test_cases (
msg_id ,
verify_body_include ,
email_subject ,
send_as_user ,
2021-02-12 08:20:45 +01:00
trigger = " mentioned " ,
2021-02-12 08:19:30 +01:00
verify_body_does_not_include = verify_body_does_not_include ,
)
2020-07-15 01:21:28 +02:00
2017-11-05 10:51:25 +01:00
def test_fix_emoji ( self ) - > None :
2017-09-27 19:39:42 +02:00
# An emoji.
2021-02-12 08:19:30 +01:00
test_data = (
' <p>See <span aria-label= " cloud with lightning and rain " class= " emoji emoji-26c8 " role= " img " title= " cloud with lightning and rain " > '
2021-02-12 08:20:45 +01:00
+ " :cloud_with_lightning_and_rain:</span>.</p> "
2021-02-12 08:19:30 +01:00
)
2017-10-28 00:55:16 +02:00
actual_output = fix_emojis ( test_data , " http://example.com " , " google " )
2021-02-12 08:19:30 +01:00
expected_output = (
' <p>See <img alt= " :cloud_with_lightning_and_rain: " src= " http://example.com/static/generated/emoji/images-google-64/26c8.png " '
+ ' title= " cloud with lightning and rain " style= " height: 20px; " >.</p> '
)
2017-09-27 19:39:42 +02:00
self . assertEqual ( actual_output , expected_output )