package uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.healthmap; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.DiseaseOccurrence; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.Location; import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.Provenance; import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.AlertService; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.DiseaseOccurrenceDataAcquirer; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.healthmap.domain.HealthMapAlert; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.healthmap.domain.HealthMapLocation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; /** * Tests the HealthMapDataConverter class. * Copyright (c) 2014 University of Oxford */ public class HealthMapDataConverterTest { private AlertService alertService; private HealthMapLocationConverter locationConverter; private HealthMapAlertConverter alertConverter; private HealthMapLookupData healthMapLookupData; private HealthMapDataConverter healthMapDataConverter; private DiseaseOccurrenceDataAcquirer diseaseOccurrenceDataAcquirer; private Provenance healthMapProvenance; @Before public void setUp() { alertService = mock(AlertService.class); locationConverter = mock(HealthMapLocationConverter.class); alertConverter = mock(HealthMapAlertConverter.class); healthMapLookupData = mock(HealthMapLookupData.class); diseaseOccurrenceDataAcquirer = mock(DiseaseOccurrenceDataAcquirer.class); healthMapDataConverter = new HealthMapDataConverter(locationConverter, alertConverter, alertService, healthMapLookupData, diseaseOccurrenceDataAcquirer); healthMapProvenance = new Provenance(); when(healthMapLookupData.getHealthMapProvenance()).thenReturn(healthMapProvenance); } @Test public void convertNoLocations() { // Arrange List<HealthMapLocation> locations = new ArrayList<>(); DateTime retrievalEndDate = DateTime.now(); // Act healthMapDataConverter.convert(locations, retrievalEndDate); // Assert verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertTwoSuccessfulLocationsEachWithTwoSuccessfulAlerts() { // Arrange // Create 2 locations each with 2 alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapLocation healthMapLocation2 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); HealthMapAlert healthMapAlert2 = new HealthMapAlert(); HealthMapAlert healthMapAlert3 = new HealthMapAlert(); HealthMapAlert healthMapAlert4 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1, healthMapAlert2)); healthMapLocation2.setAlerts(Arrays.asList(healthMapAlert3, healthMapAlert4)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1, healthMapLocation2); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapLocation2 is successfully converted into location2 Location location2 = new Location(); when(locationConverter.convert(healthMapLocation2)).thenReturn(location2); // healthMapAlert1 is successfully converted into diseaseOccurrence1 DiseaseOccurrence diseaseOccurrence1 = new DiseaseOccurrence(1); mockConvertAndAcquire(healthMapAlert1, location1, diseaseOccurrence1, true); // healthMapAlert2 is successfully converted into diseaseOccurrence2 DiseaseOccurrence diseaseOccurrence2 = new DiseaseOccurrence(2); mockConvertAndAcquire(healthMapAlert2, location1, diseaseOccurrence2, true); // healthMapAlert3 is successfully converted into diseaseOccurrence3 DiseaseOccurrence diseaseOccurrence3 = new DiseaseOccurrence(3); mockConvertAndAcquire(healthMapAlert3, location2, diseaseOccurrence3, true); // healthMapAlert4 is successfully converted into diseaseOccurrence4 DiseaseOccurrence diseaseOccurrence4 = new DiseaseOccurrence(4); mockConvertAndAcquire(healthMapAlert4, location2, diseaseOccurrence4, true); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence1, diseaseOccurrence2, diseaseOccurrence3, diseaseOccurrence4); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertTwoSuccessfulLocationsEachWithOneSuccessfulOneFailedAlerts() { // Arrange // Create 2 locations each with 2 alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapLocation healthMapLocation2 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); HealthMapAlert healthMapAlert2 = new HealthMapAlert(); HealthMapAlert healthMapAlert3 = new HealthMapAlert(); HealthMapAlert healthMapAlert4 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1, healthMapAlert2)); healthMapLocation2.setAlerts(Arrays.asList(healthMapAlert3, healthMapAlert4)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1, healthMapLocation2); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapLocation2 is successfully converted into location2 Location location2 = new Location(); when(locationConverter.convert(healthMapLocation2)).thenReturn(location2); // healthMapAlert1 is successfully converted into diseaseOccurrence1 DiseaseOccurrence diseaseOccurrence1 = new DiseaseOccurrence(1); mockConvertAndAcquire(healthMapAlert1, location1, diseaseOccurrence1, true); // healthMapAlert2 is successfully converted into diseaseOccurrence2 DiseaseOccurrence diseaseOccurrence2 = new DiseaseOccurrence(2); mockConvertAndAcquire(healthMapAlert2, location1, diseaseOccurrence2, false); // healthMapAlert3 is successfully converted into diseaseOccurrence3 DiseaseOccurrence diseaseOccurrence3 = new DiseaseOccurrence(3); mockConvertAndAcquire(healthMapAlert3, location2, diseaseOccurrence3, false); // healthMapAlert4 is successfully converted into diseaseOccurrence4 DiseaseOccurrence diseaseOccurrence4 = new DiseaseOccurrence(4); mockConvertAndAcquire(healthMapAlert4, location2, diseaseOccurrence4, true); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence1, diseaseOccurrence4); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertFirstLocationFails() { // Arrange // Create 2 locations each with 2 alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapLocation healthMapLocation2 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); HealthMapAlert healthMapAlert2 = new HealthMapAlert(); HealthMapAlert healthMapAlert3 = new HealthMapAlert(); HealthMapAlert healthMapAlert4 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1, healthMapAlert2)); healthMapLocation2.setAlerts(Arrays.asList(healthMapAlert3, healthMapAlert4)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1, healthMapLocation2); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is not successfully converted into location1 when(locationConverter.convert(healthMapLocation1)).thenReturn(null); // healthMapLocation2 is successfully converted into location2 Location location2 = new Location(); when(locationConverter.convert(healthMapLocation2)).thenReturn(location2); // healthMapAlert3 is successfully converted into diseaseOccurrence3 DiseaseOccurrence diseaseOccurrence3 = new DiseaseOccurrence(3); mockConvertAndAcquire(healthMapAlert3, location2, diseaseOccurrence3, true); // healthMapAlert4 is successfully converted into diseaseOccurrence4 DiseaseOccurrence diseaseOccurrence4 = new DiseaseOccurrence(4); mockConvertAndAcquire(healthMapAlert4, location2, diseaseOccurrence4, true); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence3, diseaseOccurrence4); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertFirstLocationSucceedsSecondLocationFails() { // Arrange // Create 2 locations each with 2 alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapLocation healthMapLocation2 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); HealthMapAlert healthMapAlert2 = new HealthMapAlert(); HealthMapAlert healthMapAlert3 = new HealthMapAlert(); HealthMapAlert healthMapAlert4 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1, healthMapAlert2)); healthMapLocation2.setAlerts(Arrays.asList(healthMapAlert3, healthMapAlert4)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1, healthMapLocation2); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapLocation2 is not successfully converted into location2 when(locationConverter.convert(healthMapLocation2)).thenReturn(null); // healthMapAlert1 is successfully converted into diseaseOccurrence1 DiseaseOccurrence diseaseOccurrence1 = new DiseaseOccurrence(1); mockConvertAndAcquire(healthMapAlert1, location1, diseaseOccurrence1, true); // healthMapAlert2 is successfully converted into diseaseOccurrence2 DiseaseOccurrence diseaseOccurrence2 = new DiseaseOccurrence(2); mockConvertAndAcquire(healthMapAlert2, location1, diseaseOccurrence2, true); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence1, diseaseOccurrence2); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertNoAlerts() { // Arrange // Create 2 locations each with no alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapLocation healthMapLocation2 = new HealthMapLocation(); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1, healthMapLocation2); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapLocation2 is successfully converted into location2 Location location2 = new Location(); when(locationConverter.convert(healthMapLocation2)).thenReturn(location2); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertThat(actualOccurrences).isEmpty(); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertFirstAlertFailsSecondAlertSucceeds() { // Arrange // Create a location with 2 alerts HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); HealthMapAlert healthMapAlert2 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1, healthMapAlert2)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapAlert1 is successfully converted into diseaseOccurrence1 DiseaseOccurrence diseaseOccurrence1 = new DiseaseOccurrence(1); mockConvertAndAcquire(healthMapAlert1, location1, diseaseOccurrence1, true); // healthMapAlert2 is not successfully converted into diseaseOccurrence2 when(alertConverter.convert(healthMapAlert2, location1)).thenReturn(new ArrayList<DiseaseOccurrence>()); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence1); verifyWriteLastRetrievalEndDate(retrievalEndDate); } @Test public void convertAlertResultsInMultipleOccurrences() { // Arrange // Create a location with 1 alert HealthMapLocation healthMapLocation1 = new HealthMapLocation(); HealthMapAlert healthMapAlert1 = new HealthMapAlert(); healthMapLocation1.setAlerts(Arrays.asList(healthMapAlert1)); List<HealthMapLocation> locations = Arrays.asList(healthMapLocation1); DateTime retrievalEndDate = DateTime.now(); // healthMapLocation1 is successfully converted into location1 Location location1 = new Location(); when(locationConverter.convert(healthMapLocation1)).thenReturn(location1); // healthMapAlert1 is successfully converted into diseaseOccurrence1 and diseaseOccurrence2 DiseaseOccurrence diseaseOccurrence1 = new DiseaseOccurrence(1); DiseaseOccurrence diseaseOccurrence2 = new DiseaseOccurrence(2); DiseaseOccurrence diseaseOccurrence3 = new DiseaseOccurrence(3); List<DiseaseOccurrence> occurrences = Arrays.asList(diseaseOccurrence1, diseaseOccurrence2, diseaseOccurrence3); List<Boolean> areOccurrencesSaved = Arrays.asList(true, false, true); mockConvertAndAcquire(healthMapAlert1, location1, occurrences, areOccurrencesSaved); // healthMapAlert2 is not successfully converted into diseaseOccurrence2 when(alertConverter.convert(healthMapAlert1, location1)).thenReturn(occurrences); // Act Set<DiseaseOccurrence> actualOccurrences = healthMapDataConverter.convert(locations, retrievalEndDate); // Assert assertSavedOccurrences(actualOccurrences, diseaseOccurrence1, diseaseOccurrence3); verifyWriteLastRetrievalEndDate(retrievalEndDate); } private void mockConvertAndAcquire(HealthMapAlert healthMapAlert, Location location, DiseaseOccurrence diseaseOccurrence, boolean isOccurrenceSaved) { mockConvertAndAcquire(healthMapAlert, location, Arrays.asList(diseaseOccurrence), Arrays.asList(isOccurrenceSaved)); } private void mockConvertAndAcquire(HealthMapAlert healthMapAlert, Location location, List<DiseaseOccurrence> diseaseOccurrences, List<Boolean> areOccurrencesSaved) { when(alertConverter.convert(same(healthMapAlert), same(location))).thenReturn(diseaseOccurrences); for (int i = 0; i < diseaseOccurrences.size(); i++) { when(diseaseOccurrenceDataAcquirer.acquire(same(diseaseOccurrences.get(i)))) .thenReturn(areOccurrencesSaved.get(i)); } } // Ensure that the saved occurrences are as expected. // NB - this only works as expected if the disease occurrences have different content (e.g. the IDs are different) private void assertSavedOccurrences(Set<DiseaseOccurrence> actualOccurrences, DiseaseOccurrence... expectedOccurrences) { assertThat(actualOccurrences.size()).isEqualTo(expectedOccurrences.length); assertThat(actualOccurrences).containsAll(Arrays.asList(expectedOccurrences)); } private void verifyWriteLastRetrievalEndDate(DateTime retrievalEndDate) { assertThat(healthMapProvenance.getLastRetrievalEndDate()).isEqualTo(retrievalEndDate); verify(alertService).saveProvenance(same(healthMapProvenance)); } }