launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02152
lp:~allenap/launchpad/bug-mail-case-sensitive-domain-bug-48464-fix into lp:launchpad
Gavin Panella has proposed merging lp:~allenap/launchpad/bug-mail-case-sensitive-domain-bug-48464-fix into lp:launchpad with lp:~allenap/launchpad/bug-mail-case-sensitive-domain-bug-48464-refactor as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
This makes MailHandler case-insensitive to domains, moves its doctests into unit tests, and updates the integration test, incomingmail.txt, to demonstrate case-insensitivity.
--
https://code.launchpad.net/~allenap/launchpad/bug-mail-case-sensitive-domain-bug-48464-fix/+merge/43547
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~allenap/launchpad/bug-mail-case-sensitive-domain-bug-48464-fix into lp:launchpad.
=== modified file 'lib/lp/services/mail/handlers.py'
--- lib/lp/services/mail/handlers.py 2010-12-13 17:38:59 +0000
+++ lib/lp/services/mail/handlers.py 2010-12-13 17:39:00 +0000
@@ -2,6 +2,9 @@
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
+__all__ = [
+ "mail_handlers",
+ ]
from canonical.config import config
from lp.answers.mail.handler import AnswerTrackerHandler
@@ -13,50 +16,31 @@
class MailHandlers:
"""All the registered mail handlers."""
+ DEFAULT = (
+ (config.launchpad.bugs_domain, MaloneHandler),
+ (config.launchpad.specs_domain, SpecificationHandler),
+ (config.answertracker.email_domain, AnswerTrackerHandler),
+ # XXX flacoste 2007-04-23 Backward compatibility for old domain.
+ # We probably want to remove it in the future.
+ ('support.launchpad.net', AnswerTrackerHandler),
+ (config.launchpad.code_domain, CodeHandler),
+ )
+
def __init__(self):
- self._handlers = {
- config.launchpad.bugs_domain: MaloneHandler(),
- config.launchpad.specs_domain: SpecificationHandler(),
- config.answertracker.email_domain: AnswerTrackerHandler(),
- # XXX flacoste 2007-04-23 Backward compatibility for old domain.
- # We probably want to remove it in the future.
- 'support.launchpad.net': AnswerTrackerHandler(),
- config.launchpad.code_domain: CodeHandler(),
- }
+ self._handlers = {}
+ for domain, handler_factory in self.DEFAULT:
+ self.add(domain, handler_factory())
def get(self, domain):
"""Return the handler for the given email domain.
Return None if no such handler exists.
-
- >>> handlers = MailHandlers()
- >>> handlers.get('bugs.launchpad.net') #doctest: +ELLIPSIS
- <...MaloneHandler...>
- >>> handlers.get('no.such.domain') is None
- True
"""
- return self._handlers.get(domain)
+ return self._handlers.get(domain.lower())
def add(self, domain, handler):
- """Adds a handler for a domain.
-
- >>> handlers = MailHandlers()
- >>> handlers.get('some.domain') is None
- True
- >>> handler = object()
- >>> handlers.add('some.domain', handler)
- >>> handlers.get('some.domain') is handler
- True
-
- If there already is a handler for the domain, the old one will
- get overwritten:
-
- >>> new_handler = object()
- >>> handlers.add('some.domain', new_handler)
- >>> handlers.get('some.domain') is new_handler
- True
- """
- self._handlers[domain] = handler
+ """Adds a handler for a domain."""
+ self._handlers[domain.lower()] = handler
mail_handlers = MailHandlers()
=== modified file 'lib/lp/services/mail/tests/incomingmail.txt'
--- lib/lp/services/mail/tests/incomingmail.txt 2010-12-13 17:38:59 +0000
+++ lib/lp/services/mail/tests/incomingmail.txt 2010-12-13 17:39:00 +0000
@@ -50,17 +50,19 @@
>>> from canonical.testing.layers import LaunchpadZopelessLayer
>>> from canonical.launchpad.mail import sendmail as original_sendmail
-For these examples, we don't want the Precedence header added.
+For these examples, we don't want the Precedence header added. Domains
+are treated without regard to case: for incoming mail, foo.com and
+FOO.COM are treated equivalently.
>>> def sendmail(msg, to_addrs=None):
... return original_sendmail(msg, to_addrs=to_addrs, bulk=False)
>>> LaunchpadZopelessLayer.switchDbUser('launchpad')
>>> msgids = {'foo.com': [], 'bar.com': [], 'baz.com': []}
- >>> for domain in ('foo.com', 'bar.com', 'foo.com', 'baz.com'):
+ >>> for domain in ('foo.com', 'bar.com', 'FOO.COM', 'baz.com'):
... msg = read_test_message('signed_detached.txt')
... msg.replace_header('To', '123@%s' % domain)
- ... msgids[domain].append("<%s>" % sendmail(msg))
+ ... msgids[domain.lower()].append("<%s>" % sendmail(msg))
handleMail will check the timestamp on signed messages, but the signatures
on our testdata are old, and in these tests we don't care to be told.
=== modified file 'lib/lp/services/mail/tests/test_handlers.py'
--- lib/lp/services/mail/tests/test_handlers.py 2010-12-13 17:38:59 +0000
+++ lib/lp/services/mail/tests/test_handlers.py 2010-12-13 17:39:00 +0000
@@ -1,10 +1,40 @@
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2010 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
-from doctest import DocTestSuite
-
-
-def test_suite():
- return DocTestSuite('lp.services.mail.handlers')
+from lp.services.mail.handlers import MailHandlers
+from lp.testing import TestCase
+
+
+class TestMailHandlers(TestCase):
+
+ def test_get(self):
+ handlers = MailHandlers()
+ self.assertIsNot(None, handlers.get("bugs.launchpad.net"))
+ self.assertIs(None, handlers.get("no.such.domain"))
+
+ def test_get_is_case_insensitive(self):
+ handlers = MailHandlers()
+ handler = object()
+ handlers.add("some.domain", handler)
+ self.assertIs(handler, handlers.get("some.domain"))
+ self.assertIs(handler, handlers.get("SOME.DOMAIN"))
+ self.assertIs(handler, handlers.get("Some.Domain"))
+
+ def test_add_for_new_domain(self):
+ handlers = MailHandlers()
+ self.assertIs(None, handlers.get("some.domain"))
+ handler = object()
+ handlers.add("some.domain", handler)
+ self.assertIs(handler, handlers.get("some.domain"))
+
+ def test_add_for_existing_domain(self):
+ # When adding a new handler for a already congfigured domain, the
+ # existing handler is overwritten.
+ handlers = MailHandlers()
+ handler1 = object()
+ handlers.add("some.domain", handler1)
+ handler2 = object()
+ handlers.add("some.domain", handler2)
+ self.assertIs(handler2, handlers.get("some.domain"))