package uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support.extent; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*; import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.*; import java.util.ArrayList; import java.util.List; import static org.mockito.AdditionalMatchers.and; import static org.mockito.Mockito.*; /** * Tests for DiseaseExtentGenerator. * Copyright (c) 2015 University of Oxford */ public class DiseaseExtentGeneratorTest extends BaseDiseaseExtentGenerationTests { private DiseaseService diseaseService; private ModelRunService modelRunService; private GeometryService geometryService; private ValidationParameterCacheService cacheService; private DiseaseExtentGenerationInputDataSelector dataSelector; private DiseaseExtentGeneratorHelperFactory helperFactory; private DiseaseExtentGenerator diseaseExtentGenerator; private DateTime minimumOccurrenceDate; private DiseaseExtentGenerationInputData validatorInputData; private DiseaseExtentGenerationInputData modellingInputData; private DiseaseExtentGeneratorHelper helper; private List<DiseaseOccurrence> validatorInputOccurrences; @Before public void setUp() { baseSetup(); diseaseService = mock(DiseaseService.class); modelRunService = mock(ModelRunService.class); geometryService = mock(GeometryService.class); cacheService = mock(ValidationParameterCacheService.class); dataSelector = mock(DiseaseExtentGenerationInputDataSelector.class); helperFactory = mock(DiseaseExtentGeneratorHelperFactory.class); validatorInputData = mock(DiseaseExtentGenerationInputData.class); validatorInputOccurrences = createOccurrences(); when(validatorInputData.getOccurrences()).thenReturn(validatorInputOccurrences); modellingInputData = mock(DiseaseExtentGenerationInputData.class); helper = mock(DiseaseExtentGeneratorHelper.class); when(dataSelector.selectForValidatorExtent(eq(diseaseGroup), eq(adminUnits), anyBoolean(), any(DiseaseProcessType.class), any(DateTime.class))).thenReturn(validatorInputData); when(dataSelector.selectForModellingExtent(eq(diseaseGroup), eq(validatorInputData))).thenReturn(modellingInputData); diseaseExtentGenerator = new DiseaseExtentGenerator(dataSelector, helperFactory, geometryService, diseaseService, modelRunService, cacheService); minimumOccurrenceDate = DateTime.now().minusHours(1); } @Test public void generateDiseaseExtentCorrectlyDetectsIfThisIsAnInitialExtent() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(false); setupHelperFactory(validatorInputData, helper, createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.AUTOMATIC); // Assert verify(dataSelector).selectForValidatorExtent(diseaseGroup, adminUnits, true, DiseaseProcessType.AUTOMATIC, minimumOccurrenceDate); verify(helper).computeDiseaseExtent(); } @Test public void generateDiseaseExtentCalculatesNewValidatorExtentWithCorrectData() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); setupHelperFactory(validatorInputData, helper, createRandomDiseaseExtentResults()); setupHelperFactory(modellingInputData, mock(DiseaseExtentGeneratorHelper.class), createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.AUTOMATIC); // Assert verify(dataSelector).selectForValidatorExtent(diseaseGroup, adminUnits, false, DiseaseProcessType.AUTOMATIC, minimumOccurrenceDate); verify(helperFactory).createHelper(diseaseGroup, validatorInputData); verify(helper).computeDiseaseExtent(); } @Test public void generateDiseaseExtentCalculatesNewModellingExtentWithCorrectDataForAutomaticNonInitial() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), createRandomDiseaseExtentResults()); setupHelperFactory(modellingInputData, helper, createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.AUTOMATIC); // Assert verify(dataSelector).selectForModellingExtent(diseaseGroup, validatorInputData); verify(helperFactory).createHelper(diseaseGroup, modellingInputData); verify(helper).computeDiseaseExtent(); } @Test public void generateDiseaseExtentSkipsNewModellingExtentWithCorrectDataForAutomaticInitial() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(false); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), createRandomDiseaseExtentResults()); setupHelperFactory(modellingInputData, helper, createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.AUTOMATIC); // Assert verify(dataSelector, never()).selectForModellingExtent(diseaseGroup, validatorInputData); verify(helperFactory, never()).createHelper(diseaseGroup, modellingInputData); verify(helper, never()).computeDiseaseExtent(); } @Test public void generateDiseaseExtentSkipsNewModellingExtentWithCorrectDataForManualInitial() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(false); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), createRandomDiseaseExtentResults()); setupHelperFactory(modellingInputData, helper, createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.MANUAL); // Assert verify(dataSelector, never()).selectForModellingExtent(diseaseGroup, validatorInputData); verify(helperFactory, never()).createHelper(diseaseGroup, modellingInputData); verify(helper, never()).computeDiseaseExtent(); } @Test public void generateDiseaseExtentSkipsNewModellingExtentWithCorrectDataForManualNonInitial() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), createRandomDiseaseExtentResults()); setupHelperFactory(modellingInputData, helper, createRandomDiseaseExtentResults()); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.MANUAL); // Assert verify(dataSelector, never()).selectForModellingExtent(diseaseGroup, validatorInputData); verify(helperFactory, never()).createHelper(diseaseGroup, modellingInputData); verify(helper, never()).computeDiseaseExtent(); } @Test public void generateDiseaseExtentSavesCalculatedResultsCorrectWhenBothResultsSetsCreated() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); DiseaseExtentGenerationOutputData validatorResult = createRandomDiseaseExtentResults(); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), validatorResult); DiseaseExtentGenerationOutputData modellingResult = createRandomDiseaseExtentResults(); setupHelperFactory(modellingInputData, mock(DiseaseExtentGeneratorHelper.class), modellingResult); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.AUTOMATIC); // Assert assertSaved(adminUnits, validatorResult, modellingResult, validatorInputOccurrences, new ArrayList<AdminUnitDiseaseExtentClass>()); } @Test public void generateDiseaseExtentSavesCalculatedResultsCorrectWhenOnlyValidatorResultsSetCreated() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); DiseaseExtentGenerationOutputData validatorResult = createRandomDiseaseExtentResults(); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), validatorResult); DiseaseExtentGenerationOutputData modellingResult = createRandomDiseaseExtentResults(); setupHelperFactory(modellingInputData, mock(DiseaseExtentGeneratorHelper.class), modellingResult); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.MANUAL); // Assert assertSaved(adminUnits, validatorResult, validatorResult, validatorInputOccurrences, new ArrayList<AdminUnitDiseaseExtentClass>()); } @Test public void generateDiseaseExtentSavesOverExistingResults() throws Exception { // Arrange setupAdminUnits(adminUnits); setupOldModelRun(true); DiseaseExtentGenerationOutputData validatorResult = createRandomDiseaseExtentResults(); setupHelperFactory(validatorInputData, mock(DiseaseExtentGeneratorHelper.class), validatorResult); DiseaseExtentGenerationOutputData modellingResult = createRandomDiseaseExtentResults(); setupHelperFactory(modellingInputData, mock(DiseaseExtentGeneratorHelper.class), modellingResult); List<AdminUnitDiseaseExtentClass> existingDiseaseExtent = createRandomExistingDiseaseExtent(); setupExistingExtent(existingDiseaseExtent); // Act diseaseExtentGenerator.generateDiseaseExtent(diseaseGroup, minimumOccurrenceDate, DiseaseProcessType.MANUAL); // Assert assertSaved(adminUnits, validatorResult, validatorResult, validatorInputOccurrences, existingDiseaseExtent); } private void assertSaved(List<? extends AdminUnitGlobalOrTropical> adminUnits, DiseaseExtentGenerationOutputData validatorResult, DiseaseExtentGenerationOutputData modellingResult, List<DiseaseOccurrence> occurrencesForLastValidatorExtent, List<AdminUnitDiseaseExtentClass> existingDiseaseExtent) { for (AdminUnitGlobalOrTropical adminUnit : adminUnits) { AdminUnitDiseaseExtentClass existingObject = findExistingObject(adminUnit.getGaulCode(), existingDiseaseExtent); AdminUnitDiseaseExtentClass expectation = new AdminUnitDiseaseExtentClass(); expectation.setDiseaseGroup(diseaseGroup); expectation.setAdminUnitGlobalOrTropical(adminUnit); expectation.setValidatorDiseaseExtentClass(validatorResult.getDiseaseExtentClassByGaulCode().get(adminUnit.getGaulCode())); expectation.setDiseaseExtentClass(modellingResult.getDiseaseExtentClassByGaulCode().get(adminUnit.getGaulCode())); if (existingObject != null && existingObject.getValidatorDiseaseExtentClass() == validatorResult.getDiseaseExtentClassByGaulCode().get(adminUnit.getGaulCode())) { expectation.setClassChangedDate(existingObject.getClassChangedDate()); } else { expectation.setClassChangedDate(DateTime.now()); } expectation.setValidatorOccurrenceCount(validatorResult.getOccurrenceCounts().get(adminUnit.getGaulCode())); expectation.setLatestValidatorOccurrences(validatorResult.getLatestOccurrencesByGaulCode().get(adminUnit.getGaulCode())); if (existingObject == null) { verify(diseaseService).saveAdminUnitDiseaseExtentClass(eq(expectation)); } else { verify(diseaseService).saveAdminUnitDiseaseExtentClass(and(eq(expectation), same(existingObject))); } } verify(cacheService).clearDistanceToExtentCacheForDisease(diseaseGroup.getId()); verify(diseaseGroup.getDiseaseExtentParameters()).setLastValidatorExtentUpdateInputOccurrences(occurrencesForLastValidatorExtent); verify(diseaseGroup).setLastExtentGenerationDate(eq(DateTime.now())); verify(diseaseService).saveDiseaseGroup(diseaseGroup); } private AdminUnitDiseaseExtentClass findExistingObject(int gaulCode, List<AdminUnitDiseaseExtentClass> existingDiseaseExtent) { for (AdminUnitDiseaseExtentClass adminUnitDiseaseExtentClass : existingDiseaseExtent) { if (adminUnitDiseaseExtentClass.getAdminUnitGlobalOrTropical().getGaulCode() == gaulCode) { return adminUnitDiseaseExtentClass; } } return null; } private void setupAdminUnits(final List<? extends AdminUnitGlobalOrTropical> expectedAdminUnits) { when(geometryService.getAllAdminUnitGlobalsOrTropicalsForDiseaseGroup(diseaseGroup)).thenAnswer(new Answer<List<? extends AdminUnitGlobalOrTropical>>() { @Override public List<? extends AdminUnitGlobalOrTropical> answer(InvocationOnMock invocationOnMock) throws Throwable { return expectedAdminUnits; } }); } private void setupOldModelRun(boolean hasRun) { when(modelRunService.getMostRecentlyRequestedModelRunWhichCompleted(diseaseGroupId)).thenReturn(hasRun ? mock(ModelRun.class) : null); } private void setupHelperFactory(DiseaseExtentGenerationInputData inputData, DiseaseExtentGeneratorHelper helperResult, DiseaseExtentGenerationOutputData result) { when(helperFactory.createHelper(diseaseGroup, inputData)).thenReturn(helperResult); when(helperResult.computeDiseaseExtent()).thenReturn(result); } private void setupExistingExtent(List<AdminUnitDiseaseExtentClass> existingDiseaseExtent) { when(diseaseService.getDiseaseExtentByDiseaseGroupId(diseaseGroup.getId())).thenReturn(existingDiseaseExtent); } }