[cvs] expresso commit by rimovm: Moved Test Cases to test-src directory

JCorporate Ltd jcorp at jcorp2.servlets.net
Fri Nov 12 08:36:37 PST 2004


Log Message:
-----------
Moved Test Cases to test-src directory

Added Files:
-----------
    expresso/expresso-web/WEB-INF/test-src/com/jcorporate/expresso/core/security:
        CryptoTests.java
    expresso/expresso-web/WEB-INF/test-src/com/jcorporate/expresso/core/utility:
        DBToolTests.java
    expresso/expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/controller/tests:
        DBMaintTests.java
        DBSecurityMatrixTests.java
        LoginControllerTest.java
        RegistrationControllerTests.java
    expresso/expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/crontab/tests:
        TestCrontabEntry.java
    expresso/expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests:
        DBObjSecurityTests.java
        MediaTest.java
        MimeTypesTests.java
        SetupTests.java
        TestSchema.java

Removed Files:
-------------
    expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/security:
        CryptoTests.java
    expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/core/utility:
        DBToolTests.java
    expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/services/controller/tests:
        DBMaintTests.java
        DBSecurityMatrixTests.java
        LoginControllerTest.java
        RegistrationControllerTests.java
    expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/services/crontab/tests:
        TestCrontabEntry.java
    expresso/expresso-web/WEB-INF/src/com/jcorporate/expresso/services/dbobj/tests:
        DBObjSecurityTests.java
        MediaTest.java
        MimeTypesTests.java
        SetupTests.java
        TestSchema.java

Revision Data
-------------
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/core/security/CryptoTests.java
@@ -0,0 +1,201 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.core.security;
+
+import com.jcorporate.expresso.services.test.ExpressoTestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Unit test cases for the Cryptographic functions
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ $Date: 2004/11/12 16:36:34 $
+ */
+public class CryptoTests
+        extends ExpressoTestCase {
+    private String[] testArray = {
+        "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()_+",
+        "abc", "rimo\n", "rimo\b\r\0", "rimovm01", "9123123456789",
+        "^\"\\...//?.<>"
+    };
+    boolean usingStrongCrypto;
+
+    public CryptoTests(String testName)
+            throws Exception {
+        super(testName);
+    }
+
+    public static void main(String[] args)
+            throws Exception {
+
+        //Set the system properties we need
+        junit.textui.TestRunner.run(suite());
+    }
+
+    public static junit.framework.Test suite() {
+        return new TestSuite(CryptoTests.class);
+    }
+
+    public void setUp()
+            throws Exception {
+        CryptoManager cm = CryptoManager.getInstance();
+        usingStrongCrypto = cm.isUsingStrongCrypto();
+    }
+
+    public void tearDown()
+            throws Exception {
+        CryptoManager cm = CryptoManager.getInstance();
+        cm.loadClasses(usingStrongCrypto);
+    }
+
+    /* public void testStrongStringEncryption() throws Exception {
+
+        String modeArray[] = { "AES", "BLO", "TWO", "RC6"};
+
+com.jcorporate.expresso.core.security.strongencryption.StringEncryption se =
+
+new com.jcorporate.expresso.core.security.strongencryption.StringEncryption();
+
+        //Test for all modes
+
+        for (int i=0; i < testArray.length; i++) {
+
+            for (int j=0; j < modeArray.length; j++) {
+
+                //Try encrypting for each cipher
+
+                byte encode[] = se.encrypt(testArray[i].getBytes(),
+
+                    modeArray[j]);
+
+                String decode = se.decryptString(encode);
+
+                this.assertTrue("Test Array" + Integer.toString(i),
+
+                            decode.equals(testArray[i]));
+
+            }
+
+        }
+
+        //Test for automatic mode given config file
+
+        for (int i=0; i < testArray.length; i++) {
+
+            byte encode[] = se.encryptString(testArray[i]);
+
+            String decode = se.decryptString(encode);
+
+            this.assertTrue("Test Array" + Integer.toString(i) + "Mode ",
+
+                             decode.equals(testArray[i]));
+
+        }
+
+}
+
+   /**
+     * Test to make sure that weakencryption (obfuscation) is working
+     * @throws Exception upon error
+     * @todo Doesn't play well until we get the component system created and specifically
+     * configure a weak encryption somehow.
+     */
+    public void testWeakEncryption()
+            throws Exception {
+//        com.jcorporate.expresso.core.security.weakencryption.StringEncryption se =
+//                new com.jcorporate.expresso.core.security.weakencryption.StringEncryption();
+//
+//        //Test for automatic mode given config file
+//        for (int i = 0; i < testArray.length; i++) {
+//            byte[] encode = se.encryptString(testArray[i]);
+//            String decode = se.decryptString(encode);
+//            this.assertTrue("Test Array" + Integer.toString(i) + "Mode ",
+//                            decode.equals(testArray[i]));
+//        }
+    }
+
+    public void testCryptoManager()
+            throws Exception {
+        CryptoManager cm = CryptoManager.getInstance();
+        boolean usingStrongCrypto = cm.isUsingStrongCrypto();
+
+        //After instantiating, try to load both the strong and the weak
+        //crypto classes.
+        cm.loadClasses(true);
+
+        //Verify that we have the right class type.
+
+        /* assertTrue("Got String Strong Encryption", cm.getStringEncryption()
+
+                    instanceof
+
+com.jcorporate.expresso.core.security.strongencryption.StringEncryption );
+
+*/
+        cm.loadClasses(false);
+        assertTrue("Got String Weak Encryption",
+                cm.getStringEncryption() instanceof com.jcorporate.expresso.core.security.weakencryption.StringEncryption);
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/core/utility/DBToolTests.java
@@ -0,0 +1,434 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.core.utility;
+
+import com.jcorporate.expresso.core.db.DBConnection;
+import com.jcorporate.expresso.core.db.DBConnectionPool;
+import com.jcorporate.expresso.core.db.DBException;
+import com.jcorporate.expresso.core.dbobj.DBObject;
+import com.jcorporate.expresso.core.dbobj.Schema;
+import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
+import com.jcorporate.expresso.kernel.ConsoleInstallLog;
+import com.jcorporate.expresso.kernel.InstallLog;
+import com.jcorporate.expresso.services.dbobj.SchemaList;
+import com.jcorporate.expresso.services.test.ExpressoTestCase;
+import com.jcorporate.expresso.services.test.SchemaDeleter;
+import com.jcorporate.expresso.services.test.TestSystemInitializer;
+import junit.framework.TestSuite;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Enumeration;
+import java.util.TreeSet;
+import java.util.Vector;
+
+
+/**
+ * What this does:
+ *
+ * Runs DBCreate on the schemas and makes sure that no exceptions are thrown
+ * while creating.
+ *
+ * NOTE: Derive a class from this class to test all derived schemas.
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ $Date: 2004/11/12 16:36:35 $
+ */
+public class DBToolTests
+        extends ExpressoTestCase {
+
+    /**
+     * Add schemas to this list to verify other schemas
+     */
+    protected Vector schemaList = new Vector();
+    static private boolean alreadyCleared = false;
+    static private boolean failedOne = false;
+    private InstallLog installLog = new ConsoleInstallLog();
+
+    public DBToolTests(String name)
+            throws Exception {
+        super(name);
+    }
+
+    public static void main(String[] args)
+            throws java.lang.Exception {
+
+        //Set the system properties we need
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Creates the test cases.  Order is important, thus the manual
+     * creation.
+     */
+    public static junit.framework.Test suite()
+            throws Exception {
+
+        //Order Matters here
+        TestSuite ts = new TestSuite("Schema Verification Tests");
+        ts.addTest(new DBToolTests("testCreate"));
+        ts.addTest(new DBToolTests("testAddingSchemas"));
+        ts.addTest(new DBToolTests("testSetupSecurity"));
+        ts.addTest(new DBToolTests("testPopulateTables"));
+        ts.addTest(new DBToolTests("testSetupConfigValues"));
+        ts.addTest(new DBToolTests("testOtherSetups"));
+        ts.addTest(new DBToolTests("testVerify"));
+
+        return ts;
+    }
+
+    /**
+     * Runs the createTables() on the schema list to make sure no exceptions
+     * are getting thrown
+     */
+    public void testCreate() {
+        try {
+            DBTool.createTables(installLog, schemaList, TestSystemInitializer.getTestContext());
+            DBTool.compareTables(installLog, schemaList, TestSystemInitializer.getTestContext());
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * If testing multiple schemas, this will make sure that the schema has
+     * been added to the dbtable when created.
+     */
+    public void testAddingSchemas() {
+        try {
+            if (!failedOne) {
+                for (Enumeration e = schemaList.elements();
+                     e.hasMoreElements();) {
+                    Schema s = (Schema) e.nextElement();
+
+                    if (!s.getClass().getName().equals("com.jcorporate.expresso.core.ExpressoSchema")) {
+                        SchemaList sl = new SchemaList(SecuredDBObject.SYSTEM_ACCOUNT);
+                        sl.setDataContext(TestSystemInitializer.getTestContext());
+                        sl.setField("SchemaClass", s.getClass().getName());
+                        sl.setField("Descrip", s.getDefaultDescription());
+                        sl.setField("ComponentCode",
+                                s.getDefaultComponentCode());
+                        sl.add();
+                    }
+                }
+            } else {
+                fail("Already Failed Earlier Test - Unable to continue");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Runs the populateTables() on the schema list to make sure no exceptions
+     * are getting thrown
+     */
+    public void testPopulateTables() {
+        try {
+            if (!failedOne) {
+                DBTool.populateTables(installLog, schemaList, TestSystemInitializer.getTestContext());
+            } else {
+                fail("Already Failed Earlier Test - Unable to continue");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+
+            //Failed Default Values don't necessarily mean failed other tests
+            //            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Runs the setupSecurity() on the schema list to make sure no exceptions
+     * are getting thrown
+     */
+    public void testSetupSecurity() {
+        try {
+            if (!failedOne) {
+                DBTool.setupSecurity(installLog, schemaList, TestSystemInitializer.getTestContext());
+            } else {
+                fail("Already Failed Earlier Test - Unable to continue");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Runs through setting up the configuration values for a particular schema
+     */
+    public void testSetupConfigValues() {
+        try {
+            if (!failedOne) {
+                DBTool.setupConfig(installLog, schemaList, TestSystemInitializer.getTestContext());
+            } else {
+                fail("Already Failed Earlier Test - Unable to continue");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Runs the othersetups() on the schema list to make sure no exceptions
+     * are getting thrown
+     */
+    public void testOtherSetups() {
+        try {
+            if (!failedOne) {
+                DBTool.otherSetups(installLog, schemaList, TestSystemInitializer.getTestContext());
+            } else {
+                fail("Already Failed Earlier Test - Unable to continue");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Call verify on all the dbobjects.  Code is borrowed from DBTool
+     *
+     * Also checks for unique table names.  More than one DBOBject shouldn't be
+     * pointing to the same table name.
+     */
+    public void testVerify() {
+        TreeSet tableNames = new TreeSet();
+        DBConnectionPool myPool = null;
+        DBConnection myConnection = null;
+
+        try {
+            if (!failedOne) {
+                assertTrue("schemaList.size() > 0", schemaList.size() > 0);
+
+                Schema thisSchema = null;
+
+                for (Enumeration als = schemaList.elements();
+                     als.hasMoreElements();) {
+                    thisSchema = (Schema) als.nextElement();
+                    System.out.println("Verifying Schema " +
+                            thisSchema.getClass().getName());
+
+                    DBObject oneObject = null;
+
+                    for (Enumeration dbo = thisSchema.getMembers();
+                         dbo.hasMoreElements();) {
+                        oneObject = (DBObject) dbo.nextElement();
+                        oneObject.setDataContext(TestSystemInitializer.getTestContext());
+
+                        //Check for unique table name
+                        if (tableNames.contains(oneObject.getJDBCMetaData().getTargetTable())) {
+
+                            //
+                            //We have a special case for SingleDBUserInfo since it
+                            //is a known duplicate table.  Under Normal Circumstances
+                            //this should not be the case.
+                            //
+                            if (oneObject.getClass().getName().equals(
+                                    com.jcorporate.expresso.services.dbobj.DefaultUserInfo.class.getName()) ||
+                                    oneObject.getClass().getName().equals(
+                                            com.jcorporate.expresso.ext.dbobj.SingleDBUserInfo.class.getName())) {
+                            } else {
+                                fail("Table name: " +
+                                        oneObject.getJDBCMetaData().getTargetTable() +
+                                        " already exists due to another DBObject.  Offending DBObject" +
+                                        oneObject.getClass().getName());
+                            }
+                        } else {
+                            tableNames.add(oneObject.getJDBCMetaData().getTargetTable());
+                        }
+                        //oneObject.setConnection(myConnection);
+                        try {
+                            oneObject.verify();
+                        } catch (DBException de) {
+                            myPool.release(myConnection);
+                            System.out.println(de.getMessage());
+                            de.printStackTrace();
+                            fail("Error in object " + oneObject.getJDBCMetaData().getName() +
+                                    ":" + de.getMessage());
+                        }
+                    } /* for each database object */
+
+                }
+
+                //                    myPool.release(myConnection);
+            } else { /* for each schema in the list */
+                fail();
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            failedOne = true;
+
+            if (myPool != null && myConnection != null) {
+                myPool.release(myConnection);
+            }
+
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * This testcase makes sure that all DBObjects within all the schemas are
+     * serializable.  Helps insure that there aren't any special custom "types"
+     * that might be causing troubles.
+     */
+    public void testSerialization() {
+        try {
+            assertTrue("schemaList.size() > 0", schemaList.size() > 0);
+
+            Schema thisSchema = null;
+
+            for (Enumeration als = schemaList.elements();
+                 als.hasMoreElements();) {
+                thisSchema = (Schema) als.nextElement();
+                System.out.println("Testing Schema Serialization: " +
+                        thisSchema.getClass().getName());
+
+                DBObject oneObject = null;
+
+                for (Enumeration dbo = thisSchema.getMembers();
+                     dbo.hasMoreElements();) {
+                    oneObject = (DBObject) dbo.nextElement();
+                    oneObject.setDataContext(TestSystemInitializer.getTestContext());
+
+                    //oneObject.setConnection(myConnection);
+                    try {
+                        DBObject secondObject = (DBObject) runThroughSerializer(
+                                oneObject);
+                    } catch (IOException ioe) {
+                        System.out.println(ioe.getMessage());
+                        ioe.printStackTrace();
+                        fail("Error serializing object " +
+                                oneObject.getJDBCMetaData().getName() + ":" + ioe.getMessage());
+                    } catch (DBException de) {
+                        System.out.println(de.getMessage());
+                        de.printStackTrace();
+                        fail("Error in object " + oneObject.getJDBCMetaData().getName() + ":" +
+                                de.getMessage());
+                    }
+                } /* for each database object */
+
+            } /* for each schema in the list */
+
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+            fail("Failed Serialization: " + ioe.getMessage());
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Helper functino that serializes a DBOBject to a memory stream and then
+     * reads a new instance out from the stream.
+     */
+    private DBObject runThroughSerializer(DBObject testObject)
+            throws Exception {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(testObject);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bis);
+
+        return (DBObject) ois.readObject();
+    }
+
+    protected void setUp()
+            throws Exception {
+        DBConnectionPool.reInitialize();
+        super.setUp();
+
+        Class c = Class.forName("com.jcorporate.expresso.core.ExpressoSchema");
+        schemaList.add(c.newInstance());
+
+        if (alreadyCleared == false) {
+            SchemaDeleter.setSchemas(schemaList);
+            SchemaDeleter.deleteSchemas(TestSystemInitializer.getTestContext());
+            alreadyCleared = true;
+        }
+    }
+}
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/controller/tests/RegistrationControllerTests.java
@@ -0,0 +1,190 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.controller.tests;
+
+import com.jcorporate.expresso.core.controller.ControllerResponse;
+import com.jcorporate.expresso.services.test.ControllerTestCase;
+import com.jcorporate.expresso.services.test.ControllerTestSuite;
+import com.jcorporate.expresso.services.test.TestSystemInitializer;
+import junit.framework.TestSuite;
+import org.apache.cactus.WebRequest;
+
+
+/**
+ * Unit tests for Registration Controller
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ */
+public class RegistrationControllerTests extends ControllerTestCase {
+
+    /**
+     * Instantiates this controller.  All that is needed is call super() with
+     * the testName passed to it as well as the name of the class we're testing.
+     * @throws Exception upon error
+     * @param testName the name of the test
+     */
+    public RegistrationControllerTests(String testName) throws Exception {
+        super(testName, com.jcorporate.expresso.services.controller.SimpleRegistration.class);
+    }
+
+
+    /**
+     * Convenience method so we can test just this class.
+     * @throws Exception upon error
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+
+    /**
+     * Determines what tests are run in the test suite.  We also tell ControllerTestSuite
+     * that we need ExpressoSchema to exist for our tests.  We also tell it that
+     * we aren't modifying the underlying database for our own tests so the schema
+     * doesn't necessarily have to be deleted when we're done with it.
+     * @throws Exception upon error
+     * @return an instantiated testsuite
+     */
+    public static TestSuite suite() throws Exception {
+        ControllerTestSuite cts = new ControllerTestSuite();
+        cts.addReadOnlySchemaDependency(com.jcorporate.expresso.core.ExpressoSchema.class);
+        cts.addTestSuite(RegistrationControllerTests.class);
+
+        return cts;
+    }
+
+
+    /**
+     * The next three classes are for testing the prompt state.
+     * beginPromptState is executed on the client side.  It sets up the appropriate
+     * parameters including using what Controller state we're testing. As well
+     * as setting up cookies for proper security credentials
+     *
+     * @param theRequest a "hyper" ServletTestRequest that allows us to set URLS,
+     * set cookies, set URL parameters, etc before the request is sent to the
+     * servlet container.
+     *
+     * @throws Exception if something went wrong with the Crypto stuff
+     */
+    public void beginDBMenuTest(WebRequest theRequest) {
+        try {
+            super.setupParameters("showDBMenu", theRequest);
+            super.logIn(theRequest);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     */
+    public void testDBMenuTest() {
+        try {
+            ControllerResponse response = super.controllerProcess();
+            assertTrue("Must get a non-null ControllerResponse Object", response != null);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+
+    /**
+     * Makes sure that the prompt self register dialog is getting displayed properly
+     * @param theRequest a "hyper" ServletTestRequest that allows us to set URLS,
+     * set cookies, set URL parameters, etc before the request is sent to the
+     * servlet container.
+     */
+    public void beginPromptSelfRegister(WebRequest theRequest) {
+        try {
+            super.setupParameters("promptSelfRegister", theRequest);
+            theRequest.addParameter("dbContext", TestSystemInitializer.getTestContext());
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Makes sure that the registration form is displaying properly
+     */
+    public void testPromptSelfRegister() {
+        try {
+            ControllerResponse response = super.controllerProcess();
+            assertTrue("Must get a non-null ControllerResponse Object",
+                    response != null);
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail(e.getMessage());
+        }
+
+
+    }
+
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/controller/tests/LoginControllerTest.java
@@ -0,0 +1,263 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.controller.tests;
+
+import com.jcorporate.expresso.core.controller.ControllerResponse;
+import com.jcorporate.expresso.core.controller.Input;
+import com.jcorporate.expresso.core.controller.Transition;
+import com.jcorporate.expresso.services.test.ControllerTestCase;
+import com.jcorporate.expresso.services.test.ControllerTestSuite;
+import junit.framework.TestSuite;
+import org.apache.cactus.WebRequest;
+
+
+/**
+ * Test case to make sure LoginController appears to be working ok without
+ * throwing errors
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ */
+
+public class LoginControllerTest extends ControllerTestCase {
+
+    /**
+     * Instantiates this controller.  All that is needed is call super() with
+     * the testName passed to it as well as the name of the class we're testing.
+     * @throws Exception upon error
+     * @param testName the name of the test
+     */
+    public LoginControllerTest(String testName) throws Exception {
+        super(testName, com.jcorporate.expresso.services.controller.SimpleLoginController.class);
+    }
+
+
+    /**
+     * Convenience method so we can test just this class.
+     * @throws Exception upon error
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+
+    /**
+     * Determines what tests are run in the test suite.  We also tell ControllerTestSuite
+     * that we need ExpressoSchema to exist for our tests.  We also tell it that
+     * we aren't modifying the underlying database for our own tests so the schema
+     * doesn't necessarily have to be deleted when we're done with it.
+     * @throws Exception upon error
+     * @return an instantiated testsuite
+     */
+    public static TestSuite suite() throws Exception {
+        ControllerTestSuite cts = new ControllerTestSuite();
+        cts.addReadOnlySchemaDependency(com.jcorporate.expresso.core.ExpressoSchema.class);
+        cts.addTestSuite(LoginControllerTest.class);
+
+        return cts;
+    }
+
+
+    /**
+     * The next three classes are for testing the prompt state.
+     * beginPromptState is executed on the client side.  It sets up the appropriate
+     * parameters including using what Controller state we're testing. As well
+     * as setting up cookies for proper security credentials
+     *
+     * @param theRequest a "hyper" ServletTestRequest that allows us to set URLS,
+     * set cookies, set URL parameters, etc before the request is sent to the
+     * servlet container.
+     *
+     * @throws Exception if something went wrong with the Crypto stuff
+     */
+
+    public void beginPromptState(WebRequest theRequest) throws Exception {
+        super.setupParameters("promptLogin", theRequest);
+    }
+
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testPromptState() throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Must get a non-null ControllerResponse Object", response != null);
+
+        Input i = response.getInput("dbContext");
+        assertTrue("Must have a dbContext Input Object", i != null);
+
+        verifyLoginForm(response);
+
+    }
+
+    /**
+     * Verify login form is a helper function that verifies the expected basic
+     * items in the controller response for a login page.
+     * @throws Exception upon error
+     * @param response the ControllerResponse to test
+     */
+    private void verifyLoginForm(ControllerResponse response) throws Exception {
+        Input i = response.getInput("LoginName");
+        assertTrue("Must have a LoginName Input Object", i != null);
+
+        i = response.getInput("Password");
+        assertTrue("Must have a Password Input Object", i != null);
+
+        i = response.getInput("Remember");
+        assertTrue("Must have a Remember Input Object", i != null);
+
+        Transition t = response.getTransition("processLogin");
+        assertTrue("Must have a processLogin Transition Object", t != null);
+
+        t = response.getTransition("processLogin");
+        assertTrue("Must have a promptRegister Transition Object", t != null);
+
+    }
+
+
+    /**
+     * This test is based upon the fact that the login form should be a little
+     * different for a user already logged in.  For example, the change password
+     * transition should be available and other changes.  This test
+     * makes sure that these details are functioning properly.
+     * @throws Exception upon error
+     * @param theRequest the WebRequest object passed in by Cactus
+     */
+    public void beginPromptStateLoggedIn(WebRequest theRequest) throws Exception {
+        super.setupParameters("promptLogin", theRequest);
+        super.logIn(theRequest);
+    }
+
+    public void testPromptStateLoggedIn() throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Must get a non-null ControllerResponse Object", response != null);
+
+        verifyLoginForm(response);
+        /**
+         * @todo Finish this out
+         */
+    }
+
+
+    /**
+     * This function makes sure that errors are proper for processing a bad
+     * login
+     * @throws Exception upon error
+     * @param theRequest the WebRequest object passed in by Cactus
+     */
+    public void beginTestBadLogin(WebRequest theRequest) throws Exception {
+        super.setupParameters("processLogin", theRequest);
+        theRequest.addParameter("LoginName", "dummyFalsePassword");
+    }
+
+
+    public void testTestBadLogin() throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Must get a non-null ControllerResponse Object", response != null);
+
+        //
+        //Now we should actually have the login form again.
+        //
+        verifyLoginForm(response);
+
+        assertTrue("Must have login error message for bad login attempt",
+                response.getErrors().size() > 0);
+    }
+
+    /**
+     * Tests to make sure that the change password dialog is getting correctly
+     * displayed.
+     * @throws Exception upon error
+     * @param theRequest the WebRequest object passed in by Cactus
+     */
+    public void beginPromptChangePasswordState(WebRequest theRequest) throws Exception {
+        super.setupParameters("promptChangePassword", theRequest);
+        super.logIn(theRequest);
+    }
+
+    /**
+     * Tests the 'prompt change password' state
+     * @throws Exception upon error
+     */
+    public void testPromptChangePasswordState() throws Exception {
+        ControllerResponse response = super.controllerProcess();
+
+        assertTrue("Must get a non-null ControllerResponse Object", response != null);
+        Input i = response.getInput("oldPassword");
+        assertTrue("Old Password Input Must Exist", i != null);
+
+        i = response.getInput("Password");
+        assertTrue("New Password Input Must Exist", i != null);
+
+        i = response.getInput("password_verify");
+        assertTrue("Password Verify Input Must Exist", i != null);
+
+        Transition t = response.getTransition("processChangePassword");
+        assertTrue("Process Change Password Transition must exist", t != null);
+
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/controller/tests/DBMaintTests.java
@@ -0,0 +1,319 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.controller.tests;
+
+import com.jcorporate.expresso.core.controller.ControllerException;
+import com.jcorporate.expresso.core.controller.ControllerResponse;
+import com.jcorporate.expresso.core.controller.Input;
+import com.jcorporate.expresso.core.controller.Transition;
+import com.jcorporate.expresso.services.controller.DBMaint;
+import com.jcorporate.expresso.services.test.ControllerTestCase;
+import com.jcorporate.expresso.services.test.ControllerTestSuite;
+import junit.framework.TestSuite;
+import org.apache.cactus.WebRequest;
+
+/**
+ * Unit tests some of the states for the DBMaint Controller.
+ * This isn't so much of a thorough test as it is a check to make sure
+ * states are displaying properly.
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ */
+public class DBMaintTests extends ControllerTestCase {
+
+    /**
+     * Instantiates this controller.  All that is needed is call super() with
+     * the testName passed to it as well as the name of the class we're testing.
+     * @param testName the name of the test
+     * @throws Exception upon error
+     */
+    public DBMaintTests(String testName)
+            throws Exception {
+        super(testName,
+                com.jcorporate.expresso.services.controller.DBMaint.class);
+    }
+
+    /**
+     * Convenience method so we can test just this class.
+     * @param args the command line arguments (unused)
+     * @throws Exception upon error
+     */
+    public static void main(String[] args)
+            throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Determines what tests are run in the test suite.  We also tell ControllerTestSuite
+     * that we need ExpressoSchema to exist for our tests.  We also tell it that
+     * we aren't modifying the underlying database for our own tests so the schema
+     * doesn't necessarily have to be deleted when we're done with it.
+     * @throws Exception upon error
+     * @return instantiated TestSuite object
+     */
+    public static TestSuite suite()
+            throws Exception {
+        ControllerTestSuite cts = new ControllerTestSuite();
+        cts.addReadOnlySchemaDependency(com.jcorporate.expresso.core.ExpressoSchema.class);
+        cts.addTestSuite(DBMaintTests.class);
+
+        return cts;
+    }
+
+
+    /**
+     * @param theRequest a "hyper" ServletTestRequest that allows us to set URLS,
+     * set cookies, set URL parameters, etc before the request is sent to the
+     * servlet container.
+     *
+     * @throws Exception if something went wrong with the Crypto stuff
+     */
+    public void beginPromptState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("prompt", theRequest);
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testPromptState()
+            throws Exception {
+        try {
+            ControllerResponse response = super.controllerProcess();
+            assertTrue("Must have a non-null response", response != null);
+            Input i = response.getInput("SchemaClass");
+            assertTrue("Must have a SchemaClass Input", i != null);
+            assertTrue("Schema Class Input must have valid values", i.getValidValues().size() > 0);
+
+            Transition t = response.getTransition("selDBObj");
+            assertTrue("Must have a transition to next state", t != null);
+            assertTrue("Must transition to this controller",
+                    t.getControllerObject().equals(DBMaint.class.getName()));
+
+            assertTrue("Must transition to appropriate state",
+                    t.getState().equals("selDBObj"));
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            fail("Caught Exception in testPromptState: " + ex.getMessage());
+        }
+    }
+
+
+    /**
+     * Sanity check to make sure that the 'select dbobject' page is working properly
+     * @param theRequest The Cactus web request
+     * @throws Exception upon error
+     */
+    public void beginSelDBObjState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("selDBObj", theRequest);
+        theRequest.addParameter("SchemaClass", com.jcorporate.expresso.core.ExpressoSchema.class.getName());
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception
+     */
+    public void testSelDBObjState()
+            throws Exception {
+        try {
+            ControllerResponse response = super.controllerProcess();
+            assertTrue("Must have a non-null response", response != null);
+            Input i = response.getInput("dbobj");
+            assertTrue("Must have dbobject input", i != null);
+            assertTrue("Must have valid values", i.getValidValues().size() > 0);
+            verifyAddListSearchButtons(response);
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            fail("Caught Exception in testListDBOBjState: " + ex.getMessage());
+        }
+
+    }
+
+
+    /**
+     * Test the "List" state of controller
+     * @param theRequest the Cactus WebRequest object
+     * @throws Exception upon error
+     */
+    public void beginListDBObjState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("List", theRequest);
+        theRequest.addParameter("dbobj", com.jcorporate.expresso.services
+                .dbobj.MimeTypes.class.getName());
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testListDBObjState()
+            throws Exception {
+        try {
+            ControllerResponse response = super.controllerProcess();
+            assertTrue("Must have a non-null response", response != null);
+            assertTrue("Must have a Buttons Block", response.getBlock("buttons") != null);
+            assertTrue("Must have a record list block", response.getBlock("recordList") != null);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            fail("Caught Exception in testListDBOBjState: " + ex.getMessage());
+        }
+
+    }
+
+    /**
+     * Checks to make sure that the Add/List/Search transitions are available.
+     * @param response the ControllerResponse object we're testing
+     * @throws ControllerException upon error
+     */
+    protected void verifyAddListSearchButtons(ControllerResponse response) throws ControllerException {
+        Transition t = response.getTransition("Add");
+        assertTrue("Must have Add Transition", t != null);
+        assertTrue("Add Must transition to this controller",
+                t.getControllerObject().equals(DBMaint.class.getName()));
+
+        assertTrue("Add Must transition to appropriate state",
+                t.getState().equals("Add"));
+
+        t = response.getTransition("List");
+        assertTrue("Must have List Transition", t != null);
+        assertTrue("List Must transition to this controller",
+                t.getControllerObject().equals(DBMaint.class.getName()));
+
+        assertTrue("List Must transition to appropriate state",
+                t.getState().equals("List"));
+
+        t = response.getTransition("Search");
+        assertTrue("Must have Search Transition", t != null);
+        assertTrue("Search Must transition to this controller",
+                t.getControllerObject().equals(DBMaint.class.getName()));
+
+        assertTrue("Search Must transition to appropriate state",
+                t.getState().equals("Search"));
+
+    }
+
+
+    /**
+     * Test the "Add DBObject" State.  Make sure a form displays, and not an
+     * error
+     * @param theRequest the Cactus WebRequest object
+     * @throws Exception upon error
+     */
+    public void beginAddDBObjState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("Add", theRequest);
+        theRequest.addParameter("dbobj", com.jcorporate.expresso.services
+                .dbobj.MimeTypes.class.getName());
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testAddDBObjState()
+            throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Must have a non-null response", response != null);
+
+    }
+
+
+    /**
+     * Test to make sure a search form is appearing properly.
+     * @param theRequest the Cactus WebRequest object
+     * @throws Exception upon error
+     */
+    public void beginSearchDBObjState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("Search", theRequest);
+        theRequest.addParameter("dbobj", com.jcorporate.expresso.services
+                .dbobj.DefaultUserInfo.class.getName());
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testSearchDBObjState()
+            throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Must have a non-null response", response != null);
+
+    }
+
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/controller/tests/DBSecurityMatrixTests.java
@@ -0,0 +1,251 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.controller.tests;
+
+import com.jcorporate.expresso.core.controller.Block;
+import com.jcorporate.expresso.core.controller.ControllerElement;
+import com.jcorporate.expresso.core.controller.ControllerResponse;
+import com.jcorporate.expresso.core.controller.Input;
+import com.jcorporate.expresso.core.controller.Output;
+import com.jcorporate.expresso.core.controller.Transition;
+import com.jcorporate.expresso.services.test.ControllerTestCase;
+import com.jcorporate.expresso.services.test.ControllerTestSuite;
+import junit.framework.TestSuite;
+import org.apache.cactus.WebRequest;
+
+import java.util.Enumeration;
+
+
+/**
+ * Unit tests some of the states for the DBSecurityMatrix Controller.
+ * @todo Implement 'update state' unit tests
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ $Date: 2004/11/12 16:36:35 $
+ */
+public class DBSecurityMatrixTests
+        extends ControllerTestCase {
+    /**
+     * Instantiates this controller.  All that is needed is call super() with
+     * the testName passed to it as well as the name of the class we're testing.
+     * @param testName the name of the test
+     * @throws Exception upon error
+     */
+    public DBSecurityMatrixTests(String testName)
+            throws Exception {
+        super(testName,
+                com.jcorporate.expresso.services.controller.DBSecurityMatrix.class);
+    }
+
+    /**
+     * Convenience method so we can test just this class.
+     * @throws Exception upon error
+     * @param args the Command line arguments
+     */
+    public static void main(String[] args)
+            throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Determines what tests are run in the test suite.  We also tell ControllerTestSuite
+     * that we need ExpressoSchema to exist for our tests.  We also tell it that
+     * we aren't modifying the underlying database for our own tests so the schema
+     * doesn't necessarily have to be deleted when we're done with it.
+     * @throws Exception upon error
+     * @return Instantiated TestSuite
+     */
+    public static TestSuite suite()
+            throws Exception {
+        ControllerTestSuite cts = new ControllerTestSuite();
+        cts.addReadOnlySchemaDependency(com.jcorporate.expresso.core.ExpressoSchema.class);
+        cts.addTestSuite(DBSecurityMatrixTests.class);
+
+        return cts;
+    }
+
+    /**
+     * The next three functions are for testing the prompt state.
+     * beginPromptState is executed on the client side.  It sets up the appropriate
+     * parameters including using what Controller state we're testing. As well
+     * as setting up cookies for proper security credentials
+     *
+     * @param theRequest a "hyper" ServletTestRequest that allows us to set URLS,
+     * set cookies, set URL parameters, etc before the request is sent to the
+     * servlet container.
+     *
+     * @throws Exception if something went wrong with the Crypto stuff
+     */
+    public void beginPromptState(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("prompt", theRequest);
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testPromptState()
+            throws Exception {
+        ControllerResponse response = super.controllerProcess();
+        assertTrue("Got a null response", response != null);
+        assertTrue("Incorrect Number Of Inputs",
+                response.getInputs().size() == 2);
+        assertTrue("Incorrect Number Of Transitions",
+                response.getTransitions().size() == 1);
+        assertTrue("GroupNames are not multivalued",
+                response.getInput("GroupName").getValidValues().size() > 0);
+        assertTrue("SchemaClass is not multivalued",
+                response.getInput("SchemaClass").getValidValues().size() > 0);
+    }
+
+    /**
+     * The next three classes are for testing getting the dbobjmatrix state for
+     * the dbobject security matrix.
+     * beginSecurityMatrix() is executed on the client side.  It sets up the appropriate
+     * parameters including using what Controller state we're testing. As well
+     * as setting up cookies for proper security credentials
+     *
+     * @throws Exception if something went wrong with the Crypto stuff
+     * @param theRequest the Cactus WebRequest object
+     */
+    public void beginSecurityMatrix(WebRequest theRequest)
+            throws Exception {
+        super.logIn(theRequest);
+        super.setupParameters("dbobjmatrix", theRequest);
+        theRequest.addParameter("SchemaClass",
+                "com.jcorporate.expresso.core.ExpressoSchema");
+        theRequest.addParameter("GroupName", "Admin");
+    }
+
+    /**
+     * Executed on the server side.  All it has to do is call the super's
+     * controllerProcess() to the Controller's State properly executed.
+     * @throws Exception upon error
+     */
+    public void testSecurityMatrix()
+            throws Exception {
+        ControllerResponse theResponse = super.controllerProcess();
+        assertTrue("Got a null response", theResponse != null);
+        assertTrue("Returned one security matrix block",
+                theResponse.getBlocks().size() == 1);
+
+        Block b = (Block) theResponse.getBlocks().elementAt(0);
+        Block matrix = (Block) b.getNested().elementAt(0);
+        assertTrue("Batch of security matrix blocks",
+                matrix.getBlocks().size() > 4);
+
+        //Check each oneRow nested block and make sure that it's properly formed.
+        for (Enumeration eRow = matrix.getNested().elements();
+             eRow.hasMoreElements();) {
+            ControllerElement ce = (ControllerElement) eRow.nextElement();
+
+            if (ce instanceof Block) {
+                Block oneRow = (Block) ce;
+
+                if (ce.getName().equals("oneRow")) {
+                    int outputCount = 0;
+                    int inputCount = 0;
+                    assertTrue("Five Elements for Security Matrix Row",
+                            oneRow.getNested().size() == 5 //BUG BUG: Why is there an empty null element at the end
+                    );
+
+                    for (Enumeration e = oneRow.getNested().elements();
+                         e.hasMoreElements();) {
+                        ControllerElement oneElement = (ControllerElement) e.nextElement();
+
+                        if (oneElement != null) {
+                            if (oneElement instanceof Output) {
+                                assertTrue("Output Label is non-empty string",
+                                        ((Output) oneElement).getContent().length() > 0);
+                                outputCount++;
+                            } else if (oneElement instanceof Input) {
+                                assertTrue("Input is a check box",
+                                        oneElement.getAttribute("checkbox") != null);
+                                inputCount++;
+                            } else if (oneElement instanceof Transition) {
+                                fail("Did not expect a tranition within the security matrix fields");
+                            } else {
+                                fail("Got Controller Element of: " +
+                                        oneElement.getClass().getName() +
+                                        " not expected element.");
+                            }
+                        }
+                    }
+
+                    assertTrue("Proper number of outputs for row",
+                            outputCount == 1);
+                    assertTrue("Proper number of inputs for a row",
+                            inputCount == 4);
+                } else if (ce.getName().equals("TransitionRow")) {
+                    super.getLog().debug("Got Here");
+                }
+            } else {
+                fail("Expected Matrix to have only blocks nested");
+            }
+        }
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/crontab/tests/TestCrontabEntry.java
@@ -0,0 +1,306 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.crontab.tests;
+
+import com.jcorporate.expresso.services.crontab.CronException;
+import com.jcorporate.expresso.services.crontab.CrontabEntry;
+import com.jcorporate.expresso.services.crontab.CrontabListenerI;
+import junit.framework.TestCase;
+import org.apache.log4j.Logger;
+
+import java.util.Calendar;
+import java.util.Date;
+
+
+/**
+ * Test case to help decipher and bugfix crontab entry.  Unfortunately, part of
+ * this test case needs to be individually verifiable.  ie, you must include the
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ */
+public class TestCrontabEntry extends TestCase {
+
+    private static final Logger log = Logger.getLogger(TestCrontabEntry.class);
+
+    CrontabListenerI listener;
+
+    public TestCrontabEntry(String _name) {
+        super(_name);
+    }
+
+    public void setUp() {
+        listener = new CrontabListenerI() {
+            public void handleCrontabEntry(CrontabEntry entry) {
+                log.info("Starting Cron process");
+            }
+        };
+    }
+
+    /**
+     * Tests the &quot;execute at such and such date&quot; crontab
+     */
+    public void testConstructor1() {
+        try {
+            //Create a crontab to execute at this time tomorrow
+            Calendar cal = Calendar.getInstance();
+            cal.add(Calendar.DATE,1);
+            Date dt = cal.getTime();
+            CrontabEntry cronID = new CrontabEntry(dt,listener);
+            if (log.isDebugEnabled()) {
+                log.debug("Constructor 1: Created cron: " + cronID.toString() + "now is: " + dt.toString());
+            }
+            assertTrue("Cron date should be the exact time we originally set",
+                       dt.equals(new Date(cronID.getAlarmTime())));
+        }
+        catch (CronException ex) {
+            ex.printStackTrace();
+            fail("crontab entry threw an exception");
+        }
+
+    }
+
+    /**
+     * Tests the &quot;Execute in X-many minutes&quot; constructor
+     */
+    public void testConstructor2() {
+
+            Calendar cal = Calendar.getInstance();
+            cal.add(Calendar.MINUTE,20);
+            Date testDate = cal.getTime();
+            //
+            //Create a crontab to execute in 20 minutes
+            //
+            CrontabEntry cronID = new CrontabEntry(20, false, listener);
+
+            //Execution time MIGHT not be exactly the same time because it takes
+            //a few milliseconds to create the crontab.  What we DO want is to verify
+            //the the difference is less than 1 minute
+            assertTrue(Math.abs(testDate.getTime() -  cronID.getAlarmTime()) < (1000 * 60));
+
+            if (log.isDebugEnabled()) {
+                log.debug("Constructor 2: Created cron: " + cronID.toString());
+            }
+            assertTrue("Cron should not be repetitive",cronID.isIsRepetitive() == false);
+            assertTrue("Cron should be relative", cronID.isIsRelative() == true);
+
+            //
+            //Create a crontab to execute in 90 minutes.
+            //
+            cal = Calendar.getInstance();
+                        cal.add(Calendar.MINUTE,90);
+            testDate = cal.getTime();
+            cronID = new CrontabEntry(90, true, listener);
+            if (log.isDebugEnabled()) {
+                log.debug("Constructor 2: Created cron: " + cronID.toString());
+            }
+            assertTrue("Cron should be repetitive",cronID.isIsRepetitive() == true);
+            assertTrue("Cron should be relative", cronID.isIsRelative() == true);
+            assertTrue(Math.abs(testDate.getTime() -  cronID.getAlarmTime()) < (1000 * 60));
+
+
+    }
+
+    /**
+     * Tests the &quot;Execute at this particular given cron-expression time&quot;
+     */
+    public void testConstructor3() {
+
+        try {
+            //Every hour cron test  Runs at 4 minutes after the hour
+            CrontabEntry cronID = new CrontabEntry(
+                    4, -1,
+                    -1, -1,
+                    -1, -1,
+                    listener);
+            {
+                Calendar now = Calendar.getInstance();
+                if (now.get(Calendar.MINUTE) > 4) {
+                    now.add(Calendar.HOUR, 1);
+                }
+                Calendar cronDate = Calendar.getInstance();
+                cronDate.setTime(new Date(cronID.getAlarmTime()));
+                if (log.isInfoEnabled()) {
+                    System.out.println("Constructor 3: Created cron: " + cronID.toString());
+                }
+                assertTrue("Cron should execute at minute 4.  Got: " +
+                           cronDate.get(Calendar.MINUTE)+ " instead",cronDate.get(Calendar.MINUTE) == 4);
+                assertTrue("Cron should execute either this hour or next hour",
+                           cronDate.get(Calendar.HOUR) == now.get(Calendar.HOUR));
+
+                assertTrue("Cron should be repetitive",cronID.isIsRepetitive() == true);
+                assertTrue("Cron should not be relative time",cronID.isIsRelative() == false);
+            }
+
+            //Every day at midnight cron test
+            Calendar curDate = Calendar.getInstance();
+            curDate.add(Calendar.DATE,1);
+            cronID = new CrontabEntry(
+                    0,  0,
+                    -1, -1,
+                    -1, -1,
+                    listener);
+
+            assertTrue("Cron should be repetitive",cronID.isIsRepetitive() == true);
+            assertTrue("Cron should not be relative time",cronID.isIsRelative() == false);
+            Calendar cal = Calendar.getInstance();
+            cal.setTime(new Date(cronID.getAlarmTime()));
+            //
+            assertTrue("Cron job should execute at midnight", cal.get(Calendar.HOUR) == 0
+                       && cal.get(Calendar.MINUTE) == 0);
+
+
+            //Should execute 'tomorrow'.  Unless we execute this test EXACTLY at
+            //midnight, then the job will execute the next calendar day.   If by
+            //some freaky reason this executes at midnight, this test will fail.
+            assertTrue("Cron job should execute tomorrow",
+                       cal.get(Calendar.DATE) == curDate.get(Calendar.DATE));
+            if (log.isInfoEnabled()) {
+               log.info("Constructor 3: Created cron: " + cronID.toString());
+            }
+
+			// every sunday at 20 minutes of every hour cron test
+			cronID = new CrontabEntry(
+					20,  -1,
+					-1, -1,
+					1, -1,
+					listener);
+			
+			if (log.isInfoEnabled()) {
+				log.info("Constructor 3: Created cron: " + cronID.toString());
+			}
+			
+			curDate = Calendar.getInstance();
+			assertTrue("Cron should be repetitive",cronID.isIsRepetitive() == true);
+			assertTrue("Cron should not be relative time",cronID.isIsRelative() == false);
+			cal = Calendar.getInstance();
+			cal.setTime(new Date(cronID.getAlarmTime()));
+			//
+			assertTrue("Cron job should execute every sunday at 20 minutes of every hour", cal.get(Calendar.DAY_OF_WEEK) == 1
+					   && cal.get(Calendar.MINUTE) == 20);
+			assertTrue("Cron job should execute at 0'th hour of next sunday ", curDate.get(Calendar.DAY_OF_WEEK) == 1 ? true : cal.get(Calendar.HOUR_OF_DAY) == 0 );
+
+
+			// Jan 2, 2004 at midnight cron test
+            cronID = new CrontabEntry(
+                    0,  0,
+                    1, 0,
+                    -1, 2024,
+                    listener);
+
+            assertTrue("Cron should not be repetitive",cronID.isIsRepetitive() == false);
+            assertTrue("Cron should not be relative time",cronID.isIsRelative() == false);
+
+            cal = Calendar.getInstance();
+            cal.setTime(new Date(cronID.getAlarmTime()));
+            assertTrue("Cron should execute year 20204", cal.get(Calendar.YEAR) == 2024);
+            assertTrue("Cron should execute in January", cal.get(Calendar.MONTH) == Calendar.JANUARY);
+            assertTrue("Cron should execute the first of the month", cal.get(Calendar.DAY_OF_MONTH) == 1);
+            assertTrue("Cron should execute at midnight", cal.get(Calendar.HOUR)  == 0 && cal.get(Calendar.MINUTE) == 0);
+            if (log.isInfoEnabled()) {
+               log.info("Constructor 3: Created cron: " + cronID.toString());
+            }
+        }
+        catch (CronException ex) {
+            ex.printStackTrace();
+            fail("crontab entry threw an exception");
+        }
+
+    }
+
+    /**
+     * Same as testConstructor3, but also checks that the job label is getting
+     * set correctly
+     */
+    public void testConstructor4() {
+        final String label = "Test Cron";
+        try {
+            //Every hour cron test
+            CrontabEntry cronID = new CrontabEntry(
+                    4, -1,
+                    -1, -1,
+                    -1, -1, label,
+                    listener);
+
+            //Check the label
+            assertTrue(label.equals(cronID.getLabel()));
+            if (log.isInfoEnabled()) {
+                log.info("Constructor 4: Created cron: " + cronID.toString());
+            }
+        }
+        catch (CronException ex) {
+            ex.printStackTrace();
+            fail("crontab entry threw an exception");
+        }
+
+    }
+
+
+
+    /** Executes the test case */
+    public static void main(String[] argv) {
+        String[] testCaseList = {TestCrontabEntry.class.getName()};
+        junit.textui.TestRunner.main(testCaseList);
+    }
+}
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests/TestSchema.java
@@ -0,0 +1,123 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.dbobj.tests;
+
+import com.jcorporate.expresso.core.db.DBException;
+import com.jcorporate.expresso.core.dbobj.Schema;
+
+
+/**
+ * Test Schema object - used by the test cases to create appropriate tables for tests
+ *
+ * @version        $Revision: 1.1 $  $Date: 2004/11/12 16:36:35 $
+ * @author        Michael Rimov
+ */
+public class TestSchema
+        extends Schema {
+    /**
+     * Constructor
+     *
+     * @throws  DBException
+     */
+    public TestSchema()
+            throws DBException {
+        super();
+
+        try {
+
+            /* Database objects */
+            addDBObject(com.jcorporate.expresso.services.dbobj.tests.MediaTest.class);
+        } catch (Exception e) {
+            throw new DBException(e);
+        }
+    } /* TestSchema() */
+
+    /**
+     *
+     *
+     * @return
+     */
+    public String getMessageBundlePath() {
+        return "com/jcorporate/expresso/core";
+    } /* getMessageBundlePath() */
+
+    /**
+     * Returns the default component code for this schema. Useful for automated
+     * component testing/installation
+     */
+    public String getDefaultComponentCode() {
+        return "tests";
+    }
+
+    /**
+     * Returns the default description for this schema. Useful for automated
+     * component testing/installation
+     */
+    public String getDefaultDescription() {
+        return "Test Schema";
+    }
+} /* TestSchema */
+
+/* TestSchema */
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests/SetupTests.java
@@ -0,0 +1,176 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.dbobj.tests;
+
+import com.jcorporate.expresso.core.cache.CacheManager;
+import com.jcorporate.expresso.core.db.DBException;
+import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
+import com.jcorporate.expresso.core.dbobj.ValidValue;
+import com.jcorporate.expresso.services.dbobj.Setup;
+import com.jcorporate.expresso.services.test.ExpressoTestCase;
+import com.jcorporate.expresso.services.test.TestSystemInitializer;
+import junit.framework.TestSuite;
+
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+
+
+/**
+ * Quick sanity check to make sure that the Setup is working properly
+ * This class currently mainly tests the cache.  Adapted from Michael Nash's
+ * unitTest() function in Setup.
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ */
+public class SetupTests
+        extends ExpressoTestCase {
+    public SetupTests(String name)
+            throws Exception {
+        super(name);
+    }
+
+    public static void main(String[] args)
+            throws java.lang.Exception {
+
+        //Set the system properties we need
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Creates the test cases.  Order is important, thus the manual
+     * creation.
+     * @throws Exception
+     * @return instanatiated test suite
+     */
+    public static junit.framework.Test suite()
+            throws Exception {
+        return new TestSuite(SetupTests.class);
+    }
+
+    /**
+     * Create a SetupCache and make sure that the values are reading correctly.
+     */
+    public void testSetupCacheCreation() {
+        try {
+            Setup s = new Setup(SecuredDBObject.SYSTEM_ACCOUNT);
+            s.setDataContext(TestSystemInitializer.getTestContext());
+            Setup.readSetups();
+
+            if (!CacheManager.existsCache(TestSystemInitializer.getTestContext(), Setup.CACHE_NAME)) {
+                fail("Setup cache was not created correctly.");
+            }
+
+            assertTrue("Setup Cache must have at least 10 values in it.",
+                    CacheManager.getItemCount(TestSystemInitializer.getTestContext(), Setup.CACHE_NAME) > 10);
+        } catch (DBException ex) {
+            ex.printStackTrace();
+            fail(ex.getMessage());
+        }
+    }
+
+    /**
+     * Goes through the setup cache and makes sure that the values in the
+     * cache are what we would expect in a newly created database
+     */
+    public void testSetupCacheValues() {
+        try {
+            Setup s = new Setup(SecuredDBObject.SYSTEM_ACCOUNT);
+            s.setDataContext(TestSystemInitializer.getTestContext());
+
+            String oneValue = null;
+            String oneSchema = null;
+            String oneCode = null;
+            ValidValue oneItem = null;
+
+            for (Enumeration e = CacheManager.getItems(TestSystemInitializer.getTestContext(), Setup.CACHE_NAME).elements();
+                 e.hasMoreElements();) {
+                oneItem = (ValidValue) e.nextElement();
+
+                //            System.out.println("Setup Code " + oneItem.getKey() + ", value "
+                //                + oneItem.getDescription());
+                StringTokenizer stk = new StringTokenizer(oneItem.getKey(), "|");
+                oneSchema = stk.nextToken();
+                oneCode = stk.nextToken();
+                oneValue = Setup.getValue(TestSystemInitializer.getTestContext(), oneSchema, oneCode);
+
+                //
+                //Beacause %context% and %webapp% are expanded, we can't check
+                //against any value that contains them in their setup value.
+                //
+                if (!(oneItem.getDescription().indexOf("%context%") != -1 ||
+                        oneItem.getDescription().indexOf("%web-app%") != -1)) {
+                    if (!oneValue.equals(oneItem.getDescription())) {
+                        fail("Setup value for default db, schema '" + oneSchema +
+                                "', code '" + oneCode + "'" + " should have been " +
+                                oneItem.getDescription() + ", but was " + oneValue);
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            fail(ex.getMessage());
+        }
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests/DBObjSecurityTests.java
@@ -0,0 +1,330 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.dbobj.tests;
+
+import com.jcorporate.expresso.core.db.DBException;
+import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
+import com.jcorporate.expresso.core.security.User;
+import com.jcorporate.expresso.services.dbobj.DBObjSecurity;
+import com.jcorporate.expresso.services.dbobj.GroupMembers;
+import com.jcorporate.expresso.services.dbobj.UserGroup;
+import com.jcorporate.expresso.services.dbobj.UserPreference;
+import com.jcorporate.expresso.services.test.ExpressoTestCase;
+import com.jcorporate.expresso.services.test.TestSystemInitializer;
+import junit.framework.TestSuite;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * Perform unit tests to determine if the db object security is working correctly.
+ * These unit tests create a temporary user entry, assign it certain permissions,
+ * verifying that the permissions
+ * are granted appropriately, then remove the permissions and check that they are
+ * removed. Note that this test requires that the default UserDBObj implentation
+ * of User is used - e.g. don't have LDAP enabled when this test is run.
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ on  $Date: 2004/11/12 16:36:35 $
+ *
+ */
+public class DBObjSecurityTests
+        extends ExpressoTestCase {
+    private static final String TEST_GROUP = "TestGroup";
+    private static final String TEST_LOGIN = "testUser";
+    private int TEST_UID = 0;
+
+    public DBObjSecurityTests(String name)
+            throws Exception {
+        super(name);
+    }
+
+    public static void main(String[] args)
+            throws java.lang.Exception {
+
+        //Set the system properties we need
+        junit.textui.TestRunner.run(suite());
+    }
+
+    /**
+     * Creates the test cases.  Order is important, thus the manual
+     * creation.
+     */
+    public static junit.framework.Test suite()
+            throws Exception {
+        return new TestSuite(DBObjSecurityTests.class);
+    }
+
+    /**
+     * Create a SetupCache and make sure that the values are reading correctly.
+     */
+    public void testDBObjSecurity()
+            throws Exception {
+
+        /* Remove all permission for the test group initially */
+        DBObjSecurity oneSec = null;
+        DBObjSecurity secList = new DBObjSecurity();
+        secList.setDataContext(TestSystemInitializer.getTestContext());
+        secList.setField("GroupName", TEST_GROUP);
+
+        for (Iterator e1 = secList.searchAndRetrieveList().iterator();
+             e1.hasNext();) {
+            oneSec = (DBObjSecurity) e1.next();
+            oneSec.delete();
+        }
+
+        /* Make sure the test user has no permission now */
+        UserPreference testPref = new UserPreference(this.TEST_UID);
+        testPref.setDataContext(TestSystemInitializer.getTestContext());
+
+        if (testPref.checkAllowed("A")) {
+            fail("Test user was allowed add permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("U")) {
+            fail("Test user was allowed update permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("D")) {
+            fail("Test user was allowed delete permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("S")) {
+            fail("Test user was allowed search permission to " +
+                    "UserPreference and should not have been");
+        }
+
+        String testPrefDB = testPref.getDataContext();
+
+        /* Now grant "add" permission and see what happens */
+        DBObjSecurity newSec = new DBObjSecurity(SecuredDBObject.SYSTEM_ACCOUNT);
+        newSec.setDataContext(TestSystemInitializer.getTestContext());
+        newSec.setField("GroupName", "TestGroup");
+        newSec.setField("MethodCode", "A");
+        newSec.setField("DBObjectName",
+                "com.jcorporate.expresso.services.dbobj.UserPreference");
+        newSec.add();
+        testPrefDB = testPref.getDataContext();
+        if (!testPref.checkAllowed("A")) {
+            fail("Test user was not allowed add permission to " +
+                    "UserPreference and should have been - add of permissions " +
+                    "did not work");
+        }
+        if (testPref.checkAllowed("U")) {
+            fail("Test user was allowed update permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("D")) {
+            fail("Test user was allowed delete permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("S")) {
+            fail("Test user was allowed search permission to " +
+                    "UserPreference and should not have been");
+        }
+
+        /* Now remove add permission and make sure it gets removed */
+        newSec.setField("GroupName", TEST_GROUP);
+        newSec.setField("MethodCode", "A");
+        newSec.setField("DBObjectName",
+                com.jcorporate.expresso.services.dbobj.UserPreference.class.getName());
+        newSec.delete();
+
+        if (testPref.checkAllowed("A")) {
+            fail("Test user was allowed add permission to " +
+                    "UserPreference and should not have been - delete of " +
+                    "permissions did not work");
+        }
+        if (testPref.checkAllowed("U")) {
+            fail("Test user was allowed update permission " +
+                    "to UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("D")) {
+            fail("Test user was allowed delete permission to " +
+                    "UserPreference and should not have been");
+        }
+        if (testPref.checkAllowed("S")) {
+            fail("Test user was allowed search permission " +
+                    "to UserPreference and should not have been");
+        }
+    }
+
+    protected void setUp()
+            throws java.lang.Exception {
+        User testUser = new User();
+        testUser.setDataContext(TestSystemInitializer.getTestContext());
+        testUser.setLoginName(TEST_LOGIN);
+
+        if (!testUser.find()) {
+            testUser.setEmail("testme at example.org");
+            testUser.setLoginName(TEST_LOGIN);
+            testUser.setDisplayName("User for DBObjSecurity unit test - remove");
+            testUser.add();
+        }
+        if (testUser.find()) {
+            TEST_UID = testUser.getUid();
+        } else {
+            fail("Unable to create Test User");
+        }
+
+        UserGroup testGroup = new UserGroup(SecuredDBObject.SYSTEM_ACCOUNT);
+        testGroup.setDataContext(TestSystemInitializer.getTestContext());
+        testGroup.setField("GroupName", TEST_GROUP);
+
+        if (!testGroup.find()) {
+            testGroup.setField("Descrip",
+                    "Group for DBObjSecurity unit test - remove");
+            testGroup.add();
+        }
+
+        GroupMembers testGroupMembers = new GroupMembers(SecuredDBObject.SYSTEM_ACCOUNT);
+        testGroupMembers.setDataContext(TestSystemInitializer.getTestContext());
+        testGroupMembers.setField("GroupName", TEST_GROUP);
+        testGroupMembers.setField("ExpUid", TEST_UID);
+
+        if (!testGroupMembers.find()) {
+            testGroupMembers.add();
+        }
+
+        /* Now the test user is in the test group */
+        super.setUp();
+    }
+
+    /**
+     * Makes sure that all objects are deleted properly.  Notice that everything
+     * is removed in reverse order to allow for referential integrity.
+     */
+    protected void tearDown()
+            throws java.lang.Exception {
+        //remove all group members
+        try {
+            GroupMembers testGroupMembers = new GroupMembers(
+                    SecuredDBObject.SYSTEM_ACCOUNT);
+            testGroupMembers.setDataContext(TestSystemInitializer.getTestContext());
+            testGroupMembers.setField("GroupName", TEST_GROUP);
+            testGroupMembers.setField("ExpUid", TEST_UID);
+            ArrayList al = testGroupMembers.searchAndRetrieveList();
+
+            for (Iterator i = al.iterator(); i.hasNext();) {
+                GroupMembers oneMember = (GroupMembers) i.next();
+                oneMember.delete();
+            }
+        } catch (DBException dbe) {
+            dbe.printStackTrace();
+            System.out.println("Error Deleting Test Group Members: " +
+                    dbe.getMessage());
+        }
+
+        //Remove all security entries for test group
+        try {
+            DBObjSecurity oneSec = null;
+            DBObjSecurity secList = new DBObjSecurity();
+            secList.setDataContext(TestSystemInitializer.getTestContext());
+            secList.setField("GroupName", TEST_GROUP);
+
+            for (Iterator e1 = secList.searchAndRetrieveList().iterator();
+                 e1.hasNext();) {
+                oneSec = (DBObjSecurity) e1.next();
+                oneSec.delete();
+            }
+        } catch (DBException dbe) {
+            dbe.printStackTrace();
+            System.out.println("DBObject Security Entries: " +
+                    dbe.getMessage());
+        }
+
+        //Remove the user group.
+        try {
+            UserGroup testGroup = new UserGroup();
+            testGroup.setDataContext(TestSystemInitializer.getTestContext());
+            testGroup.setField("GroupName", TEST_GROUP);
+
+            if (testGroup.find()) {
+                testGroup.delete();
+            }
+        } catch (DBException dbe) {
+            dbe.printStackTrace();
+            System.out.println("Error Deleting Test Group: " +
+                    dbe.getMessage());
+        }
+
+        //Remove the user himself
+        try {
+            User testUser = new User();
+            testUser.setDataContext(TestSystemInitializer.getTestContext());
+            testUser.setLoginName(TEST_LOGIN);
+
+            if (testUser.find()) {
+                testUser.delete();
+            }
+        } catch (DBException dbe) {
+            dbe.printStackTrace();
+            System.out.println("Error Deleting Test User: " +
+                    dbe.getMessage());
+        }
+
+        super.tearDown();
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests/MimeTypesTests.java
@@ -0,0 +1,172 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.dbobj.tests;
+
+import com.jcorporate.expresso.core.db.DBException;
+import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
+import com.jcorporate.expresso.services.dbobj.MimeTypes;
+import com.jcorporate.expresso.services.test.ControllerTestSuite;
+import com.jcorporate.expresso.services.test.ExpressoTestCase;
+import com.jcorporate.expresso.services.test.TestSystemInitializer;
+
+import javax.activation.MimetypesFileTypeMap;
+
+
+/**
+ * This class currently just makes sure that the MimeTypes table actually got
+ * populated with all the correct values.
+ * @author Michael Rimov
+ * @version $Revision: 1.1 $ $Date: 2004/11/12 16:36:35 $
+ */
+public class MimeTypesTests
+        extends ExpressoTestCase {
+    public MimeTypesTests(String testName)
+            throws Exception {
+        super(testName);
+    }
+
+    public static void main(String[] args)
+            throws Exception {
+        junit.textui.TestRunner.run(suite());
+    }
+
+    public static junit.framework.Test suite()
+            throws Exception {
+        ControllerTestSuite cts = new ControllerTestSuite();
+        cts.addTestSuite(MimeTypesTests.class);
+        cts.addReadOnlySchemaDependency("com.jcorporate.expresso.core.ExpressoSchema");
+
+        return cts;
+    }
+
+    /**
+     * Checks to make sure that the appropriate number of MIMETYPE entries were
+     * created during database setup
+     */
+    public void testPopulatedTables() {
+        try {
+            MimeTypes mt = new MimeTypes(SecuredDBObject.SYSTEM_ACCOUNT);
+            mt.setDataContext(TestSystemInitializer.getTestContext());
+            int number = mt.count();
+            assertTrue("Should have " + mt.getExpectedDefaultPopulation() + " entries in the MIMETYPES table.  Got:" + number + " instead",
+                    number == mt.getExpectedDefaultPopulation());
+        } catch (DBException dbe) {
+            super.getLog().error("Unable to execute count on MIMETYPES Table",
+                    dbe);
+            fail("Unable to count mime type entries: " + dbe.getDBMessage());
+        }
+    }
+
+    /**
+     * This is a sanity check.  It makes sure that manually adding thigns to
+     * the JAF MimeTypes map works properly.
+     */
+    public void testJAFFileMapper() {
+        MimetypesFileTypeMap mftm = new MimetypesFileTypeMap();
+        mftm.addMimeTypes("application/msword doc DOC rtf RTF");
+        mftm.addMimeTypes("audio/mpeg3 mp3");
+        String contentType = mftm.getContentType("test.doc");
+        assertTrue("Must have appropriate content type", "application/msword".equals(contentType));
+        contentType = mftm.getContentType("test.mp3");
+        assertTrue("Must have appropriate content type", "audio/mpeg3".equals(contentType));
+
+    }
+
+    /**
+     * Checks to make sure that the javax.activation integration stuff is
+     * working properly
+     */
+    public void testFileMapper() {
+        MimetypesFileTypeMap m = MimeTypes.getFileMap(TestSystemInitializer.getTestContext());
+        assertTrue("Must receive a null MimetypesFileTypeMap", m != null);
+
+        String content = m.getContentType("test.mp3");
+        assertTrue("Content type must be: audio/mpeg3.  Got: " + content
+                + " instead.", "audio/mpeg3".equals(content));
+
+        content = m.getContentType("test.pdf");
+        assertTrue("Content type must be: application/pdf.  Got: " + content
+                + " instead.", "application/pdf".equals(content));
+
+    }
+
+    /**
+     * Checks to make sure that the File to mimetype mapping functionality
+     * is working properly
+     */
+    public void testFactoryMethod() {
+        try {
+            MimeTypes mt = MimeTypes.getMimeType("test.pdf", TestSystemInitializer.getTestContext());
+            mt = MimeTypes.getMimeType("test.XLS", TestSystemInitializer.getTestContext());
+            String content = mt.getField(MimeTypes.FLD_MIMETYPE);
+            assertTrue("Content type must be: application/vnd.ms-excel.  Got: " + content
+                    + " instead.", "application/vnd.ms-excel".equals(content));
+        } catch (DBException ex) {
+            ex.printStackTrace();
+            fail("Error constructing mimetypes object: " + ex.getMessage());
+        }
+
+    }
+}
\ No newline at end of file
--- /dev/null
+++ expresso-web/WEB-INF/test-src/com/jcorporate/expresso/services/dbobj/tests/MediaTest.java
@@ -0,0 +1,116 @@
+/* ====================================================================
+ * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
+ *
+ * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by Jcorporate Ltd.
+ *        (http://www.jcorporate.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. "Jcorporate" and product names such as "Expresso" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written permission,
+ *    please contact info at jcorporate.com.
+ *
+ * 5. Products derived from this software may not be called "Expresso",
+ *    or other Jcorporate product names; nor may "Expresso" or other
+ *    Jcorporate product names appear in their name, without prior
+ *    written permission of Jcorporate Ltd.
+ *
+ * 6. No product derived from this software may compete in the same
+ *    market space, i.e. framework, without prior written permission
+ *    of Jcorporate Ltd. For written permission, please contact
+ *    partners at jcorporate.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jcorporate Ltd. Contributions back
+ * to the project(s) are encouraged when you make modifications.
+ * Please send them to support at jcorporate.com. For more information
+ * on Jcorporate Ltd. and its products, please see
+ * <http://www.jcorporate.com/>.
+ *
+ * Portions of this software are based upon other open source
+ * products and are subject to their respective licenses.
+ */
+
+package com.jcorporate.expresso.services.dbobj.tests;
+
+import com.jcorporate.expresso.core.db.DBConnection;
+import com.jcorporate.expresso.core.db.DBException;
+
+
+/**
+ *
+ * A basic DBObject used to verify the functions