package com.ozacc.mail.impl;

import javax.mail.Message;
import javax.mail.internet.InternetAddress;

import junit.framework.TestCase;

import org.apache.log4j.BasicConfigurator;
import org.jvnet.mock_javamail.Mailbox;

import com.ozacc.mail.Mail;
import com.ozacc.mail.MailException;

/**
 * SendMailImplクラスのテストケース。
 * 
 * @author Tomohiro Otsuka
 * @version $Id: SendMailImplTest.java,v 1.3 2004/09/14 00:06:13 otsuka Exp $
 */
public class SendMailImplTest extends TestCase {

	private SendMailImpl sendMail;

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

		BasicConfigurator.configure();

		sendMail = new SendMailImpl();
	}

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

	/**
	 * 単発メールのテスト。
	 * 
	 * @throws Exception
	 */
	public void testSendMail() 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);

		sendMail.send(mail);

		Mailbox inbox = Mailbox.get("info@example.com");
		assertEquals("1", 1, inbox.size());

		Message email = inbox.get(0);

		assertEquals("2", to, email.getHeader("To")[0]);
		assertEquals("3",
				new InternetAddress(from, fromName, Mail.JIS_CHARSET)
						.toString(), email.getHeader("From")[0]);

		assertEquals("4", mail.getSubject(), email.getSubject());
		assertEquals("5", mail.getText() + "\n", email.getContent());
		assertEquals("6", "text/plain; charset=ISO-2022-JP",
				email.getContentType());
	}

	/**
	 * 複数メールの一括送信テスト。
	 * 
	 * @throws Exception
	 */
	public void testSendMailMultiple() 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(to);
		mail2.setSubject(subject);
		mail2.setText(text);

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

		sendMail.send(new Mail[] { mail1, mail2, mail3 });

		Mailbox inbox = Mailbox.get("info@example.com");

		assertEquals("1", 3, inbox.size());

		Message email1 = inbox.get(0);

		assertEquals("2", to, email1.getHeader("To")[0]);
		assertEquals("3",
				new InternetAddress(from, fromName, Mail.JIS_CHARSET)
						.toString(), email1.getHeader("From")[0]);

		assertEquals("4", subject, email1.getSubject());
		assertEquals("5", text + "\n", email1.getContent());
	}

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

		Mail mail = new Mail();
		mail.setFrom(from, fromName);
		mail.addTo(to);
		mail.setSubject(subject);
		mail.setText(text);
		mail.setReturnPath(returnPath);
		mail.setImportance(Mail.Importance.HIGH);

		sendMail.send(mail);

		Mailbox inbox = Mailbox.get("info@example.com");

		assertEquals(1, inbox.size());
		Message email = inbox.get(0);

		// ヘッダー出力
		// Enumeration headers = email.getAllHeaders();
		// while (headers.hasMoreElements()) {
		// Header header = (Header)headers.nextElement();
		// System.out.println(header.getName() + "='" + header.getValue() +
		// "'");
		// }

		// Mock JavaMail では Return-Path ヘッダは付加されないようだ。
		// assertEquals(mail.getReturnPath().toString(),
		// email.getHeader("Return-Path"));
		// 重要度を確認
		assertEquals(mail.getImportance(), email.getHeader("Importance")[0]);
		assertEquals("1", email.getHeader("X-Priority")[0]);
	}

	/**
	 * 宛先を一件も指定していないためsend()時に例外をスロー。<br>
	 * To、Cc、Bccを一件でも指定すれば、この例外は起こらない。
	 * 
	 * @throws Exception
	 */
	public void testSendMailNoRecpient() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String subject = "件名";
		String text = "テスト成功";

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

		try {
			sendMail.send(mail);
			fail("This should never be called.");
		} catch (MailException expected) {
			assertEquals("MimeMessageの生成に失敗しました。", expected.getMessage());
		}
	}

	/**
	 * エンコーディングを SendMail#setCharset() で指定して送信するテスト。
	 */
	public void testSendMailSetCharset1() 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);

		sendMail.setCharset("UTF-8");
		sendMail.send(mail);

		Mailbox inbox = Mailbox.get("info@example.com");
		assertEquals("1", 1, inbox.size());

		Message email = inbox.get(0);
		assertEquals("text/plain; charset=UTF-8", email.getContentType());
	}

	/**
	 * エンコーディングを Mail のコンストラクタで指定して送信するテスト。
	 */
	public void testSendMailSetCharset2() throws Exception {
		String from = "from@example.com";
		String fromName = "差出人";
		String to = "info@example.com";
		String subject = "件名";
		String text = "テスト成功";

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

		sendMail.send(mail);

		Mailbox inbox = Mailbox.get("info@example.com");
		assertEquals("1", 1, inbox.size());

		Message email = inbox.get(0);
		assertEquals("text/plain; charset=UTF-8", email.getContentType());
	}
}
