/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: ClientRequestTest.java,v 1.1 2005/05/11 17:48:29 rampil Exp $
 */
package org.logical_paradox.httpd;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.logical_paradox.httpd.exception.HttpException;
import org.logical_paradox.httpd.exception.IllegalConfigException;

import junit.framework.TestCase;

/**
 * ClientRequestクラスのテストケース
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.1 $
 */
public class ClientRequestTest extends TestCase {
	/**
	 * Constructor for ClientRequestTest.
	 * @param arg0
	 */
	public ClientRequestTest(String arg0) {
		super(arg0);
	}
	/**
	 * プロトコルバージョン指定なしの場合のHTTP/1.0のリクエスト(正常)
	 */
	public void testHttp10RequestWithoutProtocolVersion() throws HttpException, IllegalConfigException {
		final String rq = "GET /index.jsp\r\n\r\n";
		ClientRequest cr = new ClientRequest(rq, new Config(new String[0]));
		// 基本パラメータの検査
		checkBasicParameters(new String[]{"GET","/index.jsp","HTTP","1.0"}, cr);
	}
	/**
	 * プロトコルバージョン指定ありの場合のHTTP/1.0のリクエスト(正常)
	 */
	public void testHttp10Request() throws HttpException, IllegalConfigException {
		final String rq = "HEAD /index.jsp?command=ModifyThreadTree&thread_no=ab11220011   FTP/2.5\r\n\r\n";
		ClientRequest cr = new ClientRequest(rq, new Config(new String[0]));
		// 基本パラメータの検査
		checkBasicParameters(new String[]{"HEAD","/index.jsp?command=ModifyThreadTree&thread_no=ab11220011","FTP","2.5"}, cr);
	}
	/**
	 * 不正なリクエストヘッダ形式のテスト
	 */
	public void testIllegalRequestHeaderFormat() throws IllegalConfigException {
		try {
			final String rq1 = "HEAD /index.jsp?command=ModifyThreadTree &thread_no=ab11220011   FTP/2.5\r\n\r\n";
			new ClientRequest(rq1, new Config(new String[0]));
			fail();
		} catch (HttpException e) {
			// フォーマットエラーを検出したので正しい
		}
		try {
			final String rq1 = "\r\n\r\n";
			new ClientRequest(rq1, new Config(new String[0]));
			fail();
		} catch (HttpException e) {
			// フォーマットエラーを検出したので正しい
		}
		try {
			final String rq1 = "HEAD \r\n\r\n";
			new ClientRequest(rq1, new Config(new String[0]));
			fail();
		} catch (HttpException e) {
			// フォーマットエラーを検出したので正しい
		}
	}
	/**
	 * 正しいヘッダのテスト
	 */
	public void testCorrectedHeaders() throws HttpException, IllegalConfigException {
		final String rq1 =
				"get /index.php?command=MonitorSystemStatus&statcd=OK HTTP/1.1\r\n" +
				"Host: localhost.localdomain\r\n" +
				"User-Agent: Mozilla 4.0(ja)\r\n" +
				"X-Blank-Header:\r\n" +
				"\r\n";
		ClientRequest cr = new ClientRequest(rq1, new Config(new String[0]));

		// 確認用マップ
		HashMap m = new HashMap();
		m.put("Host", "localhost.localdomain");
		m.put("User-Agent", "Mozilla 4.0(ja)");
		m.put("X-Blank-Header","");
		checkHeaders(m, cr);
	}
	/**
	 * 不正なヘッダのテスト
	 * @throws BadRequestException
	 */
	public void testInCorrectHeaders() throws HttpException, IllegalConfigException {
		final String rq1 =
				"get /index.php?command=MonitorSystemStatus&statcd=OK HTTP/1.1\r\n" +
				"Host: localhost.localdomain\r\n" +
				"User-Agent = Mozilla 4.0(ja)\r\n" +
				"X-Blank-Header:\r\n" +
				"\r\n";
		ClientRequest cr = new ClientRequest(rq1, new Config(new String[0]));
		// 確認用マップ
		HashMap m = new HashMap();
		m.put("Host", "localhost.localdomain");
		m.put("X-Blank-Header","");
		checkHeaders(m, cr);

		// 不正なヘッダは格納されていないはず
		assertNull(cr.getHeaderValue("User-Agent"));
	}
	/**
	 * リクエストパラメータ(基本)についてテストする
	 * @param values 正しい値(メソッド, クエリー, プロトコル, バージョンの並び)
	 * @param cr リクエストパラメータ
	 */
	protected void checkBasicParameters(String[] values, ClientRequest cr) {
		// メソッド
		assertEquals(values[0], cr.getMethod());
		// クエリー
		assertEquals(values[1], cr.getQuery());
		// プロトコル
		assertEquals(values[2], cr.getProtocol());
		// バージョン
		assertEquals(values[3], cr.getVersion());
	}
	/**
	 * 所定のヘッダが所定の設定値で正しく格納されているかどうかをテストする
	 * @param headers キーとしてヘッダ, 値としてヘッダ設定値となっているマップ
	 * @param cr リクエストパラメータ
	 */
	protected void checkHeaders(Map headers, ClientRequest cr) {
		for(Iterator it = headers.keySet().iterator(); it.hasNext();) {
			String key = (String)it.next();
			assertEquals(headers.get(key), cr.getHeaderValue(key));
		}
	}
}
