/*
 * @(#)ArtifactReceiverServletTest.java
 *
 * Copyright (C) 2006 Infocity Inc. All Rights Reserved.
 */
package test.info.dragonlady.sso.servlet;

import info.dragonlady.sso.servlet.ArtifactReceiverServlet;

import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import info.dragonlady.sso.AssertionManager;
import info.dragonlady.sso.ReceiverResource;
import info.dragonlady.sso.SSOConfig;
import info.dragonlady.sso.SSOConstants;
import info.dragonlady.sso.SiteTransfer;
import info.dragonlady.sso.util.ResourceParseException;

import org.apache.cactus.ServletTestCase;
import org.apache.cactus.WebRequest;
import org.apache.cactus.WebResponse;

/**
 * ArtifactReceiverServlet クラステストケース。
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.0 $ $Date: 2006/11/24 16:34:58 $
 */
public class ArtifactReceiverServletTest extends ServletTestCase {

	private String userId = "testuser";

	private String target = "http://172.16.3.74:8080/sso_sample/target.html";

	/**
	 * @param arg0
	 */
	public ArtifactReceiverServletTest(String arg0) {
		super(arg0);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception {
		super.setUp();
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	/**
	 * {@link info.dragonlady.sso.servlet.ArtifactReceiverServlet#ArtifactReceiverServlet()} のためのテスト・メソッド。
	 */
	public final void testArtifactReceiverServlet() {
		try {
			new ArtifactReceiverServlet();
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * サーバにアサーションを設定しておく為の処理
	 * ※SiteTransferサーブレット呼び出し
	 */
	public final void beginSetAssertion(WebRequest theRequest) {
		// ターゲットサイトを指定
		theRequest.addParameter(SSOConstants.NAME_TARGET, target, WebRequest.GET_METHOD);
	}

	/**
	 * サーバにアサーションを設定しておく為の処理
	 * ※SiteTransferサーブレット呼び出し
	 */
	public final void testSetAssertion() {
		try {
			SiteTransfer st = new SiteTransfer(request, response);
			st.forwardTo(session.getId(), userId, getAttributes());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	private final Map getAttributes() throws ResourceParseException {
		Map attributes = new HashMap();
		List keyList = SSOConfig.getSAMLAttributeList();
		for(int i = 0; i < keyList.size(); i++) {
			String key = keyList.get(i).toString();
			attributes.put(key, "val_" + key);
		}
		return attributes;
	}

	/**
	 * サーバにアサーションを設定しておく為の処理
	 * ※SiteTransferサーブレット呼び出し
	 */
	public final void endSetAssertion(WebResponse theResponse) {
		try {
			// URL確認
			String expectedReceiver = ReceiverResource.getReceiver("172.16.3.74", "sso_sample");
			String receiver = theResponse.getConnection().getHeaderField("Location");
			String[] str = receiver.split("\\?");
			assertTrue(expectedReceiver.equals(str[0]));
			String[] query = str[1].split("&");
			// TARGET,SAMLartの２パラメータ
			assertTrue(query.length == 2);
			for(int i = 0; i < query.length; i++) {
				String[] s = query[i].split("=");
				if(s[0].equals(SSOConstants.NAME_SAMLART)) {
					// artifact文字列存在設定
					ArtifactManager.getInstance().setArtifact(URLDecoder.decode(s[1], "MS932"));
				}
			}
			String sessionId = theResponse.getCookie("JSESSIONID").getValue();
			ArtifactManager.getInstance().setSessionId(sessionId);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * @param theRequest
	 */
	public final void beginServiceHttpServletRequestHttpServletResponse(WebRequest theRequest) {
		try {
			String artifactStr = ArtifactManager.getInstance().getArtifact();
			// ターゲットサイトを指定
			theRequest.addParameter(SSOConstants.NAME_TARGET, target, WebRequest.GET_METHOD);
			// アーティファクトを指定
			theRequest.addParameter(SSOConstants.NAME_SAMLART, artifactStr, WebRequest.GET_METHOD);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * SAML認証成功
	 * 
	 * {@link info.dragonlady.sso.servlet.ArtifactReceiverServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} のためのテスト・メソッド。
	 */
	public final void testServiceHttpServletRequestHttpServletResponse() {
		try {
			ArtifactReceiverServlet receiver = new ArtifactReceiverServlet();
			receiver.service(request, response);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * @param theResponse
	 */
	public final void endServiceHttpServletRequestHttpServletResponse(WebResponse theResponse) {
		try {
			// URL確認
			String url = theResponse.getConnection().getHeaderField("Location");
			assertTrue(url.equals(target));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * @param theRequest
	 */
	public final void beginServiceHttpServletRequestHttpServletResponse2(WebRequest theRequest) {
		try {
			String artifactStr = ArtifactManager.getInstance().getArtifact();
			// ターゲットサイトを指定
			theRequest.addParameter(SSOConstants.NAME_TARGET, "http://172.16.3.74:8080/sso_sample/target.html", WebRequest.GET_METHOD);
			// アーティファクトを指定
			theRequest.addParameter(SSOConstants.NAME_SAMLART, artifactStr, WebRequest.GET_METHOD);
			// アサーション登録セッションIDを指定
			theRequest.addParameter("dummySessionId", ArtifactManager.getInstance().getSessionId(), WebRequest.GET_METHOD);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * SAML認証失敗
	 * 
	 * {@link info.dragonlady.sso.servlet.ArtifactReceiverServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)} のためのテスト・メソッド。
	 */
	public final void testServiceHttpServletRequestHttpServletResponse2() {
		try {
			// 対応するアサーションを削除しておく
			AssertionManager.getInstance().removeById(request.getParameter("dummySessionId"));

			ArtifactReceiverServlet receiver = new ArtifactReceiverServlet();
			receiver.service(request, response);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/**
	 * @param theResponse
	 */
	public final void endServiceHttpServletRequestHttpServletResponse2(WebResponse theResponse) {
		try {
			assertTrue(theResponse.getStatusCode() == 403);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

}
