package uk.ac.ox.zoo.seeg.abraid.mp.publicsite.web;
import com.vividsolutions.jts.geom.Point;
import org.joda.time.DateTime;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dto.json.GeoJsonDiseaseOccurrenceFeatureCollection;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dto.json.JsonDownloadDiseaseOccurrence;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dto.json.WrappedList;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.ModelRunService;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support.ModellingLocationPrecisionAdjuster;
import uk.ac.ox.zoo.seeg.abraid.mp.testutils.AbstractDiseaseOccurrenceGeoJsonTests;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Tests for ModelRunDataController.
*/
public class ModelRunDataControllerTest extends AbstractDiseaseOccurrenceGeoJsonTests {
@Test
public void getInputDiseaseOccurrencesReturnsExpectedJson() throws Exception {
// Arrange
String name = "modelRun7";
DiseaseOccurrence occurrence = mock(DiseaseOccurrence.class);
when(occurrence.getLocation()).thenReturn(mock(Location.class));
when(occurrence.getDiseaseGroup()).thenReturn(mock(DiseaseGroup.class));
when(occurrence.getDiseaseGroup().getId()).thenReturn(123);
when(occurrence.getLocation().getGeom()).thenReturn(mock(Point.class));
when(occurrence.getLocation().getGeom().getX()).thenReturn(1.0);
when(occurrence.getLocation().getGeom().getY()).thenReturn(2.0);
when(occurrence.getFinalWeighting()).thenReturn(3.0);
when(occurrence.getLocation().getPrecision()).thenReturn(LocationPrecision.ADMIN1);
when(occurrence.getLocation().getAdminUnitQCGaulCode()).thenReturn(1234);
when(occurrence.getAlert()).thenReturn(mock(Alert.class));
when(occurrence.getAlert().getFeed()).thenReturn(mock(Feed.class));
when(occurrence.getAlert().getFeed().getName()).thenReturn("feed");
when(occurrence.getAlert().getFeed().getProvenance()).thenReturn(mock(Provenance.class));
when(occurrence.getAlert().getFeed().getProvenance().getName()).thenReturn("provenance");
ModelRun modelRun = mockCompletedModelRunWithOccurrences(Arrays.asList(occurrence));
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
HttpServletResponse httpServletResponse = mock(HttpServletResponse.class);
// Act
ResponseEntity response = controller.getInputDiseaseOccurrences(name, httpServletResponse);
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
WrappedList<JsonDownloadDiseaseOccurrence> body = (WrappedList<JsonDownloadDiseaseOccurrence>) response.getBody();
assertThat(body.getList()).hasSize(1);
assertThat(body.getList().get(0).getLongitude()).isEqualTo(1.0);
assertThat(body.getList().get(0).getLatitude()).isEqualTo(2.0);
assertThat(body.getList().get(0).getWeight()).isEqualTo(3.0);
assertThat(body.getList().get(0).getAdmin()).isEqualTo(LocationPrecision.ADMIN1.getModelValue());
assertThat(body.getList().get(0).getGaul()).isEqualTo("1234");
assertThat(body.getList().get(0).getDisease()).isEqualTo(123);
assertThat(body.getList().get(0).getProvenance()).isEqualTo("provenance");
assertThat(body.getList().get(0).getFeed()).isEqualTo("feed");
verify(httpServletResponse).setHeader(eq("Content-Disposition"), eq("attachment; filename=\"" + name + "_input.csv\""));
}
@Test
public void getInputDiseaseOccurrencesReturnsBadRequestIfModelDoesNotExist() throws Exception {
// Arrange
String name = "modelRun5";
ModelRunService modelRunService = mockModelRunService(name, null);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrences(name, mock(HttpServletResponse.class));
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
public void getInputDiseaseOccurrencesReturnsBadRequestIfModelIsNotComplete() throws Exception {
// Arrange
String name = "modelRun6";
ModelRun modelRun = mock(ModelRun.class);
when(modelRun.getStatus()).thenReturn(ModelRunStatus.IN_PROGRESS);
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrences(name, mock(HttpServletResponse.class));
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
public void getInputDiseaseOccurrencesReturnsEmptyDTOIfNoInputDiseaseOccurrences() throws Exception {
// Arrange (eg manual run)
String name = "modelRun7";
ModelRun modelRun = mockCompletedModelRunWithOccurrences(new ArrayList<DiseaseOccurrence>());
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrences(name, mock(HttpServletResponse.class));
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
WrappedList<JsonDownloadDiseaseOccurrence> body =
(WrappedList<JsonDownloadDiseaseOccurrence>) response.getBody();
assertThat(body.getList()).isEmpty();
}
@Test
public void getInputDiseaseOccurrencesGeoJsonReturnsExpectedJson() throws Exception {
// Arrange
String name = "modelRun7";
ModelRun modelRun = mockCompletedModelRunWithOccurrences(Arrays.asList(defaultDiseaseOccurrence()));
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrencesGeoJson(name);
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
GeoJsonDiseaseOccurrenceFeatureCollection body = (GeoJsonDiseaseOccurrenceFeatureCollection) response.getBody();
assertThat(body.getFeatures()).hasSize(1);
assertThat(body.getFeatures().get(0).getGeometry().getCoordinates().getLongitude()).isEqualTo(-1.0);
assertThat(body.getFeatures().get(0).getGeometry().getCoordinates().getLatitude()).isEqualTo(1.0);
assertThat(body.getFeatures().get(0).getProperties().getOccurrenceDate()).isEqualTo(DateTime.parse("1970-01-01T00:00:00.000Z"));
}
@Test
public void getInputDiseaseOccurrencesGeoJsonReturnsBadRequestIfModelDoesNotExist() throws Exception {
// Arrange
String name = "modelRun5";
ModelRunService modelRunService = mockModelRunService(name, null);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrencesGeoJson(name);
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
public void getInputDiseaseOccurrencesGeoJsonReturnsBadRequestIfModelIsNotComplete() throws Exception {
// Arrange
String name = "modelRun6";
ModelRun modelRun = mock(ModelRun.class);
when(modelRun.getStatus()).thenReturn(ModelRunStatus.IN_PROGRESS);
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrencesGeoJson(name);
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST);
}
@Test
public void getInputDiseaseOccurrencesGeoJsonReturnsEmptyDTOIfNoInputDiseaseOccurrences() throws Exception {
// Arrange (eg manual run)
String name = "modelRun7";
ModelRun modelRun = mockCompletedModelRunWithOccurrences(new ArrayList<DiseaseOccurrence>());
ModelRunService modelRunService = mockModelRunService(name, modelRun);
ModelRunDataController controller = new ModelRunDataController(modelRunService, createNoopAdjuster());
// Act
ResponseEntity response = controller.getInputDiseaseOccurrencesGeoJson(name);
// Assert
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
GeoJsonDiseaseOccurrenceFeatureCollection body =
(GeoJsonDiseaseOccurrenceFeatureCollection) response.getBody();
assertThat(body.getFeatures()).isEmpty();
}
private ModelRunService mockModelRunService(String name, ModelRun modelRun) {
ModelRunService modelRunService = mock(ModelRunService.class);
when(modelRunService.getModelRunByName(name)).thenReturn(modelRun);
return modelRunService;
}
private ModelRun mockCompletedModelRunWithOccurrences(List<DiseaseOccurrence> occurrences) {
ModelRun modelRun = mock(ModelRun.class);
when(modelRun.getStatus()).thenReturn(ModelRunStatus.COMPLETED);
when(modelRun.getInputDiseaseOccurrences()).thenReturn(occurrences);
return modelRun;
}
private ModellingLocationPrecisionAdjuster createNoopAdjuster() {
ModellingLocationPrecisionAdjuster adjuster = mock(ModellingLocationPrecisionAdjuster.class);
when(adjuster.adjust(anyInt(), anyString())).thenAnswer(new Answer<Integer>() {
@Override
public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
return (Integer) invocationOnMock.getArguments()[0];
}
});
return adjuster;
}
}