package uk.ac.ebi.fg.myequivalents.managers;
import static com.googlecode.catchexception.CatchException.catchException;
import static com.googlecode.catchexception.CatchException.caughtException;
import static java.lang.System.out;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static uk.ac.ebi.fg.myequivalents.utils.EntityIdResolver.buildUriFromAcc;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import uk.ac.ebi.fg.myequivalents.access_control.model.User;
import uk.ac.ebi.fg.myequivalents.access_control.model.User.Role;
import uk.ac.ebi.fg.myequivalents.dao.EntityMappingDAO;
import uk.ac.ebi.fg.myequivalents.dao.RepositoryDAO;
import uk.ac.ebi.fg.myequivalents.dao.ServiceDAO;
import uk.ac.ebi.fg.myequivalents.dao.access_control.UserDao;
import uk.ac.ebi.fg.myequivalents.exceptions.SecurityException;
import uk.ac.ebi.fg.myequivalents.managers.impl.db.DbManagerFactory;
import uk.ac.ebi.fg.myequivalents.managers.interfaces.AccessControlManager;
import uk.ac.ebi.fg.myequivalents.managers.interfaces.EntityMappingManager;
import uk.ac.ebi.fg.myequivalents.managers.interfaces.EntityMappingSearchResult;
import uk.ac.ebi.fg.myequivalents.managers.interfaces.EntityMappingSearchResult.Bundle;
import uk.ac.ebi.fg.myequivalents.managers.interfaces.ManagerFactory;
import uk.ac.ebi.fg.myequivalents.model.Entity;
import uk.ac.ebi.fg.myequivalents.model.EntityMapping;
import uk.ac.ebi.fg.myequivalents.model.Repository;
import uk.ac.ebi.fg.myequivalents.model.Service;
import uk.ac.ebi.fg.myequivalents.model.ServiceCollection;
import uk.ac.ebi.fg.myequivalents.resources.Resources;
import uk.ac.ebi.fg.myequivalents.utils.EntityIdResolver;
import uk.ac.ebi.utils.test.junit.TestEntityMgrProvider;
/**
* Tests for DbEntityMappingManager.
*
* <dl><dt>date</dt><dd>Jul 16, 2012</dd></dl>
* @author Marco Brandizi
*
*/
public class EntityMappingManagerTest
{
/** Normally you cast this to {@link ManagerFactory}, here we force the specific value cause we need it and we're sure of it*/
private DbManagerFactory managerFactory = (DbManagerFactory) Resources.getInstance ().getMyEqManagerFactory ();
@Rule
public TestEntityMgrProvider emProvider = new TestEntityMgrProvider ( managerFactory.getEntityManagerFactory () );
private EntityMappingManager emMgr;
private ServiceDAO serviceDao;
private Service service1, service2, service3, service4, service5;
private ServiceCollection sc1;
private Repository repo1;
private String editorPass = "test.password";
private String editorSecret = User.generateSecret ();
private User editorUser = new User (
"test.editor", "Test Editor", "User", editorPass, "test editor notes", Role.EDITOR, editorSecret );
@Before
public void init ()
{
EntityManager em = emProvider.getEntityManager ();
// An editor is needed for writing operations.
UserDao userDao = new UserDao ( em );
EntityTransaction ts = em.getTransaction ();
ts.begin ();
userDao.storeUnauthorized ( editorUser );
ts.commit ();
serviceDao = new ServiceDAO ( em );
// This is how you should obtain a manager from a factory
emMgr = managerFactory.newEntityMappingManager ( editorUser.getEmail (), editorSecret );
service1 = new Service ( "test.testemsrv.service1", "testemsrv.someType1", "A Test Service 1", "The Description of a Test Service 1" );
service1.setUriPattern ( "http://test.testemsrv.net/service1#$id" );
sc1 = new ServiceCollection (
"test.testemsrv.serviceColl1", service1.getEntityType (), "Test Service Collection 1", "The Description of the SC 1"
);
service1.setServiceCollection ( sc1 );
repo1 = new Repository ( "test.testemsrv.repo1", "Test Repo 1", "The Description of Repo1" );
service1.setRepository ( repo1 );
service2 = new Service ( "test.testemsrv.service2", "testemsrv.someType1", "A Test Service 2", "The Description of a Test Service 2" );
service2.setUriPattern ( "http://test.testemsrv.net/service2#$id" );
service3 = new Service ( "test.testemsrv.service3", "testemsrv.someType2", "A Test Service 3", "The Description of a Test Service 3" );
service4 = new Service ( "test.testemsrv.service4", "testemsrv.someType2", "A Test Service 4", "The Description of a Test Service 4" );
service5 = new Service ( "test.testemsrv.service5", "testemsrv.someType2", "A Test Service 5", "The Description of a Test Service 5" );
ts = em.getTransaction ();
ts.begin ();
emMgr.deleteEntities (
service1.getName () + ":acc1",
service2.getName () + ":acc2",
service1.getName () + ":b1.1",
service2.getName () + ":b1.2",
service1.getName () + ":b1.3",
service1.getName () + ":b1.4",
service2.getName () + ":b2.1",
service3.getName () + ":b2.2"
);
serviceDao.delete ( service1 );
serviceDao.delete ( service2 );
serviceDao.delete ( service3 );
serviceDao.delete ( service4 );
serviceDao.delete ( service5 );
ts.commit ();
ts.begin ();
new RepositoryDAO ( emProvider.getEntityManager () ).delete ( repo1 );
ts.commit ();
assertEquals ( "Entities not deleted!", 0, emMgr.getMappings (
true, service1.getName () + ":acc1", service2.getName () + ":acc2"
).getBundles ().size ()
);
// TODO: more
ts.begin ();
serviceDao.store ( service1 );
serviceDao.store ( service2 );
serviceDao.store ( service3 );
serviceDao.store ( service4 );
serviceDao.store ( service5 );
ts.commit ();
}
@After
public void cleanUp ()
{
// An editor is needed for writing operations.
EntityManager em = emProvider.getEntityManager ();
UserDao userDao = new UserDao ( em );
EntityTransaction ts = em.getTransaction ();
ts.begin ();
userDao.deleteUnauthorized ( editorUser.getEmail () );
ts.commit ();
}
@Test
public void testBasicSearch ()
{
// b1 ( (s1, b1.1) (s2, b1.2) (s1, b1.3) (s1, b1.4)
// b2 ( (s2, b2.1) (s3, b2.2) )
emMgr.storeMappingBundle (
service1.getName () + ":b1.1", service2.getName () + ":b1.2", service1.getName () + ":b1.3" );
emMgr.storeMappings (
service1.getName () + ":b1.4", service1.getName () + ":b1.1",
service2.getName () + ":b2.1", service3.getName () + ":b2.2"
);
EntityMappingSearchResult result = emMgr.getMappings (
false, service1.getName () + ":b1.3", service3.getName () + ":b2.2"
);
out.println ( "\nResult:" );
out.println ( result );
assertEquals ( "Wrong no. of services returned!", 3, result.getServices ().size () );
{
boolean found1 = false, found2 = false, found3 = false;
for ( Service service: result.getServices () )
if ( service1.equals ( service ) ) found1 = true;
else if ( service2.equals ( service ) ) found2 = true;
else if ( service3.equals ( service ) ) found3 = true;
assertTrue ( "Service 1 not found in search results!", found1 );
assertTrue ( "Service 2 not found in search results!", found2 );
assertTrue ( "Service 3 not found in search results!", found3 );
}
Collection<Bundle> bsets = result.getBundles ();
assertEquals ( "Wrong no of bundles in search result!", 2, bsets.size () );
{
// b1 ( (s1, b1.1) (s2, b1.2) (s1, b1.3) (s1, b1.4)
// b2 ( (s2, b2.1) (s3, b2.2) )
Bundle bundle1 = null, bundle2 = null;
Entity b13 = null;
for ( Bundle bset: bsets )
for ( Entity entity: bset.getEntities () )
if ( service1.equals ( entity.getService () ) && "b1.1".equals ( entity.getAccession () ) )
bundle1 = bset;
else if ( service3.equals ( entity.getService () ) && "b2.2".equals ( entity.getAccession () ) )
bundle2 = bset;
else if ( service1.getName().equals ( entity.getServiceName () ) && "b1.3".equals ( entity.getAccession () ))
b13 = entity;
assertNotNull ( "b1.3 not found in search results!", b13 );
assertEquals ( "Bad URI returned for b13!",
"http://test.testemsrv.net/service1#b1.3", b13.getURI ()
);
assertNotNull ( "Bundle 1 not found in search result!", bundle1 );
assertNotNull ( "Bundle 2 not found in search result!", bundle2 );
assertEquals ( "Wrong size for set 1", 4, bundle1.getEntities ().size () );
assertEquals ( "Wrong size for set 2", 2, bundle2.getEntities ().size () );
assertTrue ( "b1.1 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.1" ) ) );
assertTrue ( "b1.2 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service2, "b1.2" ) ) );
assertTrue ( "b1.3 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.3" ) ) );
assertTrue ( "b1.4 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.4" ) ) );
assertTrue ( "b2.1 is not in set2!", bundle2.getEntities ().contains ( new Entity ( service2, "b2.1" ) ) );
assertTrue ( "b2.2 is not in set2!", bundle2.getEntities ().contains ( new Entity ( service3, "b2.2" ) ) );
}
Set<ServiceCollection> scs = result.getServiceCollections ();
assertEquals ( "Wrong no of repo returned by the search!", 1, scs.size () );
assertTrue ( "Repo1 not found in the search result!", scs.contains ( sc1 ) );
Set<Repository> repos = result.getRepositories ();
assertEquals ( "Wrong no of repo returned by the search!", 1, repos.size () );
assertTrue ( "Repo1 not found in the search result!", repos.contains ( repo1 ) );
out.println ( "\n\nXML Result:\n" + emMgr.getMappingsAs (
"xml", true, service1.getName () + ":b1.3", service3.getName () + ":b2.2"
));
// TODO Use XPath to test the XML
}
@Test
public void testAuthentication ()
{
emMgr = managerFactory.newEntityMappingManager ();
catchException ( emMgr ).storeMappingBundle (
service1.getName () + ":b1.1", service2.getName () + ":b1.2", service1.getName () + ":b1.3" );
assertTrue ( "Authenticated EntityMappingManager.store() didn't work!", caughtException () instanceof SecurityException );
}
@Test
public void testVisibility ()
{
AccessControlManager acMgr = managerFactory.newAccessControlManager ( editorUser.getEmail (), editorSecret );
// b1 ( (s1, b1.1) (s2, b1.2) (s1, b1.3) (s1, b1.4)
// b2 ( (s2, b2.1) (s3, b2.2) )
emMgr.storeMappingBundle (
service1.getName () + ":b1.1", service2.getName () + ":b2.1", service1.getName () + ":b1.2" );
emMgr.storeMappings (
service1.getName () + ":b1.3", service1.getName () + ":b1.1",
service2.getName () + ":b2.2", service1.getName () + ":b1.3"
);
EntityMappingSearchResult emsr = emMgr.getMappings ( true, service2.getName () + ":b2.2" );
out.println ( "\n\nStored mappings:\n" + emsr + "\n\n" );
assertTrue ( "Private entity is not created!", emsr.getBundles ().iterator().next ().getEntities ()
.contains ( new Entity ( service1, "b1.1" ) )
);
acMgr.setServicesVisibility ( "false", "null", false, service1.getName () );
acMgr.setEntitiesVisibility ( "null", "null", service1.getName () + ":b1.1" );
emMgr = managerFactory.newEntityMappingManager ();
emsr = emMgr.getMappings ( true, service2.getName () + ":b2.2" );
out.println ( "\n\nProtected mappings:\n" + emsr + "\n\n" );
assertFalse ( "Private entity is accessible!", emsr.getBundles ().iterator().next ().getEntities ()
.contains ( new Entity ( service1, "b1.1" ) )
);
/**
* The result is void when asked about a private entity, cause otherwise you would be able to investigate its
* equivalents.
*/
emsr = emMgr.getMappings ( true, service1.getName () + ":b1.1" );
out.println ( "\n\nProtected mapping (sent as parameter):\n" + emsr + "\n\n" );
assertTrue (
"Private entity is accessible (as parameter)!",
emMgr.getMappings ( true, service1.getName () + ":b1.1" ).getBundles ().isEmpty ()
);
// Test with fast calls (which are not used by managers, but we've implemented them after all...
EntityManager em = emProvider.getEntityManager ();
EntityMappingDAO emDao = new EntityMappingDAO ( em );
List<String> entStrings = emDao.findMappings ( service2.getName () + ":b2.2", false );
out.println ( "\n\nResult from fast call (!mustBePublic):\n" + entStrings );
assertTrue ( "Private entity not accessible through fast call + !mustBePublic !", entStrings.contains ( "b1.1" ) );
entStrings = emDao.findMappings ( service2.getName () + ":b2.2", true );
out.println ( "\n\nResult from fast call + mustBePublic:\n" + entStrings );
assertFalse ( "Private entity is accessible through fast call!", entStrings.contains ( "b1.1" ) );
entStrings = emDao.findMappings ( service1.getName () + ":b1.1", true );
out.println ( "\n\nResult from fast call + mustBePublic + private parameter:\n" + entStrings );
assertTrue ( "Private parameter is accessible through fast call!", entStrings.isEmpty () );
}
@Test
public void testStoreBundles ()
{
// b1 ( (s1, b1.1) (s2, b1.2) (s1, b1.3) (s1, b1.4)
// b2 ( (s2, b2.1) (s3, b2.2) )
EntityMappingSearchResult sr = new EntityMappingSearchResult ( true );
sr.addAllEntityMappings ( Arrays.asList ( new EntityMapping[] {
new EntityMapping ( service1, "b1.1", "1" ),
new EntityMapping ( service2, "b1.2", "1" ),
new EntityMapping ( service1, "b1.3", "1" ),
new EntityMapping ( service1, "b1.4", "1" ),
new EntityMapping ( service2, "b2.1", "2" ),
new EntityMapping ( service3, "b2.2", "2" ),
}));
emMgr.storeMappingBundles ( sr );
EntityMappingSearchResult result = emMgr.getMappings (
false, service1.getName () + ":b1.3", service3.getName () + ":b2.2"
);
out.println ( "\nResult:" );
out.println ( result );
assertEquals ( "Wrong no. of services returned!", 3, result.getServices ().size () );
{
boolean found1 = false, found2 = false, found3 = false;
for ( Service service: result.getServices () )
if ( service1.equals ( service ) ) found1 = true;
else if ( service2.equals ( service ) ) found2 = true;
else if ( service3.equals ( service ) ) found3 = true;
assertTrue ( "Service 1 not found in search results!", found1 );
assertTrue ( "Service 2 not found in search results!", found2 );
assertTrue ( "Service 3 not found in search results!", found3 );
}
Collection<Bundle> bsets = result.getBundles ();
assertEquals ( "Wrong no of bundles in search result!", 2, bsets.size () );
{
// b1 ( (s1, b1.1) (s2, b1.2) (s1, b1.3) (s1, b1.4)
// b2 ( (s2, b2.1) (s3, b2.2) )
Bundle bundle1 = null, bundle2 = null;
Entity b13 = null;
for ( Bundle bset: bsets )
for ( Entity entity: bset.getEntities () )
if ( service1.equals ( entity.getService () ) && "b1.1".equals ( entity.getAccession () ) )
bundle1 = bset;
else if ( service3.equals ( entity.getService () ) && "b2.2".equals ( entity.getAccession () ) )
bundle2 = bset;
else if ( service1.getName().equals ( entity.getServiceName () ) && "b1.3".equals ( entity.getAccession () ))
b13 = entity;
assertNotNull ( "b1.3 not found in search results!", b13 );
assertEquals ( "Bad URI returned for b13!",
"http://test.testemsrv.net/service1#b1.3", b13.getURI ()
);
assertNotNull ( "Bundle 1 not found in search result!", bundle1 );
assertNotNull ( "Bundle 2 not found in search result!", bundle2 );
assertEquals ( "Wrong size for set 1", 4, bundle1.getEntities ().size () );
assertEquals ( "Wrong size for set 2", 2, bundle2.getEntities ().size () );
assertTrue ( "b1.1 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.1" ) ) );
assertTrue ( "b1.2 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service2, "b1.2" ) ) );
assertTrue ( "b1.3 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.3" ) ) );
assertTrue ( "b1.4 is not in set1!", bundle1.getEntities ().contains ( new Entity ( service1, "b1.4" ) ) );
assertTrue ( "b2.1 is not in set2!", bundle2.getEntities ().contains ( new Entity ( service2, "b2.1" ) ) );
assertTrue ( "b2.2 is not in set2!", bundle2.getEntities ().contains ( new Entity ( service3, "b2.2" ) ) );
}
Set<ServiceCollection> scs = result.getServiceCollections ();
assertEquals ( "Wrong no of repo returned by the search!", 1, scs.size () );
assertTrue ( "Repo1 not found in the search result!", scs.contains ( sc1 ) );
Set<Repository> repos = result.getRepositories ();
assertEquals ( "Wrong no of repo returned by the search!", 1, repos.size () );
assertTrue ( "Repo1 not found in the search result!", repos.contains ( repo1 ) );
}
@Test
public void testUrisAndAccessControl ()
{
AccessControlManager acMgr = managerFactory.newAccessControlManager ( editorUser.getEmail (), editorSecret );
emMgr.storeMappingBundle (
service1.getName () + ":b1.1", "<" + EntityIdResolver.buildUriFromAcc ( "b2.1", service2.getUriPattern () ) + ">"
);
EntityMappingSearchResult emsr = emMgr.getMappings ( true, service2.getName () + ":b2.1" );
out.println ( "\n\nStored mappings:\n" + emsr + "\n\n" );
assertTrue ( "Private entity is not created!", emsr.getBundles ().iterator().next ().getEntities ()
.contains ( new Entity ( service1, "b1.1" ) )
);
acMgr.setServicesVisibility ( "false", "null", false, service1.getName () );
acMgr.setEntitiesVisibility ( "null", "null",
"<" + EntityIdResolver.buildUriFromAcc ( "b1.1", service1.getUriPattern () ) + ">"
);
emMgr = managerFactory.newEntityMappingManager ();
emsr = emMgr.getMappings ( true, service2.getName () + ":b2.1" );
out.println ( "\n\nProtected mappings:\n" + emsr + "\n\n" );
assertFalse ( "Private entity is accessible!", emsr.getBundles ().iterator().next ().getEntities ()
.contains ( new Entity ( service1, "b1.1" ) )
);
// Clean up
emMgr = managerFactory.newEntityMappingManager ( editorUser.getEmail (), editorSecret );
emMgr.deleteMappings (
service2.getName () + ":<" + buildUriFromAcc ( "b2.1", service2.getUriPattern () ) + ">"
);
emsr = emMgr.getMappings ( true, service1.getName () + ":b1.1" );
assertTrue ( "Test data not deleted!", emsr.getBundles ().isEmpty () );
}
}