<commit_before>package uk.ac.ox.zoo.seeg.abraid.mp.datamanager;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
import org.joda.time.DateTime;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.DiseaseGroupDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.DiseaseOccurrenceDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.GeoNameDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.ModelRunService;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support.ModelRunRequesterException;
import uk.ac.ox.zoo.seeg.abraid.mp.common.util.GeometryUtils;

import java.io.File;
import java.net.URI;
import java.util.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.offset;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.startsWith;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.contains;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.same;

/**
 * Tests the Main class.
 *
 * Copyright (c) 2014 University of Oxford
 */
public class MainTest extends AbstractWebServiceClientIntegrationTests {
    public static final String HEALTHMAP_URL_PREFIX = "http://healthmap.org";
    public static final String GEONAMES_URL_PREFIX = "http://api.geonames.org/getJSON?username=edwiles&geonameId=";
    public static final String MODELWRAPPER_URL_PREFIX = "http://api:key-to-access-model-wrapper@localhost:8080/modelwrapper";
    public static final String LARGE_RASTER_FILENAME =
            "Common/test/uk/ac/ox/zoo/seeg/abraid/mp/common/service/workflow/support/testdata/test_raster_large_double.tif";

    public static final String EXPECTED_PREDICTION_FAILURE_RESPONSE = "No prediction";

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private DiseaseOccurrenceDao diseaseOccurrenceDao;

    @Autowired
    private DiseaseGroupDao diseaseGroupDao;

    @Autowired
    private GeoNameDao geoNameDao;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private ModelRunService modelRunService;

    @Test
    public void mainMethodAcquiresDataFromWebService() throws Exception {
        // Arrange
        int diseaseGroupId = 87;
        mockHealthMapRequest();
        mockGeoNamesRequests();
        mockModelWrapperRequest();
        mockMachineWeightingPredictorRequest();
        createAndSaveTestModelRun(diseaseGroupId);
        insertTestDiseaseExtent(diseaseGroupId, GeometryUtils.createMultiPolygon(getFivePointedPolygon()));
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(diseaseGroupId);

        // Act
        runMain(new String[]{});

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatDiseaseOccurrenceValidationParametersAreCorrect();
        assertThatRelevantDiseaseOccurrencesHaveFinalWeightings();
        assertThatModelWrapperWebServiceWasCalledCorrectly();
        assertThatRollbackDidNotOccur();
    }

    private void setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(int diseaseGroupId) {
        DiseaseGroup diseaseGroup = diseaseGroupDao.getById(diseaseGroupId);
        diseaseGroup.setMinDataVolume(27);
        diseaseGroup.setOccursInAfrica(false);
        diseaseGroup.setMinDistinctCountries(null);
        diseaseGroup.setAutomaticModelRunsStartDate(DateTime.now());
        diseaseGroupDao.save(diseaseGroup);
    }

    @Test
    public void mainMethodAcquiresDataFromFiles() {
        // Arrange
        String[] fileNames = {
                "DataManager/test/uk/ac/ox/zoo/seeg/abraid/mp/datamanager/healthmap_json1.txt",
                "DataManager/test/uk/ac/ox/zoo/seeg/abraid/mp/datamanager/healthmap_json2.txt"
        };
        mockGeoNamesRequests();
        mockModelWrapperRequest();
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(87);

        // Act
        runMain(fileNames);

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatRelevantDiseaseOccurrencesHaveFinalWeightings();
        assertThatModelWrapperWebServiceWasCalledCorrectly();
        assertThatRollbackDidNotOccur();
    }

    @Test
    public void mainMethodRollsBackModelRunIfItFails() {
        // Arrange
        mockHealthMapRequest();
        mockGeoNamesRequests();
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(87);
        when(webServiceClient.makePostRequestWithJSON(startsWith(MODELWRAPPER_URL_PREFIX), anyString()))
                .thenThrow(new ModelRunRequesterException("Test message"));

        // Act
        runMain(new String[]{});

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatRollbackOccurred();
    }

    private void runMain(String[] fileNames) {
        Main.runMain(applicationContext, fileNames);
    }

    private void assertThatDiseaseOccurrencesAreCorrect() {
        // Assert that we have created two disease occurrences and they are the correct ones
        List<DiseaseOccurrence> occurrences = getLastTwoDiseaseOccurrences();
        assertFirstOccurrence(occurrences.get(0));
        assertSecondOccurrence(occurrences.get(1));
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreCorrect() {
        // Assert that we have created two disease occurrences and they are the correct ones
        // Only occurrences with non-country locations have validation parameters assigned.
        List<DiseaseOccurrence> occurrences = getLastTwoDiseaseOccurrences();

        DiseaseOccurrence validatedOccurrence = occurrences.get(0);
        assertThatDiseaseOccurrenceValidationParametersAreCorrect(validatedOccurrence, 0.46, 8814.186615);

        DiseaseOccurrence countryOccurrence = occurrences.get(1);
        assertThatDiseaseOccurrenceValidationParametersAreDefault(countryOccurrence);
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreCorrect(DiseaseOccurrence occurrence,
                                                                           double environmentalSuitability,
                                                                           double distanceFromDiseaseExtent) {
        assertThat(occurrence.getEnvironmentalSuitability()).isEqualTo(environmentalSuitability, offset(5e-7));
        assertThat(occurrence.getDistanceFromDiseaseExtent()).isEqualTo(distanceFromDiseaseExtent, offset(5e-7));
        // At present, mwPredictor is only set up to return null weighting, which means occurrence must go to validator
        assertThat(occurrence.getMachineWeighting()).isNull();
        assertThat(occurrence.getStatus()).isEqualTo(DiseaseOccurrenceStatus.IN_REVIEW);
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreDefault(DiseaseOccurrence occurrence) {
        assertThat(occurrence.getEnvironmentalSuitability()).isNull();
        assertThat(occurrence.getDistanceFromDiseaseExtent()).isNull();
        assertThat(occurrence.getMachineWeighting()).isNull();
        assertThat(occurrence.getStatus()).isEqualTo(DiseaseOccurrenceStatus.READY);
    }

    private void assertThatModelWrapperWebServiceWasCalledCorrectly() {
        // Assert that the model wrapper web service has been called once for dengue (disease group 87), with
        // the specified number of occurrence points and disease extent classes
        verify(modelWrapperWebService, atLeastOnce()).startRun(
                eq(URI.create(MODELWRAPPER_URL_PREFIX)),
                argThat(new DiseaseGroupIdMatcher(87)),
                argThat(new ListSizeMatcher<DiseaseOccurrence>(27)),
                argThat(new MapSizeMatcher<Integer, Integer>(460)));
        verify(webServiceClient, atLeastOnce()).makePostRequestWithJSON(
                startsWith(MODELWRAPPER_URL_PREFIX), anyString());
    }

    private void assertThatRelevantDiseaseOccurrencesHaveFinalWeightings() {
        List<DiseaseOccurrence> occurrences = diseaseOccurrenceDao.getByDiseaseGroupId(87);
        for (DiseaseOccurrence occurrence : occurrences) {
            if (occurrence.getStatus().equals(DiseaseOccurrenceStatus.READY) &&
                    occurrence.getLocation().getPrecision() != LocationPrecision.COUNTRY) {
                assertThat(occurrence.getFinalWeighting()).isNotNull();
            }
        }
    }

    private void assertThatRollbackOccurred() {<commit_msg>Fix test<commit_after>package uk.ac.ox.zoo.seeg.abraid.mp.datamanager;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Polygon;
import org.joda.time.DateTime;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.DiseaseGroupDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.DiseaseOccurrenceDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.dao.GeoNameDao;
import uk.ac.ox.zoo.seeg.abraid.mp.common.domain.*;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.core.ModelRunService;
import uk.ac.ox.zoo.seeg.abraid.mp.common.service.workflow.support.ModelRunRequesterException;
import uk.ac.ox.zoo.seeg.abraid.mp.common.util.GeometryUtils;

import java.io.File;
import java.net.URI;
import java.util.*;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.offset;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.startsWith;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.contains;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.same;

/**
 * Tests the Main class.
 *
 * Copyright (c) 2014 University of Oxford
 */
public class MainTest extends AbstractWebServiceClientIntegrationTests {
    public static final String HEALTHMAP_URL_PREFIX = "http://healthmap.org";
    public static final String GEONAMES_URL_PREFIX = "http://api.geonames.org/getJSON?username=edwiles&geonameId=";
    public static final String MODELWRAPPER_URL_PREFIX = "http://api:key-to-access-model-wrapper@localhost:8080/modelwrapper";
    public static final String LARGE_RASTER_FILENAME =
            "Common/test/uk/ac/ox/zoo/seeg/abraid/mp/common/service/workflow/support/testdata/test_raster_large_double.tif";

    public static final String EXPECTED_PREDICTION_FAILURE_RESPONSE = "No prediction";

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private DiseaseOccurrenceDao diseaseOccurrenceDao;

    @Autowired
    private DiseaseGroupDao diseaseGroupDao;

    @Autowired
    private GeoNameDao geoNameDao;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private ModelRunService modelRunService;

    @Test
    public void mainMethodAcquiresDataFromWebService() throws Exception {
        // Arrange
        int diseaseGroupId = 87;
        mockHealthMapRequest();
        mockGeoNamesRequests();
        mockModelWrapperRequest();
        mockMachineWeightingPredictorRequest();
        createAndSaveTestModelRun(diseaseGroupId);
        insertTestDiseaseExtent(diseaseGroupId, GeometryUtils.createMultiPolygon(getFivePointedPolygon()));
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(diseaseGroupId);

        // Act
        runMain(new String[]{});

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatDiseaseOccurrenceValidationParametersAreCorrect();
        assertThatRelevantDiseaseOccurrencesHaveFinalWeightings();
        assertThatModelWrapperWebServiceWasCalledCorrectly();
        assertThatRollbackDidNotOccur();
    }

    private void setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(int diseaseGroupId) {
        DiseaseGroup diseaseGroup = diseaseGroupDao.getById(diseaseGroupId);
        diseaseGroup.setMinDataVolume(27);
        diseaseGroup.setOccursInAfrica(false);
        diseaseGroup.setMinDistinctCountries(null);
        diseaseGroup.setAutomaticModelRunsStartDate(DateTime.now());
        diseaseGroupDao.save(diseaseGroup);
    }

    @Test
    public void mainMethodAcquiresDataFromFiles() {
        // Arrange
        String[] fileNames = {
                "DataManager/test/uk/ac/ox/zoo/seeg/abraid/mp/datamanager/healthmap_json1.txt",
                "DataManager/test/uk/ac/ox/zoo/seeg/abraid/mp/datamanager/healthmap_json2.txt"
        };
        mockGeoNamesRequests();
        mockModelWrapperRequest();
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(87);

        // Act
        runMain(fileNames);

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatRelevantDiseaseOccurrencesHaveFinalWeightings();
        assertThatModelWrapperWebServiceWasCalledCorrectly();
        assertThatRollbackDidNotOccur();
    }

    @Test
    public void mainMethodRollsBackModelRunIfItFails() {
        // Arrange
        mockHealthMapRequest();
        mockGeoNamesRequests();
        setDiseaseGroupParametersToEnsureHelperReturnsOccurrences(87);
        when(webServiceClient.makePostRequestWithJSON(startsWith(MODELWRAPPER_URL_PREFIX), anyString()))
                .thenThrow(new ModelRunRequesterException("Test message"));

        // Act
        runMain(new String[]{});

        // Assert
        assertThatDiseaseOccurrencesAreCorrect();
        assertThatRollbackOccurred();
    }

    private void runMain(String[] fileNames) {
        Main.runMain(applicationContext, fileNames);
    }

    private void assertThatDiseaseOccurrencesAreCorrect() {
        // Assert that we have created two disease occurrences and they are the correct ones
        List<DiseaseOccurrence> occurrences = getLastTwoDiseaseOccurrences();
        assertFirstOccurrence(occurrences.get(0));
        assertSecondOccurrence(occurrences.get(1));
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreCorrect() {
        // Assert that we have created two disease occurrences and they are the correct ones
        // Only occurrences with non-country locations have validation parameters assigned.
        List<DiseaseOccurrence> occurrences = getLastTwoDiseaseOccurrences();

        DiseaseOccurrence validatedOccurrence = occurrences.get(0);
        assertThatDiseaseOccurrenceValidationParametersAreCorrect(validatedOccurrence, 0.46, 8814.186615);

        DiseaseOccurrence countryOccurrence = occurrences.get(1);
        assertThatDiseaseOccurrenceValidationParametersAreDefault(countryOccurrence);
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreCorrect(DiseaseOccurrence occurrence,
                                                                           double environmentalSuitability,
                                                                           double distanceFromDiseaseExtent) {
        assertThat(occurrence.getEnvironmentalSuitability()).isEqualTo(environmentalSuitability, offset(5e-7));
        assertThat(occurrence.getDistanceFromDiseaseExtent()).isEqualTo(distanceFromDiseaseExtent, offset(5e-7));
        // At present, mwPredictor is only set up to return null weighting, which means occurrence must go to validator
        assertThat(occurrence.getMachineWeighting()).isNull();
        assertThat(occurrence.getStatus()).isEqualTo(DiseaseOccurrenceStatus.IN_REVIEW);
    }

    private void assertThatDiseaseOccurrenceValidationParametersAreDefault(DiseaseOccurrence occurrence) {
        assertThat(occurrence.getEnvironmentalSuitability()).isNull();
        assertThat(occurrence.getDistanceFromDiseaseExtent()).isNull();
        assertThat(occurrence.getMachineWeighting()).isNull();
        assertThat(occurrence.getStatus()).isEqualTo(DiseaseOccurrenceStatus.READY);
    }

    private void assertThatModelWrapperWebServiceWasCalledCorrectly() {
        // Assert that the model wrapper web service has been called once for dengue (disease group 87), with
        // the specified number of occurrence points and disease extent classes
        verify(modelWrapperWebService, atLeastOnce()).startRun(
                eq(URI.create(MODELWRAPPER_URL_PREFIX)),
                argThat(new DiseaseGroupIdMatcher(87)),
                argThat(new ListSizeMatcher<DiseaseOccurrence>(27)),
                argThat(new MapSizeMatcher<Integer, Integer>(451)));
        verify(webServiceClient, atLeastOnce()).makePostRequestWithJSON(
                startsWith(MODELWRAPPER_URL_PREFIX), anyString());
    }

    private void assertThatRelevantDiseaseOccurrencesHaveFinalWeightings() {
        List<DiseaseOccurrence> occurrences = diseaseOccurrenceDao.getByDiseaseGroupId(87);
        for (DiseaseOccurrence occurrence : occurrences) {
            if (occurrence.getStatus().equals(DiseaseOccurrenceStatus.READY) &&
                    occurrence.getLocation().getPrecision() != LocationPrecision.COUNTRY) {
                assertThat(occurrence.getFinalWeighting()).isNotNull();
            }
        }
    }

    private void assertThatRollbackOccurred() {
{'fraction_non_alphanumeric': 0.08466754031109339, 'fraction_numerical': 0.005697681043815167, 'mean_word_length': 3.6980728051391862, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3438610', 'n_tokens_mistral': 5030, 'n_tokens_neox': 4813, 'n_words': 763}