예제 #1
0
class EmailDistributorTestCase(unittest.TestCase):
    def setUp(self):
        self.env = EnvironmentStub(
            enable=['trac.*', TestEmailSender, TestFormatter, TestSubscriber])
        config = self.env.config
        config.set('notification', 'smtp_from', '*****@*****.**')
        config.set('notification', 'smtp_enabled', 'enabled')
        config.set('notification', 'smtp_always_cc', '*****@*****.**')
        config.set('notification', 'smtp_always_bcc', '*****@*****.**')
        config.set('notification', 'email_sender', 'TestEmailSender')
        self.sender = TestEmailSender(self.env)
        self.notsys = NotificationSystem(self.env)
        with self.env.db_transaction:
            self._add_session('foo', email='*****@*****.**')
            self._add_session('bar',
                              email='*****@*****.**',
                              name=u"Bäŕ's name")

    def tearDown(self):
        self.env.reset_db()

    def _notify_event(self, text, category='created', time=None, author=None):
        self.sender.history[:] = ()
        event = TestNotificationEvent('test',
                                      category,
                                      TestModel(text),
                                      time or datetime.now(utc),
                                      author=author)
        self.notsys.notify(event)

    def _add_session(self, sid, **attrs):
        session = DetachedSession(self.env, sid)
        for name, value in attrs.iteritems():
            session[name] = value
        session.save()

    def _add_subscription(self, **kwargs):
        subscription = {
            'sid': None,
            'authenticated': 1,
            'distributor': 'email',
            'format': 'text/plain',
            'adverb': 'always',
            'class': 'TestSubscriber'
        }
        subscription.update(kwargs)
        Subscription.add(self.env, subscription)

    def test_smtp_disabled(self):
        self.env.config.set('notification', 'smtp_enabled', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
        self._notify_event('blah')
        self.assertEqual([], self.sender.history)

    def _assert_mail(self, message, content_type, body):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual([content_type],
                         [p.get_content_type() for p in payload])
        self.assertEqual([body], [p.get_payload() for p in payload])

    def _assert_alternative_mail(self, message, body_plain, body_html):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual(['multipart/alternative'],
                         [p.get_content_type() for p in payload])
        alternative = list(payload[0].get_payload())
        self.assertEqual(['text/plain', 'text/html'],
                         [p.get_content_type() for p in alternative])
        self.assertEqual([body_plain, body_html],
                         [p.get_payload() for p in alternative])

    def test_plain(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(
            set(('*****@*****.**', '*****@*****.**', '*****@*****.**',
                 '*****@*****.**')), set(recipients))
        self._assert_mail(message, 'text/plain', 'blah')

    def test_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual(set(('*****@*****.**', '*****@*****.**')),
                                 set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')

    def test_plain_and_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual(
                    set(('*****@*****.**', '*****@*****.**',
                         '*****@*****.**')), set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')
            if '*****@*****.**' in recipients:
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')

    def test_broken_plain_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(['*****@*****.**'], recipients)
        self._assert_mail(message, 'text/html', '<p>raise-text-plain</p>')

    def test_broken_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
            self._add_subscription(sid='bar', format='text/plain')
        self._notify_event('raise-text-html')

        # fallback to text/plain
        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(
            set(('*****@*****.**', '*****@*****.**', '*****@*****.**',
                 '*****@*****.**')), set(recipients))
        self._assert_mail(message, 'text/plain', 'raise-text-html')

    def test_broken_plain_and_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain raise-text-html')

        history = self.sender.history
        self.assertEqual([], history)

    def test_username_in_always_cc(self):
        self.env.config.set('notification', 'smtp_always_cc',
                            'foo, [email protected]')
        self.env.config.set('notification', 'smtp_always_bcc',
                            'bar, foo, [email protected]')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(
            set(('*****@*****.**', '*****@*****.**', '*****@*****.**',
                 '*****@*****.**')), set(recipients))
        self.assertEqual('[email protected], [email protected]', message['Cc'])
        self.assertEqual(None, message['Bcc'])
        self._assert_mail(message, 'text/plain', 'blah')

    def test_from_author_disabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

    def test_from_author_enabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'enabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"=?utf-8?b?QsOkxZUncyBuYW1l?=" <*****@*****.**>',
                         message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author='foo')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('*****@*****.**', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))
예제 #2
0
파일: mail.py 프로젝트: starworldx/trac
class EmailDistributorTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(enable=['trac.*', TestEmailSender,
                                           TestFormatter, TestSubscriber,
                                           TestEmailAddressResolver])
        self.config = config = self.env.config
        config.set('notification', 'smtp_from', '*****@*****.**')
        config.set('notification', 'smtp_enabled', 'enabled')
        config.set('notification', 'smtp_always_cc', '*****@*****.**')
        config.set('notification', 'smtp_always_bcc', '*****@*****.**')
        config.set('notification', 'email_sender', 'TestEmailSender')
        config.set('notification', 'email_address_resolvers',
                   'SessionEmailResolver,TestEmailAddressResolver')
        self.sender = TestEmailSender(self.env)
        self.notsys = NotificationSystem(self.env)
        with self.env.db_transaction:
            self._add_session('foo', email='*****@*****.**')
            self._add_session('bar', email='*****@*****.**',
                              name=u"Bäŕ's name")
            self._add_session('baz', name='Baz')
            self._add_session('qux', tz='UTC')
            self._add_session('corge', email='corge-mail')

    def tearDown(self):
        self.env.reset_db()

    def _notify_event(self, text, category='created', time=None, author=None):
        self.sender.history[:] = ()
        event = TestNotificationEvent('test', category, TestModel(text),
                                      time or datetime_now(utc), author=author)
        self.notsys.notify(event)

    def _add_session(self, sid, values=None, **attrs):
        session = DetachedSession(self.env, sid)
        if values is not None:
            attrs.update(values)
        for name, value in attrs.iteritems():
            session[name] = value
        session.save()

    def _add_subscription(self, **kwargs):
        subscription = {'sid': None, 'authenticated': 1, 'distributor': 'email',
                        'format': 'text/plain', 'adverb': 'always',
                        'class': 'TestSubscriber'}
        subscription.update(kwargs)
        Subscription.add(self.env, subscription)

    def test_smtp_disabled(self):
        self.env.config.set('notification', 'smtp_enabled', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
        self._notify_event('blah')
        self.assertEqual([], self.sender.history)

    def _assert_mail(self, message, content_type, body):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual([content_type],
                         [p.get_content_type() for p in payload])
        self.assertEqual([body], [p.get_payload() for p in payload])

    def _assert_alternative_mail(self, message, body_plain, body_html):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual(['multipart/alternative'],
                         [p.get_content_type() for p in payload])
        alternative = list(payload[0].get_payload())
        self.assertEqual(['text/plain', 'text/html'],
                         [p.get_content_type() for p in alternative])
        self.assertEqual([body_plain, body_html],
                         [p.get_payload() for p in alternative])

    def test_plain(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
            self._add_subscription(sid='baz')
            self._add_subscription(sid='qux')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual({'*****@*****.**', '*****@*****.**',
                          '*****@*****.**', '*****@*****.**',
                          '*****@*****.**', '*****@*****.**'},
                         set(recipients))
        self._assert_mail(message, 'text/plain', 'blah')

    def test_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual({'*****@*****.**', '*****@*****.**'},
                                 set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')

    def test_plain_and_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual(
                    {'*****@*****.**', '*****@*****.**', '*****@*****.**'},
                    set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')
            if '*****@*****.**' in recipients:
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')

    def test_formats_in_session_and_tracini(self):
        self.config.set('notification', 'smtp_always_cc', 'bar,quux')
        self.config.set('notification', 'smtp_always_bcc', '')
        self.config.set('notification', 'default_format.email', 'text/html')
        with self.env.db_transaction:
            for user in ('foo', 'bar', 'baz', 'qux', 'quux'):
                self._add_session(user, email='*****@*****.**' % user)
            self._add_subscription(sid='foo', format='text/plain')
            # bar - no subscriptions
            self._add_session('bar',
                              {'notification.format.email': 'text/plain'})
            self._add_subscription(sid='baz', format='text/plain')
            self._add_session('baz',
                              {'notification.format.email': 'text/html'})
            self._add_subscription(sid='qux', format='text/html')
            self._add_session('qux',
                              {'notification.format.email': 'text/plain'})
            # quux - no subscriptions and no preferred format in session
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            self.assertEqual('*****@*****.**', from_addr)
            recipients = sorted(recipients)
            if '*****@*****.**' in recipients:
                self.assertEqual(['*****@*****.**', '*****@*****.**',
                                  '*****@*****.**'], recipients)
                self._assert_mail(message, 'text/plain', 'blah')
            if '*****@*****.**' in recipients:
                self.assertEqual(['*****@*****.**', '*****@*****.**'],
                                 recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')

    def test_broken_plain_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(['*****@*****.**'], recipients)
        self._assert_mail(message, 'text/html', '<p>raise-text-plain</p>')

    def test_broken_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
            self._add_subscription(sid='bar', format='text/plain')
        self._notify_event('raise-text-html')

        # fallback to text/plain
        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual({'*****@*****.**', '*****@*****.**',
                          '*****@*****.**', '*****@*****.**'},
                         set(recipients))
        self._assert_mail(message, 'text/plain', 'raise-text-html')

    def test_broken_plain_and_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain raise-text-html')

        history = self.sender.history
        self.assertEqual([], history)

    def test_username_in_always_cc(self):
        self.env.config.set('notification', 'smtp_always_cc',
                            'foo, [email protected]')
        self.env.config.set('notification', 'smtp_always_bcc',
                            'bar, foo, [email protected]')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual({'*****@*****.**', '*****@*****.**',
                          '*****@*****.**', '*****@*****.**'},
                         set(recipients))
        self.assertEqual('[email protected], [email protected]', message['Cc'])
        self.assertIsNone(message['Bcc'])
        self._assert_mail(message, 'text/plain', 'blah')

    def test_from_author_disabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

    def test_from_author_enabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'enabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"=?utf-8?b?QsOkxZUncyBuYW1l?=" <*****@*****.**>',
                         message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author='foo')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('*****@*****.**', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

    def test_ignore_domains(self):
        config = self.env.config
        config.set('notification', 'smtp_always_cc',
                   '[email protected], [email protected]')
        config.set('notification', 'smtp_always_bcc',
                   '[email protected], [email protected]')
        config.set('notification', 'ignore_domains',
                   'example.org, example.com')

        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
            self._add_subscription(sid='baz')
            self._add_subscription(sid='qux')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(set(('*****@*****.**', '*****@*****.**',
                              '*****@*****.**', '*****@*****.**')),
                         set(recipients))

    def _test_without_domain(self, use_short_addr='disabled',
                             smtp_default_domain=''):
        config = self.env.config
        config.set('notification', 'use_short_addr', use_short_addr)
        config.set('notification', 'smtp_default_domain', smtp_default_domain)
        config.set('notification', 'smtp_from', 'from-trac')
        config.set('notification', 'smtp_always_cc', 'qux, [email protected]')
        config.set('notification', 'smtp_always_bcc', '[email protected], bcc2')
        config.set('notification', 'email_address_resolvers',
                   'SessionEmailResolver')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='baz')
            self._add_subscription(sid='corge')
        self._notify_event('blah')
        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        return history

    def _assert_equal_sets(self, expected, actual):
        expected = set(expected)
        actual = set(actual)
        if expected != actual:
            self.fail('%r != %r' % ((expected - actual, actual - expected)))

    def _cclist(self, cc):
        return _fixup_cc_list(cc).split(', ')

    def test_use_short_addr(self):
        history = self._test_without_domain(use_short_addr='enabled')
        from_addr, recipients, message = history[0]
        self.assertEqual('from-trac', from_addr)
        self.assertEqual('"My Project" <from-trac>', message['From'])
        self._assert_equal_sets(['qux', '*****@*****.**', '*****@*****.**',
                                 'bcc2', '*****@*****.**', 'baz',
                                 'corge-mail'], recipients)
        self._assert_equal_sets(['qux', '*****@*****.**'],
                                self._cclist(message['Cc']))

    def test_smtp_default_domain(self):
        history = self._test_without_domain(smtp_default_domain='example.com')
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>',
                         message['From'])
        self._assert_equal_sets(['*****@*****.**', '*****@*****.**',
                                 '*****@*****.**', '*****@*****.**',
                                 '*****@*****.**', '*****@*****.**',
                                 '*****@*****.**'], recipients)
        self._assert_equal_sets(['*****@*****.**', '*****@*****.**'],
                                self._cclist(message['Cc']))

    def test_username_is_email(self):
        config = self.env.config
        config.set('notification', 'email_address_resolvers',
                   'SessionEmailResolver')
        with self.env.db_transaction:
            self._add_session(sid='*****@*****.**')
            self._add_session(sid='*****@*****.**',
                              email='*****@*****.**')
            self._add_subscription(sid='*****@*****.**')
            self._add_subscription(sid='*****@*****.**')
            self._add_subscription(sid='*****@*****.**')  # no session
        self._notify_event('blah')
        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual({'*****@*****.**', '*****@*****.**',
                          '*****@*****.**', '*****@*****.**',
                          '*****@*****.**'}, set(recipients))
        self._assert_equal_sets(['*****@*****.**'],
                                self._cclist(message['Cc']))
예제 #3
0
파일: mail.py 프로젝트: pkdevbox/trac
class EmailDistributorTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(enable=['trac.*', TestEmailSender,
                                           TestFormatter, TestSubscriber])
        config = self.env.config
        config.set('notification', 'smtp_from', '*****@*****.**')
        config.set('notification', 'smtp_enabled', 'enabled')
        config.set('notification', 'smtp_always_cc', '*****@*****.**')
        config.set('notification', 'smtp_always_bcc', '*****@*****.**')
        config.set('notification', 'email_sender', 'TestEmailSender')
        self.sender = TestEmailSender(self.env)
        self.notsys = NotificationSystem(self.env)
        with self.env.db_transaction:
            self._add_session('foo', email='*****@*****.**')
            self._add_session('bar', email='*****@*****.**',
                              name=u"Bäŕ's name")

    def tearDown(self):
        self.env.reset_db()

    def _notify_event(self, text, category='created', time=None, author=None):
        self.sender.history[:] = ()
        event = TestNotificationEvent('test', category, TestModel(text),
                                      time or datetime.now(utc), author=author)
        self.notsys.notify(event)

    def _add_session(self, sid, **attrs):
        session = DetachedSession(self.env, sid)
        for name, value in attrs.iteritems():
            session[name] = value
        session.save()

    def _add_subscription(self, **kwargs):
        subscription = {'sid': None, 'authenticated': 1, 'distributor': 'email',
                        'format': 'text/plain', 'adverb': 'always',
                        'class': 'TestSubscriber'}
        subscription.update(kwargs)
        Subscription.add(self.env, subscription)

    def test_smtp_disabled(self):
        self.env.config.set('notification', 'smtp_enabled', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
        self._notify_event('blah')
        self.assertEqual([], self.sender.history)

    def _assert_mail(self, message, content_type, body):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual([content_type],
                         [p.get_content_type() for p in payload])
        self.assertEqual([body], [p.get_payload() for p in payload])

    def _assert_alternative_mail(self, message, body_plain, body_html):
        self.assertNotIn('Bcc', message)
        self.assertEqual('multipart/related', message.get_content_type())
        payload = list(message.get_payload())
        self.assertEqual(['multipart/alternative'],
                         [p.get_content_type() for p in payload])
        alternative = list(payload[0].get_payload())
        self.assertEqual(['text/plain', 'text/html'],
                         [p.get_content_type() for p in alternative])
        self.assertEqual([body_plain, body_html],
                         [p.get_payload() for p in alternative])

    def test_plain(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(set(('*****@*****.**', '*****@*****.**',
                              '*****@*****.**', '*****@*****.**')),
                         set(recipients))
        self._assert_mail(message, 'text/plain', 'blah')

    def test_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')
            if '*****@*****.**' in recipients:
                self.assertEqual('*****@*****.**', from_addr)
                self.assertEqual(set(('*****@*****.**', '*****@*****.**')),
                                 set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')

    def test_plain_and_html(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(2, len(history))
        for from_addr, recipients, message in history:
            if '*****@*****.**' in recipients:
                self.assertEqual(set(('*****@*****.**', '*****@*****.**',
                                      '*****@*****.**')),
                                 set(recipients))
                self._assert_mail(message, 'text/plain', 'blah')
            if '*****@*****.**' in recipients:
                self.assertEqual(['*****@*****.**'], recipients)
                self._assert_alternative_mail(message, 'blah', '<p>blah</p>')

    def test_broken_plain_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(['*****@*****.**'], recipients)
        self._assert_mail(message, 'text/html', '<p>raise-text-plain</p>')

    def test_broken_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/html')
            self._add_subscription(sid='bar', format='text/plain')
        self._notify_event('raise-text-html')

        # fallback to text/plain
        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(set(('*****@*****.**', '*****@*****.**',
                              '*****@*****.**', '*****@*****.**')),
                         set(recipients))
        self._assert_mail(message, 'text/plain', 'raise-text-html')

    def test_broken_plain_and_html_formatter(self):
        with self.env.db_transaction:
            self._add_subscription(sid='foo', format='text/plain')
            self._add_subscription(sid='bar', format='text/html')
        self._notify_event('raise-text-plain raise-text-html')

        history = self.sender.history
        self.assertEqual([], history)

    def test_username_in_always_cc(self):
        self.env.config.set('notification', 'smtp_always_cc',
                            'foo, [email protected]')
        self.env.config.set('notification', 'smtp_always_bcc',
                            'bar, foo, [email protected]')
        self._notify_event('blah')

        history = self.sender.history
        self.assertNotEqual([], history)
        self.assertEqual(1, len(history))
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual(set(('*****@*****.**', '*****@*****.**',
                              '*****@*****.**', '*****@*****.**')),
                         set(recipients))
        self.assertEqual('[email protected], [email protected]', message['Cc'])
        self.assertEqual(None, message['Bcc'])
        self._assert_mail(message, 'text/plain', 'blah')

    def test_from_author_disabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'disabled')
        with self.env.db_transaction:
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

    def test_from_author_enabled(self):
        self.env.config.set('notification', 'smtp_from_author', 'enabled')
        with self.env.db_transaction:
            self._add_subscription(sid='foo')
            self._add_subscription(sid='bar')

        self._notify_event('blah', author='bar')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"=?utf-8?b?QsOkxZUncyBuYW1l?=" <*****@*****.**>',
                         message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author='foo')
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('*****@*****.**', message['From'])
        self.assertEqual(1, len(history))

        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"My Project" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))

        self.env.config.set('notification', 'smtp_from_name', 'Trac')
        self._notify_event('blah', author=None)
        history = self.sender.history
        self.assertNotEqual([], history)
        from_addr, recipients, message = history[0]
        self.assertEqual('*****@*****.**', from_addr)
        self.assertEqual('"Trac" <*****@*****.**>', message['From'])
        self.assertEqual(1, len(history))