package com.ozacc.mail.mock;

import junit.framework.TestCase;

import org.apache.log4j.BasicConfigurator;

import com.dumbster.smtp.SimpleSmtpServer;
import com.ozacc.mail.Mail;

/**
 * SendMailImplクラスのテストケース。
 * <p>
 * Dumbsterを使用してテストしているが、サポートされていない機能が多い。
 * 
 * @author Tomohiro Otsuka
 * @version $Id: MockSendMailTest.java,v 1.6.2.1 2005/01/18 07:24:47 otsuka Exp $
 */
public class MockSendMailTest extends TestCase {

	private MockSendMail mockSendMail;

	private SimpleSmtpServer server;

	/*
	 * @see TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();

		BasicConfigurator.configure();

		mockSendMail = new MockSendMail();
		mockSendMail.setDebug(true);
	}

	/**
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		BasicConfigurator.resetConfiguration();
	}

	public void testSendMailNotMatchMailNum() throws Exception {
		Mail mail = new Mail();
		mail.addTo("to@example.com");

		mockSendMail.addExpectedMail(mail);
		mockSendMail.addExpectedMail(mail);

		mockSendMail.send(mail);

		try {
			mockSendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}
	}

	public void testSendMailSuccess() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail = new Mail();
		mail.setFrom(from, fromName);
		mail.addTo(to);
		mail.setSubject(subject);
		mail.setText(text);

		mockSendMail.addExpectedMail(mail);

		mockSendMail.send(mail);

		mockSendMail.verify();
	}

	public void testSendMailToAddressNotMatch() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail1 = new Mail();
		mail1.setFrom(from, fromName);
		mail1.addTo(to);
		mail1.setSubject(subject);
		mail1.setText(text);

		Mail mail2 = new Mail();
		mail2.setFrom(from, fromName);
		mail2.addTo("contact@example.com");
		mail2.setSubject(subject);
		mail2.setText(text);

		mockSendMail.addExpectedMail(mail1);

		mockSendMail.send(mail2);

		try {
			mockSendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}
	}

	public void testSendMailWithMockMail() throws Exception {
		Mail sentMail = new Mail();
		sentMail.setFrom("from@example.com");
		sentMail.setSubject("件名");
		sentMail.addTo("to@example.com");
		sentMail.setText("動的生成される本文");

		Mail expectedMail = new Mail();
		expectedMail.setFrom("from@example.com");
		expectedMail.setSubject("件名");

		MockMail mockMail = new MockMail();
		mockMail.setFrom("from@example.com");
		mockMail.setSubject("件名");

		MockSendMail sendMail = new MockSendMail();
		sendMail.setDebug(true);

		sendMail.addExpectedMail(mockMail);
		sendMail.send(sentMail);
		sendMail.verify(); // 成功

		sendMail = new MockSendMail();
		sendMail.addExpectedMail(expectedMail);
		sendMail.send(sentMail);
		try {
			sendMail.verify(); // エラー
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}
	}

	public void testSendMailWithMockMulitpartMail() throws Exception {
		Mail sentMail = new Mail();
		sentMail.setFrom("from@example.com");
		sentMail.setSubject("件名");
		sentMail.addTo("to@example.com");
		sentMail.setText("動的生成される本文");

		Mail expectedMail = new Mail();
		expectedMail.setFrom("from@example.com");
		expectedMail.setSubject("件名");
		expectedMail.addTo("to@example.com");
		expectedMail.setText("動的生成される本文");
		expectedMail.setHtmlText("<html><body>HTMLの本文</body></html>");

		MockSendMail sendMail = new MockSendMail();
		sendMail.setDebug(true);

		sendMail.addExpectedMail(expectedMail);
		sendMail.send(sentMail);

		try {
			sendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}

		sendMail.initialize();

		sendMail.addExpectedMail(expectedMail);
		sendMail.send(sentMail);
		try {
			sendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// HTML本文が一致しない
		}

		sendMail.initialize();

		sentMail.setHtmlText("<html><body>HTMLの本文</body></html>");
		sendMail.addExpectedMail(expectedMail);
		sendMail.send(sentMail);
		sendMail.verify();

		sendMail.initialize();

		expectedMail.setHtmlText(null);
		sendMail.addExpectedMail(expectedMail);
		sendMail.send(sentMail);
		// expectedはマルチパートではないからsentMailのHTMLとは比較されない
		sendMail.verify();

		sendMail.initialize();

		MockMail expectedMockMail = new MockMail(expectedMail);
		sendMail.addExpectedMail(expectedMockMail);
		sendMail.send(sentMail);
		try {
			sendMail.verify();
		} catch (AssertionFailedException expected) {
			fail("This should never be called.");
		}
	}

	public void testSendMailToNameNotMatch() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail1 = new Mail();
		mail1.setFrom(from, fromName);
		mail1.addTo(to, "宛先A");
		mail1.setSubject(subject);
		mail1.setText(text);

		Mail mail2 = new Mail();
		mail2.setFrom(from, fromName);
		mail2.addTo(to, "宛先B");
		mail2.setSubject(subject);
		mail2.setText(text);

		mockSendMail.addExpectedMail(mail1);

		mockSendMail.send(mail2);

		try {
			mockSendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}
	}
	
	public void testSendMailFromNotMatch() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

		Mail mail1 = new Mail();
		mail1.setFrom(from, fromName);
		mail1.addTo(to);
		mail1.setSubject(subject);
		mail1.setText(text);

		Mail mail2 = new Mail();
		mail2.setFrom("from@foo.com", fromName);
		mail2.addTo(to);
		mail2.setSubject(subject);
		mail2.setText(text);

		mockSendMail.addExpectedMail(mail1);

		mockSendMail.send(mail2);

		try {
			mockSendMail.verify();
			fail("This should never be called.");
		} catch (AssertionFailedException expected) {
			// success
		}
	}
	
}