11import asyncore
22import base64
33import email .mime .text
4+ from email import policy
45from email .message import EmailMessage
56from email .base64mime import body_encode as encode_base64
67import email .utils
@@ -1219,6 +1220,8 @@ def test_send_message_uses_smtputf8_if_addrs_non_ascii(self):
12191220 self .assertEqual (self .serv .last_rcpt_options , [])
12201221
12211222 def test_send_message_error_on_non_ascii_addrs_if_no_smtputf8 (self ):
1223+ self .serv .enable_SMTPUTF8 = False
1224+ self .serv ._extra_features = []
12221225 msg = EmailMessage ()
12231226 msg ['From' ] = "Páolo <főo@bar.com>"
12241227 msg ['To' ] = 'Dinsdale'
@@ -1227,7 +1230,103 @@ def test_send_message_error_on_non_ascii_addrs_if_no_smtputf8(self):
12271230 HOST , self .port , local_hostname = 'localhost' , timeout = 3 )
12281231 self .addCleanup (smtp .close )
12291232 self .assertRaises (smtplib .SMTPNotSupportedError ,
1230- smtp .send_message (msg ))
1233+ lambda : smtp .send_message (msg ))
1234+
1235+ def test_send_message_uses_8bitmime_if_cte_type_8bitmime (self ):
1236+ msg = EmailMessage ()
1237+ msg ['From' ] = 'Dinsdale <foo@bar.com>'
1238+ msg ['To' ] = 'Dinsdale'
1239+ msg ['Subject' ] = 'Nudge nudge, wink, wink \u1F60 9'
1240+ # XXX I don't know why I need two \n's here, but this is an existing
1241+ # bug (if it is one) and not a problem with the new functionality.
1242+ msg .set_content ("oh là là, know what I mean, know what I mean?\n \n " )
1243+ # XXX smtpd converts received /r/n to /n, so we can't easily test that
1244+ # we are successfully sending /r/n :(.
1245+ expected = textwrap .dedent ("""\
1246+ From: Dinsdale <foo@bar.com>
1247+ To: Dinsdale
1248+ Subject: Nudge nudge, wink, wink =?utf-8?q?=E1=BD=A09?=
1249+ Content-Type: text/plain; charset="utf-8"
1250+ Content-Transfer-Encoding: 8bit
1251+ MIME-Version: 1.0
1252+
1253+ oh là là, know what I mean, know what I mean?
1254+ """ )
1255+ smtp = smtplib .SMTP (
1256+ HOST , self .port , local_hostname = 'localhost' , timeout = 3 )
1257+ self .addCleanup (smtp .close )
1258+ self .assertEqual (smtp .send_message (msg ), {})
1259+ self .assertEqual (self .serv .last_mailfrom , 'foo@bar.com' )
1260+ self .assertEqual (self .serv .last_rcpttos , ['Dinsdale' ])
1261+ self .assertEqual (self .serv .last_message .decode (), expected )
1262+ self .assertIn ('BODY=8BITMIME' , self .serv .last_mail_options )
1263+ self .assertNotIn ('SMTPUTF8' , self .serv .last_mail_options )
1264+ self .assertEqual (self .serv .last_rcpt_options , [])
1265+
1266+ def test_send_message_uses_7bit_if_requested_even_with_8bitmime (self ):
1267+ msg = EmailMessage (policy = policy .default .clone (cte_type = '7bit' ))
1268+ msg ['From' ] = 'Dinsdale <foo@bar.com>'
1269+ msg ['To' ] = 'Dinsdale'
1270+ msg ['Subject' ] = 'Nudge nudge, wink, wink \u1F60 9'
1271+ # XXX I don't know why I need two \n's here, but this is an existing
1272+ # bug (if it is one) and not a problem with the new functionality.
1273+ msg .set_content ("oh là là, know what I mean, know what I mean?\n \n " )
1274+ # XXX smtpd converts received /r/n to /n, so we can't easily test that
1275+ # we are successfully sending /r/n :(.
1276+ # XXX This uses quoted-printable but the case below happens to end up
1277+ # with base64...
1278+ expected = textwrap .dedent ("""\
1279+ From: Dinsdale <foo@bar.com>
1280+ To: Dinsdale
1281+ Subject: Nudge nudge, wink, wink =?utf-8?q?=E1=BD=A09?=
1282+ Content-Type: text/plain; charset="utf-8"
1283+ Content-Transfer-Encoding: quoted-printable
1284+ MIME-Version: 1.0
1285+
1286+ oh l=C3=A0 l=C3=A0, know what I mean, know what I mean?
1287+ """ )
1288+ smtp = smtplib .SMTP (
1289+ HOST , self .port , local_hostname = 'localhost' , timeout = 3 )
1290+ self .addCleanup (smtp .close )
1291+ self .assertEqual (smtp .send_message (msg ), {})
1292+ self .assertEqual (self .serv .last_mailfrom , 'foo@bar.com' )
1293+ self .assertEqual (self .serv .last_rcpttos , ['Dinsdale' ])
1294+ self .assertEqual (self .serv .last_message .decode (), expected )
1295+ self .assertNotIn ('BODY=8BITMIME' , self .serv .last_mail_options )
1296+ self .assertNotIn ('SMTPUTF8' , self .serv .last_mail_options )
1297+ self .assertEqual (self .serv .last_rcpt_options , [])
1298+
1299+ def test_send_message_uses_7bit_if_cte_type_8bitmime_but_no_8bitmime (self ):
1300+ self .serv .enable_SMTPUTF8 = False
1301+ self .serv ._extra_features = []
1302+ msg = EmailMessage ()
1303+ msg ['From' ] = 'Dinsdale <foo@bar.com>'
1304+ msg ['To' ] = 'Dinsdale'
1305+ msg ['Subject' ] = 'Nudge nudge, wink, wink \u1F60 9'
1306+ # XXX I don't know why I need two \n's here, but this is an existing
1307+ # bug (if it is one) and not a problem with the new functionality.
1308+ msg .set_content ("oh là là, know what I mean, know what I mean?\n \n " )
1309+ # XXX smtpd converts received /r/n to /n, so we can't easily test that
1310+ # we are successfully sending /r/n :(.
1311+ expected = textwrap .dedent ("""\
1312+ From: Dinsdale <foo@bar.com>
1313+ To: Dinsdale
1314+ Subject: Nudge nudge, wink, wink =?utf-8?q?=E1=BD=A09?=
1315+ Content-Type: text/plain; charset="utf-8"
1316+ Content-Transfer-Encoding: base64
1317+ MIME-Version: 1.0
1318+
1319+ b2ggbMOgIGzDoCwga25vdyB3aGF0IEkgbWVhbiwga25vdyB3aGF0IEkgbWVhbj8KCg==""" )
1320+ smtp = smtplib .SMTP (
1321+ HOST , self .port , local_hostname = 'localhost' , timeout = 3 )
1322+ self .addCleanup (smtp .close )
1323+ self .assertEqual (smtp .send_message (msg ), {})
1324+ self .assertEqual (self .serv .last_mailfrom , 'foo@bar.com' )
1325+ self .assertEqual (self .serv .last_rcpttos , ['Dinsdale' ])
1326+ self .assertEqual (self .serv .last_message .decode (), expected )
1327+ self .assertNotIn ('BODY=8BITMIME' , self .serv .last_mail_options )
1328+ self .assertNotIn ('SMTPUTF8' , self .serv .last_mail_options )
1329+ self .assertEqual (self .serv .last_rcpt_options , [])
12311330
12321331
12331332EXPECTED_RESPONSE = encode_base64 (b'\0 psu\0 doesnotexist' , eol = '' )
0 commit comments