package uk.ac.ox.zoo.seeg.abraid.mp.common.dao; import org.apache.commons.lang.StringUtils; import org.hibernate.exception.ConstraintViolationException; import org.joda.time.DateTime; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import uk.ac.ox.zoo.seeg.abraid.mp.common.AbstractCommonSpringIntegrationTests; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*; import java.util.List; import static ch.lambdaj.Lambda.extract; import static ch.lambdaj.Lambda.on; import static org.assertj.core.api.Assertions.assertThat; /** * Tests the DiseaseGroupDao class. * * Copyright (c) 2014 University of Oxford */ public class DiseaseGroupDaoTest extends AbstractCommonSpringIntegrationTests { @Autowired private DiseaseGroupDao diseaseGroupDao; @Autowired private DiseaseOccurrenceDao diseaseOccurrenceDao; @Autowired private ValidatorDiseaseGroupDao validatorDiseaseGroupDao; @Autowired private DiseaseOccurrenceReviewDao diseaseOccurrenceReviewDao; @Autowired private AdminUnitReviewDao adminUnitReviewDao; @Autowired private AdminUnitTropicalDao adminUnitTropicalDao; @Autowired private AdminUnitGlobalDao adminUnitGlobalDao; @Autowired private DiseaseExtentClassDao diseaseExtentClassDao; @Autowired private AdminUnitDiseaseExtentClassDao adminUnitDiseaseExtentClassDao; @Autowired private ExpertDao expertDao; @Autowired private LocationDao locationDao; @Autowired private AlertDao alertDao; @Test public void saveAndReloadDiseaseCluster() { // Arrange String diseaseClusterName = "Test disease cluster"; String diseaseClusterPublicName = "Test disease cluster public name"; String diseaseClusterShortName = "Short name"; String diseaseClusterAbbreviation = "tdc"; String mode = "Bhatt2013"; int validatorDiseaseGroupId = 2; ValidatorDiseaseGroup validatorDiseaseGroup = validatorDiseaseGroupDao.getById(validatorDiseaseGroupId); DateTime lastModelRunPrepDate = DateTime.now().minusHours(2); int minNewLocations = 100; double maxEnvironmentalSuitability = 0.5; double minDistanceFromDiseaseExtent = 1; double maxEnvironmentalSuitabilityWithoutML = 0.4; double weighting = 0.5; DiseaseGroup diseaseGroup = new DiseaseGroup(); DiseaseExtent parameters = new DiseaseExtent(diseaseGroup); diseaseGroup.setName(diseaseClusterName); diseaseGroup.setGroupType(DiseaseGroupType.CLUSTER); diseaseGroup.setPublicName(diseaseClusterPublicName); diseaseGroup.setShortName(diseaseClusterShortName); diseaseGroup.setAbbreviation(diseaseClusterAbbreviation); diseaseGroup.setValidatorDiseaseGroup(validatorDiseaseGroup); diseaseGroup.setLastModelRunPrepDate(lastModelRunPrepDate); diseaseGroup.setMinNewLocationsTrigger(minNewLocations); diseaseGroup.setMaxEnvironmentalSuitabilityForTriggering(maxEnvironmentalSuitability); diseaseGroup.setMinDistanceFromDiseaseExtentForTriggering(minDistanceFromDiseaseExtent); diseaseGroup.setMaxEnvironmentalSuitabilityWithoutML(maxEnvironmentalSuitabilityWithoutML); diseaseGroup.setWeighting(weighting); diseaseGroup.setUseMachineLearning(false); diseaseGroup.setGlobal(true); diseaseGroup.setPriorityDisease(true); diseaseGroup.setDiseaseExtentParameters(parameters); diseaseGroup.setModelMode(mode); // Act diseaseGroupDao.save(diseaseGroup); // Assert assertThat(diseaseGroup.getCreatedDate()).isNotNull(); Integer id = diseaseGroup.getId(); flushAndClear(); diseaseGroup = diseaseGroupDao.getById(id); assertThat(diseaseGroup).isNotNull(); assertThat(diseaseGroup.getName()).isEqualTo(diseaseClusterName); assertThat(diseaseGroup.getGroupType()).isEqualTo(DiseaseGroupType.CLUSTER); assertThat(diseaseGroup.getPublicName()).isEqualTo(diseaseClusterPublicName); assertThat(diseaseGroup.getShortName()).isEqualTo(diseaseClusterShortName); assertThat(diseaseGroup.getAbbreviation()).isEqualTo(diseaseClusterAbbreviation); assertThat(diseaseGroup.getModelMode()).isEqualTo(mode); assertThat(diseaseGroup.getValidatorDiseaseGroup()).isNotNull(); assertThat(diseaseGroup.getValidatorDiseaseGroup().getId()).isEqualTo(validatorDiseaseGroupId); assertThat(diseaseGroup.getLastModelRunPrepDate()).isEqualTo(lastModelRunPrepDate); assertThat(diseaseGroup.getMinNewLocationsTrigger()).isEqualTo(minNewLocations); assertThat(diseaseGroup.getMaxEnvironmentalSuitabilityForTriggering()).isEqualTo(maxEnvironmentalSuitability); assertThat(diseaseGroup.getMinDistanceFromDiseaseExtentForTriggering()).isEqualTo(minDistanceFromDiseaseExtent); assertThat(diseaseGroup.getMaxEnvironmentalSuitabilityWithoutML()).isEqualTo( maxEnvironmentalSuitabilityWithoutML); assertThat(diseaseGroup.useMachineLearning()).isFalse(); assertThat(diseaseGroup.getWeighting()).isEqualTo(weighting); assertThat(diseaseGroup.isGlobal()).isTrue(); assertThat(diseaseGroup.isPriorityDisease()).isTrue(); assertThat(diseaseGroup.getParentGroup()).isNull(); assertThat(diseaseGroup.getCreatedDate()).isNotNull(); assertThat(diseaseGroup.getDiseaseExtentParameters()).isEqualToIgnoringGivenFields(parameters, "lastValidatorExtentUpdateInputOccurrences"); assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).isEmpty(); // Null should become empty collection } @Test public void saveAndReloadDiseaseMicroCluster() { // Arrange String diseaseClusterName = "Test disease microcluster"; DiseaseGroup diseaseCluster = diseaseGroupDao.getById(1); DiseaseGroup diseaseGroup = new DiseaseGroup(); DiseaseExtent parameters = new DiseaseExtent(diseaseGroup); diseaseGroup.setName(diseaseClusterName); diseaseGroup.setGroupType(DiseaseGroupType.MICROCLUSTER); diseaseGroup.setParentGroup(diseaseCluster); diseaseGroup.setDiseaseExtentParameters(parameters); // Act diseaseGroupDao.save(diseaseGroup); Integer id = diseaseGroup.getId(); flushAndClear(); // Assert diseaseGroup = diseaseGroupDao.getById(id); assertThat(diseaseGroup).isNotNull(); assertThat(diseaseGroup.getName()).isEqualTo(diseaseClusterName); assertThat(diseaseGroup.getGroupType()).isEqualTo(DiseaseGroupType.MICROCLUSTER); assertThat(diseaseGroup.getParentGroup()).isNotNull(); assertThat(diseaseGroup.getParentGroup()).isEqualTo(diseaseCluster); assertThat(diseaseGroup.getCreatedDate()).isNotNull(); assertThat(diseaseGroup.useMachineLearning()).isTrue(); assertThat(diseaseGroup.getDiseaseExtentParameters()).isEqualToIgnoringGivenFields(parameters, "lastValidatorExtentUpdateInputOccurrences"); assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).isEmpty(); // Null should become empty collection } @Test public void saveAndReloadDisease() { // Arrange String diseaseName = "Test single disease"; String diseaseMicroClusterName = "Test microcluster"; DiseaseGroup diseaseCluster = diseaseGroupDao.getById(5); DiseaseGroup diseaseMicroCluster = new DiseaseGroup(diseaseCluster, diseaseMicroClusterName, DiseaseGroupType.MICROCLUSTER); DiseaseGroup disease = new DiseaseGroup(diseaseMicroCluster, diseaseName, DiseaseGroupType.SINGLE); DiseaseExtent parameters = new DiseaseExtent(disease); disease.setDiseaseExtentParameters(parameters); // Act diseaseGroupDao.save(diseaseMicroCluster); diseaseGroupDao.save(disease); Integer id = disease.getId(); flushAndClear(); // Assert disease = diseaseGroupDao.getById(id); assertThat(disease).isNotNull(); assertThat(disease.getName()).isEqualTo(diseaseName); assertThat(disease.getGroupType()).isEqualTo(DiseaseGroupType.SINGLE); assertThat(disease.getParentGroup()).isNotNull(); assertThat(disease.getParentGroup()).isEqualTo(diseaseMicroCluster); assertThat(disease.getParentGroup().getParentGroup()).isNotNull(); assertThat(disease.getParentGroup().getParentGroup()).isEqualTo(diseaseCluster); assertThat(disease.getCreatedDate()).isNotNull(); assertThat(disease.getDiseaseExtentParameters()).isEqualToIgnoringGivenFields(parameters, "lastValidatorExtentUpdateInputOccurrences"); assertThat(disease.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).isEmpty(); // Null should become empty collection } @Test public void loadNonExistentDiseaseGroup() { DiseaseGroup diseaseGroup = diseaseGroupDao.getById(-1); assertThat(diseaseGroup).isNull(); } @Test public void getAllDiseaseGroups() { List<DiseaseGroup> diseaseGroups = diseaseGroupDao.getAll(); assertThat(diseaseGroups).hasSize(391); } @Test public void getIdsForAutomaticModelRunsIsEmpty() { List<Integer> ids = diseaseGroupDao.getIdsForAutomaticModelRuns(); assertThat(ids).hasSize(0); } @Test public void getIdsForAutomaticModelRuns() { int id = 87; setAutomaticModelRunsStartDate(id); List<Integer> ids = diseaseGroupDao.getIdsForAutomaticModelRuns(); assertThat(ids).hasSize(1); assertThat(ids.get(0)).isEqualTo(id); } @Test public void getDiseaseGroupsNeedingOccurrenceReviewByExpert() { // Arrange setAuto(31); setAuto(112); setAuto(14); flushAndClear(); int id1 = createOccurrenceNeedingReview(31); // reviewed int id2 = createOccurrenceNeedingReview(112); // reviewed int id3 = createOccurrenceNeedingReview(112); // only reviewed by other experts int id4 = createOccurrenceNeedingReview(22); // not reviewed, but not auto int id5 = createOccurrenceNeedingReview(14); // not review flushAndClear(); createOccurrenceReview(1, id1); createOccurrenceReview(1, id2); createOccurrenceReview(2, id3); flushAndClear(); // Act List<DiseaseGroup> result = diseaseGroupDao.getDiseaseGroupsNeedingOccurrenceReviewByExpert(1); // Assert assertThat(extract(result, on(DiseaseGroup.class).getId())).containsOnly(112, 14); } private void createOccurrenceReview(int expertId, int occurrenceId) { DiseaseOccurrenceReview review = new DiseaseOccurrenceReview( expertDao.getById(expertId), diseaseOccurrenceDao.getById(occurrenceId), DiseaseOccurrenceReviewResponse.UNSURE ); diseaseOccurrenceReviewDao.save(review); } private int createOccurrenceNeedingReview(int diseaseGroupId) { DiseaseOccurrence occurrence = new DiseaseOccurrence( diseaseGroupDao.getById(diseaseGroupId), DateTime.now(), locationDao.getById(6), alertDao.getById(212855)); occurrence.setStatus(DiseaseOccurrenceStatus.IN_REVIEW); diseaseOccurrenceDao.save(occurrence); return occurrence.getId(); } @Test public void getDiseaseGroupsNeedingExtentReviewByExpert() { // Arrange setAuto(31); setAuto(112); setAuto(14); setAuto(52); flushAndClear(); createAdminUnitDiseaseExtentClass(2, null, 31); // reviewed createAdminUnitDiseaseExtentClass(14, null, 112); // reviewed createAdminUnitDiseaseExtentClass(null, 13, 112); // only reviewed by other experts createAdminUnitDiseaseExtentClass(null, 13, 22); // not reviewed, but not auto createAdminUnitDiseaseExtentClass(null, 21, 52); // not reviewed AdminUnitDiseaseExtentClass toChange = createAdminUnitDiseaseExtentClass(null, 13, 14); // reviewed flushAndClear(); createAdminUnitReview(1, 2, null, 31); createAdminUnitReview(1, 14, null, 112); createAdminUnitReview(2, null, 13, 112); createAdminUnitReview(1, null, 13, 14); flushAndClear(); toChange = adminUnitDiseaseExtentClassDao.getById(toChange.getId()); toChange.setClassChangedDate(DateTime.now().plusHours(1)); adminUnitDiseaseExtentClassDao.save(toChange); // review is now too old flushAndClear(); // Act List<DiseaseGroup> result = diseaseGroupDao.getDiseaseGroupsNeedingExtentReviewByExpert(1); // Assert assertThat(extract(result, on(DiseaseGroup.class).getId())).containsOnly(112, 14, 52); } private void setAuto(int diseaseGroupId) { DiseaseGroup diseaseGroup = diseaseGroupDao.getById(diseaseGroupId); diseaseGroup.setAutomaticModelRunsStartDate(DateTime.now()); diseaseGroupDao.save(diseaseGroup); } private AdminUnitReview createAdminUnitReview(int expertId, Integer adminUnitGlobalGaulCode, Integer adminUnitTropicalGaulCode, int diseaseGroupId) { AdminUnitReview review = new AdminUnitReview( expertDao.getById(expertId), adminUnitGlobalGaulCode, adminUnitTropicalGaulCode, diseaseGroupDao.getById(diseaseGroupId), diseaseExtentClassDao.getByName(DiseaseExtentClass.UNCERTAIN)); adminUnitReviewDao.save(review); return review; } private AdminUnitDiseaseExtentClass createAdminUnitDiseaseExtentClass(Integer adminUnitGlobalGaulCode, Integer adminUnitTropicalGaulCode, int diseaseGroupId) { AdminUnitDiseaseExtentClass extentClass = null; if (adminUnitGlobalGaulCode == null) { extentClass = new AdminUnitDiseaseExtentClass( adminUnitTropicalDao.getByGaulCode(adminUnitTropicalGaulCode), diseaseGroupDao.getById(diseaseGroupId), diseaseExtentClassDao.getByName(DiseaseExtentClass.PRESENCE), diseaseExtentClassDao.getByName(DiseaseExtentClass.PRESENCE), 3); } else { extentClass = new AdminUnitDiseaseExtentClass( adminUnitGlobalDao.getByGaulCode(adminUnitGlobalGaulCode), diseaseGroupDao.getById(diseaseGroupId), diseaseExtentClassDao.getByName(DiseaseExtentClass.PRESENCE), diseaseExtentClassDao.getByName(DiseaseExtentClass.PRESENCE), 3); } extentClass.setClassChangedDate(DateTime.now().minusDays(1)); adminUnitDiseaseExtentClassDao.save(extentClass); return extentClass; } @Test(expected = ConstraintViolationException.class) public void duplicatingADiseaseGroupNameViolatesCaseInsensitiveUniqueConstraint() { DiseaseGroup diseaseGroup1 = diseaseGroupDao.getById(22); DiseaseGroup diseaseGroup2 = diseaseGroupDao.getById(87); String name = StringUtils.swapCase(diseaseGroup1.getName()); diseaseGroup2.setName(name); diseaseGroupDao.save(diseaseGroup2); flushAndClear(); } @Test(expected = ConstraintViolationException.class) public void duplicatingADiseaseGroupPublicNameViolatesCaseInsensitiveUniqueConstraint() { DiseaseGroup diseaseGroup1 = diseaseGroupDao.getById(22); DiseaseGroup diseaseGroup2 = diseaseGroupDao.getById(87); String publicName = StringUtils.swapCase(diseaseGroup1.getPublicName()); diseaseGroup2.setPublicName(publicName); diseaseGroupDao.save(diseaseGroup2); flushAndClear(); } @Test(expected = ConstraintViolationException.class) public void duplicatingADiseaseGroupShortNameViolatesCaseInsensitiveUniqueConstraint() { DiseaseGroup diseaseGroup1 = diseaseGroupDao.getById(22); DiseaseGroup diseaseGroup2 = diseaseGroupDao.getById(87); String shortName = StringUtils.swapCase(diseaseGroup1.getShortName()); diseaseGroup2.setShortName(shortName); diseaseGroupDao.save(diseaseGroup2); flushAndClear(); } @Test(expected = ConstraintViolationException.class) public void duplicatingADiseaseGroupAbbreviationViolatesCaseInsensitiveUniqueConstraint() { DiseaseGroup diseaseGroup1 = diseaseGroupDao.getById(22); DiseaseGroup diseaseGroup2 = diseaseGroupDao.getById(87); String abbreviation = StringUtils.swapCase(diseaseGroup1.getAbbreviation()); diseaseGroup2.setAbbreviation(abbreviation); diseaseGroupDao.save(diseaseGroup2); flushAndClear(); } private void setAutomaticModelRunsStartDate(int id) { DiseaseGroup diseaseGroup = diseaseGroupDao.getById(id); diseaseGroup.setAutomaticModelRunsStartDate(DateTime.now()); diseaseGroupDao.save(diseaseGroup); flushAndClear(); } @Test public void getExistingDiseaseExtent() { DiseaseGroup diseaseGroup = diseaseGroupDao.getById(87); DiseaseExtent diseaseExtent = diseaseGroup.getDiseaseExtentParameters(); assertThat(diseaseExtent.getMaxMonthsAgoForHigherOccurrenceScore()).isEqualTo(24); assertThat(diseaseExtent.getMinValidationWeighting()).isEqualTo(0.6); } @Test public void updateExistingDiseaseExtent() { // Arrange DiseaseGroup diseaseGroup = diseaseGroupDao.getById(87); DiseaseExtent diseaseExtent = diseaseGroup.getDiseaseExtentParameters(); // Act diseaseExtent.setMaxMonthsAgoForHigherOccurrenceScore(48); diseaseGroupDao.save(diseaseGroup); flushAndClear(); // Assert diseaseGroup = diseaseGroupDao.getById(87); assertThat(diseaseGroup.getDiseaseExtentParameters().getMaxMonthsAgoForHigherOccurrenceScore()).isEqualTo(48); } @Test public void updateExistingDiseaseExtentWithLastOccurrences() { // Arrange DiseaseGroup diseaseGroup = diseaseGroupDao.getById(87); DiseaseExtent diseaseExtent = diseaseGroup.getDiseaseExtentParameters(); List<DiseaseOccurrence> dengueOccurrences = diseaseOccurrenceDao.getByDiseaseGroupId(87); assertThat(dengueOccurrences).isNotEmpty(); // Act diseaseExtent.setLastValidatorExtentUpdateInputOccurrences(dengueOccurrences); diseaseGroupDao.save(diseaseGroup); flushAndClear(); // Assert diseaseGroup = diseaseGroupDao.getById(87); for (DiseaseOccurrence occurrence : dengueOccurrences) { assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).contains(occurrence); } assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).hasSameSizeAs(dengueOccurrences); } @Test public void updateExistingDiseaseExtentWithLastOccurrencesTwice() { // Arrange List<DiseaseOccurrence> dengueOccurrences = diseaseOccurrenceDao.getByDiseaseGroupId(87); assertThat(dengueOccurrences).isNotEmpty(); // Act DiseaseGroup diseaseGroup = diseaseGroupDao.getById(87); diseaseGroup.getDiseaseExtentParameters().setLastValidatorExtentUpdateInputOccurrences(dengueOccurrences); diseaseGroupDao.save(diseaseGroup); flushAndClear(); diseaseGroup = diseaseGroupDao.getById(87); diseaseGroup.getDiseaseExtentParameters().setLastValidatorExtentUpdateInputOccurrences(dengueOccurrences.subList(2, 3)); diseaseGroupDao.save(diseaseGroup); sessionFactory.getCurrentSession().merge(diseaseGroup); flushAndClear(); // Assert diseaseGroup = diseaseGroupDao.getById(87); for (DiseaseOccurrence occurrence : dengueOccurrences.subList(2, 3)) { assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).contains(occurrence); } assertThat(diseaseGroup.getDiseaseExtentParameters().getLastValidatorExtentUpdateInputOccurrences()).hasSameSizeAs(dengueOccurrences.subList(2, 3)); } @Test public void addDiseaseExtentToDiseaseGroupSavesWithSameDiseaseGroupId() { // Arrange int diseaseGroupId = 1; DiseaseGroup diseaseGroup = diseaseGroupDao.getById(diseaseGroupId); DiseaseExtent diseaseExtent = new DiseaseExtent(diseaseGroup); diseaseGroup.setDiseaseExtentParameters(diseaseExtent); // Act diseaseGroupDao.save(diseaseGroup); flushAndClear(); // Assert diseaseGroup = diseaseGroupDao.getById(diseaseGroupId); assertThat(diseaseGroup.getDiseaseExtentParameters()).isNotNull(); assertThat(diseaseGroup.getDiseaseExtentParameters().getDiseaseGroupId()).isEqualTo(diseaseGroupId); } @Test public void getDiseaseGroupNamesForHealthMapReport() { // Act List<String> actual = diseaseGroupDao.getDiseaseGroupNamesForHealthMapReport(); // Assert assertThat(actual).hasSize(34); assertThat(actual.get(0)).isEqualTo("Ascariasis"); assertThat(actual.get(1)).isEqualTo("Chikungunya"); assertThat(actual.get(2)).isEqualTo("Cholera"); } @Test public void saveNewDiseaseGroupSavesDiseaseExtentWithSameId() { // Arrange DiseaseGroup diseaseGroup = initialiseDiseaseGroup(); DiseaseExtent parameters = new DiseaseExtent(diseaseGroup); diseaseGroup.setDiseaseExtentParameters(parameters); // Act diseaseGroupDao.save(diseaseGroup); flushAndClear(); // Assert assertThat(diseaseGroup.getId()).isNotNull(); assertThat(parameters.getDiseaseGroupId()).isEqualTo(diseaseGroup.getId()); } private DiseaseGroup initialiseDiseaseGroup() { DiseaseGroup diseaseGroup = new DiseaseGroup("Name"); diseaseGroup.setGroupType(DiseaseGroupType.SINGLE); diseaseGroup.setAutomaticModelRunsStartDate(DateTime.now()); return diseaseGroup; } }