/* * Copyright 2008 Glencoe Software, Inc. All rights reserved. * Use is subject to license terms supplied in LICENSE.txt */ package ome.services.delete; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import ome.api.IDelete; import ome.api.local.LocalAdmin; import ome.api.local.LocalQuery; import ome.api.local.LocalUpdate; import ome.conditions.ApiUsageException; import ome.conditions.SecurityViolation; import ome.model.IObject; import ome.model.containers.Dataset; import ome.model.core.Image; import ome.model.core.Pixels; import ome.model.core.PlaneInfo; import ome.model.display.RenderingDef; import ome.model.display.Thumbnail; import ome.model.meta.Experimenter; import ome.model.meta.ExperimenterGroup; import ome.security.AdminAction; import ome.security.SecuritySystem; import ome.system.EventContext; import ome.system.Roles; import ome.testing.ObjectFactory; import ome.tools.hibernate.HibernateUtils; import ome.tools.hibernate.SessionFactory; import ome.util.CBlock; import org.hibernate.Query; import org.hibernate.Session; import org.jmock.Mock; import org.jmock.MockObjectTestCase; import org.jmock.core.Constraint; import org.jmock.core.Invocation; import org.jmock.core.Stub; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @Test public class DeleteUnitTest extends MockObjectTestCase { DeleteBean bean; IDelete service; Image i; Mock am, qm, um, ecm, sm, hm, xm; LocalAdmin a; LocalQuery q; LocalUpdate u; EventContext ec; SecuritySystem s; Session hibernate; Query query; @Override @BeforeClass protected void setUp() throws Exception { super.setUp(); am = mock(LocalAdmin.class); a = (LocalAdmin) am.proxy(); hm = mock(Session.class); hibernate = (Session) hm.proxy(); xm = mock(Query.class); query = (Query) xm.proxy(); hm.expects(atLeastOnce()).method("createQuery").will(returnValue(query)); xm.expects(atLeastOnce()).method("executeUpdate").will(returnValue(0)); Mock sfMock = mock(org.hibernate.SessionFactory.class); sfMock.expects(once()).method("getAllClassMetadata").will( returnValue(new HashMap<String, Object>())); org.hibernate.SessionFactory sf = (org.hibernate.SessionFactory) sfMock.proxy(); bean = new DeleteBean(a, new SessionFactory(sf, null){ @Override public Session getSession() { return hibernate; } }); service = bean; qm = mock(LocalQuery.class); q = (LocalQuery) qm.proxy(); bean.setQueryService(q); um = mock(LocalUpdate.class); u = (LocalUpdate) um.proxy(); bean.setUpdateService(u); sm = mock(SecuritySystem.class); s = (SecuritySystem) sm.proxy(); sm.expects(atLeastOnce()).method("getSecurityRoles").will( returnValue(new Roles())); bean.setSecuritySystem(s); ecm = mock(EventContext.class); ec = (EventContext) ecm.proxy(); } @Test(expectedExceptions = SecurityViolation.class) public void testImageNotOwnedByUser() throws Exception { setReturnedImage(1L, 1L); setCurrentEventContext("user", 100L, false); setConstrainingObjects(Arrays.<Dataset> asList(), false); bean.deleteImage(4, true); } @Test public void testImageNotOwnedByPI() throws Exception { setReturnedImage(1L, 1L); setCurrentEventContext("pi", 50L, false, 1L); setConstrainingObjects(Arrays.<Dataset> asList(), false); setDeleteObjects(i); bean.deleteImage(4, true); } @Test public void testImageNotOwnedByRoot() throws Exception { setReturnedImage(1L, 1L); setCurrentEventContext("root", 0L, true, 0L); setConstrainingObjects(Arrays.<Dataset> asList(), false); setDeleteObjects(i); bean.deleteImage(4, true); } /* * Annotations are currently not restrictive * * @Test(expectedExceptions = ApiUsageException.class) public void * testImageHasAnnotations() throws Exception { * * setReturnedImage(100L, 100L); setCurrentEventContext("user", 100L); * setConstrainingObjects(Arrays.<Dataset> asList(), false); * bean.deleteImage(4, false); } */ @Test(expectedExceptions = ApiUsageException.class) public void testImageInOtherDatasets() throws Exception { setReturnedImage(100L, 100L); setCurrentEventContext("user", 100L, false); setConstrainingObjects(Arrays.<Dataset> asList(new Dataset()), false); bean.deleteImage(4, false); } @Test(expectedExceptions = ApiUsageException.class) public void testImageInOwnDatasetsNoForce() throws Exception { setReturnedImage(100L, 100L); setCurrentEventContext("user", 100L, false); setConstrainingObjects(Arrays.<Dataset> asList(new Dataset()), false); bean.deleteImage(4, false); } @Test public void testImageInOwnDatasetsForce() throws Exception { setReturnedImage(100L, 100L); setCurrentEventContext("user", 100L, false); setConstrainingObjects(Arrays.<Dataset> asList(), true); setDeleteObjects(i); bean.deleteImage(4, true); } @Test public void testAllMetadataIsGone() throws Exception { // Setup graph Pixels p = ObjectFactory.createPixelGraph(null); i = new Image(); i.addPixels(p); // Locate deletes List<IObject> deletes = new ArrayList<IObject>(); deletes.add(i); deletes.add(p); deletes.addAll(p.linkedOriginalFileList()); deletes.addAll(p.collectPlaneInfo((CBlock<PlaneInfo>) null)); deletes.addAll(p.collectSettings((CBlock<RenderingDef>) null)); deletes.addAll(p.collectThumbnails((CBlock<Thumbnail>) null)); } private void setDeleteObjects(IObject... objects) { qm.expects(once()).method("execute"); // Clearing session for (final IObject o : objects) { um.expects(once()).method("deleteObject").with(new Constraint() { public boolean eval(Object arg0) { if (arg0 instanceof IObject) { IObject obj = (IObject) arg0; return HibernateUtils.idEqual(o, obj); } return false; } public StringBuffer describeTo(StringBuffer arg0) { return arg0.append("has id " + o.getId()); } }); } } private void setReturnedImage(long owner, long group) { i = new Image(-1L, true); i.getDetails().setOwner(new Experimenter(owner, false)); i.getDetails().setGroup(new ExperimenterGroup(group, false)); // The findByQuery is now run within an AdminAction hm.expects(atLeastOnce()).method("clear"); qm.expects(atLeastOnce()).method("get").will(returnValue(i)); xm.expects(atLeastOnce()).method("setParameter"); sm.expects(atLeastOnce()).method("runAsAdmin").will(new Stub() { public Object invoke(Invocation arg0) throws Throwable { AdminAction aa = (AdminAction) arg0.parameterValues.get(0); aa.runAsAdmin(); return null; } public StringBuffer describeTo(StringBuffer arg0) { return arg0.append(" calls runAsAdmin"); } }); // delete settings & channels qm.expects(atLeastOnce()).method("projection").will(returnValue(new ArrayList())); } private void setCurrentEventContext(String name, long user, boolean admin, Long... leaderof) { sm.expects(atLeastOnce()).method("getEventContext").will(returnValue(ec)); ecm.expects(atLeastOnce()).method("getCurrentUserName").will( returnValue(name)); ecm.expects(atLeastOnce()).method("getCurrentUserId").will( returnValue(user)); ecm.expects(atLeastOnce()).method("isCurrentUserAdmin").will( returnValue(admin)); ecm.expects(atLeastOnce()).method("getLeaderOfGroupsList").will( returnValue(Arrays.asList(leaderof))); } private void setConstrainingObjects(final List<Dataset> datasets, boolean force) { sm.expects(once()).method("runAsAdmin").will(new Stub() { public Object invoke(Invocation arg0) throws Throwable { QueryConstraints qc = (QueryConstraints) arg0.parameterValues .get(0); qc.getResults().addAll(datasets); return null; } public StringBuffer describeTo(StringBuffer arg0) { return arg0.append("fill result list"); } }); // force is currently not used but determines which query will be passed // in } }