/* * Copyright 2005 Konstantin Pribluda ( J-Tec-Team.de ) * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. * See the License for the specific language governing permissions * and limitations under the License. */ package de.jtec.user.hibernate; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import org.hibernate.collection.PersistentBag; import org.hibernate.collection.PersistentList; import org.hibernate.collection.PersistentMap; import org.hibernate.collection.PersistentSet; import org.hibernate.collection.PersistentSortedMap; import org.hibernate.collection.PersistentSortedSet; import org.hibernate.proxy.HibernateProxy; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.alias.ClassMapper; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.javabean.JavaBeanConverter; import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.converters.reflection.ReflectionConverter; import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.mapper.Mapper; import com.thoughtworks.xstream.mapper.MapperWrapper; import de.jtec.user.CircularDependencyException; import de.jtec.user.DuplicateEntityException; import de.jtec.user.EntityException; import de.jtec.user.Group; import de.jtec.user.User; /** * test capabilities of hibernate user manager * * @author konstantin * @version $Revision: 101 $ */ public class HibernateUserManagerTest extends AbstractTestBase { HibernateUserManager _userManager; /** * Constructor for the HibernateUserManagerTest object * * @param name Description of Parameter * @exception Exception Description of Exception */ public HibernateUserManagerTest(String name) throws Exception { super(name); } /** * The JUnit setup method * * @exception Exception Description of Exception */ public void setUp() throws Exception { super.setUp(); _session = _sessionFactory.openSession(); _userManager = new HibernateUserManager(_session); } /** * test user creation capability * * @exception Exception Description of Exception */ public void testUserCreation() throws Exception { // check that we can create user User user = _userManager.createUser("foo"); assertNotNull(user); assertEquals("foo", user.getName()); // and that it is in database restartSession(); assertTrue(!_session.createQuery("from de.jtec.user.hibernate.UserImpl as user where user.name='foo'").list().isEmpty()); } /** * test group creation capability * * @exception Exception Description of Exception */ public void testGroupCreation() throws Exception { // check that we can create user Group group = _userManager.createGroup("foo"); assertNotNull(group); assertEquals("foo", group.getName()); // and that it is in database restartSession(); assertTrue(!_session.createQuery("from de.jtec.user.hibernate.GroupImpl as gr where gr.name='foo'").list().isEmpty()); } /** * test that no duplicate entity is allowed to exist * * @exception Exception Description of Exception */ public void testDuplicatesAreNotAllowed() throws Exception { _userManager.createGroup("foo"); _userManager.createUser("bar"); refreshUserManager(); try { _userManager.createGroup("foo"); fail("allowed creation of group with taken name"); } catch (DuplicateEntityException ex) { } try { _userManager.createGroup("bar"); fail("allowed creation of group with taken name"); } catch (DuplicateEntityException ex) { } try { _userManager.createUser("foo"); fail("allowed creation of user with taken name"); } catch (DuplicateEntityException ex) { } try { _userManager.createUser("bar"); fail("allowed creation of user with taken name"); } catch (DuplicateEntityException ex) { } } /** * test user and group listing capability * * @exception Exception Description of Exception */ public void testThatUserAndGroupListingWorks() throws Exception { _userManager.createGroup("foo"); _userManager.createUser("bar"); _userManager.createGroup("baz"); _userManager.createUser("bang"); refreshUserManager(); assertEquals(2, _userManager.getUsers().size()); assertEquals(2, _userManager.getGroups().size()); Iterator iter = _userManager.getUsers().iterator(); assertEquals("bang", ((User) iter.next()).getName()); assertEquals("bar", ((User) iter.next()).getName()); iter = _userManager.getGroups().iterator(); assertEquals("baz", ((Group) iter.next()).getName()); assertEquals("foo", ((Group) iter.next()).getName()); } /** * test that user is found properly * * @exception Exception Description of Exception */ public void testUserFindingWorks() throws Exception { _userManager.createUser("foo"); _userManager.createUser("bar"); refreshUserManager(); User user = _userManager.getUser("foo"); assertNotNull(user); assertEquals("foo", user.getName()); user = _userManager.getUser("bar"); assertNotNull(user); assertEquals("bar", user.getName()); assertNull(_userManager.getGroup("foo")); assertNull(_userManager.getGroup("bar")); } /** * test that group is found properly * * @exception Exception Description of Exception */ public void testGroupFindingWorks() throws Exception { _userManager.createGroup("foo"); _userManager.createGroup("bar"); refreshUserManager(); Group group = _userManager.getGroup("foo"); assertNotNull(group); assertEquals("foo", group.getName()); group = _userManager.getGroup("bar"); assertNotNull(group); assertEquals("bar", group.getName()); assertNull(_userManager.getUser("foo")); assertNull(_userManager.getUser("bar")); } /** * test that password hashing returns the same hash * * @exception Exception Description of Exception */ public void testPasswordHashing() throws Exception { assertEquals(_userManager.hashPassword("blam"), _userManager.hashPassword("blam")); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testUserPasswordSetting() throws Exception { UserImpl user = (UserImpl) _userManager.createUser("foo"); _userManager.setPassword(user, "bar"); assertEquals(_userManager.hashPassword("bar"), user.getPassword()); refreshUserManager(); user = (UserImpl) _userManager.getUser("foo"); assertEquals(_userManager.hashPassword("bar"), user.getPassword()); } /** * test that user is authenticated properly * * @exception Exception Description of Exception */ public void testUserAuthentication() throws Exception { User user = _userManager.createUser("foo"); _userManager.setPassword(user, "bar"); refreshUserManager(); assertTrue(_userManager.authenticate("foo", "bar")); assertFalse(_userManager.authenticate("foo", "blurge")); assertFalse(_userManager.authenticate("blam", "glarch")); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testPropertyManagement() throws Exception { User user = _userManager.createUser("foo"); refreshUserManager(); user = _userManager.getUser("foo"); // properties shall be empty assertTrue(_userManager.listProperties(user).isEmpty()); _userManager.setProperty(user, "boolean", Boolean.TRUE); Date date = new Date(); _userManager.setProperty(user, "date", date); _userManager.setProperty(user, "double", new Double(239.239)); _userManager.setProperty(user, "integer", new Integer(239)); _userManager.setProperty(user, "long", new Long(932)); _userManager.setProperty(user, "string", "foo bar baz bang"); try { _userManager.setProperty(user, "bogus", new ArrayList()); fail("was not bombed on illegal property type"); } catch (EntityException ex) { assertEquals("property type not supported: java.util.ArrayList", ex.getMessage()); } refreshUserManager(); user = _userManager.getUser("foo"); assertTrue(_userManager.listProperties(user).contains("boolean")); assertTrue(_userManager.listProperties(user).contains("date")); assertTrue(_userManager.listProperties(user).contains("double")); assertTrue(_userManager.listProperties(user).contains("integer")); assertTrue(_userManager.listProperties(user).contains("boolean")); assertTrue(_userManager.listProperties(user).contains("string")); assertEquals(Boolean.TRUE, _userManager.getProperty(user, "boolean")); assertEquals(date, _userManager.getProperty(user, "date")); assertEquals(new Double(239.239), _userManager.getProperty(user, "double")); assertEquals(new Integer(239), _userManager.getProperty(user, "integer")); assertEquals(new Long(932), _userManager.getProperty(user, "long")); assertEquals("foo bar baz bang", _userManager.getProperty(user, "string")); assertNull(_userManager.getProperty(user, "blum")); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testBeanMarshalling() throws Exception { User user = _userManager.createUser("foo"); refreshUserManager(); user = _userManager.getUser("foo"); BeanToMarshall btm = new BeanToMarshall(); btm.setBooleanValue(Boolean.FALSE); btm.setPrimitiveBoolean(true); btm.setByteValue(new Byte((byte) 33)); btm.setPrimitiveByte((byte) -34); btm.setCharacterValue(new Character('a')); btm.setPrimitiveChar('n'); btm.setDateValue(new Date()); btm.setDoubleValue(new Double(239.239)); btm.setPrimitiveDouble(533.26); btm.setFloatValue(new Float(322.23345)); btm.setPrimitiveFloat((float) 33423.22332); btm.setIntegerValue(new Integer(239)); btm.setIntValue(22232323); btm.setLongValue(new Long(932)); btm.setPrimitiveLong(224333L); btm.setShortValue(new Short((short) 233)); btm.setPrimitiveShort((short) 4554); btm.setStringValue("bla bla alb"); btm.setNotSupportedList(new ArrayList()); btm.setPackageString("blam"); btm.setNullString(null); _userManager.saveBean(user, "just bean", btm); refreshUserManager(); user = _userManager.getUser("foo"); // class name property shall be set assertEquals("de.jtec.user.hibernate.BeanToMarshall", _userManager.getProperty(user, "just bean|class")); // load into bean by key BeanToMarshall loadedBean = (BeanToMarshall) _userManager.loadBean(user, "just bean", BeanToMarshall.class); // ...and by wrong key BeanToMarshall emptyLoadedBean = (BeanToMarshall) _userManager.loadBean(user, "blurge", BeanToMarshall.class); assertNotNull(emptyLoadedBean); // test that bean is instantiated and load by property name BeanToMarshall loadByKey = (BeanToMarshall) _userManager.loadBean(user, "just bean"); assertNotNull(loadByKey); // test that loading by invalid key returns null assertNull(_userManager.loadBean(user, "glee")); assertEquals(btm.getBooleanValue(), loadedBean.getBooleanValue()); assertEquals(btm.getPrimitiveBoolean(), loadedBean.getPrimitiveBoolean()); assertEquals(btm.getByteValue(), loadedBean.getByteValue()); assertEquals(btm.getPrimitiveByte(), loadedBean.getPrimitiveByte()); assertEquals(btm.getCharacterValue(), loadedBean.getCharacterValue()); assertEquals(btm.getPrimitiveChar(), loadedBean.getPrimitiveChar()); assertEquals(btm.getDateValue(), loadedBean.getDateValue()); // those tests are disabled due to rounding problems //assertEquals(btm.getDoubleValue(), loadedBean.getDoubleValue()); //assertEquals("", btm.getPrimitiveDouble(), loadedBean.getPrimitiveDouble(), 0.01); //assertEquals(btm.getFloatValue().floatValue(), loadedBean.getFloatValue().floatValue(), 0.01); //assertEquals("", btm.getPrimitiveFloat(), loadedBean.getPrimitiveFloat(), 0.01); assertEquals(btm.getIntegerValue(), loadedBean.getIntegerValue()); assertEquals(btm.getIntValue(), loadedBean.getIntValue()); assertEquals(btm.getLongValue(), loadedBean.getLongValue()); assertEquals(btm.getPrimitiveLong(), loadedBean.getPrimitiveLong()); assertEquals(btm.getShortValue(), loadedBean.getShortValue()); assertEquals(btm.getPrimitiveShort(), loadedBean.getPrimitiveShort()); assertEquals(btm.getStringValue(), loadedBean.getStringValue()); assertNull(loadedBean.getNotSupportedList()); assertNull(loadedBean.getNullString()); assertNull(loadedBean.getPackageString()); } /** * test user and group membership management ( adding and removal ) * * @exception Exception Description of Exception */ public void testMembershipManagement() throws Exception { User foo = _userManager.createUser("foo"); User bar = _userManager.createUser("bar"); Group baz = _userManager.createGroup("baz"); Group bang = _userManager.createGroup("bang"); _userManager.addMember(baz, foo); _userManager.addMember(baz, bar); _userManager.addMember(bang, foo); _userManager.addMember(bang, baz); // check that no adding to itself is possible try { _userManager.addMember(bang, bang); fail("allowed addition to itself"); } catch (EntityException ex) { } // check that no double adding is allowed try { _userManager.addMember(baz, foo); fail("did not bombed double addition"); } catch (EntityException ex) { } // check that circular dependency is diasllowed try { _userManager.addMember(baz, bang); fail("allowed circular dependency"); } catch (CircularDependencyException ex) { } refreshUserManager(); foo = _userManager.getUser("foo"); bar = _userManager.getUser("bar"); baz = _userManager.getGroup("baz"); bang = _userManager.getGroup("bang"); assertTrue(foo.getGroups().contains(baz)); assertTrue(foo.getGroups().contains(bang)); assertEquals(2, foo.getGroups().size()); assertTrue(bar.getGroups().contains(baz)); assertEquals(1, bar.getGroups().size()); assertEquals(2, baz.getMembers().size()); assertTrue(baz.getMembers().contains(foo)); assertTrue(baz.getMembers().contains(bar)); assertEquals(1, baz.getGroups().size()); assertTrue(baz.getGroups().contains(bang)); assertEquals(2, bang.getMembers().size()); assertTrue(bang.getMembers().contains(foo)); assertTrue(bang.getMembers().contains(baz)); assertTrue(bang.getGroups().isEmpty()); // shall do nothing _userManager.removeMember(bang, bar); _userManager.removeMember(bang, foo); _userManager.removeMember(bang, baz); refreshUserManager(); foo = _userManager.getUser("foo"); baz = _userManager.getGroup("baz"); bang = _userManager.getGroup("bang"); assertTrue(bang.getMembers().isEmpty()); assertTrue(bang.getGroups().isEmpty()); assertFalse(foo.getGroups().contains(bang)); assertTrue(foo.getGroups().contains(baz)); assertEquals(1, foo.getGroups().size()); assertFalse(baz.getGroups().contains(bang)); } /** * test that entities can be removed and that entity removal also zaps all * group-member relations * * @exception Exception Description of Exception */ public void testEntityRemoval() throws Exception { User foo = _userManager.createUser("foo"); User bar = _userManager.createUser("bar"); Group baz = _userManager.createGroup("baz"); Group bang = _userManager.createGroup("bang"); _userManager.addMember(baz, foo); _userManager.addMember(baz, bar); _userManager.addMember(bang, foo); _userManager.addMember(bang, baz); refreshUserManager(); baz = _userManager.getGroup("baz"); _userManager.removeEntity(baz); refreshUserManager(); assertNull(_userManager.getGroup("baz")); bar = _userManager.getUser("bar"); assertNotNull(bar); bang = _userManager.getGroup("bang"); assertNotNull(bang); assertEquals(1, bang.getMembers().size()); assertTrue(bar.getGroups().isEmpty()); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testParentship() throws Exception { User foo = _userManager.createUser("foo"); User bar = _userManager.createUser("bar"); User blurge = _userManager.createUser("blurge"); Group baz = _userManager.createGroup("baz"); Group bang = _userManager.createGroup("bang"); _userManager.addMember(baz, foo); _userManager.addMember(baz, bar); _userManager.addMember(bang, bar); _userManager.addMember(bang, baz); _userManager.addMember(bang, blurge); refreshUserManager(); foo = _userManager.getUser("foo"); bar = _userManager.getUser("bar"); blurge = _userManager.getUser("blurge"); baz = _userManager.getGroup("baz"); bang = _userManager.getGroup("bang"); assertTrue(_userManager.isMember(foo, baz)); assertTrue(_userManager.isMember("foo", "baz")); assertFalse(_userManager.isMember(foo, bang)); assertTrue(_userManager.isMember(bar, baz)); assertTrue(_userManager.isMember(bar, bang)); assertTrue(_userManager.isMember(blurge, baz)); assertTrue(_userManager.isMember(blurge, bang)); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testThatNullUserIsNotMemberAnywhere() throws Exception { Group group = _userManager.createGroup("foo"); refreshUserManager(); group = _userManager.getGroup("foo"); assertFalse(_userManager.isMember(null, "foo")); assertFalse(_userManager.isMember(null, group)); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testThatUserIsNotMemberOfUnknownGroup() throws Exception { _userManager.createUser("bar"); refreshUserManager(); assertFalse(_userManager.isMember("bar", null)); } /** * A unit test for JUnit * * @exception Exception Description of Exception */ public void testThatPropertySetToNullIsRemoved() throws Exception { Group group = _userManager.createGroup("foo"); refreshUserManager(); group = _userManager.getGroup("foo"); _userManager.setProperty(group, "blam", "foo bar"); refreshUserManager(); group = _userManager.getGroup("foo"); _userManager.setProperty(group, "blam", null); refreshUserManager(); group = _userManager.getGroup("foo"); assertEquals(null, _userManager.getProperty(group, "blam")); } /** * test that authentication without proper values does not produce NPE and * works properly * * @exception Exception Description of Exception */ public void testThatAuthenticationWithoutProperValuesWork() throws Exception { User user = _userManager.createUser("foo"); assertFalse(_userManager.authenticate(null, null)); assertFalse(_userManager.authenticate("foo", null)); assertFalse(_userManager.authenticate(null, "bar")); _userManager.setPassword(user, "bar"); assertFalse(_userManager.authenticate("foo", null)); assertFalse(_userManager.authenticate(null, "bar")); } /** * restart session and recreate user manager * * @exception Exception Description of Exception */ void refreshUserManager() throws Exception { restartSession(); _userManager = new HibernateUserManager(_session); } /** * just a test to see how xstream can be used to * exorcise hibernate out of POJO (GOOMPJ) * */ public void testXStreamSerialisation() throws Exception { User foo = _userManager.createUser("foo"); BeanToMarshall btm = new BeanToMarshall(); _userManager.saveBean(foo,"bar",btm); refreshUserManager(); foo = _userManager.getUser("foo"); System.err.println("class:" + foo.getClass()); XStream xstream = new XStream() { protected MapperWrapper wrapMapper(MapperWrapper next) { return new HibernateMapper(next); } }; xstream.registerConverter(new HibernateProxyConverter(xstream.getMapper(),new PureJavaReflectionProvider()),XStream.PRIORITY_VERY_HIGH); String xml = xstream.toXML(foo); System.err.println("******************** serialized *********"); System.err.println(xml); System.err .println("******************************************"); } /** * sanitize hibernate collections, and cure class name * @author k.pribluda * */ class HibernateMapper extends MapperWrapper { Map collectionMap = new HashMap(); public HibernateMapper(ClassMapper arg0) { super(arg0); init(); } public void init() { collectionMap.put(PersistentBag.class,ArrayList.class); collectionMap.put(PersistentList.class,ArrayList.class); collectionMap.put(PersistentMap.class,HashMap.class); collectionMap.put(PersistentSet.class,Set.class); collectionMap.put(PersistentSortedMap.class,SortedMap.class); collectionMap.put(PersistentSortedSet.class,SortedSet.class); } public HibernateMapper(Mapper arg0) { super(arg0); init(); } public Class defaultImplementationOf(Class clazz) { System.err.println("checking class:" + clazz); if(collectionMap.containsKey(clazz)) { System.err.println("** substituting " + clazz + " with " + collectionMap.get(clazz)); return (Class) collectionMap.get(clazz); } return super.defaultImplementationOf(clazz); } public String serializedClass(Class clazz) { // chekc whether we are hibernate proxy and substitute real name for(int i = 0; i < clazz.getInterfaces().length;i++) { if(HibernateProxy.class.equals(clazz.getInterfaces()[i])){ System.err.println("resolving to class name:" + clazz.getSuperclass().getName()); return clazz.getSuperclass().getName(); } } if(collectionMap.containsKey(clazz)) { System.err.println("** substituting " + clazz + " with " + collectionMap.get(clazz)); return ((Class) collectionMap.get(clazz)).getName(); } return super.serializedClass(clazz); } } class HibernateProxyConverter extends ReflectionConverter { public HibernateProxyConverter(Mapper arg0, ReflectionProvider arg1) { super(arg0, arg1); } /** * be responsible for hibernate proxy */ public boolean canConvert(Class clazz) { System.err.println("converter says can convert " + clazz + ":"+ HibernateProxy.class.isAssignableFrom(clazz)); return HibernateProxy.class.isAssignableFrom(clazz); } public void marshal(Object arg0, HierarchicalStreamWriter arg1, MarshallingContext arg2) { System.err.println("converter marshalls: " + ((HibernateProxy)arg0).getHibernateLazyInitializer().getImplementation()); super.marshal(((HibernateProxy)arg0).getHibernateLazyInitializer().getImplementation(), arg1, arg2); } } }