from twisted.trial import unittest
import os, sets, string

from MailPing import probe, fileutil

class TestTiming(unittest.TestCase):
    expected = [
        ({ 'success': 42,
           'pending/f0e241677fa9f2e0d7884776e4a6846b19703e6d': 42,
           },
         10,
         52,
         False),

        ({ 'success': 42,
           'pending/f0e241677fa9f2e0d7884776e4a6846b19703e6d': 42,
           },
         10,
         53,
         True),

        ({ 'success': 42,
           'pending/f0e241677fa9f2e0d7884776e4a6846b19703e6d': 42,
           },
         50,
         100,
         True),

        ({ 'success': 52,
           'pending/f0e241677fa9f2e0d7884776e4a6846b19703e6d': 42,
           },
         50,
         100,
         False),

        ({ 'success': 42,
           'pending/f0e241677fa9f2e0d7884776e4a6846b19703e6d': 52,
           },
         50,
         100,
         False),

        ]
    def setUp(self):
        self.statedir = self.mktemp()
        os.mkdir(self.statedir)
        os.mkdir(os.path.join(self.statedir, 'pending'))

    def testShouldOrShouldNot(self):
        for data, interval, time, want in self.expected:
            for filename, timestamp in data.items():
                fileutil.writeFile(os.path.join(self.statedir, filename),
                                   '%f\n' % timestamp)

            got = probe.shouldSend(self.statedir,
                                   interval,
                                   time)
            self.assertEquals(got, want)


class TestIdent(unittest.TestCase):
    def testCreation(self):
        ident = probe.randomIdent()
        self.failUnless(isinstance(ident, str))
        self.assertEquals(len(ident), 40)
        for c in ident:
            self.failUnless(c in string.hexdigits)

    def testRandomness(self):
        seen = sets.Set()
        for i in range(20):
            ident = probe.randomIdent()
            self.failIf(ident in seen)
            seen.add(ident)

class TestProbeMessage(unittest.TestCase):
    def testMakeProbe(self):
        msg = probe.makeProbe(
            ident='f0e241677fa9f2e0d7884776e4a6846b19703e6d',
            fromAddress='The Sender <from@source.invalid>',
            toAddress='Recipient, The <to@destination.invalid>')

        msgid = msg['Message-ID']
        del msg['Message-ID']
        self.failUnless(msgid.startswith('<'))
        self.failUnless(msgid.endswith('>'))
        msgid = msgid[1:-1]
        lead, host = msgid.split('@', 1)
        self.failUnless(lead.endswith('.mailping.f0e241677fa9f2e0d7884776e4a6846b19703e6d'))
        lead = lead[:-len('.mailping.f0e241677fa9f2e0d7884776e4a6846b19703e6d')]
        for c in lead:
            self.failUnless(c in '0123456789.')

        self.assertEquals(msg.as_string(),
                          """\
From: The Sender <from@source.invalid>
To: Recipient, The <to@destination.invalid>
Subject: Mail ping f0e241677fa9f2e0d7884776e4a6846b19703e6d

""" + probe.MESSAGE_TEXT)

    def testMakeProbeWithAdmin(self):
        msg = probe.makeProbe(
            ident='f0e241677fa9f2e0d7884776e4a6846b19703e6d',
            fromAddress='The Sender <from@source.invalid>',
            toAddress='Recipient, The <to@destination.invalid>',
            adminAddress='Administrator <root@source.invalid>')
        del msg['Message-ID']
        self.assertEquals(msg.as_string(),
                          """\
From: The Sender <from@source.invalid>
To: Recipient, The <to@destination.invalid>
Reply-To: Administrator <root@source.invalid>
Subject: Mail ping f0e241677fa9f2e0d7884776e4a6846b19703e6d

""" + probe.MESSAGE_TEXT)
