/*
 * blanco Framework
 * Copyright (C) 2004-2007 IGA Tosiki
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */
package blanco.mail.core.connect;

import java.io.IOException;
import java.net.ConnectException;

import junit.framework.TestCase;
import blanco.mail.core.BlancoMailSenderFactory;
import blanco.mail.core.BlancoMailSettingFactory;
import blanco.mail.core.BlancoMailTestConstants;
import blanco.mail.core.valueobject.BlancoMailAddress;
import blanco.mail.core.valueobject.BlancoMailMessage;
import blanco.mail.core.valueobject.BlancoMailSetting;

/**
 * 注意！
 * 
 * このJUnitコードを実行すると、メールサーバへの接続を実際に行います。
 * 
 * このJUnitコードを実行することは 推奨しません。内容を良く理解した上で、試験用のメールサーバなどを準備してから実行するようにしてください。
 * 
 * @author IGA Tosiki
 */
public class BlancoMailSenderConnectTest extends TestCase {
    /**
     * 典型的な設定値を取得します。
     * 
     * @return
     */
    private BlancoMailSetting getSetting() {
        final BlancoMailSetting setting = BlancoMailSettingFactory
                .getInstance();
        if (true) {
            // 設定値は BlancoMailSetting.properties から取得します。
        } else {
            setting.setSendHost("localhost");
            setting.setSendUserName("userName");
            setting.setSendPassword("password");
        }

        return setting;
    }

    /**
     * 典型的なメッセージを取得します。
     * 
     * @return
     */
    private BlancoMailMessage getMessage() {
        final BlancoMailMessage message = new BlancoMailMessage();

        final BlancoMailAddress addrFrom = new BlancoMailAddress();
        addrFrom.setAddress(BlancoMailTestConstants.MAIL_SEND_FROM_ADDR);
        message.setFrom(addrFrom);

        final BlancoMailAddress addrTo1 = new BlancoMailAddress();
        addrTo1.setAddress(BlancoMailTestConstants.MAIL_SEND_TO_ADDRS[0]);
        message.getTo().add(addrTo1);

        final BlancoMailAddress addrTo2 = new BlancoMailAddress();
        addrTo2.setAddress(BlancoMailTestConstants.MAIL_SEND_TO_ADDRS[1]);
        message.getTo().add(addrTo2);

        final BlancoMailAddress addrCc1 = new BlancoMailAddress();
        addrCc1.setAddress(BlancoMailTestConstants.MAIL_SEND_CC_ADDRS[0]);
        message.getCc().add(addrCc1);

        final BlancoMailAddress addrCc2 = new BlancoMailAddress();
        addrCc2.setAddress(BlancoMailTestConstants.MAIL_SEND_CC_ADDRS[1]);
        message.getCc().add(addrCc2);

        final BlancoMailAddress addrBcc1 = new BlancoMailAddress();
        addrBcc1.setAddress(BlancoMailTestConstants.MAIL_SEND_BCC_ADDRS[0]);
        message.getBcc().add(addrBcc1);

        message.setSubject("[blanco] テストメール");
        message.setText("本文");

        return message;
    }

    /**
     * 接続系。
     * 
     * MBMCS201 から MBMCS204
     * 
     * TODO MBMCS301から MBMCS304およびMBMCS901は 現時点ではJUnit化非実施。
     * 
     * @throws Exception
     */
    public void testSendConnect() throws Exception {
        try {
            final BlancoMailSetting setting = getSetting();
            final BlancoMailMessage message = getMessage();
            setting.setSendProtocol("usotp");
            BlancoMailSenderFactory.getInstance().send(setting, message);
            fail("発生すべき例外が発生していません。");
        } catch (ConnectException e) {
            assertTrue("メッセージIDチェック", e.getMessage().indexOf("MBMCS201") >= 0);
        }

        try {
            final BlancoMailSetting setting = getSetting();
            final BlancoMailMessage message = getMessage();
            setting.setSendUserName("notexist");
            setting.setSendUserName("failpassword");
            BlancoMailSenderFactory.getInstance().send(setting, message);

            // SMTP認証をサポートするサーバにおいては、この場所でSMTP認証による接続エラーが発生する。
            // fail("発生すべき例外が発生していません。");
        } catch (ConnectException e) {
            // SMTP認証をサポートしたサーバで動作確認を実施。適切に通過することを確認
            // ※メールサーバへのTCP接続そのものが失敗すると、この自動テストは失敗します。
            assertTrue("メッセージIDチェック", e.getMessage().indexOf("MBMCS202") >= 0);
        }

        try {
            final BlancoMailSetting setting = getSetting();
            final BlancoMailMessage message = getMessage();
            // 存在しないホスト名。
            setting.setSendHost("localhost.notexist");
            BlancoMailSenderFactory.getInstance().send(setting, message);
            fail("発生すべき例外が発生していません。");
        } catch (ConnectException e) {
            assertTrue("メッセージIDチェック", e.getMessage().indexOf("MBMCS203") >= 0);
        }
    }

    /**
     * タイムアウト系の試験。
     * 
     * このJUnitはサーバにある種の特殊な負荷をかける可能性があります。
     * 
     * @throws Exception
     */
    public void testSendTimeout() throws Exception {
        if (false)
            try {
                final BlancoMailSetting setting = getSetting();
                final BlancoMailMessage message = getMessage();
                // 接続タイムアウトは環境しだいで発生したりしなかったりします。
                // setting.setMailConnectionTimeout(1);
                setting.setMailTimeout(1);
                BlancoMailSenderFactory.getInstance().send(setting, message);
                fail("発生すべき例外が発生していません。");
            } catch (IOException e) {
                assertTrue("メッセージIDチェック",
                        e.getMessage().indexOf("MBMCS301") >= 0);
                // この経路を通過した場合には、MBMCS302 も内部的に発生する場合があります。ただし それも環境依存のものとなります。
            }
    }
}
