package edu.ualberta.med.biobank.test.action; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.validation.ConstraintViolationException; import junit.framework.Assert; import org.hibernate.Query; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventDeleteAction; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventGetEventAttrInfoAction; 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.collectionEvent.CollectionEventSaveAction; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventSaveAction.CEventAttrSaveInfo; import edu.ualberta.med.biobank.common.action.collectionEvent.CollectionEventSaveAction.SaveCEventSpecimenInfo; import edu.ualberta.med.biobank.common.action.collectionEvent.EventAttrInfo; import edu.ualberta.med.biobank.common.action.eventattr.GlobalEventAttrInfo; import edu.ualberta.med.biobank.common.action.eventattr.GlobalEventAttrInfoGetAction; import edu.ualberta.med.biobank.common.action.patient.PatientGetInfoAction; import edu.ualberta.med.biobank.common.action.patient.PatientGetInfoAction.PatientInfo; import edu.ualberta.med.biobank.common.action.specimenType.SpecimenTypeSaveAction; import edu.ualberta.med.biobank.common.action.study.StudyEventAttrSaveAction; import edu.ualberta.med.biobank.common.action.study.StudyGetInfoAction; import edu.ualberta.med.biobank.common.action.study.StudyInfo; import edu.ualberta.med.biobank.common.wrappers.EventAttrTypeEnum; import edu.ualberta.med.biobank.model.ActivityStatus; import edu.ualberta.med.biobank.model.CollectionEvent; import edu.ualberta.med.biobank.model.EventAttr; import edu.ualberta.med.biobank.model.Specimen; import edu.ualberta.med.biobank.model.StudyEventAttr; import edu.ualberta.med.biobank.model.util.MathUtil; import edu.ualberta.med.biobank.test.Utils; import edu.ualberta.med.biobank.test.action.helper.CollectionEventHelper; import edu.ualberta.med.biobank.test.action.helper.SiteHelper.Provisioning; public class TestCollectionEvent extends TestAction { @Rule public TestName testname = new TestName(); private String name; private Provisioning provisioning; @Override @Before public void setUp() throws Exception { super.setUp(); name = getMethodNameR(); provisioning = new Provisioning(getExecutor(), name); } @Test public void saveNoSpecsNoAttrs() throws Exception { final Integer visitNumber = getR().nextInt(20) + 1; final String commentText = Utils.getRandomString(20, 30); // test add final Integer ceventId = getExecutor() .exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), visitNumber, ActivityStatus.ACTIVE, commentText, null, null)).getId(); // Check CollectionEvent is in database with correct values CollectionEvent cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); Assert.assertEquals(visitNumber, cevent.getVisitNumber()); Assert.assertEquals(ActivityStatus.ACTIVE, cevent.getActivityStatus()); Assert.assertEquals(1, cevent.getComments().size()); } @Test public void saveWithSpecs() throws Exception { final Integer visitNumber = getR().nextInt(20) + 1; final String commentText = Utils.getRandomString(20, 30); final Integer typeId = getSpecimenTypes().get(0).getId(); final Map<String, SaveCEventSpecimenInfo> specs = CollectionEventHelper.createSaveCEventSpecimenInfoRandomList(5, typeId, getExecutor().getUserId(), provisioning.siteId); // Save a new cevent final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), visitNumber, ActivityStatus.ACTIVE, commentText, new ArrayList<SaveCEventSpecimenInfo>(specs.values()), null)) .getId(); // Check CollectionEvent is in database with correct values CollectionEvent cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); Assert.assertEquals(visitNumber, cevent.getVisitNumber()); Assert.assertEquals(ActivityStatus.ACTIVE, cevent.getActivityStatus()); Assert.assertNotNull(cevent.getComments()); Assert.assertEquals(1, cevent.getComments().size()); Assert.assertEquals(specs.size(), cevent.getAllSpecimens() .size()); Assert.assertEquals(specs.size(), cevent .getOriginalSpecimens().size()); for (Iterator<Specimen> iter = cevent.getOriginalSpecimens().iterator(); iter.hasNext();) { Specimen sp = iter.next(); Assert.assertEquals(typeId, sp.getSpecimenType().getId()); SaveCEventSpecimenInfo info = specs.get(sp.getInventoryId()); Assert.assertNotNull(info); if (info != null) { Assert.assertEquals(1, sp.getComments().size()); Assert.assertEquals(info.inventoryId, sp.getInventoryId()); Assert .assertTrue(MathUtil.equals(info.quantity, sp.getQuantity())); Assert.assertEquals(info.specimenTypeId, sp.getSpecimenType() .getId()); Assert .assertEquals(info.activityStatus, sp.getActivityStatus()); Assert.assertEquals(info.createdAt, sp.getCreatedAt()); // set the id to make some modification tests after that. info.id = sp.getId(); } } // Save the same cevent with only one kept from previous list (and // modified) and with a new one List<SaveCEventSpecimenInfo> newSpecList = new ArrayList<SaveCEventSpecimenInfo>(); SaveCEventSpecimenInfo modifiedSpec = specs.values().iterator().next(); modifiedSpec.inventoryId += "Modified"; modifiedSpec.quantity = modifiedSpec.quantity.add(BigDecimal.ONE); newSpecList.add(modifiedSpec); SaveCEventSpecimenInfo newSpec = CollectionEventHelper.createSaveCEventSpecimenInfoRandom(typeId, getExecutor().getUserId(), provisioning.siteId); newSpecList.add(newSpec); // modify cevent exec(new CollectionEventSaveAction(ceventId, provisioning.patientIds.get(0), visitNumber + 1, ActivityStatus.ACTIVE, commentText, newSpecList, null)); // Check CollectionEvent is modified session.clear(); cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); session.refresh(cevent); Assert .assertEquals(visitNumber + 1, cevent.getVisitNumber().intValue()); Assert.assertEquals(2, cevent.getAllSpecimens().size()); Assert.assertEquals(2, cevent.getOriginalSpecimens().size()); for (Iterator<Specimen> iter = cevent.getOriginalSpecimens().iterator(); iter.hasNext();) { Specimen sp = iter.next(); Assert.assertEquals(typeId, sp.getSpecimenType().getId()); Assert.assertTrue(sp.getInventoryId().equals(newSpec.inventoryId) || sp.getInventoryId().equals(modifiedSpec.inventoryId)); if (sp.getInventoryId().equals(newSpec.inventoryId)) { Assert.assertNotNull(sp.getComments()); Assert.assertEquals(1, sp.getComments().size()); Assert.assertEquals(newSpec.inventoryId, sp.getInventoryId()); Assert.assertTrue(MathUtil.equals(newSpec.quantity, sp.getQuantity())); Assert.assertEquals(newSpec.specimenTypeId, sp .getSpecimenType().getId()); Assert.assertEquals(newSpec.activityStatus, sp.getActivityStatus()); Assert.assertEquals(newSpec.createdAt, sp.getCreatedAt()); } if (sp.getInventoryId().equals(modifiedSpec.inventoryId)) { Assert.assertEquals(modifiedSpec.inventoryId, sp.getInventoryId()); Assert .assertTrue(MathUtil.equals(modifiedSpec.quantity, sp.getQuantity())); } } } @Test public void checkGetAction() throws Exception { // add specimen type final Integer typeId = exec(new SpecimenTypeSaveAction(name, name)).getId(); final Map<String, SaveCEventSpecimenInfo> specs = CollectionEventHelper.createSaveCEventSpecimenInfoRandomList(5, typeId, getExecutor().getUserId(), provisioning.siteId); setEventAttrs(provisioning.studyId); StudyInfo studyInfo = exec(new StudyGetInfoAction(provisioning.studyId)); Assert.assertEquals(5, studyInfo.getStudyEventAttrs().size()); StudyEventAttr phlebotomistStudyAttr = null; for (StudyEventAttr attr : studyInfo.getStudyEventAttrs()) { if ("Phlebotomist".equals(attr.getGlobalEventAttr().getLabel())) { phlebotomistStudyAttr = attr; } } Assert.assertNotNull(phlebotomistStudyAttr); List<CEventAttrSaveInfo> attrs = new ArrayList<CollectionEventSaveAction.CEventAttrSaveInfo>(); CEventAttrSaveInfo attrInfo = CollectionEventHelper.createSaveCEventAttrInfo( phlebotomistStudyAttr.getId(), EventAttrTypeEnum.getEventAttrType(phlebotomistStudyAttr .getGlobalEventAttr().getEventAttrType().getName()), "abcdefghi"); attrs.add(attrInfo); Integer visitNber = getR().nextInt(20) + 1; String commentText = Utils.getRandomString(20, 30); // Save a new cevent final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds.get(0), visitNber, ActivityStatus.ACTIVE, commentText, new ArrayList<SaveCEventSpecimenInfo>(specs.values()), attrs)).getId(); // Call get infos action PatientInfo patientInfo = exec(new PatientGetInfoAction(provisioning.patientIds .get(0))); CEventInfo info = exec(new CollectionEventGetInfoAction(ceventId)); // no aliquoted specimens added Assert.assertEquals(0, info.aliquotedSpecimenInfos.size()); Assert.assertNotNull(info.cevent); Assert.assertEquals(visitNber, info.cevent.getVisitNumber()); Assert.assertEquals(ActivityStatus.ACTIVE, info.cevent.getActivityStatus()); Assert.assertEquals(patientInfo.patient.getPnumber(), info.cevent .getPatient().getPnumber()); Assert.assertEquals(patientInfo.patient.getStudy().getName(), info.cevent .getPatient().getStudy().getName()); // TODO: add test to check if the comments' user is fetched Assert.assertNotNull(info.cevent.getComments()); // FIXME sometimes size not correct !!??!! Assert.assertEquals(1, info.cevent.getComments() .size()); Assert.assertEquals(attrs.size(), info.eventAttrs.size()); Assert.assertEquals(specs.size(), info.sourceSpecimenInfos.size()); // FIXME need to add test with aliquoted specimens } @Test public void saveWithAttrs() throws Exception { setEventAttrs(provisioning.studyId); StudyInfo studyInfo = exec(new StudyGetInfoAction(provisioning.studyId)); Assert.assertEquals(5, studyInfo.getStudyEventAttrs().size()); StudyEventAttr phlebotomistStudyAttr = null; for (StudyEventAttr attr : studyInfo.getStudyEventAttrs()) { if ("Phlebotomist".equals(attr.getGlobalEventAttr().getLabel())) { phlebotomistStudyAttr = attr; } } Assert.assertNotNull(phlebotomistStudyAttr); final Integer visitNumber = getR().nextInt(20) + 1; final String commentText = Utils.getRandomString(20, 30); List<CEventAttrSaveInfo> attrs = new ArrayList<CollectionEventSaveAction.CEventAttrSaveInfo>(); String value1 = name + "abcdefghi"; CEventAttrSaveInfo attrInfo = CollectionEventHelper.createSaveCEventAttrInfo( phlebotomistStudyAttr .getId(), EventAttrTypeEnum.getEventAttrType(phlebotomistStudyAttr .getGlobalEventAttr() .getEventAttrType() .getName()), value1); attrs.add(attrInfo); // Save a new cevent final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), visitNumber, ActivityStatus.ACTIVE, commentText, null, attrs)).getId(); // Check CollectionEvent is in database with correct values CollectionEvent cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); Assert.assertEquals(visitNumber, cevent.getVisitNumber()); Assert.assertEquals(ActivityStatus.ACTIVE, cevent.getActivityStatus()); Assert.assertEquals(1, cevent.getComments() .size()); Assert.assertEquals(1, cevent.getEventAttrs().size()); EventAttr eventAttr = cevent.getEventAttrs().iterator().next(); Assert.assertEquals(value1, eventAttr.getValue()); Assert.assertEquals(phlebotomistStudyAttr.getId(), eventAttr .getStudyEventAttr() .getId()); Integer eventAttrId = eventAttr.getId(); String value2 = name + "jklmnopqr"; attrInfo.value = value2; // Save with a different value for attrinfo exec(new CollectionEventSaveAction(ceventId, provisioning.patientIds.get(0), visitNumber, ActivityStatus.ACTIVE, commentText, null, attrs)); session.clear(); cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); session.refresh(cevent); Assert.assertEquals(1, cevent.getEventAttrs().size()); eventAttr = cevent.getEventAttrs().iterator().next(); Assert.assertEquals(value2, eventAttr.getValue()); Assert.assertEquals(eventAttrId, eventAttr.getId()); // make sure only one value in database Query q = session.createQuery( "select eattr from " + CollectionEvent.class.getName() + " as ce " + "join ce.eventAttrs as eattr " + "join eattr.studyEventAttr as seattr " + "join seattr.globalEventAttr as geattr " + "where ce.id = ? and geattr.label= ?"); q.setParameter(0, cevent.getId()); q.setParameter(1, "Phlebotomist"); @SuppressWarnings("unchecked") List<EventAttr> results = q.list(); Assert.assertEquals(1, results.size()); } /* * add Event Attr to study */ private void setEventAttrs(Integer studyId) throws Exception { Map<Integer, GlobalEventAttrInfo> globalEattrs = exec(new GlobalEventAttrInfoGetAction()).getMap(); Assert.assertFalse("EventAttrTypes not initialized", globalEattrs.isEmpty()); HashMap<String, GlobalEventAttrInfo> globalEattrsByLabel = new HashMap<String, GlobalEventAttrInfo>(); for (GlobalEventAttrInfo gEattr : globalEattrs.values()) { globalEattrsByLabel.put(gEattr.attr.getLabel(), gEattr); } // make sure the global event attributes are present Assert.assertTrue( "Missing global event attribute", globalEattrsByLabel.keySet().containsAll( Arrays.asList("PBMC Count (x10^6)", "Consent", "Patient Type", "Visit Type"))); StudyEventAttrSaveAction seAttrSave = new StudyEventAttrSaveAction(); seAttrSave.setGlobalEventAttrId(globalEattrsByLabel .get("PBMC Count (x10^6)").attr .getId()); seAttrSave.setRequired(true); seAttrSave.setActivityStatus(ActivityStatus.ACTIVE); seAttrSave.setStudyId(studyId); exec(seAttrSave); seAttrSave = new StudyEventAttrSaveAction(); seAttrSave.setGlobalEventAttrId(globalEattrsByLabel .get("Consent").attr.getId()); seAttrSave.setRequired(false); seAttrSave.setPermissible("c1;c2;c3"); seAttrSave.setActivityStatus(ActivityStatus.ACTIVE); seAttrSave.setStudyId(studyId); exec(seAttrSave); seAttrSave = new StudyEventAttrSaveAction(); seAttrSave.setGlobalEventAttrId(globalEattrsByLabel .get("Patient Type").attr.getId()); seAttrSave.required = true; seAttrSave.setActivityStatus(ActivityStatus.ACTIVE); seAttrSave.setStudyId(studyId); exec(seAttrSave); seAttrSave = new StudyEventAttrSaveAction(); seAttrSave.setGlobalEventAttrId(globalEattrsByLabel .get("Visit Type").attr.getId()); seAttrSave.required = false; seAttrSave.setPermissible("v1;v2;v3;v4"); seAttrSave.setActivityStatus(ActivityStatus.ACTIVE); seAttrSave.setStudyId(studyId); exec(seAttrSave); seAttrSave = new StudyEventAttrSaveAction(); seAttrSave.setGlobalEventAttrId(globalEattrsByLabel .get("Phlebotomist").attr.getId()); seAttrSave.required = false; seAttrSave.setActivityStatus(ActivityStatus.ACTIVE); seAttrSave.setStudyId(studyId); exec(seAttrSave); } @Test public void deleteWithoutSpecimens() throws Exception { final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), getR().nextInt(20) + 1, ActivityStatus.ACTIVE, Utils .getRandomString(20, 30), null, null)).getId(); // test delete CEventInfo info = exec(new CollectionEventGetInfoAction(ceventId)); exec(new CollectionEventDeleteAction(info.cevent)); CollectionEvent cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); Assert.assertNull(cevent); } @Test public void deleteWithSpecimens() throws Exception { // add specimen type final Integer typeId = exec(new SpecimenTypeSaveAction(name, name)).getId(); final Map<String, SaveCEventSpecimenInfo> specs = CollectionEventHelper.createSaveCEventSpecimenInfoRandomList(5, typeId, getExecutor().getUserId(), provisioning.siteId); // Save a new cevent final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), getR().nextInt(20) + 1, ActivityStatus.ACTIVE, null, new ArrayList<SaveCEventSpecimenInfo>(specs.values()), null)) .getId(); // try to delete this cevent CEventInfo info = exec(new CollectionEventGetInfoAction(ceventId)); try { exec(new CollectionEventDeleteAction(info.cevent)); Assert .fail("should throw an exception because specimens are still in the cevent"); } catch (ConstraintViolationException ae) { Assert.assertTrue(true); } // Check CollectionEvent is in database with correct values CollectionEvent cevent = (CollectionEvent) session.get(CollectionEvent.class, ceventId); Assert.assertNotNull(cevent); } @Test public void saveNotUniqueVisitNumber() throws Exception { final Integer visitNumber = getR().nextInt(20) + 1; // add exec(new CollectionEventSaveAction(null, provisioning.patientIds.get(0), visitNumber, ActivityStatus.ACTIVE, null, null, null)); // try to add a second collection event with the same visit number try { exec(new CollectionEventSaveAction(null, provisioning.patientIds.get(0), visitNumber, ActivityStatus.ACTIVE, null, null, null)); Assert .fail("should throw an exception because the visit number is already used"); } catch (ConstraintViolationException e) { Assert.assertTrue(true); } } @Test public void gsetEventAttrInfos() throws Exception { // add specimen type setEventAttrs(provisioning.studyId); StudyInfo studyInfo = exec(new StudyGetInfoAction(provisioning.studyId)); Assert.assertEquals(5, studyInfo.getStudyEventAttrs().size()); StudyEventAttr phlebotomistStudyAttr = null; for (StudyEventAttr attr : studyInfo.getStudyEventAttrs()) { if ("Phlebotomist".equals(attr.getGlobalEventAttr().getLabel())) { phlebotomistStudyAttr = attr; } } Assert.assertNotNull(phlebotomistStudyAttr); EventAttrTypeEnum eventAttrType = EventAttrTypeEnum.getEventAttrType(phlebotomistStudyAttr .getGlobalEventAttr().getEventAttrType().getName()); List<CEventAttrSaveInfo> attrs = new ArrayList<CollectionEventSaveAction.CEventAttrSaveInfo>(); String value = "abcdefghi"; CEventAttrSaveInfo attrInfo = CollectionEventHelper.createSaveCEventAttrInfo( phlebotomistStudyAttr.getId(), eventAttrType, value); attrs.add(attrInfo); Integer visitNber = getR().nextInt(20) + 1; // Save a new cevent final Integer ceventId = exec( new CollectionEventSaveAction(null, provisioning.patientIds .get(0), visitNber, ActivityStatus.ACTIVE, null, null, attrs)).getId(); // Call get eventAttr infos action Map<Integer, EventAttrInfo> infos = exec(new CollectionEventGetEventAttrInfoAction( ceventId)).getMap(); Assert.assertEquals(1, infos.size()); EventAttrInfo info = infos.values().iterator().next(); Assert.assertNotNull(info.attr); Assert.assertEquals(eventAttrType, info.type); Assert.assertEquals(ceventId, info.attr.getCollectionEvent().getId()); Assert.assertEquals(value, info.attr.getValue()); Assert.assertEquals(phlebotomistStudyAttr.getId(), info.attr .getStudyEventAttr().getId()); } }