# Copyright (C) 2014-2017 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # # GNU Mailman is free software: you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) # any later version. # # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # # You should have received a copy of the GNU General Public License along with # GNU Mailman. If not, see . """Test the decorate handler.""" import os import unittest from mailman.app.lifecycle import create_list from mailman.config import config from mailman.handlers import decorate from mailman.interfaces.archiver import IArchiver from mailman.interfaces.template import ITemplateManager from mailman.testing.helpers import ( LogFileMark, specialized_message_from_string as mfs) from mailman.testing.layers import ConfigLayer from tempfile import TemporaryDirectory from zope.component import getUtility from zope.interface import implementer @implementer(IArchiver) class TestArchiver: """A test archiver""" name = 'testarchiver' is_enabled = False @staticmethod def permalink(mlist, msg): return 'http://example.com/link_to_message' @implementer(IArchiver) class BrokenArchiver: name = 'broken' is_enabled = True @staticmethod def permalink(mlist, msg): raise RuntimeError('Cannot get permalink') class TestDecorate(unittest.TestCase): """Test the cook_headers handler.""" layer = ConfigLayer def setUp(self): self._mlist = create_list('ant@example.com') self._msg = mfs("""\ To: ant@example.com From: aperson@example.com Message-ID: Content-Type: text/plain; This is a test message. """) temporary_dir = TemporaryDirectory() self.addCleanup(temporary_dir.cleanup) template_dir = temporary_dir.name config.push('archiver', """\ [paths.testing] template_dir: {} [archiver.testarchiver] class: mailman.handlers.tests.test_decorate.TestArchiver enable: yes """.format(template_dir)) self.addCleanup(config.pop, 'archiver') def test_decorate_footer_with_archive_url(self): site_dir = os.path.join(config.TEMPLATE_DIR, 'site', 'en') os.makedirs(site_dir) footer_path = os.path.join(site_dir, 'myfooter.txt') with open(footer_path, 'w', encoding='utf-8') as fp: print('${testarchiver_url}', file=fp) getUtility(ITemplateManager).set( 'list:member:regular:footer', None, 'mailman:///myfooter.txt') self._mlist.preferred_language = 'en' decorate.process(self._mlist, self._msg, {}) self.assertIn('http://example.com/link_to_message', self._msg.as_string()) def test_list_id_allowed_in_template_uri(self): # Issue #196 - allow the list_id in the template uri expansion. list_dir = os.path.join( config.TEMPLATE_DIR, 'lists', 'ant.example.com', 'en') os.makedirs(list_dir) footer_path = os.path.join(list_dir, 'myfooter.txt') with open(footer_path, 'w', encoding='utf-8') as fp: print('${testarchiver_url}', file=fp) getUtility(ITemplateManager).set( 'list:member:regular:footer', self._mlist.list_id, 'mailman:///${list_id}/myfooter.txt') self._mlist.preferred_language = 'en' decorate.process(self._mlist, self._msg, {}) self.assertIn('http://example.com/link_to_message', self._msg.as_string()) def test_list_id_and_language_code_allowed_in_template_uri(self): # Issue #196 - allow the list_id in the template uri expansion. list_dir = os.path.join( config.TEMPLATE_DIR, 'lists', 'ant.example.com', 'it') os.makedirs(list_dir) footer_path = os.path.join(list_dir, 'myfooter.txt') with open(footer_path, 'w', encoding='utf-8') as fp: print('${testarchiver_url}', file=fp) getUtility(ITemplateManager).set( 'list:member:regular:footer', self._mlist.list_id, 'mailman:///${list_id}/${language}/myfooter.txt') self._mlist.preferred_language = 'it' decorate.process(self._mlist, self._msg, {}) self.assertIn('http://example.com/link_to_message', self._msg.as_string()) class TestBrokenPermalink(unittest.TestCase): layer = ConfigLayer def setUp(self): self._mlist = create_list('ant@example.com') self._msg = mfs("""\ To: ant@example.com From: aperson@example.com Message-ID: Content-Type: text/plain; This is a test message. """) temporary_dir = TemporaryDirectory() self.addCleanup(temporary_dir.cleanup) template_dir = temporary_dir.name config.push('archiver', """\ [paths.testing] template_dir: {} [archiver.testarchiver] class: mailman.handlers.tests.test_decorate.BrokenArchiver enable: yes """.format(template_dir)) self.addCleanup(config.pop, 'archiver') def test_broken_permalink(self): # GL issue #208 - IArchive messages raise exceptions, breaking the # rfc-2369 handler and shunting messages. site_dir = os.path.join(config.TEMPLATE_DIR, 'site', 'en') os.makedirs(site_dir) footer_path = os.path.join(site_dir, 'myfooter.txt') with open(footer_path, 'w', encoding='utf-8') as fp: print('${broken_url}', file=fp) getUtility(ITemplateManager).set( 'list:member:regular:footer', self._mlist.list_id, 'mailman:///myfooter.txt') self._mlist.preferred_language = 'en' mark = LogFileMark('mailman.archiver') decorate.process(self._mlist, self._msg, {}) log_messages = mark.read() self.assertNotIn('http:', self._msg.as_string()) self.assertIn('Exception in "broken" archiver', log_messages) self.assertIn('RuntimeError: Cannot get permalink', log_messages)