/*
 * @(#)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();
			byte[] handle = am.add(assertion);

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

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

			Map<String, String> assertionMap = new HashMap<String, String>();
			assertionMap.put(ResourceUtils.toHexString(handle), assertion.toString());

			Map<String, String> handleMap = new HashMap<String, String>();
			handleMap.put(assertion.getId(), ResourceUtils.toHexString(handle));

			am.setMap(assertionMap, handleMap);
			Map<String, String> result = am.getAssertionMap();

			// Map不変確認
			try {
				result.put("key", "value");
				assertTrue(false);
			} catch(UnsupportedOperationException e) {
				assertTrue(true);
			}

			// アサーション確認
			assertTrue(result.get(ResourceUtils.toHexString(handle)).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<String, String> assertionMap = new HashMap<String, String>();
			assertionMap.put(ResourceUtils.toHexString(handle), assertion.toString());

			Map<String, String> handleMap = new HashMap<String, String>();
			handleMap.put(assertion.getId(), ResourceUtils.toHexString(handle));

			am.setMap(assertionMap, handleMap);
			Map<String, String> result = am.getHandleMap();
			// Map不変確認
			try {
				result.put("key", "value");
				assertTrue(false);
			} catch(UnsupportedOperationException e) {
				assertTrue(true);
			}

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

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

	public final void testSetMap() {
		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<String, String> assertionMap = new HashMap<String, String>();
			assertionMap.put(ResourceUtils.toHexString(handle), assertion.toString());

			Map<String, String> handleMap = new HashMap<String, String>();
			handleMap.put(assertion.getId(), ResourceUtils.toHexString(handle));

			am.setMap(assertionMap, handleMap);
			Map<String, String> result = am.getAssertionMap();
			assertTrue(result.get(ResourceUtils.toHexString(handle)).equals(assertion.toString()));
			// Map不変確認
			try {
				result.put("key", "value");
				assertTrue(false);
			} catch(UnsupportedOperationException e) {
				assertTrue(true);
			}
			result = am.getHandleMap();
			assertTrue(result.get(assertion.getId()).equals(ResourceUtils.toHexString(handle)));
			// Map不変確認
			try {
				result.put("key", "value");
				assertTrue(false);
			} catch(UnsupportedOperationException e) {
				assertTrue(true);
			}

			am.setMap(am.getAssertionMap(), am.getHandleMap());
			// アサーション追加可能確認
			try {
				am.add(assertion);
			} catch(UnsupportedOperationException e) {
				assertTrue(false);
			}

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

	public final void testPut() {
		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));


			// ハンドルとアサーションを登録
			am.put(handle, assertion);

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

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

	public final void testToSAMLAssertion() {
		try {
			SAMLAssertion assertion = getTestAssertion();

			// アサーション確認
			assertNotNull(AssertionManager.toSAMLAssertion(assertion.toString()));
			assertEquals(AssertionManager.toSAMLAssertion(assertion.toString()).toString(), assertion.toString());
		} catch(Exception e) {
			assertTrue(e.toString(), false);
		}
	}

	public final void testClear() {
		try {
			AssertionManager am = AssertionManager.getInstance();
			SAMLAssertion assertion = getTestAssertion();
			byte[] handle = am.add(assertion);

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

			// 消去
			am.clear();

			// アサーション確認
			assertNull(am.get(handle));
			assertNull(am.get(assertion.getId()));
			assertTrue(am.getAssertionMap().isEmpty());
			assertTrue(am.getHandleMap().isEmpty());
		} 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);
		}
	}

}
