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

import info.dragonlady.sso.AssertionManager;
import info.dragonlady.sso.util.AssertionGenerator;
import info.dragonlady.sso.util.ResourceParseException;
import info.dragonlady.sso.util.ResourceUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.opensaml.SAMLAssertion;
import org.opensaml.SAMLAuthenticationStatement;
import org.opensaml.SAMLException;
import org.opensaml.SAMLSubject;

import junit.framework.TestCase;

/**
 * AssertionManagerクラスのテストケース
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.1 $ $Date: 2005/11/11 14:10:23 $
 */
public class AssertionManagerTest extends TestCase {

	private int assertionLife = 10;
	/**
	 * Constructor for AssertionManagerTest.
	 * @param arg0
	 */
	public AssertionManagerTest(String arg0) {
		super(arg0);
	}

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

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

	private final SAMLAssertion getTestAssertion() throws SAMLException, ResourceParseException {
		SAMLAssertion assertion = AssertionGenerator.generateAuthenticationAssertion("dummy_id", SAMLSubject.CONF_ARTIFACT, SAMLAuthenticationStatement.AuthenticationMethod_Password);
		// 生存期間を再設定
		assertion.setNotOnOrAfter(new Date(assertion.getNotBefore().getTime() + assertionLife * 1000));
		return assertion;
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.getInstance()'
	 */
	public final void testGetInstance() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			assertNotNull(am);
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.getAssertion(byte[])'
	 */
	public final void testGetAssertionByteArray() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーション登録
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション比較
			assertTrue(am.get(handle).toString().equals(assertion.toString()));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.getAssertion(String)'
	 */
	public final void testGetAssertionString() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーション登録
			SAMLAssertion assertion = getTestAssertion();
			am.add(assertion);

			// アサーション比較
			assertTrue(am.get(assertion.getId()).toString().equals(assertion.toString()));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.add(SAMLAssertion, String)'
	 */
	public final void testAdd() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーション登録
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション比較
			assertTrue(am.get(handle).toString().equals(assertion.toString()));
			assertTrue(am.get(assertion.getId()).toString().equals(assertion.toString()));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.remove(String)'
	 */
	public final void testRemoveString() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーション登録
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション存在確認
			assertNotNull(am.get(assertion.getId()));

			// アサーション削除
			am.remove(assertion.getId());

			// アサーション削除確認
			assertNull(am.get(handle));
			assertNull(am.get(assertion.getId()));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.remove(byte[])'
	 */
	public final void testRemoveByteArray() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーション登録
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション存在確認
			assertNotNull(am.get(handle));

			// アサーション削除
			am.remove(handle);

			// アサーション削除確認
			assertNull(am.get(handle));
			assertNull(am.get(assertion.getId()));
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.getAssertionMap()'
	 */
	public final void testGetAssertionMap() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーションマップ作成
			SAMLAssertion assertion = getTestAssertion();
			Map assertionMap = new HashMap();
			assertionMap.put(assertion.getId(), assertion);
			am.setAssertionMap(assertionMap);
			Map result = am.getAssertionMap();

			// アサーション確認
			assertTrue(result.get(assertion.getId()).toString().equals(assertion.toString()));

			// アサーション削除
			am.remove(assertion.getId());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.setAssertionMap(Map)'
	 */
	public final void testSetAssertionMap() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーションマップ作成
			SAMLAssertion assertion = getTestAssertion();
			Map assertionMap = new HashMap();
			assertionMap.put(assertion.getId(), assertion);
			am.setAssertionMap(assertionMap);
			Map result = am.getAssertionMap();

			// アサーション確認
			assertTrue(result.get(assertion.getId()).toString().equals(assertion.toString()));

			// アサーション削除
			am.remove(assertion.getId());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.getHandleMap()'
	 */
	public final void testGetHandleMap() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーションマップ作成
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション削除
			am.remove(assertion.getId());

			// アサーション確認
			assertNull(am.get(assertion.getId()));
			assertNull(am.get(handle));

			Map handleMap = new HashMap();
			handleMap.put(assertion.getId(), ResourceUtils.toBase64String(handle));
			am.setHandleMap(handleMap);
			Map result = am.getHandleMap();

			// アサーション確認
			assertTrue(result.get(assertion.getId()).equals(ResourceUtils.toBase64String(handle)));

			// アサーション削除
			am.remove(assertion.getId());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	/*
	 * Test method for 'info.dragonlady.sso.AssertionManager.setHandleMap(Map)'
	 */
	public final void testSetHandleMap() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			// アサーションマップ作成
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

			// アサーション削除
			am.remove(assertion.getId());

			// アサーション確認
			assertNull(am.get(assertion.getId()));
			assertNull(am.get(handle));

			Map handleMap = new HashMap();
			handleMap.put(assertion.getId(), ResourceUtils.toBase64String(handle));
			am.setHandleMap(handleMap);
			Map result = am.getHandleMap();

			// アサーション確認
			assertTrue(result.get(assertion.getId()).equals(ResourceUtils.toBase64String(handle)));

			// アサーション削除
			am.remove(assertion.getId());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	public final void testAutoRemove() {
		try {
			int num = 100;
			AssertionManager am = AssertionManager.getInstance();
			List<String> assertionId = new ArrayList<String>();
			// アサーション登録
			for(int i = 0; i < num; i++) {
				SAMLAssertion assertion = getTestAssertion();
				am.add(assertion);
				assertionId.add(assertion.getId());
			}

			// アサーション存在確認
			for(int i = 0; i < num; i++) {
				assertNotNull(am.get(assertionId.get(i)));
			}
			// 待機
			Thread.sleep(assertionLife * 1000);

			// アサーション削除済み確認
			for(int i = 0; i < num; i++) {
				assertNull(am.get(assertionId.get(i)));
			}
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

}
