test_handler_multi.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. import pytest
  2. from redmail import EmailSender
  3. from redmail import MultiEmailHandler
  4. import logging
  5. from convert import payloads_to_dict
  6. def _create_dummy_send(messages:list):
  7. def _dummy_send(msg):
  8. messages.append(msg)
  9. return _dummy_send
  10. def test_default_body():
  11. hdlr = MultiEmailHandler(host="localhost", port=0, receivers=["me@example.com"], subject="Some logging")
  12. # By default, this should be body if text/html/html_template/text_template not specified
  13. assert hdlr.email.text == MultiEmailHandler.default_text
  14. def test_sender_with_login():
  15. hdlr = MultiEmailHandler(host="localhost", port=0, username="myuser", password="1234", receivers=["me@example.com"], subject="Some logging")
  16. # By default, this should be body if text/html/html_template/text_template not specified
  17. sender = hdlr.email
  18. assert sender.username == "myuser"
  19. assert sender.password == "1234"
  20. assert sender.receivers == ["me@example.com"]
  21. assert sender.subject == "Some logging"
  22. @pytest.mark.parametrize("kwargs,exp_headers,exp_payload",
  23. [
  24. pytest.param(
  25. {
  26. "email": EmailSender(host="localhost", port=0),
  27. "subject": "A log record",
  28. "sender": "me@example.com",
  29. "receivers": ["he@example.com", "she@example.com"],
  30. },
  31. {
  32. "From": "me@example.com",
  33. "To": "he@example.com, she@example.com",
  34. "Subject": "A log record",
  35. 'Content-Transfer-Encoding': '7bit',
  36. 'Content-Type': 'text/plain; charset="utf-8"',
  37. 'MIME-Version': '1.0',
  38. },
  39. {
  40. 'text/plain': 'Log Recods:\na message\n'
  41. },
  42. id="Minimal",
  43. ),
  44. pytest.param(
  45. {
  46. "email": EmailSender(host="localhost", port=0),
  47. "subject": "A log record",
  48. "sender": "me@example.com",
  49. "receivers": ["he@example.com", "she@example.com"],
  50. "text": "The records: \n{% for msg in msgs %}Log: {{ msg }}{% endfor %}",
  51. "fmt": '%(name)s - %(levelname)s - %(message)s'
  52. },
  53. {
  54. "From": "me@example.com",
  55. "To": "he@example.com, she@example.com",
  56. "Subject": "A log record",
  57. 'Content-Transfer-Encoding': '7bit',
  58. 'Content-Type': 'text/plain; charset="utf-8"',
  59. 'MIME-Version': '1.0',
  60. },
  61. {
  62. 'text/plain': 'The records: \nLog: _test - INFO - a message\n'
  63. },
  64. id="Custom message (msgs)",
  65. ),
  66. pytest.param(
  67. {
  68. "email": EmailSender(host="localhost", port=0),
  69. "subject": "A log record",
  70. "sender": "me@example.com",
  71. "receivers": ["he@example.com", "she@example.com"],
  72. "text": "The records: \n{% for rec in records %}Log: {{ rec.levelname }} - {{ rec.message }}{% endfor %}",
  73. "fmt": '%(name)s - %(levelname)s - %(message)s'
  74. },
  75. {
  76. "From": "me@example.com",
  77. "To": "he@example.com, she@example.com",
  78. "Subject": "A log record",
  79. 'Content-Transfer-Encoding': '7bit',
  80. 'Content-Type': 'text/plain; charset="utf-8"',
  81. 'MIME-Version': '1.0',
  82. },
  83. {
  84. 'text/plain': 'The records: \nLog: INFO - a message\n',
  85. },
  86. id="Custom message (records)",
  87. ),
  88. pytest.param(
  89. {
  90. "email": EmailSender(host="localhost", port=0),
  91. "subject": "Logs: {min_level_name} - {max_level_name}",
  92. "sender": "me@example.com",
  93. "receivers": ["he@example.com", "she@example.com"],
  94. },
  95. {
  96. "From": "me@example.com",
  97. "To": "he@example.com, she@example.com",
  98. "Subject": "Logs: INFO - INFO",
  99. 'Content-Transfer-Encoding': '7bit',
  100. 'Content-Type': 'text/plain; charset="utf-8"',
  101. 'MIME-Version': '1.0',
  102. },
  103. {
  104. 'text/plain': 'Log Recods:\na message\n',
  105. },
  106. id="Sender with fomatted subject",
  107. ),
  108. pytest.param(
  109. {
  110. "email": EmailSender(host="localhost", port=0),
  111. "subject": "A log record",
  112. "sender": "me@example.com",
  113. "receivers": ["he@example.com", "she@example.com"],
  114. "fmt": '%(name)s - %(levelname)s - %(message)s',
  115. "html": "<h1>The records:</h1><p>{% for msg in msgs %}Log: {{ msg }}{% endfor %}</p>"
  116. },
  117. {
  118. "From": "me@example.com",
  119. "To": "he@example.com, she@example.com",
  120. "Subject": "A log record",
  121. 'Content-Type': 'multipart/mixed',
  122. },
  123. {
  124. 'multipart/mixed': {
  125. 'multipart/alternative': {
  126. 'text/html': "<h1>The records:</h1><p>Log: _test - INFO - a message</p>\n",
  127. }
  128. }
  129. },
  130. id="Custom message (HTML, msgs)",
  131. ),
  132. pytest.param(
  133. {
  134. "email": EmailSender(host="localhost", port=0),
  135. "subject": "A log record",
  136. "sender": "me@example.com",
  137. "receivers": ["he@example.com", "she@example.com"],
  138. "fmt": '%(name)s: %(levelname)s: %(message)s',
  139. "html": "<h1>The records:</h1><p>{% for rec in records %}Log: {{ rec.levelname }} - {{ rec.message }}{% endfor %}</p>"
  140. },
  141. {
  142. "From": "me@example.com",
  143. "To": "he@example.com, she@example.com",
  144. "Subject": "A log record",
  145. 'Content-Type': 'multipart/mixed',
  146. },
  147. {
  148. 'multipart/mixed': {
  149. 'multipart/alternative': {
  150. 'text/html': "<h1>The records:</h1><p>Log: INFO - a message</p>\n",
  151. }
  152. }
  153. },
  154. id="Custom message (HTML, records)",
  155. ),
  156. ]
  157. )
  158. def test_emit(logger, kwargs, exp_headers, exp_payload):
  159. msgs = []
  160. fmt = kwargs.pop("fmt", None)
  161. hdlr = MultiEmailHandler(**kwargs)
  162. hdlr.formatter = logging.Formatter(fmt)
  163. hdlr.email.send_message = _create_dummy_send(msgs)
  164. logger.addHandler(hdlr)
  165. logger.setLevel(logging.INFO)
  166. logger.info("a message")
  167. hdlr.flush()
  168. assert len(msgs) == 1
  169. msg = msgs[0]
  170. headers = {
  171. key: val
  172. for key, val in msg.items()
  173. if key not in ('Message-ID', 'Date')
  174. }
  175. payload = msg.get_payload()
  176. assert headers == exp_headers
  177. structure = payloads_to_dict(msg)
  178. assert structure == exp_payload
  179. def test_flush_multiple(logger):
  180. msgs = []
  181. hdlr = MultiEmailHandler(
  182. email=EmailSender(host="localhost", port=0),
  183. subject="Logs: {min_level_name} - {max_level_name}",
  184. receivers=["he@example.com", "she@example.com"],
  185. text="Records: \n{% for rec in records %}{{ rec.levelname }} - {{ rec.message }}\n{% endfor %}"
  186. )
  187. hdlr.email.send_message = _create_dummy_send(msgs)
  188. logger.addHandler(hdlr)
  189. logger.setLevel(logging.DEBUG)
  190. logger.info("an info")
  191. logger.debug("a debug")
  192. hdlr.flush()
  193. assert len(msgs) == 1
  194. msg = msgs[0]
  195. headers = {
  196. key: val
  197. for key, val in msg.items()
  198. if key not in ('Message-ID', 'Date')
  199. }
  200. text = msg.get_payload()
  201. assert headers == {
  202. "From": "None",
  203. "To": "he@example.com, she@example.com",
  204. "Subject": "Logs: DEBUG - INFO",
  205. 'Content-Transfer-Encoding': '7bit',
  206. 'Content-Type': 'text/plain; charset="utf-8"',
  207. 'MIME-Version': '1.0',
  208. }
  209. assert text == "Records: \nINFO - an info\nDEBUG - a debug\n"
  210. def test_flush_none():
  211. msgs = []
  212. hdlr = MultiEmailHandler(
  213. email=EmailSender(host="localhost", port=0),
  214. subject="Logs: {min_level_name} - {max_level_name}",
  215. receivers=["he@example.com", "she@example.com"],
  216. text="Records: \n{% for rec in records %}{{ rec.levelname }} - {{ rec.message }}\n{% endfor %}"
  217. )
  218. hdlr.email.send_message = _create_dummy_send(msgs)
  219. logger = logging.getLogger("_test")
  220. logger.addHandler(hdlr)
  221. logger.setLevel(logging.DEBUG)
  222. hdlr.flush()
  223. assert len(msgs) == 1
  224. msg = msgs[0]
  225. headers = {
  226. key: val
  227. for key, val in msg.items()
  228. if key not in ('Message-ID', 'Date')
  229. }
  230. text = msg.get_payload()
  231. assert headers == {
  232. "From": "None",
  233. "To": "he@example.com, she@example.com",
  234. "Subject": "Logs: NOTSET - NOTSET",
  235. 'Content-Transfer-Encoding': '7bit',
  236. 'Content-Type': 'text/plain; charset="utf-8"',
  237. 'MIME-Version': '1.0',
  238. }
  239. assert text == "Records: \n"