~danci-emanuel/mailman/dlist_runner

« back to all changes in this revision

Viewing changes to src/mailman/chains/tests/test_headers.py

  • Committer: Barry Warsaw
  • Date: 2012-04-06 22:40:09 UTC
  • mfrom: (7143.1.2 coverage)
  • Revision ID: barry@list.org-20120406224009-uo9njbd2op89521v
 * Header check specifications in the `mailman.cfg` file have changed quite
   bit.  The previous `[spam.header.foo]` sections have been removed.
   Instead, there's a new `[antispam]` section that contains a `header_checks`
   variable.  This variable takes multiple lines of `Header: regexp` values,
   one per line.  There is also a new `jump_chain` variable which names the
   chain to jump to should any of the header checks (including the
   list-specific, and programmatically added ones) match.

 * Fixed a typo when returning the configuration file's header match checks.
   (LP: #953497)

Also:

 - Remove an unused method.
 - Improve test coverage for mailman/app/bounces.py
 - 100% test coverage for mailman/chains/headers.py
 - Various other minor code cleanup.
 - Fixed the 'any' rule, which was checking a bogus metadata dictionary key.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2012 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
 
 
18
"""Test the header chain."""
 
19
 
 
20
from __future__ import absolute_import, print_function, unicode_literals
 
21
 
 
22
__metaclass__ = type
 
23
__all__ = [
 
24
    'TestHeaderChain',
 
25
    ]
 
26
 
 
27
 
 
28
import unittest
 
29
 
 
30
from mailman.app.lifecycle import create_list
 
31
from mailman.chains.headers import HeaderMatchRule
 
32
from mailman.config import config
 
33
from mailman.email.message import Message
 
34
from mailman.interfaces.chain import LinkAction
 
35
from mailman.testing.layers import ConfigLayer
 
36
from mailman.testing.helpers import LogFileMark, configuration
 
37
 
 
38
 
 
39
 
 
40
class TestHeaderChain(unittest.TestCase):
 
41
    """Test the header chain code."""
 
42
 
 
43
    layer = ConfigLayer
 
44
 
 
45
    def setUp(self):
 
46
        self._mlist = create_list('test@example.com')
 
47
        # Python 2.6 does not have assertListEqual().
 
48
        self._leq = getattr(self, 'assertListEqual', self.assertEqual)
 
49
 
 
50
    @configuration('antispam', header_checks="""
 
51
    Foo: a+
 
52
    Bar: bb?
 
53
    """)
 
54
    def test_config_checks(self):
 
55
        # Test that the header-match chain has the header checks from the
 
56
        # configuration file.
 
57
        chain = config.chains['header-match']
 
58
        # The links are created dynamically; the rule names will all start
 
59
        # with the same prefix, but have a variable suffix.  The actions will
 
60
        # all be to jump to the named chain.  Do these checks now, while we
 
61
        # collect other useful information.
 
62
        post_checks = []
 
63
        saw_any_rule = False
 
64
        for link in chain.get_links(self._mlist, Message(), {}):
 
65
            if link.rule.name == 'any':
 
66
                saw_any_rule = True
 
67
                self.assertEqual(link.action, LinkAction.jump)
 
68
            elif saw_any_rule:
 
69
                raise AssertionError("'any' rule was not last")
 
70
            else:
 
71
                self.assertEqual(link.rule.name[:13], 'header-match-')
 
72
                self.assertEqual(link.action, LinkAction.defer)
 
73
                post_checks.append((link.rule.header, link.rule.pattern))
 
74
        self._leq(post_checks, [
 
75
            ('Foo', 'a+'),
 
76
            ('Bar', 'bb?'),
 
77
            ])
 
78
 
 
79
    @configuration('antispam', header_checks="""
 
80
    Foo: foo
 
81
    A-bad-line
 
82
    Bar: bar
 
83
    """)
 
84
    def test_bad_configuration_line(self):
 
85
        # Take a mark on the error log file.
 
86
        mark = LogFileMark('mailman.error')
 
87
        # A bad value in [antispam]header_checks should just get ignored, but
 
88
        # with an error message logged.
 
89
        chain = config.chains['header-match']
 
90
        # The links are created dynamically; the rule names will all start
 
91
        # with the same prefix, but have a variable suffix.  The actions will
 
92
        # all be to jump to the named chain.  Do these checks now, while we
 
93
        # collect other useful information.
 
94
        post_checks = []
 
95
        saw_any_rule = False
 
96
        for link in chain.get_links(self._mlist, Message(), {}):
 
97
            if link.rule.name == 'any':
 
98
                saw_any_rule = True
 
99
                self.assertEqual(link.action, LinkAction.jump)
 
100
            elif saw_any_rule:
 
101
                raise AssertionError("'any' rule was not last")
 
102
            else:
 
103
                self.assertEqual(link.rule.name[:13], 'header-match-')
 
104
                self.assertEqual(link.action, LinkAction.defer)
 
105
                post_checks.append((link.rule.header, link.rule.pattern))
 
106
        self._leq(post_checks, [
 
107
            ('Foo', 'foo'),
 
108
            ('Bar', 'bar'),
 
109
            ])
 
110
        # Check the error log.
 
111
        self.assertEqual(mark.readline()[-77:-1],
 
112
                         'Configuration error: [antispam]header_checks '
 
113
                         'contains bogus line: A-bad-line')
 
114
 
 
115
    def test_duplicate_header_match_rule(self):
 
116
        # 100% coverage: test an assertion in a corner case.
 
117
        #
 
118
        # Save the existing rules so they can be restored later.
 
119
        saved_rules = config.rules.copy()
 
120
        next_rule_name = 'header-match-{0:02}'.format(HeaderMatchRule._count)
 
121
        config.rules[next_rule_name] = object()
 
122
        try:
 
123
            self.assertRaises(AssertionError,
 
124
                              HeaderMatchRule, 'x-spam-score', '.*')
 
125
        finally:
 
126
            config.rules = saved_rules