package org.itscool.weber.testcase;

import java.net.URL;
import junit.framework.TestCase;

import org.itscool.commons.bean.BeanFactory;
import org.itscool.commons.connection.ConnectionManager;
import org.itscool.commons.logging.AbstractLog;
import org.itscool.commons.logging.SimpleLog;
import org.itscool.weber.action.Action;
import org.itscool.weber.controller.Globals;
import org.itscool.weber.user.RoleException;
import org.itscool.weber.user.User;
import org.w3c.dom.Document;

/**
 * <p>
 * JUnitを拡張したWeberフレームワーク用テストクラスです<br/>
 * </p>
 *
 * <p>
 * WeberTestCaseクラスは、org.itscool.weber.action.Actionクラスを
 * 継承して作成されたアクションクラスのdoExecute()メソッドと
 * doValidate()メソッドの単体テストを行うための抽象テストクラスです<br/>
 * </p>
 *
 * <p>
 * このクラスはコンテナ非依存であるため、JUnitライブラリとJavaの実行環境さえ
 * あれば、単体テストの実施が可能です。<br/>
 * 以下にテストケースのサンプルを示します。<br/>
 * </p>
 *
 * <p>テストケースのサンプル<hr></p>
 * <PRE>
 * import org.itscool.weber.testcase.WeberTestCase;
 *
 * public class TestSampleAction extends WeberTestCase{
 *     public void testDoExecute(){
 *         //クライアントからポストされた結果生成されるフォーム
 *         //インスタンスを生成します
 *         SampleForm form = new SampleForm();
 *         form.setId(1);
 *         form.setName("hogehoge");
 *
 *         //WeberTestCaseクラスには、暗黙オブジェクトとして
 *         //MockActionBucketインスタンスを提供しています。
 *         //このインスタンスに先ほど作成したフォームインス
 *         //タンスをセットします。
 *         bucket.setForm(form);
 *
 *         //テスト対象となるアクションインスタンスを生成します
 *         SampleAction action = new SampleAction();
 *
 *         //アクションクラスのdoExecuteを検証します
 *         assertDoExecute(action, form, "success");
 *     }
 *
 *     public void testDoValidate(){
 *         //doValidate()を検証する場合はrequestオブジェクトにパラメータを
 *         //セットしなければなりません。
 *         //その場合は、MockPostGereralFormインスタンスを使用します。
 *         //WeberTestCaseクラスには、暗黙オブジェクトとして
 *         //requestインスタンスを使用することができます。
 *         request.addParameter("id", "数値以外のオブジェクトをセット");
 *
 *         //テスト対象となるアクションインスタンスを生成します
 *         SampleAction action = new SampleAction();
 *
 *         //アクションクラスのdoValidateメソッドを検証します
 *         assertValidate(action, "org.itscool.weber.INPUT_ERROR");
 *     }
 * }
 * </PRE>
 *
 * <p>
 * WeberTestCaseを利用したテストを行う場合、別途JUnitクラスライブラリ
 * が必要です
 * </p>
 *
 * @author KANO
 * @since jdk1.4.1
 * @version 1.00A 2005/08/01
 */
public abstract class WeberTestCase extends TestCase{
    
    protected BeanFactory factory = BeanFactory.getInstance();
    /**
     * ActionBucketのモックオブジェクトを生成
     */
    protected MockActionBucket bucket = new MockActionBucket();
    /**
     * AbstractPostRequestのモックオブジェクトを生成
     */
    protected MockGeneralForm request = new MockGeneralForm();
    
    protected Document responseXml;
    protected String responseText;
    
    protected static AbstractLog log = SimpleLog.getInstance();
    
    public WeberTestCase(){
        ClassLoader parent = Thread.currentThread().getContextClassLoader();
        URL diconfigUrl = parent.getResource("di-config.xml");
        
        String configFwName;
        //System.out.println("di-config.xml path use = " + diconfigUrl.getPath());
        if(diconfigUrl == null ){
            String err = "di-config.xml path is null.";
            fail(err);
            log.error(err);
            return;
        }else{
            configFwName = diconfigUrl.getPath();
        }
        BeanFactory factory = BeanFactory.getInstance();
        try{
            if(!log.isInit()){
                log = (AbstractLog)factory.createInstance("Log");
            }
        }catch(Exception ioe){}
        try{
            factory.create(configFwName);
            ConnectionManager mgr = (ConnectionManager) factory.createInstance("ConnectionManager");
            mgr.init();
        }catch(Exception e){}
    }
    
    /**
     * アクションのdoExecuteメソッドを検証します。
     * @param action Action アクションオブジェクト
     * @param form Form フォームオブジェクト
     * @param forward アクションの実行結果の予測値
     */
    public void assertDoExecute(Action action, Object form, String forward) throws Exception{
        //doExcecuteメソッドのテストを実施
        String result = "";
        try{
            bucket.setForm(form);
            action.init(bucket, request);
//moidfy 2007/03/26 kano start 純粋に業務ロジックのみにテストを対象とする
//            result = action.beforeExecute();
//            if( result.equals(Globals.RET_SUCCESS)){
//                result = action.doExecute(bucket);
//            }
            result = action.doExecute(bucket);
            responseXml = bucket.getResponseXml();
            responseText = bucket.getResponseText();
//modify 2007/03/26 kano end
            
//add 2007/02/01 kano Weber4.x 対応 start
        }catch(RoleException re){
            throw re;
//add 2007/02/01 kano Weber4.x 対応 end
        }
        assertEquals("doExcecute", forward, result);
    }
    
    /**
     * アクションのcheckUserRoleメソッドを検証します。<BR>
     * データベースの更新が行われた場合はコミット/ロールバック制御を行います。
     * @param action Action アクションオブジェクト
     * @param user ユーザオブジェクト
     * @param ret ユーザチェック結果
     */
    public void assertCheckUserRole(Action action, User user, boolean ret){
        
        //doExcecuteメソッドのテストを実施
        try{
            bucket.setAttributeFromSession(Globals.REQ_PARAM_USER, user);
            action.init(bucket, request);
            action.beforeCheckRole();
            boolean isUser = action.checkRole(bucket);
            assertEquals("checkUserRole",ret, isUser);
//add 2007/02/01 kano Weber4.x 対応 start
        }catch(RoleException re){
            assertEquals("checkUserRole",ret, false);
            //throw re;
//add 2007/02/01 kano Weber4.x 対応 end
        }
    }
    
    /**
     * アクションのvalidateメソッドを検証します。
     * @param action Action アクションオブジェクト
     * @param form Form フォームオブジェクト
     * @param forward アクションの実行結果の予測値
     */
    //public void assertValidate(Action action, Object form, String forward){
    public void assertValidate(Action action, String forward) throws Exception{
        //bucket.setForm(form);
        action.setGeneralForm(request);
        
        //doExcecuteメソッドのテストを実施
        String ret = action.validate(bucket);
        assertEquals("validate", forward, ret);
    }
    
    
//    public static void main(String[] argv) throws Exception{
//    	String rootPath = System.getProperty("user.dir");
//    	String path = rootPath + "/WEB-INF/web.xml";
//    	HashMap map = new HashMap();
//    	WebReader reader = new WebReader();
//    	reader.create(path, map);
//
//    	Set set = map.keySet();
//    	Iterator it = set.iterator();
//    	while(it.hasNext()){
//    		Object key = it.next();
//    		String value = (String)map.get(key);
//    		System.out.println(key+"->"+value);
//    	}
//    }
}
