PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/src/mailman/app/tests/test_notifications.py

https://gitlab.com/mmhat/mailman
Python | 317 lines | 291 code | 8 blank | 18 comment | 0 complexity | 5002ccb753f3a68b2069441e774be754 MD5 | raw file
  1. # Copyright (C) 2012-2019 by the Free Software Foundation, Inc.
  2. #
  3. # This file is part of GNU Mailman.
  4. #
  5. # GNU Mailman is free software: you can redistribute it and/or modify it under
  6. # the terms of the GNU General Public License as published by the Free
  7. # Software Foundation, either version 3 of the License, or (at your option)
  8. # any later version.
  9. #
  10. # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
  11. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  13. # more details.
  14. #
  15. # You should have received a copy of the GNU General Public License along with
  16. # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
  17. """Test notifications."""
  18. import os
  19. import unittest
  20. from contextlib import ExitStack
  21. from mailman.app.lifecycle import create_list
  22. from mailman.config import config
  23. from mailman.interfaces.languages import ILanguageManager
  24. from mailman.interfaces.member import MemberRole
  25. from mailman.interfaces.subscriptions import ISubscriptionManager
  26. from mailman.interfaces.template import ITemplateManager
  27. from mailman.interfaces.usermanager import IUserManager
  28. from mailman.testing.helpers import (
  29. get_queue_messages, set_preferred, subscribe)
  30. from mailman.testing.layers import ConfigLayer
  31. from mailman.utilities.datetime import now
  32. from tempfile import TemporaryDirectory
  33. from zope.component import getUtility
  34. class TestNotifications(unittest.TestCase):
  35. """Test notifications."""
  36. layer = ConfigLayer
  37. maxDiff = None
  38. def setUp(self):
  39. resources = ExitStack()
  40. self.addCleanup(resources.close)
  41. self.var_dir = resources.enter_context(TemporaryDirectory())
  42. self._mlist = create_list('test@example.com')
  43. self._mlist.display_name = 'Test List'
  44. getUtility(ITemplateManager).set(
  45. 'list:user:notice:welcome', self._mlist.list_id,
  46. 'mailman:///welcome.txt')
  47. config.push('template config', """\
  48. [paths.testing]
  49. template_dir: {}/templates
  50. """.format(self.var_dir))
  51. resources.callback(config.pop, 'template config')
  52. # Populate the template directories with a few fake templates.
  53. path = os.path.join(self.var_dir, 'templates', 'site', 'en')
  54. os.makedirs(path)
  55. full_path = os.path.join(path, 'list:user:notice:welcome.txt')
  56. with open(full_path, 'w', encoding='utf-8') as fp:
  57. print("""\
  58. Welcome to the $list_name mailing list.
  59. Posting address: $fqdn_listname
  60. Help and other requests: $list_requests
  61. Your name: $user_name
  62. Your address: $user_address""", file=fp)
  63. # Write a list-specific welcome message.
  64. path = os.path.join(self.var_dir, 'templates', 'lists',
  65. 'test@example.com', 'xx')
  66. os.makedirs(path)
  67. full_path = os.path.join(path, 'list:user:notice:welcome.txt')
  68. with open(full_path, 'w', encoding='utf-8') as fp:
  69. print('You just joined the $list_name mailing list!', file=fp)
  70. # Write a list-specific welcome message with non-ascii.
  71. path = os.path.join(self.var_dir, 'templates', 'lists',
  72. 'test@example.com', 'yy')
  73. os.makedirs(path)
  74. full_path = os.path.join(path, 'list:user:notice:welcome.txt')
  75. with open(full_path, 'w', encoding='utf-8') as fp:
  76. print('Yöu just joined the $list_name mailing list!', file=fp)
  77. # Write a list-specific address confirmation message with non-ascii.
  78. full_path = os.path.join(path, 'list:user:action:subscribe.txt')
  79. with open(full_path, 'w', encoding='utf-8') as fp:
  80. print('Wé need your confirmation', file=fp)
  81. def test_welcome_message(self):
  82. subscribe(self._mlist, 'Anne', email='anne@example.com')
  83. # Now there's one message in the virgin queue.
  84. items = get_queue_messages('virgin', expected_count=1)
  85. message = items[0].msg
  86. self.assertEqual(str(message['subject']),
  87. 'Welcome to the "Test List" mailing list')
  88. self.assertMultiLineEqual(message.get_payload(), """\
  89. Welcome to the Test List mailing list.
  90. Posting address: test@example.com
  91. Help and other requests: test-request@example.com
  92. Your name: Anne Person
  93. Your address: anne@example.com
  94. """)
  95. def test_more_specific_welcome_message_nonenglish(self):
  96. # The welcome message url can contain placeholders for the fqdn list
  97. # name and language.
  98. getUtility(ITemplateManager).set(
  99. 'list:user:notice:welcome', self._mlist.list_id,
  100. 'mailman:///$listname/$language/welcome.txt')
  101. # Add the xx language and subscribe Anne using it.
  102. manager = getUtility(ILanguageManager)
  103. manager.add('xx', 'us-ascii', 'Xlandia')
  104. # We can't use the subscribe() helper because that would send the
  105. # welcome message before we set the member's preferred language.
  106. address = getUtility(IUserManager).create_address(
  107. 'anne@example.com', 'Anne Person')
  108. address.preferences.preferred_language = 'xx'
  109. self._mlist.subscribe(address)
  110. # Now there's one message in the virgin queue.
  111. items = get_queue_messages('virgin', expected_count=1)
  112. message = items[0].msg
  113. self.assertEqual(str(message['subject']),
  114. 'Welcome to the "Test List" mailing list')
  115. self.assertMultiLineEqual(
  116. message.get_payload(),
  117. 'You just joined the Test List mailing list!')
  118. def test_more_specific_messages_nonascii(self):
  119. # The welcome message url can contain placeholders for the fqdn list
  120. # name and language.
  121. getUtility(ITemplateManager).set(
  122. 'list:user:notice:welcome', self._mlist.list_id,
  123. 'mailman:///$listname/$language/welcome.txt')
  124. # Add the yy language and subscribe Anne using it.
  125. getUtility(ILanguageManager).add('yy', 'utf-8', 'Ylandia')
  126. # We can't use the subscribe() helper because that would send the
  127. # welcome message before we set the member's preferred language.
  128. address = getUtility(IUserManager).create_address(
  129. 'anne@example.com', 'Anné Person')
  130. address.preferences.preferred_language = 'yy'
  131. # Get the admin notice too.
  132. self._mlist.admin_notify_mchanges = True
  133. # Make another non-ascii replacement.
  134. self._mlist.display_name = 'Tést List'
  135. # And set the list's language.
  136. self._mlist.preferred_language = 'yy'
  137. self._mlist.subscribe(address)
  138. # Now there are two messages in the virgin queue.
  139. items = get_queue_messages('virgin', expected_count=2)
  140. if str(items[0].msg['subject']).startswith('Welcome'):
  141. welcome = items[0].msg
  142. admin_notice = items[1].msg
  143. else:
  144. welcome = items[1].msg
  145. admin_notice = items[0].msg
  146. self.assertEqual(str(welcome['subject']),
  147. 'Welcome to the "Tést List" mailing list')
  148. self.assertMultiLineEqual(
  149. welcome.get_payload(decode=True).decode('utf-8'),
  150. 'Yöu just joined the Tést List mailing list!')
  151. # Ensure the message is single part and properly encoded.
  152. raw_payload = welcome.get_payload()
  153. self.assertEqual(
  154. raw_payload.encode('us-ascii', 'replace').decode('us-ascii'),
  155. raw_payload)
  156. self.assertEqual(str(admin_notice['subject']),
  157. 'Tést List subscription notification')
  158. self.assertMultiLineEqual(
  159. admin_notice.get_payload(decode=True).decode('utf-8'),
  160. '=?utf-8?q?Ann=C3=A9_Person?= <anne@example.com> has been'
  161. ' successfully subscribed to Tést List.\n')
  162. # Ensure the message is single part and properly encoded.
  163. raw_payload = admin_notice.get_payload()
  164. self.assertEqual(
  165. raw_payload.encode('us-ascii', 'replace').decode('us-ascii'),
  166. raw_payload)
  167. def test_confirmation_message(self):
  168. # Create an address to subscribe.
  169. address = getUtility(IUserManager).create_address(
  170. 'anne@example.com', 'Anne Person')
  171. # Register the address with the list to create a confirmation notice.
  172. ISubscriptionManager(self._mlist).register(address)
  173. # Now there's one message in the virgin queue.
  174. items = get_queue_messages('virgin', expected_count=1)
  175. message = items[0].msg
  176. self.assertTrue(str(message['subject']).startswith('confirm'))
  177. self.assertMultiLineEqual(
  178. message.get_payload(), """\
  179. Email Address Registration Confirmation
  180. Hello, this is the GNU Mailman server at example.com.
  181. We have received a registration request for the email address
  182. anne@example.com
  183. Before you can start using GNU Mailman at this site, you must first confirm
  184. that this is your email address. You can do this by replying to this message,
  185. keeping the Subject header intact.
  186. If you do not wish to register this email address, simply disregard this
  187. message. If you think you are being maliciously subscribed to the list, or
  188. have any other questions, you may contact
  189. test-owner@example.com
  190. """)
  191. def test_nonascii_confirmation_message(self):
  192. # Add the 'yy' language and set it
  193. getUtility(ILanguageManager).add('yy', 'utf-8', 'Ylandia')
  194. self._mlist.preferred_language = 'yy'
  195. # Create an address to subscribe.
  196. address = getUtility(IUserManager).create_address(
  197. 'anne@example.com', 'Anne Person')
  198. # Register the address with the list to create a confirmation notice.
  199. ISubscriptionManager(self._mlist).register(address)
  200. # Now there's one message in the virgin queue.
  201. items = get_queue_messages('virgin', expected_count=1)
  202. message = items[0].msg
  203. self.assertTrue(str(message['subject']).startswith('confirm'))
  204. self.assertMultiLineEqual(
  205. message.get_payload(decode=True).decode('utf-8'),
  206. 'Wé need your confirmation\n')
  207. def test_no_welcome_message_to_owners(self):
  208. # Welcome messages go only to mailing list members, not to owners.
  209. subscribe(self._mlist, 'Anne', MemberRole.owner, 'anne@example.com')
  210. # There is no welcome message in the virgin queue.
  211. get_queue_messages('virgin', expected_count=0)
  212. def test_no_welcome_message_to_nonmembers(self):
  213. # Welcome messages go only to mailing list members, not to nonmembers.
  214. subscribe(self._mlist, 'Anne', MemberRole.nonmember,
  215. 'anne@example.com')
  216. # There is no welcome message in the virgin queue.
  217. get_queue_messages('virgin', expected_count=0)
  218. def test_no_welcome_message_to_moderators(self):
  219. # Welcome messages go only to mailing list members, not to moderators.
  220. subscribe(self._mlist, 'Anne', MemberRole.moderator,
  221. 'anne@example.com')
  222. # There is no welcome message in the virgin queue.
  223. get_queue_messages('virgin', expected_count=0)
  224. def test_member_susbcribed_address_has_display_name(self):
  225. address = getUtility(IUserManager).create_address(
  226. 'anne@example.com', 'Anne Person')
  227. address.verified_on = now()
  228. self._mlist.subscribe(address)
  229. items = get_queue_messages('virgin', expected_count=1)
  230. message = items[0].msg
  231. self.assertEqual(message['to'], 'Anne Person <anne@example.com>')
  232. def test_member_subscribed_address_has_no_display_name(self):
  233. address = getUtility(IUserManager).create_address('anne@example.com')
  234. address.verified_on = now()
  235. self._mlist.subscribe(address)
  236. items = get_queue_messages('virgin', expected_count=1)
  237. message = items[0].msg
  238. self.assertEqual(message['to'], 'anne@example.com')
  239. def test_member_is_user_and_has_display_name(self):
  240. user = getUtility(IUserManager).create_user(
  241. 'anne@example.com', 'Anne Person')
  242. set_preferred(user)
  243. self._mlist.subscribe(user)
  244. items = get_queue_messages('virgin', expected_count=1)
  245. message = items[0].msg
  246. self.assertEqual(message['to'], 'Anne Person <anne@example.com>')
  247. def test_member_is_user_and_has_no_display_name(self):
  248. user = getUtility(IUserManager).create_user('anne@example.com')
  249. set_preferred(user)
  250. self._mlist.subscribe(user)
  251. items = get_queue_messages('virgin', expected_count=1)
  252. message = items[0].msg
  253. self.assertEqual(message['to'], 'anne@example.com')
  254. def test_member_has_linked_user_display_name(self):
  255. user = getUtility(IUserManager).create_user(
  256. 'anne@example.com', 'Anne Person')
  257. set_preferred(user)
  258. address = getUtility(IUserManager).create_address('anne2@example.com')
  259. address.verified_on = now()
  260. user.link(address)
  261. self._mlist.subscribe(address)
  262. items = get_queue_messages('virgin', expected_count=1)
  263. message = items[0].msg
  264. self.assertEqual(message['to'], 'Anne Person <anne2@example.com>')
  265. def test_member_has_no_linked_display_name(self):
  266. user = getUtility(IUserManager).create_user('anne@example.com')
  267. set_preferred(user)
  268. address = getUtility(IUserManager).create_address('anne2@example.com')
  269. address.verified_on = now()
  270. user.link(address)
  271. self._mlist.subscribe(address)
  272. items = get_queue_messages('virgin', expected_count=1)
  273. message = items[0].msg
  274. self.assertEqual(message['to'], 'anne2@example.com')
  275. def test_member_has_address_and_user_display_name(self):
  276. user = getUtility(IUserManager).create_user(
  277. 'anne@example.com', 'Anne Person')
  278. set_preferred(user)
  279. address = getUtility(IUserManager).create_address(
  280. 'anne2@example.com', 'Anne X Person')
  281. address.verified_on = now()
  282. user.link(address)
  283. self._mlist.subscribe(address)
  284. items = get_queue_messages('virgin', expected_count=1)
  285. message = items[0].msg
  286. self.assertEqual(message['to'], 'Anne X Person <anne2@example.com>')