package edu.ualberta.med.biobank.test.action; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import javax.validation.ConstraintViolationException; import org.hibernate.Query; import org.hibernate.validator.constraints.NotEmpty; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import edu.ualberta.med.biobank.common.action.ListResult; import edu.ualberta.med.biobank.common.action.SetResult; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventGetInfoAction; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventGetInfoAction.CEventInfo; import edu.ualberta.med.biobank.common.action.container.ContainerDeleteAction; import edu.ualberta.med.biobank.common.action.container.ContainerGetInfoAction; import edu.ualberta.med.biobank.common.action.container.ContainerGetInfoAction.ContainerInfo; import edu.ualberta.med.biobank.common.action.containerType.ContainerTypeDeleteAction; import edu.ualberta.med.biobank.common.action.containerType.ContainerTypeGetInfoAction; import edu.ualberta.med.biobank.common.action.containerType.ContainerTypeGetInfoAction.ContainerTypeInfo; import edu.ualberta.med.biobank.common.action.containerType.ContainerTypeSaveAction; import edu.ualberta.med.biobank.common.action.dispatch.DispatchDeleteAction; import edu.ualberta.med.biobank.common.action.dispatch.DispatchGetInfoAction; import edu.ualberta.med.biobank.common.action.dispatch.DispatchGetSpecimenInfosAction; import edu.ualberta.med.biobank.common.action.exception.ModelNotFoundException; import edu.ualberta.med.biobank.common.action.info.DispatchReadInfo; import edu.ualberta.med.biobank.common.action.info.SiteContainerTypeInfo; import edu.ualberta.med.biobank.common.action.info.SiteInfo; import edu.ualberta.med.biobank.common.action.info.StudyCountInfo; import edu.ualberta.med.biobank.common.action.processingEvent.ProcessingEventDeleteAction; import edu.ualberta.med.biobank.common.action.processingEvent.ProcessingEventGetInfoAction; import edu.ualberta.med.biobank.common.action.processingEvent.ProcessingEventGetInfoAction.PEventInfo; import edu.ualberta.med.biobank.common.action.processingEvent.ProcessingEventSaveAction; import edu.ualberta.med.biobank.common.action.site.SiteDeleteAction; import edu.ualberta.med.biobank.common.action.site.SiteGetContainerTypeInfoAction; import edu.ualberta.med.biobank.common.action.site.SiteGetInfoAction; import edu.ualberta.med.biobank.common.action.site.SiteGetStudyInfoAction; import edu.ualberta.med.biobank.common.action.site.SiteGetTopContainersAction; import edu.ualberta.med.biobank.common.action.site.SiteSaveAction; import edu.ualberta.med.biobank.common.action.specimen.SpecimenDeleteAction; import edu.ualberta.med.biobank.common.action.specimen.SpecimenInfo; import edu.ualberta.med.biobank.common.util.HibernateUtil; import edu.ualberta.med.biobank.model.ActivityStatus; import edu.ualberta.med.biobank.model.Address; import edu.ualberta.med.biobank.model.Container; import edu.ualberta.med.biobank.model.ContainerLabelingScheme; import edu.ualberta.med.biobank.model.DispatchSpecimen; import edu.ualberta.med.biobank.model.Site; import edu.ualberta.med.biobank.model.Specimen; import edu.ualberta.med.biobank.test.Utils; import edu.ualberta.med.biobank.test.action.helper.CollectionEventHelper; import edu.ualberta.med.biobank.test.action.helper.ContainerTypeHelper; import edu.ualberta.med.biobank.test.action.helper.DispatchHelper; import edu.ualberta.med.biobank.test.action.helper.PatientHelper; import edu.ualberta.med.biobank.test.action.helper.SiteHelper; import edu.ualberta.med.biobank.test.action.helper.SiteHelper.Provisioning; import edu.ualberta.med.biobank.test.action.helper.StudyHelper; public class TestSite extends TestAction { private String name; private SiteSaveAction siteSaveAction; @Override @Before public void setUp() throws Exception { super.setUp(); name = getMethodNameR(); siteSaveAction = SiteHelper.getSaveAction(name, name, ActivityStatus.ACTIVE); } @Test public void saveNew() throws Exception { // null name siteSaveAction.setName(null); try { exec(siteSaveAction); Assert.fail("should not be allowed to add site with no name"); } catch (ConstraintViolationException e) { Assert.assertTrue(TestAction.contains(e, NotEmpty.class, Site.class, "getName")); Assert.assertTrue(true); } // null short name siteSaveAction.setName(name); siteSaveAction.setNameShort(null); try { exec(siteSaveAction); Assert.fail( "should not be allowed to add site with no short name"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } siteSaveAction.setNameShort(name); siteSaveAction.setActivityStatus(null); try { exec(siteSaveAction); Assert.fail( "should not be allowed to add Site with no activity status"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } siteSaveAction.setActivityStatus(ActivityStatus.ACTIVE); siteSaveAction.setAddress(null); try { exec(siteSaveAction); Assert.fail( "should not be allowed to add site with no address"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // TODO: test invalid act status: 5, -1 Address address = new Address(); address.setCity(name); siteSaveAction.setAddress(address); Set<Integer> studyIds = new HashSet<Integer>(); studyIds.add(null); siteSaveAction.setStudyIds(studyIds); try { exec(siteSaveAction); Assert.fail( "should not be allowed to add site with a null site id"); } catch (ModelNotFoundException e) { Assert.assertTrue(true); } studyIds.clear(); studyIds.add(-1); siteSaveAction.setStudyIds(studyIds); try { exec(siteSaveAction); Assert.fail( "should not be allowed to add site with an invalid site id"); } catch (ModelNotFoundException e) { Assert.assertTrue(true); } // success path siteSaveAction.setStudyIds(new HashSet<Integer>()); exec(siteSaveAction); } @Test public void checkGetAction() throws Exception { Provisioning provisioning = new Provisioning(getExecutor(), name); Integer ceventId = CollectionEventHelper .createCEventWithSourceSpecimens(getExecutor(), provisioning.patientIds.get(0), provisioning.clinicId); CEventInfo ceventInfo = exec(new CollectionEventGetInfoAction(ceventId)); List<SpecimenInfo> sourceSpecs = ceventInfo.sourceSpecimenInfos; HashSet<Integer> added = new HashSet<Integer>(); added.add(sourceSpecs.get(0).specimen.getId()); exec(new ProcessingEventSaveAction( null, provisioning.siteId, Utils.getRandomDate(), Utils .getRandomString(5, 8), ActivityStatus.ACTIVE, null, added, new HashSet<Integer>())).getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); Assert.assertEquals(name + "_site_city", siteInfo.getSite() .getAddress() .getCity()); Assert.assertEquals(ActivityStatus.ACTIVE, siteInfo.getSite().getActivityStatus()); Assert.assertEquals(new Long(1), siteInfo.getPatientCount()); Assert.assertEquals(new Long(1), siteInfo.getProcessingEventCount()); Assert.assertEquals(new Long(1), siteInfo.getSpecimenCount()); } @Test public void nameChecks() throws Exception { Integer siteId = exec(siteSaveAction).getId(); // ensure we can change name on existing clinic SiteInfo siteInfo = exec(new SiteGetInfoAction(siteId)); siteInfo.getSite().setName(name + "_2"); siteSaveAction = SiteHelper.getSaveAction(siteInfo); exec(siteSaveAction); // ensure we can change short name on existing site siteInfo = exec(new SiteGetInfoAction(siteId)); siteInfo.getSite().setNameShort(name + "_2"); siteSaveAction = SiteHelper.getSaveAction(siteInfo); exec(siteSaveAction); // test for duplicate name SiteSaveAction saveSite = SiteHelper.getSaveAction(name + "_2", name, ActivityStatus.ACTIVE); try { exec(saveSite); Assert.fail("should not be allowed to add site with same name"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // test for duplicate name short saveSite.setName(Utils.getRandomString(5, 10)); saveSite.setNameShort(name + "_2"); try { exec(saveSite); Assert.fail( "should not be allowed to add site with same name short"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } } @Test public void comments() { // save with no comments Integer siteId = exec(siteSaveAction).getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertEquals(0, siteInfo.getSite().getComments().size()); siteInfo = addComment(siteId); Assert.assertEquals(1, siteInfo.getSite().getComments().size()); siteInfo = addComment(siteId); Assert.assertEquals(2, siteInfo.getSite().getComments().size()); // TODO: check full name on each comment's user // for (Comment comment : siteInfo.site.getCommentCollection()) { // // } } private SiteInfo addComment(Integer siteId) { SiteSaveAction siteSaveAction = SiteHelper.getSaveAction( exec(new SiteGetInfoAction(siteId))); siteSaveAction.setCommentText(Utils.getRandomString(20, 30)); exec(siteSaveAction).getId(); return exec(new SiteGetInfoAction(siteId)); } @Test public void studyCollection() throws Exception { Set<Integer> studyIds; List<Integer> allStudyIds = new ArrayList<Integer>(); Set<Integer> studyIdsSet1 = new HashSet<Integer>(); Set<Integer> studyIdsSet2 = new HashSet<Integer>(); for (int i = 0; i < 20; ++i) { Integer id = StudyHelper.createStudy( getExecutor(), name + "_study" + i, ActivityStatus.ACTIVE); allStudyIds.add(id); if (i < 10) { studyIdsSet1.add(id); } else { studyIdsSet2.add(id); } } // add study set 1 one by one Integer siteId = exec(siteSaveAction).getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(siteId)); Set<Integer> expectedStudyIds = new HashSet<Integer>(); for (Integer studyId : studyIdsSet1) { expectedStudyIds.add(studyId); SiteSaveAction siteSaveAction = SiteHelper.getSaveAction(siteInfo); studyIds = getStudyIds(siteInfo.getStudyCountInfos()); studyIds.add(studyId); siteSaveAction.setStudyIds(studyIds); exec(siteSaveAction); siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertEquals(expectedStudyIds, getStudyIds(siteInfo.getStudyCountInfos())); } // create a second site, site 2, with the second set of studies Integer siteId2 = SiteHelper.createSite(getExecutor(), name + "_2", Utils.getRandomString(8, 12), ActivityStatus.ACTIVE, studyIdsSet2); siteInfo = exec(new SiteGetInfoAction(siteId2)); expectedStudyIds.clear(); expectedStudyIds.addAll(studyIdsSet2); Assert.assertEquals(expectedStudyIds, getStudyIds(siteInfo.getStudyCountInfos())); // make sure site 1 still has same collection siteInfo = exec(new SiteGetInfoAction(siteId)); expectedStudyIds.clear(); expectedStudyIds.addAll(studyIdsSet1); Assert.assertEquals(expectedStudyIds, getStudyIds(siteInfo.getStudyCountInfos())); // delete studies one by one from Site 1 siteInfo = exec(new SiteGetInfoAction(siteId)); for (Integer studyId : studyIdsSet1) { expectedStudyIds.remove(studyId); siteSaveAction = SiteHelper.getSaveAction(siteInfo); studyIds = getStudyIds(siteInfo.getStudyCountInfos()); studyIds.remove(studyId); siteSaveAction.setStudyIds(studyIds); exec(siteSaveAction); siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertEquals(expectedStudyIds, getStudyIds(siteInfo.getStudyCountInfos())); } // delete studies from Site 2 siteInfo = exec(new SiteGetInfoAction(siteId2)); studyIds = getStudyIds(siteInfo.getStudyCountInfos()); studyIds.removeAll(studyIdsSet2); siteSaveAction = SiteHelper.getSaveAction(siteInfo); exec(siteSaveAction); siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertTrue(getStudyIds(siteInfo.getStudyCountInfos()).isEmpty()); // attempt to add an invalid study ID siteInfo = exec(new SiteGetInfoAction(siteId)); SiteSaveAction siteSaveAction = SiteHelper.getSaveAction(siteInfo); studyIds = getStudyIds(siteInfo.getStudyCountInfos()); studyIds.add(-1); siteSaveAction.setStudyIds(studyIds); try { exec(siteSaveAction); Assert.fail("should not be allowed to add an invalid study id"); } catch (ModelNotFoundException e) { Assert.assertTrue(true); } } @Test public void containerTypes() { Integer siteId = exec(siteSaveAction).getId(); List<ContainerLabelingScheme> labelingSchemes = new ArrayList<ContainerLabelingScheme>( getContainerLabelingSchemes().values()); String ctName = name + "FREEZER01"; ContainerTypeSaveAction ctSaveAction = ContainerTypeHelper.getSaveAction(ctName, ctName, siteId, true, 6, 10, labelingSchemes.get(0).getId(), getR().nextDouble()); Integer ctId = exec(ctSaveAction).getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertEquals(1, siteInfo.getContainerTypeCount().longValue()); Assert.assertEquals(ctId, siteInfo.getContainerTypeInfos().get(0) .getContainerType().getId()); Assert.assertEquals(ctName, siteInfo.getContainerTypeInfos().get(0) .getContainerType().getName()); // add another container ctName += "_2"; ctSaveAction = ContainerTypeHelper.getSaveAction(ctName, ctName, siteId, true, 3, 8, labelingSchemes.get(1).getId(), getR().nextDouble()); ctId = exec(ctSaveAction).getId(); siteInfo = exec(new SiteGetInfoAction(siteId)); Assert.assertEquals(2, siteInfo.getContainerTypeCount().longValue()); Assert.assertEquals(ctId, siteInfo.getContainerTypeInfos().get(1) .getContainerType().getId()); Assert.assertEquals(ctName, siteInfo.getContainerTypeInfos().get(1) .getContainerType().getName()); } private Set<Integer> getStudyIds(List<StudyCountInfo> studyCountInfo) { Set<Integer> ids = new HashSet<Integer>(); for (StudyCountInfo info : studyCountInfo) { ids.add(info.getStudy().getId()); } return ids; } @Test public void delete() { Integer siteId = exec(siteSaveAction).getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(siteId)); exec(new SiteDeleteAction(siteInfo.getSite())); // hql query for site should return empty Query q = session.createQuery("SELECT COUNT(*) FROM " + Site.class.getName() + " WHERE id=?"); q.setParameter(0, siteId); Long result = HibernateUtil.getCountFromQuery(q); Assert.assertTrue(result.equals(0L)); } private Provisioning createSiteWithContainerType() { Provisioning provisioning = new Provisioning(getExecutor(), name); provisioning.addContainerType(getExecutor(), name, getContainerLabelingSchemes().values().iterator().next() .getId(), getR().nextDouble()); return provisioning; } @Test public void checkSiteGetCtypeInfoAction() throws Exception { Provisioning provisioning = createSiteWithContainerType(); List<SiteContainerTypeInfo> ctypeInfo = exec( new SiteGetContainerTypeInfoAction(provisioning.siteId)) .getList(); Assert.assertEquals(0L, ctypeInfo.get(0).getContainerCount() .longValue()); Integer containerTypeId = provisioning.containerTypeIds.get(0); provisioning.addContainer(getExecutor(), containerTypeId, "01"); ctypeInfo = exec( new SiteGetContainerTypeInfoAction(provisioning.siteId)) .getList(); Assert.assertEquals(1L, ctypeInfo.get(0).getContainerCount() .longValue()); } @Test public void deleteWithContainerTypes() { Provisioning provisioning = createSiteWithContainerType(); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); try { exec(new SiteDeleteAction(siteInfo.getSite())); Assert .fail( "should not be allowed to delete a site with container types"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // delete container type followed by site - should work now ContainerTypeInfo containerTypeInfo = exec(new ContainerTypeGetInfoAction( provisioning.containerTypeIds.get(0))); exec(new ContainerTypeDeleteAction(containerTypeInfo .getContainerType())); exec(new SiteDeleteAction(siteInfo.getSite())); } @Test public void deleteWithContainers() { Provisioning provisioning = createSiteWithContainerType(); Integer containerTypeId = provisioning.containerTypeIds.get(0); Integer containerId = provisioning.addContainer(getExecutor(), containerTypeId, "01"); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); try { exec(new SiteDeleteAction(siteInfo.getSite())); Assert .fail( "should not be allowed to delete a site with containers"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } List<Container> topContainers = exec(new SiteGetTopContainersAction(provisioning.siteId)) .getList(); Assert.assertEquals(1, topContainers.size()); // delete container followed by site - should work now ContainerInfo containerInfo = exec(new ContainerGetInfoAction(containerId)); exec(new ContainerDeleteAction(containerInfo.container)); ContainerTypeInfo containerTypeInfo = exec(new ContainerTypeGetInfoAction(containerTypeId)); exec(new ContainerTypeDeleteAction(containerTypeInfo .getContainerType())); exec(new SiteDeleteAction(siteInfo.getSite())); } @Test public void deleteWithProcessingEvents() throws Exception { Provisioning provisioning = new Provisioning(getExecutor(), name); // create a collection event Integer ceventId = CollectionEventHelper .createCEventWithSourceSpecimens(getExecutor(), provisioning.patientIds.get(0), provisioning.clinicId); CEventInfo ceventInfo = exec(new CollectionEventGetInfoAction(ceventId)); List<SpecimenInfo> sourceSpecs = ceventInfo.sourceSpecimenInfos; // create a processing event with one of the collection event source // specimens Integer peventId = exec( new ProcessingEventSaveAction( null, provisioning.siteId, Utils.getRandomDate(), Utils .getRandomString(5, 8), ActivityStatus.ACTIVE, null, new HashSet<Integer>( Arrays.asList(sourceSpecs.get(0).specimen.getId())), new HashSet<Integer>())) .getId(); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); try { exec(new SiteDeleteAction(siteInfo.getSite())); Assert .fail( "should not be allowed to delete a site with processing events"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // delete the processing event PEventInfo peventInfo = exec(new ProcessingEventGetInfoAction(peventId)); exec(new ProcessingEventDeleteAction(peventInfo.pevent)); exec(new SiteDeleteAction(siteInfo.getSite())); } @Test public void deleteWithSrcDispatch() throws Exception { Provisioning provisioning = new Provisioning(getExecutor(), name); Integer dispatchId1 = DispatchHelper.createDispatch(getExecutor(), provisioning.clinicId, provisioning.siteId, provisioning.patientIds.get(0)); // create a second site to dispatch to Integer siteId2 = exec( SiteHelper.getSaveAction(name + "_site2", name + "_site2", ActivityStatus.ACTIVE)).getId(); Integer dispatchId2 = DispatchHelper.createDispatch(getExecutor(), provisioning.siteId, siteId2, provisioning.patientIds.get(0)); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); try { exec(new SiteDeleteAction(siteInfo.getSite())); Assert .fail( "should not be allowed to delete a site which is a source of dispatches"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // delete the dispatch and then the site Set<Specimen> specimens = new HashSet<Specimen>(); SetResult<DispatchSpecimen> dispatchSpecimens = getExecutor() .exec(new DispatchGetSpecimenInfosAction(dispatchId1)); for (DispatchSpecimen dspec : dispatchSpecimens.getSet()) { specimens.add(dspec.getSpecimen()); } dispatchSpecimens = getExecutor() .exec(new DispatchGetSpecimenInfosAction(dispatchId2)); for (DispatchSpecimen dspec : dispatchSpecimens.getSet()) { specimens.add(dspec.getSpecimen()); } DispatchReadInfo dispatchInfo = exec(new DispatchGetInfoAction(dispatchId2)); exec(new DispatchDeleteAction(dispatchInfo.dispatch)); dispatchInfo = exec(new DispatchGetInfoAction(dispatchId1)); exec(new DispatchDeleteAction(dispatchInfo.dispatch)); for (Specimen specimen : specimens) { exec(new SpecimenDeleteAction(specimen)); } deleteOriginInfos(provisioning.siteId); exec(new SiteDeleteAction(siteInfo.getSite())); } @Test public void deleteWithDstDispatch() throws Exception { Provisioning provisioning = new Provisioning(getExecutor(), name); Integer dispatchId = DispatchHelper.createDispatch(getExecutor(), provisioning.clinicId, provisioning.siteId, provisioning.patientIds.get(0)); SiteInfo siteInfo = exec(new SiteGetInfoAction(provisioning.siteId)); try { exec(new SiteDeleteAction(siteInfo.getSite())); Assert .fail( "should not be allowed to delete a site which is a destination for dispatches"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } // delete the dispatch and then the site - no need to delete dispatch // specimens DispatchReadInfo dispatchInfo = exec(new DispatchGetInfoAction(dispatchId)); exec(new DispatchDeleteAction(dispatchInfo.dispatch)); exec(new SiteDeleteAction(siteInfo.getSite())); } @Test public void getStudyInfo() throws Exception { Set<Integer> studyIds = new HashSet<Integer>(); studyIds.add(StudyHelper.createStudy(getExecutor(), name + Utils.getRandomString(5), ActivityStatus.ACTIVE)); Integer siteId = SiteHelper.createSite(getExecutor(), name + Utils.getRandomString(5), "Edmo", ActivityStatus.ACTIVE, studyIds); Integer patients = getR().nextInt(5); Integer collectionEvents = getR().nextInt(5); for (int i = 0; i < patients; i++) { Integer patient = PatientHelper.createPatient(getExecutor(), name + Utils.getRandomString(5), studyIds.iterator() .next()); for (int j = 0; j < collectionEvents; j++) CollectionEventHelper.createCEventWithSourceSpecimens( getExecutor(), patient, siteId); } SiteGetStudyInfoAction action = new SiteGetStudyInfoAction(siteId); ListResult<StudyCountInfo> studies = exec(action); Assert .assertTrue(studies.getList().get(0).getCollectionEventCount() .intValue() == (collectionEvents * patients)); Assert .assertTrue(studies.getList().get(0).getCollectionEventCount() .intValue() == (patients)); Assert.assertTrue(studies.getList().get(0).getStudy().getId() .equals(studyIds.iterator().next())); } }