# -*- coding: utf-8 -*-
## $Id: test_smtp.py 8020 2012-04-02 11:05:40Z henrik $
##
## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
# Tests for email-related components
import base64
import logging
import tempfile
import shutil
import unittest
from StringIO import StringIO
from zope.component import getUtility
from zope.component.hooks import setSite
from zope.sendmail.interfaces import IMailDelivery
from waeup.kofa.app import University
from waeup.kofa.interfaces import IMailService
from waeup.kofa.smtp import (
    encode_header_item, encode_address, encode_body, FakeSMTPDelivery,
    send_mail)
from waeup.kofa.testing import FunctionalTestCase
from waeup.uniben.testing import FunctionalLayer

#
# SMTP test config
#

# Also run tests that send mail to external servers?
#   If you enable this, please make sure the external smtp hosts and receivers
#   do exist really and are not bothered by being spammed by a test programme.
EXTERNAL_MAIL_TESTS = False

# Maybe existing receiver of externally sent mail. If this mail account
# exists really, it might receive mail from the tests!
EXTERNAL_MAIL_RECEIVER = 'existing_address@waeup.org'

# Names of mail deliveries to use when external mail tests are enabled.
#   See local mail.zcml for names of available deliveries.
EXTERNAL_DIRECT_DELIVERY = 'Direct SMTP on mail server'
EXTERNAL_QUEUED_DELIVERY = 'Queued SMTP on mail server'

#
# end of SMTP test config
#

def external_mail_test(func):
    if not EXTERNAL_MAIL_TESTS:
        myself = __file__
        if myself.endswith('.pyc'):
            myself = myself[:-2]
        print "WARNING: external mail tests are skipped!"
        print "WARNING: edit %s to enable them." % myself
        return
    return func

class ExternalMailerTests(FunctionalTestCase):

    layer = FunctionalLayer

    def setUp(self):
        super(ExternalMailerTests, self).setUp()
        # Setup a sample site for each test
        app = University()
        self.dc_root = tempfile.mkdtemp()
        app['datacenter'].setStoragePath(self.dc_root)

        # Prepopulate the ZODB...
        self.getRootFolder()['app'] = app
        self.app = self.getRootFolder()['app']
        return

    def tearDown(self):
        super(ExternalMailerTests, self).tearDown()
        shutil.rmtree(self.dc_root)
        return

    def test_config_default_mailer(self):
        # The default mailer set in config is 'no mailer'.
        self.assertEqual(
            getattr(self.app.get('configuration', None), 'smtp_mailer'),
            u'No email service')
        return

    @external_mail_test
    def test_send_direct_mail(self):
        # send mail using direct mail delivery
        self.app['configuration'].smtp_mailer = EXTERNAL_DIRECT_DELIVERY
        setSite(self.app)
        result = send_mail(
            'test program', 'no-reply@waeup.org',
            'test mail receiver', EXTERNAL_MAIL_RECEIVER,
            'Test Mail from WAeUP Kofa',
            'Hi from test mailer!\n\nRegards,\nTest Programme\n'
            )
        import transaction
        transaction.commit() # The mail is really sent when transactions is
                             # committed
        self.assertTrue('@' in result)
        return

    @external_mail_test
    def test_send_queued_mail(self):
        # send mail using queued mail delivery
        self.app['configuration'].smtp_mailer = EXTERNAL_QUEUED_DELIVERY
        setSite(self.app)
        result = send_mail(
            'test program', 'no-reply@waeup.org',
            'test mail receiver', EXTERNAL_MAIL_RECEIVER,
            'Test Mail from WAeUP Kofa',
            'Hi from test mailer!\n\nRegards,\nTest Programme\n'
            )
        import transaction
        transaction.commit() # The mail is really sent when transactions is
                             # committed
        self.assertTrue('@' in result)
        return
