package uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support; import org.junit.Before; import org.junit.Test; import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.NativeSQL; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*; import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.LocationService; import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.ValidationParameterCacheService; import java.util.ArrayList; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Tests the DistanceFromDiseaseExtentHelper class. * * Copyright (c) 2014 University of Oxford */ public class DistanceFromDiseaseExtentHelperTest { private NativeSQL nativeSQL; private DistanceFromDiseaseExtentHelper helper; private LocationService locationService; private ValidationParameterCacheService cacheService; @Before public void setUp() { nativeSQL = mock(NativeSQL.class); locationService = mock(LocationService.class); cacheService = mock(ValidationParameterCacheService.class); when(cacheService.getDistanceToExtentFromCache(anyInt(), anyInt())).thenReturn(null); helper = new DistanceFromDiseaseExtentHelper(nativeSQL, locationService, cacheService); } @Test public void findDistanceFromDiseaseExtentWhenLocationIsOutsideTheExtentReturnsDistanceOutside() { // Arrange int diseaseGroupId = 87; int locationId = 123; double expectedDistance = 25; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.UNCERTAIN, DiseaseExtentClass.POSSIBLE_ABSENCE, DiseaseExtentClass.ABSENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(expectedDistance); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(321d); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isEqualTo(expectedDistance); verify(cacheService).saveDistanceToExtentCacheEntry(diseaseGroupId, locationId, actualDistance); } @Test public void findDistanceFromDiseaseExtentWhenLocationIsWithinTheExtentReturnsDistanceWithin() { // Arrange int diseaseGroupId = 87; int locationId = 123; double expectedDistance = 25; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.POSSIBLE_PRESENCE, DiseaseExtentClass.PRESENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(123d); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(expectedDistance); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isEqualTo(-expectedDistance); verify(cacheService).saveDistanceToExtentCacheEntry(diseaseGroupId, locationId, actualDistance); } @Test public void findDistanceFromDiseaseExtentWhenCalculationOutsideReturnsNull() { int diseaseGroupId = 87; int locationId = 123; double expectedDistance = 25; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.UNCERTAIN, DiseaseExtentClass.POSSIBLE_ABSENCE, DiseaseExtentClass.ABSENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(null); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(321d); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isNull(); } @Test public void findDistanceFromDiseaseExtentWhenCalculationInsideReturnsNull() { int diseaseGroupId = 87; int locationId = 123; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.POSSIBLE_PRESENCE, DiseaseExtentClass.PRESENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(123d); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(null); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isNull(); } @Test public void findDistanceFromDiseaseExtentWhenSplitCountryCrossingBoarder() { int diseaseGroupId = 87; int locationId = 123; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.PRESENCE, DiseaseExtentClass.POSSIBLE_PRESENCE, DiseaseExtentClass.UNCERTAIN, DiseaseExtentClass.POSSIBLE_ABSENCE, DiseaseExtentClass.ABSENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(123d); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(321d); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isEqualTo(0); } @Test public void findDistanceFromDiseaseExtentWhenNoExtent() { int diseaseGroupId = 87; int locationId = 123; boolean isGlobal = false; Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); when(nativeSQL.findDistanceInsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(123d); when(nativeSQL.findDistanceOutsideDiseaseExtent(diseaseGroupId, isGlobal, locationId)).thenReturn(321d); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isNull(); } public void findDistanceFromDiseaseExtentUsesCacheWhenOutside() { int diseaseGroupId = 87; int locationId = 123; double expectedDistance = 25; boolean isGlobal = false; when(cacheService.getDistanceToExtentFromCache(diseaseGroupId, locationId)).thenReturn(expectedDistance); Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.UNCERTAIN, DiseaseExtentClass.POSSIBLE_ABSENCE, DiseaseExtentClass.ABSENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isEqualTo(expectedDistance); } public void findDistanceFromDiseaseExtentUsesCacheWhenInside() { // Arrange int diseaseGroupId = 87; int locationId = 123; double expectedDistance = -25; boolean isGlobal = false; when(cacheService.getDistanceToExtentFromCache(diseaseGroupId, locationId)).thenReturn(expectedDistance); Location location = mock(Location.class); when(location.getId()).thenReturn(locationId); setupExtentClass(diseaseGroupId, isGlobal, location, DiseaseExtentClass.POSSIBLE_PRESENCE, DiseaseExtentClass.PRESENCE); DiseaseOccurrence occurrence = createDiseaseOccurrence(diseaseGroupId, isGlobal, location); // Act Double actualDistance = helper.findDistanceFromDiseaseExtent(occurrence); // Assert assertThat(actualDistance).isEqualTo(expectedDistance); } private void setupExtentClass(int disease, boolean isGlobal, Location location, String... extentClassNames) { List<AdminUnitDiseaseExtentClass> classes = new ArrayList<>(); for (String name : extentClassNames) { AdminUnitDiseaseExtentClass adminExtentClass = mock(AdminUnitDiseaseExtentClass.class); DiseaseExtentClass extentClass = mock(DiseaseExtentClass.class); when(adminExtentClass.getDiseaseExtentClass()).thenReturn(extentClass); when(extentClass.getName()).thenReturn(name); classes.add(adminExtentClass); } when(locationService.getAdminUnitDiseaseExtentClassesForLocation(disease, isGlobal, location)).thenReturn(classes); } private DiseaseOccurrence createDiseaseOccurrence(int diseaseGroupId, boolean isGlobal, Location location) { DiseaseOccurrence occurrence = new DiseaseOccurrence(); DiseaseGroup diseaseGroup = new DiseaseGroup(diseaseGroupId); diseaseGroup.setGlobal(isGlobal); occurrence.setDiseaseGroup(diseaseGroup); occurrence.setLocation(location); return occurrence; } }