#!/usr/bin/env python
# -*- coding: utf-8 -*-
# $Id: CloudTest.py 9578 2016-03-02 12:08:29Z Judy $
#
# Copyright (c) 2016 Nuwa Information Co., Ltd, All Rights Reserved.
#
# Licensed under the Proprietary License,
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at our web site.
#
# See the License for the specific language governing permissions and
# limitations under the License.
#
# $Author: Judy $
# $Date: 2016-03-02 20:08:29 +0800 (Wed, 02 Mar 2016) $
# $Revision: 9578 $

import unittest
import os
import time
import threading
import subprocess

from django.core.mail import send_mail
from django.test import TestCase, override_settings
from Iuppiter.test import testEmailRecieve

class SendMailThread(threading.Thread):
    """
    Thread for email sending.    
    """

    def __init__(self, subject, content, sender, receiver):
        """
        Constructor.

        @param subject Email subject.
        @param content Email content.
        @param sender Email sender.
        @param receiver Email receiver.
        """
        super(SendMailThread,  self ).__init__()
        self.subject = subject
        self.content = content
        self.sender = sender
        self.receiver = receiver
        
    def run(self):
        send_mail(self.subject, self.content, self.sender, self.receiver)

# In django test case, EMAIL_BACKEND will be set to
# 'django.core.mail.backends.locmem.EmailBackend',
# so we have to change EMAIL_BACKEND here.
#
# Some similar problem:
# http://stackoverflow.com/questions/17171406/
# calling-djangos-send-mail-during-testing
# 
# Doc for overwrite django settings:
# https://docs.djangoproject.com/en/dev/topics/
# testing/tools/#overriding-settings

@override_settings(EMAIL_BACKEND='Iuno.cloud.mail.EmailBackend')
class MailWorkerTest(TestCase):
    """
    Test case for mail worker.
    """
    
    originalDir = os.path.abspath((os.path.curdir))
    
    def setUp(self):
        self.worker = None
    
    def sendEmail(self, subject, content, sender, receiver):
        """
        Send email in a new thread.                
        
        @param subject Email subject.
        @param content Email content.
        @param sender Email sender.
        @param receiver Email receiver.
        """
        
        _receiver = []
        if not isinstance(receiver, list):
            _receiver.append(receiver)
        else:
            _reciever = receiver

        SendMailThread(subject, content, sender, _receiver).start()
    
    def startWorker(self):
        """
        Start email worker.
        
        @return (status, worker) A tuple include status and worker process.
                status The status of worker. 
                       It can be "FAILED" or "OK".
                worker The process of worker.
        """
        status = "FAILED"
        worker = subprocess.Popen(
                  "celery -A Iuno.cloud.queue.App worker "
                  "-l info -Q mail --autoscale=10",
                  stdin=subprocess.PIPE, stdout=subprocess.PIPE, 
                  stderr=subprocess.PIPE)
        stdout = worker.stdout.readline()
        lineNum = 1
        while stdout:
            print stdout
            if lineNum > 30:
                break
            if '. Iuno.cloud.mail.tasks.send' in stdout:
                status = "OK"
                break
            lineNum += 1
            stdout = worker.stdout.readline()            
        return status, worker
        
    def testEmailWorker(self):
        """
        Test for email worker.
        """
        host = 'imap.gmail.com'
        userName = 'nuwainfotest@gmail.com'
        password = 'test25025529'
            
        # For email content comparison
        sender = 'test@nuwainfo.com'
        subject = 'test'        
        receiver = 'nuwainfotest@gmail.com'
        cc = ''
        content = 'test'
        
        self.sendEmail(subject, content, sender, receiver)
        workerStatus, worker = self.startWorker()
        self.assertEqual(workerStatus, "OK")
        self.worker = worker        
        testEmailRecieve(host, userName, password, sender,
                         subject=subject, receiver=receiver, cc=cc, 
                         content=content, testCase=self)

    def tearDown(self):
        if self.worker:
            self.worker.kill()

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