package uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.csv; 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.dataacquisition.acquirers.DataAcquisitionException; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.DiseaseOccurrenceDataAcquirer; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.ManualValidationEnforcer; import uk.ac.ox.zoo.seeg.abraid.mp.dataacquisition.acquirers.csv.domain.CsvDiseaseOccurrence; import java.util.Arrays; import java.util.HashSet; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; /** * Tests the CsvDataAcquirer class. * * Copyright (c) 2014 University of Oxford */ public class CsvDataAcquirerTest { private CsvDiseaseOccurrenceConverter converter; private DiseaseOccurrenceDataAcquirer diseaseOccurrenceDataAcquirer; private CsvLookupData csvLookupData; private CsvDataAcquirer csvDataAcquirer; private ManualValidationEnforcer manualValidationEnforcer; @Before public void setUp() { converter = mock(CsvDiseaseOccurrenceConverter.class); diseaseOccurrenceDataAcquirer = mock(DiseaseOccurrenceDataAcquirer.class); csvLookupData = mock(CsvLookupData.class); manualValidationEnforcer = mock(ManualValidationEnforcer.class); csvDataAcquirer = new CsvDataAcquirer(converter, diseaseOccurrenceDataAcquirer, csvLookupData, manualValidationEnforcer); } @Test public void acquireReturnsErrorMessageIfCannotBeParsed() { // Arrange String csv = "\nMy site,Invalid double"; // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, false, null); // Assert assertThat(messages).hasSize(1); assertThat(messages.get(0)).startsWith("CSV file has invalid format"); } @Test public void acquireReturnsErrorMessageIfCannotBeConverted() { // Arrange DataAcquisitionException exception = new DataAcquisitionException("Test message"); String csv = "\nMy site\n"; when(converter.convert(any(CsvDiseaseOccurrence.class), anyBoolean())).thenThrow(exception); // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, false, null); // Assert assertThat(messages).hasSize(3); assertThat(messages.get(0)).isEqualTo("Found 1 CSV file line(s) to convert."); assertThat(messages.get(1)).isEqualTo("Did not save any disease occurrences."); assertThat(messages.get(2)).isEqualTo("Error in CSV file on line 2: Test message."); } @Test public void acquireReturnsErrorMessagesIfMultipleLinesCannotBeConverted() { // Arrange DataAcquisitionException exception = new DataAcquisitionException("Test message"); String csv = "\nMy site\nMy second site\n"; when(converter.convert(any(CsvDiseaseOccurrence.class), anyBoolean())).thenThrow(exception); // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, false, null); // Assert assertThat(messages).hasSize(4); assertThat(messages.get(0)).isEqualTo("Found 2 CSV file line(s) to convert."); assertThat(messages.get(1)).isEqualTo("Did not save any disease occurrences."); assertThat(messages.get(2)).isEqualTo("Error in CSV file on line 2: Test message."); assertThat(messages.get(3)).isEqualTo("Error in CSV file on line 3: Test message."); } @Test public void doesNotCallManualValidationEnforcerIfConversionFails() { // Arrange String csv = "\nMy site,Invalid double"; // Act csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, false, null); // Assert verify(manualValidationEnforcer, never()).addRandomSubsetToManualValidation(anySetOf(DiseaseOccurrence.class)); } @Test public void doesNotCallManualValidationEnforcerForBias() { // Arrange boolean isGoldStandard = false; Location location1 = createLocation(1, true); Location location2 = createLocation(2, false); Location location3 = createLocation(3, true); Location location4 = createLocation(4, true); DiseaseOccurrence diseaseOccurrence1 = createAndSetUpDiseaseOccurrence(1, location1, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence2 = createAndSetUpDiseaseOccurrence(2, location2, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence3 = createAndSetUpDiseaseOccurrence(3, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(4, location4, isGoldStandard, false); createAndSetUpDiseaseOccurrence(5, location1, isGoldStandard, false); DiseaseOccurrence diseaseOccurrence6 = createAndSetUpDiseaseOccurrence(6, location2, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence7 = createAndSetUpDiseaseOccurrence(7, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(8, location4, isGoldStandard, false); String csv = "\n1\n2\n3\n4\n5\n6\n7\n8\n"; // Act csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), true, false, null); // Assert verify(manualValidationEnforcer, never()).addRandomSubsetToManualValidation(anySetOf(DiseaseOccurrence.class)); } @Test public void initialMessageHasCorrectCountsIfAtLeastOneDiseaseOccurrenceWasAcquired() { // Disease occurrence 1 has location 1 (passed QC) // Disease occurrence 2 has location 2 (failed QC) // Disease occurrence 3 has location 3 (passed QC) // Disease occurrence 4 has location 4 (passed QC) but was not saved // Disease occurrence 5 has location 1 (passed QC) but was not saved // Disease occurrence 6 has location 2 (failed QC) // Disease occurrence 7 has location 3 (passed QC) // Disease occurrence 8 has location 4 (passed QC) but was not saved // Arrange boolean isGoldStandard = false; Location location1 = createLocation(1, true); Location location2 = createLocation(2, false); Location location3 = createLocation(3, true); Location location4 = createLocation(4, true); createAndSetUpDiseaseOccurrence(1, location1, isGoldStandard, true); createAndSetUpDiseaseOccurrence(2, location2, isGoldStandard, true); createAndSetUpDiseaseOccurrence(3, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(4, location4, isGoldStandard, false); createAndSetUpDiseaseOccurrence(5, location1, isGoldStandard, false); createAndSetUpDiseaseOccurrence(6, location2, isGoldStandard, true); createAndSetUpDiseaseOccurrence(7, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(8, location4, isGoldStandard, false); String csv = "\n1\n2\n3\n4\n5\n6\n7\n8\n"; // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, isGoldStandard, null); // Assert assertThat(messages).hasSize(2); assertThat(messages.get(0)).isEqualTo("Found 8 CSV file line(s) to convert."); assertThat(messages.get(1)).isEqualTo("Saved 5 disease occurrence(s) in 3 location(s) (of which 2 location(s) passed QC)."); } @Test public void callsManualValidationEnforcerWithConvertedOccurrences() { // Arrange boolean isGoldStandard = false; Location location1 = createLocation(1, true); Location location2 = createLocation(2, false); Location location3 = createLocation(3, true); Location location4 = createLocation(4, true); DiseaseOccurrence diseaseOccurrence1 = createAndSetUpDiseaseOccurrence(1, location1, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence2 = createAndSetUpDiseaseOccurrence(2, location2, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence3 = createAndSetUpDiseaseOccurrence(3, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(4, location4, isGoldStandard, false); createAndSetUpDiseaseOccurrence(5, location1, isGoldStandard, false); DiseaseOccurrence diseaseOccurrence6 = createAndSetUpDiseaseOccurrence(6, location2, isGoldStandard, true); DiseaseOccurrence diseaseOccurrence7 = createAndSetUpDiseaseOccurrence(7, location3, isGoldStandard, true); createAndSetUpDiseaseOccurrence(8, location4, isGoldStandard, false); String csv = "\n1\n2\n3\n4\n5\n6\n7\n8\n"; // Act csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, isGoldStandard, null); // Assert verify(manualValidationEnforcer).addRandomSubsetToManualValidation(eq(new HashSet<>(Arrays.asList( diseaseOccurrence1, diseaseOccurrence2, diseaseOccurrence3, diseaseOccurrence6, diseaseOccurrence7 )))); } @Test public void initialMessageHasCorrectCountsIfNoDiseaseOccurrencesWereAcquired() { // Arrange String csv = "\n"; // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, false, null); // Assert assertThat(messages).hasSize(2); assertThat(messages.get(0)).isEqualTo("Found 0 CSV file line(s) to convert."); assertThat(messages.get(1)).isEqualTo("Did not save any disease occurrences."); } @Test public void initialMessageHasCorrectCountsForGoldStandardDataSet() { // Arrange boolean isGoldStandard = true; Location location1 = createLocation(1, true); Location location2 = createLocation(2, false); createAndSetUpDiseaseOccurrence(1, location1, isGoldStandard, true); createAndSetUpDiseaseOccurrence(2, location2, isGoldStandard, true); String csv = "\n1\n2\n"; // Act List<String> messages = csvDataAcquirer.acquireDataFromCsv(csv.getBytes(), false, isGoldStandard, null); // Assert assertThat(messages).hasSize(2); assertThat(messages.get(0)).isEqualTo("Found 2 CSV file line(s) to convert."); assertThat(messages.get(1)).isEqualTo("Saved 2 disease occurrence(s) in 2 location(s) (of which 1 location(s) passed QC)."); } private Location createLocation(int id, boolean hasPassedQc) { Location location = new Location(id); location.setHasPassedQc(hasPassedQc); return location; } private DiseaseOccurrence createAndSetUpDiseaseOccurrence(int id, Location location, boolean isGoldStandard, boolean wasDiseaseOccurrenceSaved) { DiseaseOccurrence diseaseOccurrence = new DiseaseOccurrence(id); diseaseOccurrence.setLocation(location); CsvDiseaseOccurrence csvDiseaseOccurrence = new CsvDiseaseOccurrence(); csvDiseaseOccurrence.setSite(Integer.toString(id)); when(converter.convert(csvDiseaseOccurrence, isGoldStandard)).thenReturn(diseaseOccurrence); when(diseaseOccurrenceDataAcquirer.acquire(diseaseOccurrence)).thenReturn(wasDiseaseOccurrenceSaved); return diseaseOccurrence; } }