~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/services/features/tests/test_scopes.py

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-08-01 13:37:39 UTC
  • mfrom: (12913.2.23 mail-scope)
  • Revision ID: launchpad@pqm.canonical.com-20110801133739-r61kp1hfiqe0x83z
[r=adeuring,gmb][bug=810290] add 'mail_header:' feature scope

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
__metaclass__ = type
7
7
 
 
8
import email
 
9
 
8
10
from canonical.testing.layers import DatabaseFunctionalLayer
9
11
from lp.testing import TestCaseWithFactory
10
12
from lp.services.features.scopes import (
11
 
    BaseScope,
12
13
    BaseWebRequestScope,
 
14
    DefaultScope,
 
15
    MailHeaderScope,
13
16
    MultiScopeHandler,
 
17
    ScopesForMail,
14
18
    ScopesForScript,
15
19
    ScriptScope,
16
 
    )
 
20
    ServerScope,
 
21
    TeamScope,
 
22
    )
 
23
from testtools.matchers import (
 
24
    Matcher,
 
25
    MatchesAll,
 
26
    Mismatch,
 
27
    Not,
 
28
    )
 
29
 
 
30
 
 
31
class MultiScopeContains(Matcher):
 
32
    """Matches if a MultiScopeHandler checks the given scope."""
 
33
 
 
34
    def __init__(self, scope_class):
 
35
        self.scope_class = scope_class
 
36
 
 
37
    def __str__(self):
 
38
        return "contains %r scope handler" % self.scope_class
 
39
 
 
40
    def match(self, multi_handler):
 
41
        for h in multi_handler.handlers:
 
42
            if isinstance(h, self.scope_class):
 
43
                return
 
44
        else:
 
45
            return Mismatch(
 
46
                "Scope class %r not found in %r"
 
47
                % (self.scope_class, multi_handler))
 
48
 
 
49
 
 
50
class ScopeMatches(Matcher):
 
51
    """True if a particular scope is detected as active."""
 
52
 
 
53
    def __init__(self, scope_string):
 
54
        self.scope_string = scope_string
 
55
 
 
56
    def __str__(self):
 
57
        return "%s(%r)" % (
 
58
            self.__class__.__name__,
 
59
            self.scope_string)
 
60
 
 
61
    def match(self, scope_handler):
 
62
        if not scope_handler.lookup(self.scope_string):
 
63
            return Mismatch(
 
64
                "Handler %r didn't match scope string %r" %
 
65
                (scope_handler, self.scope_string))
17
66
 
18
67
 
19
68
class FakeScope(BaseWebRequestScope):
67
116
        script_name = self.factory.getUniqueString()
68
117
        scopes = ScopesForScript(script_name)
69
118
        self.assertFalse(scopes.lookup("script:other"))
 
119
 
 
120
 
 
121
sample_message = """\
 
122
From: rae@example.com
 
123
To: new@bugs.launchpad.net
 
124
Message-Id: <20110107085110.EB4A1181C2A@whatever>
 
125
Date: Fri,  7 Jan 2011 02:51:10 -0600 (CST)
 
126
Received: by other.example.com (Postfix, from userid 1000)
 
127
\tid DEADBEEF; Fri,  7 Jan 2011 02:51:10 -0600 (CST)
 
128
Received: by lithe (Postfix, from userid 1000)
 
129
\tid JOB_ID; Fri,  7 Jan 2011 02:51:10 -0600 (CST)
 
130
Subject: email scopes don't work
 
131
 
 
132
This is awful.
 
133
"""
 
134
 
 
135
 
 
136
class TestMailScopes(TestCaseWithFactory):
 
137
 
 
138
    layer = DatabaseFunctionalLayer
 
139
 
 
140
    def make_mail_scopes(self):
 
141
        # actual Launchpad uses an ISignedMessage which is a zinterface around
 
142
        # an email.message, but the basic one will do
 
143
        sample_email_message = email.message_from_string(sample_message)
 
144
        scopes = ScopesForMail(sample_email_message)
 
145
        return scopes
 
146
 
 
147
    def test_ScopesForMail_examines_server(self):
 
148
        mail_scopes = self.make_mail_scopes()
 
149
        self.assertThat(mail_scopes, MatchesAll(
 
150
            MultiScopeContains(ServerScope),
 
151
            MultiScopeContains(DefaultScope),
 
152
            MultiScopeContains(MailHeaderScope),
 
153
            MultiScopeContains(TeamScope),
 
154
            ))
 
155
 
 
156
    def test_mail_header_scope(self):
 
157
        mail_scopes = self.make_mail_scopes()
 
158
        self.assertThat(mail_scopes, MatchesAll(
 
159
            ScopeMatches("mail_header:From:rae@example.com")))
 
160
        # Regexs are case-sensitive by default, like Python.
 
161
        self.assertThat(mail_scopes, Not(
 
162
            ScopeMatches("mail_header:From:rae@Example.com")))
 
163
        # But header field names are case-insensitive, like rfc2822.
 
164
        self.assertThat(mail_scopes,
 
165
            ScopeMatches("mail_header:from:rae@example.com"))
 
166
        # Repeated headers check all values.
 
167
        self.assertThat(mail_scopes, MatchesAll(
 
168
            ScopeMatches(r"mail_header:Received:other\.example\.com"),
 
169
            ScopeMatches(r"mail_header:Received:lithe")))
 
170
        # Long lines are not unfolded, but you can match them if you turn on
 
171
        # DOTALL.
 
172
        self.assertThat(mail_scopes,
 
173
            ScopeMatches(r"mail_header:Received:(?s)other\.example\.com.*"
 
174
                "id DEADBEEF"))