/* =================================================================== * AbstractSpringEnabledTest.java * * Copyright (c) 2004 Matt Magoffin. Created Sep 9, 2004 10:07:47 AM. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * =================================================================== * $Id: AbstractSpringEnabledTest.java 74 2009-05-15 04:44:37Z msqr $ * =================================================================== */ package magoffin.matt.ieat.test; import java.net.URL; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; import junit.framework.TestCase; import magoffin.matt.ieat.biz.BizContext; import magoffin.matt.ieat.biz.DomainObjectFactory; import magoffin.matt.ieat.biz.RecipeBiz; import magoffin.matt.ieat.biz.RecipeSearchBiz; import magoffin.matt.ieat.biz.RecipeSearchIndexBiz; import magoffin.matt.ieat.biz.UserBiz; import magoffin.matt.ieat.dao.BaseDao; import magoffin.matt.ieat.dao.CourseDao; import magoffin.matt.ieat.dao.DifficultyDao; import magoffin.matt.ieat.dao.EthnicityDao; import magoffin.matt.ieat.dao.IngredientDao; import magoffin.matt.ieat.dao.MealDao; import magoffin.matt.ieat.dao.PrepTimeDao; import magoffin.matt.ieat.dao.RecipeDao; import magoffin.matt.ieat.dao.UnitDao; import magoffin.matt.ieat.dao.UserDao; import magoffin.matt.ieat.domain.Base; import magoffin.matt.ieat.domain.Course; import magoffin.matt.ieat.domain.Difficulty; import magoffin.matt.ieat.domain.Ethnicity; import magoffin.matt.ieat.domain.Ingredient; import magoffin.matt.ieat.domain.PrepTime; import magoffin.matt.ieat.domain.Recipe; import magoffin.matt.ieat.domain.RecipeIngredient; import magoffin.matt.ieat.domain.RecipeStep; import magoffin.matt.ieat.domain.System; import magoffin.matt.ieat.domain.Unit; import magoffin.matt.ieat.domain.User; import magoffin.matt.xweb.util.AppContextSupport; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; /** * Base JUnit test case for Spring related test cases. * *

Code derived from Robert Newson's posts on * http://opensource.atlassian.com/confluence/spring/pages/viewpage.action?pageId=146&showComments=true#comments *

* * @author Matt Magoffin (spamsqr@msqr.us) * @version $Revision: 74 $ $Date: 2009-05-15 16:44:37 +1200 (Fri, 15 May 2009) $ */ public abstract class AbstractSpringEnabledTest extends TestCase { /** A class logger. */ protected final Logger log = Logger.getLogger(getClass()); /** The test user login. */ public static final String TEST_USER_LOGIN = "_test_"; /** The test user password. */ public static final String TEST_USER_PASS = "_foo_"; /** The default load ID. */ public static final Integer DEFAULT_LOAD_ID = new Integer(1); private static Logger LOG = Logger.getLogger(AbstractSpringEnabledTest.class); private static Map applicationContextCache = new HashMap(); private static final String[] DEFAULT_APP_CONTEXT_PATHS = { //"classpath:magoffin/matt/ieat/test/AbstractSpringEnabledTestContext.xml", "web/WEB-INF/applicationContext.xml" }; private AbstractApplicationContext context; /** * Constructor. */ public AbstractSpringEnabledTest() { super(); } /** * Construct with a name. * @param name the name */ public AbstractSpringEnabledTest(String name) { super(name); } /** * Get a test BizContext. * @return the biz context */ protected BizContext getBizContext() { AppContextSupport appContextSupport = getAppContextSupport(); return new TestBizContext(appContextSupport,getDummyUser()); } /** * Get the domain object factory. * @return the domain object factory */ protected DomainObjectFactory getDomainObjectFactory() { return (DomainObjectFactory)getContext().getBean("domainObjectFactory"); } /** * Get the application context. * @return the context */ protected ApplicationContext getContext() { assertNotNull(context); return context; } /** * Get a test property from the test resource bundle. * @param key the key * @return the property value */ protected String getTestProperty(String key) { ResourceBundle rsrc = ResourceBundle.getBundle("test.properties"); return rsrc.getString(key); } /** * Get a list of file paths to add as Spring contexts. * *

Extending test cases can override this method to provide * a different default set (or null for none).

* @return the contexts */ protected String[] getDefaultContexts() { return DEFAULT_APP_CONTEXT_PATHS; } @Override protected void setUp() throws Exception { super.setUp(); context = null; List> classHierarchy = getClassHierarchy(); for (int i = classHierarchy.size() - 1; i >= 0; i--) { Class clazz = classHierarchy.get(i); context = getApplicationContext(clazz, getClassName(clazz) + "Context.xml", context); } if ( getDefaultContexts() != null && getDefaultContexts().length > 0 ) { context = new FileSystemXmlApplicationContext(getDefaultContexts(),context); } } @Override protected void tearDown() throws Exception { closeContext(); } /** * Close the context. */ protected final void closeContext() { if (context != null) { context.close(); context = null; } } private List> getClassHierarchy() { List> result = new ArrayList>(); Class superclass = getClass(); do { result.add(superclass); } while ((superclass = superclass.getSuperclass()) != null); return result; } private String getClassName(Class clazz) { String fullClassName = clazz.getName(); String result = fullClassName .substring(fullClassName.lastIndexOf(".") + 1); return result; } private AbstractApplicationContext getApplicationContext(Class clazz, String resourceName, AbstractApplicationContext parentContext) { /*if ( clazz == AbstractSpringEnabledTest.class ) { return null; // don't load this class or any parent class }*/ log.debug("Attempting to locate " + resourceName); URL url = clazz.getResource(resourceName); if (url == null) { return parentContext; } if (!applicationContextCache.containsKey(url)) { log.info("Loading " + url); applicationContextCache.put(url, new ClassPathXmlApplicationContext(new String[] { url .toString() }, parentContext)); } return applicationContextCache.get(url); } /** * Delete a recipe. * @param r the recipe */ protected void cleanOutRecipe(Recipe r) { if ( r == null || r.getRecipeId() == null ) { return; } RecipeDao recipeDao = getRecipeDao(); try { recipeDao.delete(recipeDao.get(r.getRecipeId())); } catch ( Exception e ) { LOG.warn("Unable to clean out recipe",e); } } /** * Delete a user. * @param u the user to delete */ protected void cleanOutUser(User u) { if ( u == null || u.getUserId() == null ) { return; } UserDao userDao = getUserDao(); try { userDao.delete(userDao.get(u.getUserId())); } catch ( Exception e ) { LOG.warn("Unable to clean out user",e); } } /** * Get a dummy recipe (non-persisted). * @return recipe */ @SuppressWarnings("unchecked") protected Recipe getDummyRecipe() { DomainObjectFactory dof = getDomainObjectFactory(); Recipe r = dof.getRecipeInstance(); r.setCreatedDate(Calendar.getInstance()); r.setBase(getTestBase()); r.setCourse(getTestCourse()); r.setDifficulty(getTestDifficulty()); r.setEthnicity(getTestEthnicity()); r.setExcerpt("This is the test recipe description."); r.setName("My Test Recipe " +r.getCreatedDate().getTime() ); r.setPrepTime(getTestPrepTime()); r.setServingSize(new Integer(1)); r.setSource("iEat Test Case"); System system = dof.getSystemInstance(); system.setSystemId(getTestSystemId()); system.setValue("US"); r.setSystem(system); List units = getUnitDao().getUnits(); List ingredients = getIngredientDao().getIngredients(); for ( int i = 0; i < 3 && i < ingredients.size(); i++ ) { RecipeIngredient ri = dof.getRecipeIngredientInstance(); ri.setQuantity(1.5); ri.setIngredient((Ingredient)ingredients.get(i)); ri.setUnit((Unit)units.get(0)); r.getIngredient().add(ri); } for ( int i = 0; i < 3; i++ ) { RecipeStep step = dof.getRecipeStepInstance(); step.setValue("Dummy step " +i); r.getStep().add(step); } return r; } /** * API for test callback with dummy user. */ protected static interface TestWithDummyUser { /** * Perform the test. * @param user the dummy user to test with * @throws Exception if any error occurs */ public void test(User user) throws Exception; } /** * Run a test with a registered dummy user. * @param callback the callback test * @throws Exception if any error occurs */ protected void doTestWithRegisteredDummyUser(TestWithDummyUser callback) throws Exception { User u = null; UserBiz userBiz = getUserBiz(); try { u = getDummyUser(); u = userBiz.storeUser(u,null); callback.test(u); } finally { if ( u != null && u.getUserId() != null ) { userBiz.removeUser(u.getUserId(),null); } } } /** * API for a test with a persisted recipe. */ protected static interface TestWithRecipe { /** * Run the test. * @param recipe the persisted recipe * @param context the test context * @throws Exception if an error occurs */ public void test(Recipe recipe, BizContext context) throws Exception; } /** * Run a test with a persisted recipe. * @param callback the callback * @throws Exception if an error occurs */ protected void doTestWithRecipe(final TestWithRecipe callback) throws Exception { doTestWithRegisteredDummyUser(new TestWithDummyUser() { public void test(User user) throws Exception { Recipe r = null; RecipeBiz recipeBiz = getRecipeBiz(); BizContext bizContext = new TestBizContext(getAppContextSupport(),user); try { r = getDummyRecipe(); r = recipeBiz.storeRecipe(r,bizContext); callback.test(r,bizContext); } finally { if ( r != null && r.getRecipeId() != null ) { recipeBiz.removeRecipe(r.getRecipeId(),bizContext); } } } }); } /** * @return the AppContextSupport */ protected AppContextSupport getAppContextSupport() { AppContextInitializer init = (AppContextInitializer)getContext() .getBean("applicationInitializer",AppContextInitializer.class); return init.getAppContextSupport(); } /** * @return the RecipeDao */ protected RecipeDao getRecipeDao() { return (RecipeDao)getContext().getBean("recipeDao"); } /** * @return the MealDao */ protected MealDao getMealDao() { return (MealDao)getContext().getBean("mealDao"); } /** * @return the BaseDao */ protected BaseDao getBaseDao() { return (BaseDao)getContext().getBean("baseDao"); } /** * @return the CourseDao */ protected CourseDao getCourseDao() { return (CourseDao)getContext().getBean("courseDao"); } /** * @return the DifficultyDao */ protected DifficultyDao getDifficultyDao() { return (DifficultyDao)getContext().getBean("difficultyDao"); } /** * @return the EthnicityDao */ protected EthnicityDao getEthnicityDao() { return (EthnicityDao)getContext().getBean("ethnicityDao"); } /** * @return the IngredientDao */ protected IngredientDao getIngredientDao() { return (IngredientDao)getContext().getBean("ingredientDao"); } /** * @return the PrepTimeDao */ protected PrepTimeDao getPrepTimeDao() { return (PrepTimeDao)getContext().getBean("prepTimeDao"); } /** * @return the UnitDao */ protected UnitDao getUnitDao() { return (UnitDao)getContext().getBean("unitDao"); } /** * @return a test recipe ID */ protected Integer getTestRecipeId() { return getTestIdOrDefault("test.load.recipe.id",DEFAULT_LOAD_ID); } /** * @return a test Base ID */ protected Integer getTestBaseId() { return getTestIdOrDefault("test.load.base.id",DEFAULT_LOAD_ID); } /** * @return a test Base */ protected Base getTestBase() { return getBaseDao().getBases().get(0); } /** * @return a test Course ID */ protected Integer getTestCourseId() { return getTestIdOrDefault("test.load.course.id",DEFAULT_LOAD_ID); } /** * @return a test Difficulty */ protected Difficulty getTestDifficulty() { return getDifficultyDao().getDifficulties().get(0); } /** * @return a test Difficulty ID */ protected Integer getTestDifficultyId() { return getTestIdOrDefault("test.load.difficulty.id",DEFAULT_LOAD_ID); } /** * @return a test Ethnicity */ protected Ethnicity getTestEthnicity() { return getEthnicityDao().getEthnicities().get(0); } /** * @return a test Ehtnicity ID */ protected Integer getTestEthnicityId() { return getTestIdOrDefault("test.load.ethnicity.id",DEFAULT_LOAD_ID); } /** * @return a test PrepTime */ protected PrepTime getTestPrepTime() { return getPrepTimeDao().getPrepTimes().get(0); } /** * @return a test PrepTime ID */ protected Integer getTestPrepTimeId() { return getTestIdOrDefault("test.load.preptime.id",DEFAULT_LOAD_ID); } /** * @return a test System ID */ protected Integer getTestSystemId() { return getTestIdOrDefault("test.load.system.id",DEFAULT_LOAD_ID); } private Integer getTestIdOrDefault(String key, Integer defaultId) { try { return Integer.valueOf(getTestProperty(key)); } catch ( Exception e ) { // nothing } return defaultId; } /** * Get a dummy user. * @return the dummy user. */ protected User getDummyUser() { User u = getDomainObjectFactory().getUserInstance(); u.setAccessLevel(new Integer(1)); u.setCountry(Locale.getDefault().getCountry()); u.setCreatedDate(Calendar.getInstance()); u.setEmail("ieat.test@msqr.us"); u.setLanguage(Locale.getDefault().getLanguage()); u.setLogin(TEST_USER_LOGIN); u.setName("Test User"); u.setPassword(TEST_USER_PASS); return u; } /** * @return the UserBiz */ protected UserBiz getUserBiz() { return (UserBiz)getContext().getBean("userBiz"); } /** * @return the UserDao */ protected UserDao getUserDao() { return (UserDao)getContext().getBean("userDao"); } /** * @return a test Course */ protected Course getTestCourse() { return getCourseDao().getCourses().get(0); } /** * @return the RecipeBiz */ protected RecipeBiz getRecipeBiz() { return (RecipeBiz)getContext().getBean("recipeBiz"); } /** * @return the RecipeSearchBiz */ protected RecipeSearchBiz getRecipeSearchBiz() { return (RecipeSearchBiz)getContext().getBean("recipeSearchBiz"); } /** * @return the RecipeSearchIndexBiz */ protected RecipeSearchIndexBiz getRecipeSearchIndexBiz() { return (RecipeSearchIndexBiz)getContext().getBean("recipeSearchIndexBiz"); } }