# Copyright (c) 2007-2011 Simplistix Ltd
#
# This Software is released under the MIT License:
# http://www.opensource.org/licenses/mit-license.html
# See license.txt for more details.

import logging
import time

from mailinglogger.common import RegexConversion
from mailinglogger.MailingLogger import MailingLogger
from shared import DummySMTP, setUp, tearDown
from unittest import TestSuite,makeSuite,TestCase,main

class TestMailingLogger(TestCase):

    def getLogger(self):
        return logging.getLogger('')
    
    def setUp(self):
        setUp(None, self, stdout=False)

    def tearDown(self):
        tearDown(None,self)
        
    def test_imports(self):
        from mailinglogger.MailingLogger import MailingLogger
        from mailinglogger import MailingLogger
    
    def test_default_flood_limit(self):
        # set up logger
        self.handler = MailingLogger('from@example.com',('to@example.com',))
        logger = self.getLogger()
        logger.addHandler(self.handler)
        # log 11 entries
        for i in range(12):
            logger.critical('message')
        # only 1st 10 should get sent
        # +1 for the final warning
        self.assertEqual(len(DummySMTP.sent),11)
        
    def test_flood_protection_bug(self):
        # set up logger
        self.handler = MailingLogger('from@example.com',('to@example.com',),
                                     flood_level=1)
        logger = self.getLogger()
        logger.addHandler(self.handler)
        # make it 11pm
        self.datetime.set(2007,3,15,23)
        # paranoid check
        self.assertEqual(len(DummySMTP.sent),0)
        # log until flood protection kicked in
        logger.critical('message1')
        logger.critical('message2')
        # check - 1 logged, 1 final warning
        self.assertEqual(len(DummySMTP.sent),2)
        # check nothing emitted
        logger.critical('message3')
        self.assertEqual(len(DummySMTP.sent),2)
        # advance time past midnight
        self.datetime.set(2007,3,15)
        # log again
        logger.critical('message4')
        # check we are emitted now!
        self.assertEqual(len(DummySMTP.sent),3)

    def test_ignore(self):
        ignored = [ RegexConversion('^bad start')
                  , RegexConversion('(.*)Some String')
                  , RegexConversion('(.*)http:(.*)\/view')
                  ]
        self.handler = MailingLogger( 'from@example.com'
                                    , ('to@example.com',)
                                    , ignore=ignored
                                    )
        logger = self.getLogger()
        logger.addHandler(self.handler)
        # paranoid check
        self.assertEqual(len(DummySMTP.sent),0)

        # Now test a few variations
        logger.critical('This Line Contains Some String.')
        self.assertEqual(len(DummySMTP.sent),0)

        logger.critical('bad starts and terrible endings')
        self.assertEqual(len(DummySMTP.sent),0)

        logger.critical('NotFoundError: http://my.site.com/some/path/view')
        self.assertEqual(len(DummySMTP.sent),0)

        # Interpolations are also ignored
        logger.critical('NotFoundError: %s',
                        'http://my.site.com/some/path/view')
        self.assertEqual(len(DummySMTP.sent),0)

        # Non-matching stuff still gets through
        logger.critical('message1')
        self.assertEqual(len(DummySMTP.sent),1)

    def test_headers_supplied_get_added_to_those_generated(self):
        # set up logger
        self.handler = MailingLogger('from@example.com',('to@example.com',),
                                     headers={'From':'someidiot',
                                              'to':'someidiot'})
        logger = self.getLogger()
        logger.addHandler(self.handler)
        logger.critical('message')
        self.assertEqual(len(DummySMTP.sent),1)
        m = DummySMTP.sent[0][3]
        # the headers specified in the `headers` parameter get added
        # to those generated by mailinglogger - be careful!
        self.failUnless('From: from@example.com' in m)
        self.failUnless('From: someidiot' in m)
        # however, if you try hard you *can* break things :-S
        self.failUnless('To: to@example.com' in m)
        self.failUnless('to: someidiot' in m)
        
    def test_subject_contains_date(self):
        # set up logger
        self.handler = MailingLogger('from@example.com',('to@example.com',),
                                     subject="%(asctime)s")
        logger = self.getLogger()
        logger.addHandler(self.handler)
        logger.critical('message')
        self.assertEqual(len(DummySMTP.sent),1)
        m = DummySMTP.sent[0][3]
        self.failUnless('Subject: 2007-01-01 10:00:00,000' in m, m)

    def test_non_string_error_messages_dont_break_logging(self):
        self.handler = MailingLogger('from@example.com',('to@example.com',),)
        logger = self.getLogger()
        logger.addHandler(self.handler)
        logger.critical(object())
        self.assertEqual(len(DummySMTP.sent),1)

def test_suite():
    return TestSuite((
        makeSuite(TestMailingLogger),
        ))

if __name__ == '__main__':
    unittest.main(default='test_suite')
