diff --git a/build.sh b/build.sh index 9920c6a345..3f74b10cbb 100755 --- a/build.sh +++ b/build.sh @@ -6,4 +6,4 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" PROJECT_DIR=$DIR/ # This will: compile the project, run lint, run tests under JVM, package apk, check the code quality and run tests on the device/emulator. -"$PROJECT_DIR"/gradlew clean build --scan connectedAndroidTest +"$PROJECT_DIR"/gradlew clean build --scan diff --git a/core/build.gradle b/core/build.gradle index c681da0c3d..ee3a7b1927 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -36,8 +36,8 @@ ext { buildToolsVersion: "28.0.3", minSdkVersion : 19, targetSdkVersion : 28, - versionCode : 130, - versionName : "0.15.5-SNAPSHOT" + versionCode : 131, + versionName : "0.16.0-SNAPSHOT" ] libraries = [ @@ -46,13 +46,14 @@ ext { paging : '2.1.0', // java - jackson : "2.8.5", + jackson : "2.9.8", autovalue : "1.3", autovaluecursor : "1.0.1", - retrofit : "2.1.0", - okhttp : "3.5.0", + retrofit : "2.5.0", + okhttp : "3.14.0", duktape : "1.1.0", dagger : "2.14.1", + rxjava : "2.2.8", // code checks findbugs : "3.0.0", @@ -147,13 +148,17 @@ android { dependencies { + api "io.reactivex.rxjava2:rxjava:${libraries.rxjava}" + // sqlbrite-migrations library - api "com.github.lykmapipo:sqlbrite-migrations:${libraries.sqlbritemigrations}" + api ("com.github.lykmapipo:sqlbrite-migrations:${libraries.sqlbritemigrations}") { + exclude group: 'io.reactivex.rxjava2', module: 'rxjava' + } // Support libraries api "androidx.annotation:annotation:${libraries.support}" - api "android.arch.paging:runtime:${libraries.paging}" + api "androidx.paging:paging-runtime:${libraries.paging}" // Google's auto-value. Annotations are used only during compilation time, as well as @@ -175,6 +180,7 @@ dependencies { api "com.squareup.okhttp3:okhttp:${libraries.okhttp}" api "com.squareup.retrofit2:retrofit:${libraries.retrofit}" api "com.squareup.retrofit2:converter-jackson:${libraries.retrofit}" + api "com.squareup.retrofit2:adapter-rxjava2:${libraries.retrofit}" // Apache libraries api "org.apache.commons:commons-lang3:3.7" @@ -187,7 +193,7 @@ dependencies { api "joda-time:joda-time:2.9.9" // sms compression library - compile 'com.github.eHealthAfrica:dhis2-sms-compression:0.0.9' + api 'com.github.eHealthAfrica:dhis2-sms-compression:0.0.9' // Extension which generates mappers for work with cursor and content values api "com.gabrielittner.auto.value:auto-value-cursor-annotations:${libraries.autovaluecursor}" diff --git a/core/gradle.properties b/core/gradle.properties index c50a07fa94..a290f336af 100644 --- a/core/gradle.properties +++ b/core/gradle.properties @@ -29,8 +29,8 @@ # Properties which are consumed by plugins/gradle-mvn-push.gradle plugin. # They are used for publishing artifact to snapshot repository. -VERSION_NAME=0.15.5-SNAPSHOT -VERSION_CODE=130 +VERSION_NAME=0.16.0-SNAPSHOT +VERSION_CODE=131 GROUP=org.hisp.dhis diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/EventWithLimitCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/EventWithLimitCallMockIntegrationShould.java index 63e339fba4..7462323a84 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/EventWithLimitCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/EventWithLimitCallMockIntegrationShould.java @@ -28,11 +28,8 @@ package org.hisp.dhis.android.core; -import androidx.test.runner.AndroidJUnit4; - import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.event.Event; import org.hisp.dhis.android.core.event.EventStore; @@ -45,6 +42,8 @@ import java.io.IOException; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -59,7 +58,7 @@ public class EventWithLimitCallMockIntegrationShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); } @@ -81,7 +80,7 @@ public void download_events() throws Exception { dhis2MockServer.enqueueMockResponse("systeminfo/system_info.json"); dhis2MockServer.enqueueMockResponse("event/events_1.json"); - d2.eventModule().downloadSingleEvents(eventLimitByOrgUnit, false).call(); + d2.eventModule().downloadSingleEvents(eventLimitByOrgUnit, false, false).call(); EventStore eventStore = EventStoreImpl.create(databaseAdapter()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/TeisCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/TeisCallRealIntegrationShould.java index 5c55d05ec1..09ad3d4600 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/TeisCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/TeisCallRealIntegrationShould.java @@ -28,6 +28,9 @@ package org.hisp.dhis.android.core; +import android.util.Log; + +import org.hisp.dhis.android.core.arch.call.D2Progress; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.server.RealServerMother; @@ -36,6 +39,8 @@ import java.io.IOException; +import io.reactivex.observers.TestObserver; + import static com.google.common.truth.Truth.assertThat; public class TeisCallRealIntegrationShould extends AbsStoreTestCase { @@ -56,8 +61,15 @@ public void download_tracked_entity_instances() throws Exception { d2.syncMetaData().call(); - d2.trackedEntityModule().downloadTrackedEntityInstances(5, false).call(); + TestObserver testObserver = d2.trackedEntityModule().downloadTrackedEntityInstances(5, false, false) + .asObservable() + .doOnEach(e -> Log.w("EVENT", e.toString())) + .test(); + + testObserver.awaitTerminalEvent(); + + int count = TrackedEntityInstanceStoreImpl.create(databaseAdapter()).count(); - assertThat(TrackedEntityInstanceStoreImpl.create(databaseAdapter()).count() >= 5).isTrue(); + assertThat(count >= 5).isTrue(); } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/category/CategoryEndpointCallShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/category/CategoryEndpointCallShould.java index 292d887197..8697b3c0bd 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/category/CategoryEndpointCallShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/category/CategoryEndpointCallShould.java @@ -33,7 +33,6 @@ import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.junit.After; import org.junit.Before; @@ -54,7 +53,7 @@ public class CategoryEndpointCallShould extends AbsStoreTestCase { @Before public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); } @Override diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/common/D2Factory.java b/core/src/androidTest/java/org/hisp/dhis/android/core/common/D2Factory.java index 642c48fb4a..679861d42a 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/common/D2Factory.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/common/D2Factory.java @@ -28,17 +28,17 @@ package org.hisp.dhis.android.core.common; -import androidx.test.InstrumentationRegistry; - import com.facebook.stetho.okhttp3.StethoInterceptor; import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.arch.api.retrofit.PreventURLDecodeInterceptor; import org.hisp.dhis.android.core.configuration.Configuration; import org.hisp.dhis.android.core.data.api.BasicAuthenticatorFactory; import org.hisp.dhis.android.core.data.database.DatabaseAdapter; import java.util.concurrent.TimeUnit; +import androidx.test.InstrumentationRegistry; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; @@ -49,21 +49,23 @@ public static D2 create(String url, DatabaseAdapter databaseAdapter) { .serverUrl(HttpUrl.parse(url)) .build(); - HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); - loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); - return new D2.Builder() .configuration(config) .databaseAdapter(databaseAdapter) - .okHttpClient( - new OkHttpClient.Builder() - .addInterceptor(BasicAuthenticatorFactory.create(databaseAdapter)) - .addInterceptor(loggingInterceptor) - .addNetworkInterceptor(new StethoInterceptor()) - .readTimeout(30, TimeUnit.SECONDS) - .build() - ) + .okHttpClient(okHttpClient(databaseAdapter)) .context(InstrumentationRegistry.getTargetContext().getApplicationContext()) .build(); } + + private static OkHttpClient okHttpClient(DatabaseAdapter databaseAdapter) { + HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); + loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC); + return new OkHttpClient.Builder() + .addInterceptor(new PreventURLDecodeInterceptor()) + .addInterceptor(BasicAuthenticatorFactory.create(databaseAdapter)) + .addInterceptor(loggingInterceptor) + .addNetworkInterceptor(new StethoInterceptor()) + .readTimeout(30, TimeUnit.SECONDS) + .build(); + } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/SyncedDatabaseMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/SyncedDatabaseMockIntegrationShould.java index 7db6488599..0418930668 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/SyncedDatabaseMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/data/database/SyncedDatabaseMockIntegrationShould.java @@ -39,9 +39,12 @@ import org.hisp.dhis.android.core.arch.api.retrofit.APIClientDIModule; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.ObjectStore; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; +import org.hisp.dhis.android.core.data.imports.TrackerImportConflictSamples; import org.hisp.dhis.android.core.data.maintenance.D2ErrorSamples; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; +import org.hisp.dhis.android.core.imports.ImportStatus; +import org.hisp.dhis.android.core.imports.TrackerImportConflict; +import org.hisp.dhis.android.core.imports.TrackerImportConflictStore; import org.hisp.dhis.android.core.maintenance.D2Error; import org.hisp.dhis.android.core.maintenance.D2ErrorCode; import org.hisp.dhis.android.core.maintenance.D2ErrorComponent; @@ -71,50 +74,47 @@ public static void setUpClass() throws Exception { InstrumentationRegistry.getTargetContext().getApplicationContext(), "synced.db"); sqLiteDatabase = dbOpenHelper.getWritableDatabase(); databaseAdapter = new SqLiteDatabaseAdapter(dbOpenHelper); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter); Stetho.initializeWithDefaults(InstrumentationRegistry.getTargetContext().getApplicationContext()); d2.wipeModule().wipeEverything(); + dhis2MockServer.setRequestDispatcher(); + login(); downloadMetadata(); downloadTrackedEntityInstances(); downloadEvents(); downloadAggregatedData(); storeSomeD2Errors(); + storeSomeConflicts(); } } @AfterClass public static void tearDownClass() throws IOException { dhis2MockServer.shutdown(); - sqLiteDatabase.close(); } private static void login() throws Exception { - dhis2MockServer.enqueueLoginResponses(); d2.userModule().logIn("android", "Android123").call(); } private static void downloadMetadata() throws Exception { - dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } - private static void downloadTrackedEntityInstances() throws Exception { - dhis2MockServer.enqueueTrackedEntityInstanceResponses(); - d2.trackedEntityModule().downloadTrackedEntityInstances(2, false).call(); + private static void downloadTrackedEntityInstances() { + d2.trackedEntityModule().downloadTrackedEntityInstances(2, false, false).asObservable().subscribe(); } private static void downloadEvents() throws Exception { - dhis2MockServer.enqueueEventResponses(); - d2.eventModule().downloadSingleEvents(2, false).call(); + d2.eventModule().downloadSingleEvents(2, false, false).call(); } - private static void downloadAggregatedData() throws Exception { - dhis2MockServer.enqueueAggregatedDataResponses(); - d2.aggregatedModule().data().download().call(); + private static void downloadAggregatedData() { + d2.aggregatedModule().data().download().asObservable().subscribe(); } private static void storeSomeD2Errors() { @@ -132,6 +132,28 @@ private static void storeSomeD2Errors() { ); } + private static void storeSomeConflicts() { + ObjectStore trackerImportConflictStore = + TrackerImportConflictStore.create(databaseAdapter); + trackerImportConflictStore.insert(TrackerImportConflictSamples.get().toBuilder() + .trackedEntityInstance(null) + .enrollment(null) + .event(null) + .build()); + + trackerImportConflictStore.insert(TrackerImportConflictSamples.get().toBuilder() + .conflict("conflict_2") + .value("value_2") + .trackedEntityInstance("nWrB0TfWlvh") + .enrollment("enroll2") + .event("event2") + .tableReference("table_reference_2") + .errorCode("error_code_2") + .status(ImportStatus.ERROR) + .build() + ); + } + protected D2DIComponent getD2DIComponent() { return DaggerD2DIComponent.builder() .databaseDIModule(new DatabaseDIModule(databaseAdapter)) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/data/server/RealServerMother.java b/core/src/androidTest/java/org/hisp/dhis/android/core/data/server/RealServerMother.java index 2f5d693358..3334f55e5e 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/data/server/RealServerMother.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/data/server/RealServerMother.java @@ -31,7 +31,8 @@ public class RealServerMother { public static String url2_29 = "https://play.dhis2.org/2.29/api/"; public static String url2_30 = "https://play.dhis2.org/2.30/api/"; - public static String url2_31 = "https://play.dhis2.org/2.31.0/api/"; + public static String url2_31 = "https://play.dhis2.org/2.31.3/api/"; + public static String url2_32 = "https://play.dhis2.org/2.32.0/api/"; public static String url_dev = "https://play.dhis2.org/dev/api/"; public static String android_current = "https://play.dhis2.org/android-current/api/"; public static String url = android_current; diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetCompleteRegistrationPostCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetCompleteRegistrationPostCallRealIntegrationShould.java index 6df5ab99e2..d12ec1e834 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetCompleteRegistrationPostCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetCompleteRegistrationPostCallRealIntegrationShould.java @@ -65,14 +65,14 @@ public void setUp() throws IOException { public void upload_data_set_complete_registrations_with_to_post_state() throws Exception { d2.userModule().logIn("android", "Android123").call(); d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); - DataSetCompleteRegistration dataValueModel - = getTestDataSetCompleteRegistrationWith(State.TO_POST); + DataSetCompleteRegistration dataSetCompleteRegistration + = getTestDataSetCompleteRegistrationWith(State.TO_POST, "2018"); ReadWriteWithUploadCollectionRepository repository = d2.dataSetModule().dataSetCompleteRegistrations; - repository.add(dataValueModel); + repository.add(dataSetCompleteRegistration); DataValueImportSummary dataValueImportSummary = repository.upload().call(); @@ -88,10 +88,10 @@ public void upload_data_set_complete_registrations_with_to_post_state() throws E public void upload_data_set_complete_registrations_with_to_update_state() throws Exception { d2.userModule().logIn("android", "Android123").call(); d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); DataSetCompleteRegistration dataSetCompleteRegistration - = getTestDataSetCompleteRegistrationWith(State.TO_UPDATE); + = getTestDataSetCompleteRegistrationWith(State.TO_UPDATE, "2018"); assertThat(insertToPostDataSetCompleteRegistration(dataSetCompleteRegistration)).isTrue(); @@ -103,16 +103,63 @@ public void upload_data_set_complete_registrations_with_to_update_state() throws assertThat(importCountTotal == 1).isTrue(); } + // commented out since it is a flaky test that works against a real server. + //@Test + public void update_and_delete_different_data_set_complete_registrations() throws Exception { + d2.userModule().logIn("android", "Android123").call(); + d2.syncMetaData().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); + + DataSetCompleteRegistration toDeleteDataSetCompleteRegistration + = getTestDataSetCompleteRegistrationWith(State.TO_UPDATE, "2019"); + + DataSetCompleteRegistration dataSetCompleteRegistration + = getTestDataSetCompleteRegistrationWith(State.TO_UPDATE, "2018"); + + ReadWriteWithUploadCollectionRepository repository + = d2.dataSetModule().dataSetCompleteRegistrations; + repository.add(toDeleteDataSetCompleteRegistration); + repository.add(dataSetCompleteRegistration); + dataSetCompleteRegistrationStore.setState(toDeleteDataSetCompleteRegistration, State.TO_DELETE); + + DataValueImportSummary dataValueImportSummary = repository.upload().call(); + + int importCountTotal = dataValueImportSummary.importCount().updated() + + dataValueImportSummary.importCount().ignored(); + assertThat(importCountTotal == 1).isTrue(); + assertThat(dataValueImportSummary.importCount().deleted() == 1).isTrue(); + } + + // commented out since it is a flaky test that works against a real server. + //@Test + public void delete_data_set_complete_registrations_with_to_delete_state() throws Exception { + d2.userModule().logIn("android", "Android123").call(); + d2.syncMetaData().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); + + DataSetCompleteRegistration dataSetCompleteRegistration + = getTestDataSetCompleteRegistrationWith(State.TO_UPDATE, "2018"); + + ReadWriteWithUploadCollectionRepository repository + = d2.dataSetModule().dataSetCompleteRegistrations; + repository.add(dataSetCompleteRegistration); + dataSetCompleteRegistrationStore.setState(dataSetCompleteRegistration, State.TO_DELETE); + + DataValueImportSummary dataValueImportSummary = repository.upload().call(); + + assertThat(dataValueImportSummary.importCount().deleted() == 1).isTrue(); + } private boolean insertToPostDataSetCompleteRegistration(DataSetCompleteRegistration dataSetCompleteRegistration){ return (dataSetCompleteRegistrationStore.insert(dataSetCompleteRegistration) > 0); } - private DataSetCompleteRegistration getTestDataSetCompleteRegistrationWith(State state) throws Exception { + private DataSetCompleteRegistration getTestDataSetCompleteRegistrationWith(State state, String period) + throws Exception { return DataSetCompleteRegistration.builder() - .period("2018") + .period(period) .dataSet("BfMAe6Itzgt") .attributeOptionCombo("HllvX50cXC0") .organisationUnit("DiszpKrYNg8") @@ -121,5 +168,4 @@ private DataSetCompleteRegistration getTestDataSetCompleteRegistrationWith(State .state(state) .build(); } - -} +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModuleMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModuleMockIntegrationShould.java index f7c558edb1..da0b9715cf 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModuleMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/dataset/DataSetModuleMockIntegrationShould.java @@ -28,8 +28,6 @@ package org.hisp.dhis.android.core.dataset; -import androidx.test.runner.AndroidJUnit4; - import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.data.database.SyncedDatabaseMockIntegrationShould; import org.hisp.dhis.android.core.dataelement.DataElementOperand; @@ -37,9 +35,10 @@ import org.junit.Test; import org.junit.runner.RunWith; -import java.text.ParseException; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -111,7 +110,7 @@ public void allow_access_to_compulsory_data_element_operands() { } @Test - public void allow_access_data_input_periods() throws ParseException { + public void allow_access_data_input_periods() { DataSet dataSet = d2.dataSetModule().dataSets.uid("lyLU2wR22tC").withAllChildren().get(); List dataInputPeriods = dataSet.dataInputPeriods(); assertThat(dataInputPeriods.size(), is(1)); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallMockIntegrationShould.java new file mode 100644 index 0000000000..4d210354a7 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallMockIntegrationShould.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.datavalue; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.arch.call.D2Progress; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.data.server.Dhis2MockServer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +import io.reactivex.observers.TestObserver; + +public class AggregatedDataCallMockIntegrationShould extends AbsStoreTestCase { + + private Dhis2MockServer dhis2MockServer; + + @Override + @Before + public void setUp() throws IOException { + super.setUp(); + dhis2MockServer = new Dhis2MockServer(); + dhis2MockServer.setRequestDispatcher(); + } + + @Override + @After + public void tearDown() throws IOException { + super.tearDown(); + dhis2MockServer.shutdown(); + } + + @Test + public void emit_progress() throws Exception { + D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); + d2.syncMetaData().call(); + TestObserver testObserver = d2.aggregatedModule().data().download().asObservable().test(); + testObserver.assertValueCount(3); + + testObserver.assertValueAt(0, v -> assertDouble(v.percentage(), 33.33) && v.lastCall().equals("SystemInfo")); + testObserver.assertValueAt(1, v -> assertDouble(v.percentage(), 66.66)); + testObserver.assertValueAt(2, v -> assertDouble(v.percentage(), 100)); + testObserver.dispose(); + } + + private boolean assertDouble(double d1, double d2) { + return d2 - d1 < 0.01; + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java index bc935a3250..7226b1a121 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/AggregatedDataCallRealIntegrationShould.java @@ -75,7 +75,7 @@ public void response_successful_on_sync_data_once() throws Exception { d2.userModule().logIn("android", "Android123").call(); d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); } //@Test @@ -83,9 +83,9 @@ public void response_successful_on_sync_data_value_two_times() throws Exception d2.userModule().logIn("android", "Android123").call(); d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); } } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValuePostCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValuePostCallRealIntegrationShould.java index 7be7741013..51a85abcd7 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValuePostCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/datavalue/DataValuePostCallRealIntegrationShould.java @@ -61,7 +61,7 @@ public void setUp() throws IOException { public void dataValuesWithToPostState_shouldBeUploaded() throws Exception { d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); DataValue dataValue = getTestDataValueWith(State.TO_POST, 1); @@ -81,7 +81,7 @@ public void dataValuesWithToPostState_shouldBeUploaded() throws Exception { public void dataValuesWithToUpdateState_shouldBeUploaded() throws Exception { d2.syncMetaData().call(); - d2.aggregatedModule().data().download().call(); + d2.aggregatedModule().data().download().asObservable().subscribe(); DataValue dataValue = getTestDataValueWith(State.TO_UPDATE,2); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java index 1aadf61a21..055ba9a4dd 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/enrollment/EnrollmentCollectionRepositoryMockIntegrationShould.java @@ -64,6 +64,16 @@ public void allow_access_to_one_enrollment_without_children() { assertThat(enrollment.events() == null, is(true)); } + @Test + public void include_events_as_children() { + Enrollment enrollment1 = d2.enrollmentModule().enrollments + .withEvents().uid("enroll1").get(); + Enrollment enrollment2 = d2.enrollmentModule().enrollments + .withEvents().uid("enroll2").get(); + assertThat(enrollment1.events().size(), is(1)); + assertThat(enrollment2.events().size(), is(1)); + } + @Test public void include_notes_as_children() { Enrollment enrollment1 = d2.enrollmentModule().enrollments diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndpointCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndpointCallMockIntegrationShould.java index 6b549a8212..8cfdd2fcf7 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndpointCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventEndpointCallMockIntegrationShould.java @@ -30,8 +30,8 @@ import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.common.State; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.junit.After; import org.junit.Before; @@ -58,7 +58,7 @@ public class EventEndpointCallMockIntegrationShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); } @@ -118,6 +118,59 @@ public void rollback_transaction_when_insert_a_event_with_wrong_foreign_key() assertThat(d2.trackedEntityModule().trackedEntityDataValues.count(), is(0)); } + @Test + public void not_overwrite_events_marked_as_to_post_to_update_or_error() throws Exception { + givenAMetadataInDatabase(); + + int pageSize = 1; + + Callable> eventEndpointCall = EventCallFactory.create(d2.retrofit(), d2.databaseAdapter(), "DiszpKrYNg8", pageSize); + dhis2MockServer.enqueueMockResponse("event/events_1.json"); + + List events = eventEndpointCall.call(); + d2.eventModule().eventPersistenceCallFactory.getCall(events).call(); + + Event event = events.get(0); + assertThat(event.uid(), is("V1CerIi3sdL")); + assertThat(d2.eventModule().events.count(), is(pageSize)); + + EventStoreImpl.create(d2.databaseAdapter()).update(event.toBuilder() + .state(State.SYNCED).status(EventStatus.SKIPPED).build()); + + d2.eventModule().eventPersistenceCallFactory.getCall(events).call(); + + Event event1 = d2.eventModule().events.one().get(); + assertThat(event1.uid(), is("V1CerIi3sdL")); + assertThat(event1.status(), is(EventStatus.COMPLETED)); // Because in Synced state should overwrite. + + EventStoreImpl.create(d2.databaseAdapter()).update(event.toBuilder() + .state(State.TO_UPDATE).status(EventStatus.SKIPPED).build()); + + d2.eventModule().eventPersistenceCallFactory.getCall(events).call(); + + Event event2 = d2.eventModule().events.one().get(); + assertThat(event2.uid(), is("V1CerIi3sdL")); + assertThat(event2.status(), is(EventStatus.SKIPPED)); + + EventStoreImpl.create(d2.databaseAdapter()).update(event.toBuilder() + .state(State.ERROR).status(EventStatus.SKIPPED).build()); + + d2.eventModule().eventPersistenceCallFactory.getCall(events).call(); + + Event event3 = d2.eventModule().events.one().get(); + assertThat(event3.uid(), is("V1CerIi3sdL")); + assertThat(event3.status(), is(EventStatus.SKIPPED)); + + EventStoreImpl.create(d2.databaseAdapter()).update(event.toBuilder() + .state(State.TO_POST).status(EventStatus.SKIPPED).build()); + + d2.eventModule().eventPersistenceCallFactory.getCall(events).call(); + + Event event4 = d2.eventModule().events.one().get(); + assertThat(event4.uid(), is("V1CerIi3sdL")); + assertThat(event4.status(), is(EventStatus.SKIPPED)); + } + private void givenAMetadataInDatabase() throws Exception { dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventPostCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventPostCallMockIntegrationShould.java new file mode 100644 index 0000000000..7cc4e6d139 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventPostCallMockIntegrationShould.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.event; + +import com.google.common.collect.Lists; + +import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2Factory; +import org.hisp.dhis.android.core.common.State; +import org.hisp.dhis.android.core.common.UidsHelper; +import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; +import org.hisp.dhis.android.core.data.server.Dhis2MockServer; +import org.hisp.dhis.android.core.data.trackedentity.TrackedEntityDataValueSamples; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; +import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; +import org.hisp.dhis.android.core.program.Program; +import org.hisp.dhis.android.core.program.ProgramStage; +import org.hisp.dhis.android.core.program.ProgramStageStore; +import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValue; +import org.hisp.dhis.android.core.trackedentity.TrackedEntityDataValueStoreImpl; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import androidx.test.runner.AndroidJUnit4; + +import static com.google.common.truth.Truth.assertThat; + +@RunWith(AndroidJUnit4.class) +public class EventPostCallMockIntegrationShould extends AbsStoreTestCase { + + private Dhis2MockServer dhis2MockServer; + private D2 d2; + + private EventPostCall eventPostCall; + + @Override + @Before + public void setUp() throws IOException { + super.setUp(); + + dhis2MockServer = new Dhis2MockServer(); + d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); + + eventPostCall = getD2DIComponent(d2).eventPostCall(); + } + + @Override + @After + public void tearDown() throws IOException { + super.tearDown(); + + dhis2MockServer.shutdown(); + } + + @Test + public void build_payload_with_different_enrollments() throws Exception { + givenAMetadataInDatabase(); + + storeEvents(); + + List events = eventPostCall.queryDataToSync(null); + + assertThat(events.size()).isEqualTo(3); + + for (Event event : events) { + assertThat(event.trackedEntityDataValues().size()).isEqualTo(1); + } + } + + @Test + public void handle_import_conflicts_correctly() throws Exception { + givenAMetadataInDatabase(); + + storeEvents(); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_event_import_conflicts.json"); + + d2.eventModule().events.upload().call(); + + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(3); + } + + @Test + public void delete_old_import_conflicts() throws Exception { + givenAMetadataInDatabase(); + + storeEvents(); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_event_import_conflicts.json"); + d2.eventModule().events.upload().call(); + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(3); + + EventStoreImpl.create(databaseAdapter()).setState("event1Id", State.TO_POST); + EventStoreImpl.create(databaseAdapter()).setState("event2Id", State.TO_POST); + EventStoreImpl.create(databaseAdapter()).setState("event3Id", State.TO_POST); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_event_import_conflicts2.json"); + d2.eventModule().events.upload().call(); + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(2); + } + + @Test + public void handle_event_deletions() throws Exception { + givenAMetadataInDatabase(); + + storeEvents(); + + assertThat(d2.eventModule().events.count()).isEqualTo(4); + + EventStoreImpl.create(databaseAdapter()).setState("event1Id", State.TO_DELETE); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_event_import_conflicts2.json"); + + d2.eventModule().events.upload().call(); + + assertThat(d2.eventModule().events.count()).isEqualTo(3); + } + + @Test + public void recreate_events_with_filters() throws Exception { + givenAMetadataInDatabase(); + + String event1 = "event1"; + String event2 = "event2"; + String event3 = "event3"; + String event4 = "event4"; + + Program program = d2.programModule().programs.one().get(); + + storeSingleEvent(event1, program, State.TO_POST); + storeSingleEvent(event2, program, State.TO_UPDATE); + storeSingleEvent(event3, program, State.TO_DELETE); + storeSingleEvent(event4, program, State.SYNCED); + + List events = eventPostCall.queryDataToSync( + d2.eventModule().events.byProgramUid().eq(program.uid()) + .byState().in(State.TO_POST, State.TO_UPDATE, State.TO_DELETE).get()); + + assertThat(events.size()).isEqualTo(3); + assertThat(UidsHelper.getUidsList(events).containsAll(Lists.newArrayList(event1, event2, event3))) + .isEqualTo(true); + } + + private void givenAMetadataInDatabase() throws Exception { + dhis2MockServer.enqueueMetadataResponses(); + d2.syncMetaData().call(); + } + + private void storeEvents() { + String event1Id = "event1Id"; + String event2Id = "event2Id"; + String event3Id = "event3Id"; + String event4Id = "event4Id"; + + OrganisationUnit orgUnit = OrganisationUnitStore.create(databaseAdapter()).selectFirst(); + Program program = d2.programModule().programs.one().get(); + ProgramStage programStage = ProgramStageStore.create(databaseAdapter()).selectFirst(); + + TrackedEntityDataValue dataValue1 = TrackedEntityDataValueSamples.get().toBuilder().event(event1Id).build(); + + Event event1 = Event.builder() + .uid(event1Id) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(State.TO_POST) + .trackedEntityDataValues(Collections.singletonList(dataValue1)) + .build(); + + TrackedEntityDataValue dataValue2 = TrackedEntityDataValueSamples.get().toBuilder().event(event2Id).build(); + + Event event2 = Event.builder() + .uid(event2Id) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(State.TO_POST) + .trackedEntityDataValues(Collections.singletonList(dataValue2)) + .build(); + + TrackedEntityDataValue dataValue3 = TrackedEntityDataValueSamples.get().toBuilder().event(event3Id).build(); + + Event event3 = Event.builder() + .uid(event3Id) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(State.TO_POST) + .trackedEntityDataValues(Collections.singletonList(dataValue3)) + .build(); + + TrackedEntityDataValue dataValue4 = TrackedEntityDataValueSamples.get().toBuilder().event(event4Id).build(); + + Event event4 = Event.builder() + .uid(event4Id) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(State.ERROR) + .trackedEntityDataValues(Collections.singletonList(dataValue4)) + .build(); + + EventStoreImpl.create(databaseAdapter()).insert(event1); + EventStoreImpl.create(databaseAdapter()).insert(event2); + EventStoreImpl.create(databaseAdapter()).insert(event3); + EventStoreImpl.create(databaseAdapter()).insert(event4); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue1); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue2); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue3); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue4); + + assertThat(d2.eventModule().events.count()).isEqualTo(4); + } + + private void storeSingleEvent(String eventUid, Program program, State state) { + OrganisationUnit orgUnit = OrganisationUnitStore.create(databaseAdapter()).selectFirst(); + ProgramStage programStage = ProgramStageStore.create(databaseAdapter()).selectFirst(); + + EventStoreImpl.create(databaseAdapter()).insert( + Event.builder() + .uid(eventUid) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(state) + .deleted(false) + .build()); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventWithLimitCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventWithLimitCallRealIntegrationShould.java index b521b684c5..67d93e5230 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventWithLimitCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/event/EventWithLimitCallRealIntegrationShould.java @@ -56,7 +56,10 @@ public void download_tracked_entity_instances() throws Exception { d2.syncMetaData().call(); - d2.eventModule().downloadSingleEvents(20, false).call(); - assertThat(EventStoreImpl.create(databaseAdapter()).selectAll().size()).isEqualTo(20); + d2.eventModule().downloadSingleEvents(20, false, false).call(); + + int count = d2.eventModule().events.count(); + + assertThat(count).isEqualTo(20); } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/imports/TrackerImportConflictStoreIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/imports/TrackerImportConflictStoreIntegrationShould.java new file mode 100644 index 0000000000..4eeba6e0be --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/imports/TrackerImportConflictStoreIntegrationShould.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.imports; + +import org.hisp.dhis.android.core.data.database.DatabaseAdapterFactory; +import org.hisp.dhis.android.core.data.database.ObjectStoreAbstractIntegrationShould; +import org.hisp.dhis.android.core.data.imports.TrackerImportConflictSamples; +import org.junit.runner.RunWith; + +import androidx.test.runner.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +public class TrackerImportConflictStoreIntegrationShould + extends ObjectStoreAbstractIntegrationShould { + + public TrackerImportConflictStoreIntegrationShould() { + super(TrackerImportConflictStore.create(DatabaseAdapterFactory.get(false)), + TrackerImportConflictTableInfo.TABLE_INFO, DatabaseAdapterFactory.get(false)); + } + + @Override + protected TrackerImportConflict buildObject() { + return TrackerImportConflictSamples.get(); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java index 26ca83243f..9939c3fb48 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/maintenance/ForeignKeyCleanerShould.java @@ -29,17 +29,17 @@ package org.hisp.dhis.android.core.maintenance; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import com.google.common.truth.Truth; import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.category.CategoryCategoryComboLink; +import org.hisp.dhis.android.core.category.CategoryCategoryComboLinkTableInfo; import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; import org.hisp.dhis.android.core.common.D2CallExecutor; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.program.Program; import org.hisp.dhis.android.core.program.ProgramRule; @@ -63,6 +63,8 @@ import java.util.ArrayList; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @@ -88,7 +90,7 @@ public class ForeignKeyCleanerShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); } @@ -118,6 +120,33 @@ public void remove_rows_that_produce_foreign_key_errors() throws Exception { cursor.close(); } + @Test + public void not_cause_null_records_on_fk_table() throws Exception { + final D2CallExecutor executor = D2CallExecutor.create(d2.databaseAdapter()); + + executor.executeD2CallTransactionally(() -> { + givenAMetadataInDatabase(); + + CategoryCategoryComboLink categoryCategoryComboLink = CategoryCategoryComboLink.builder() + .category("no_category") + .categoryCombo("no_category_combo") + .sortOrder(2) + .build(); + + d2.databaseAdapter().database().insert(CategoryCategoryComboLinkTableInfo.TABLE_INFO.name(), + null, categoryCategoryComboLink.toContentValues()); + + ForeignKeyCleanerImpl.create(d2.databaseAdapter()).cleanForeignKeyErrors(); + + return null; + }); + + List foreignKeyViolationList = + ForeignKeyViolationStore.create(d2.databaseAdapter()).selectAll(); + + Truth.assertThat(foreignKeyViolationList.size()).isEqualTo(3); + } + @Test public void save_foreign_key_violations_when_some_errors_are_find() throws Exception { syncMetadataAndAddFKViolation(); @@ -145,7 +174,7 @@ public void save_foreign_key_violations_when_some_errors_are_find() throws Excep @Test public void cascade_deletion_on_foreign_key_error() throws Exception { - final D2CallExecutor executor = new D2CallExecutor(d2.databaseAdapter()); + final D2CallExecutor executor = D2CallExecutor.create(d2.databaseAdapter()); final String PROGRAM_RULE_UID = "program_rule_uid"; @@ -201,7 +230,7 @@ public void cascade_deletion_on_foreign_key_error() throws Exception { private void syncMetadataAndAddFKViolation() throws D2Error { - final D2CallExecutor executor = new D2CallExecutor(d2.databaseAdapter()); + final D2CallExecutor executor = D2CallExecutor.create(d2.databaseAdapter()); executor.executeD2CallTransactionally(() -> { givenAMetadataInDatabase(); @@ -228,7 +257,7 @@ private void syncMetadataAndAddFKViolation() throws D2Error { private void givenAMetadataInDatabase() { try { - dhis2MockServer.enqueueMetadataResponses(); + dhis2MockServer.setRequestDispatcher(); d2.syncMetaData().call(); } catch (Exception ignore) { } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java index 3f22ef9517..c50c236715 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/option/OptionSetCallShould.java @@ -29,7 +29,6 @@ package org.hisp.dhis.android.core.option; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,7 +39,6 @@ import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.ValueType; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.maintenance.ForeignKeyCleanerImpl; import org.hisp.dhis.android.core.utils.ColumnsArrayUtils; @@ -55,6 +53,8 @@ import java.util.Set; import java.util.concurrent.Callable; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @@ -69,7 +69,7 @@ public class OptionSetCallShould extends AbsStoreTestCase { @Before public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); dhis2MockServer.enqueueMockResponse("option/option_sets.json"); // ToDo: consider moving this out @@ -83,7 +83,7 @@ public void setUp() throws IOException { optionSetCall = getD2DIComponent(d2).optionSetCallFactory().create(uids); - d2CallExecutor = new D2CallExecutor(databaseAdapter()); + d2CallExecutor = D2CallExecutor.create(databaseAdapter()); } @@ -109,6 +109,16 @@ public void persist_option_set_with_options_in_data_base_when_call() throws Exce "2015-08-06T14:23:38.789", // lastUpdated 1, // version "TEXT" // valueType + ).hasRow( + 2L, // id + "TQ2lai3OfVG", // uid + null, // code + "One option", // name + "One option", // displayName + "2014-06-22T10:59:26.564", // created + "2015-08-06T14:23:38.789", // lastUpdated + 2, // version + "NUMBER" // valueType ).isExhausted(); assertThatCursor(optionCursor) @@ -122,10 +132,7 @@ public void persist_option_set_with_options_in_data_base_when_call() throws Exce "2014-08-18T12:39:16.000", // lastUpdated 1, // sortOrder "VQ2lai3OfVG" // optionSet - ); - - assertThatCursor(optionCursor) - .hasRow( + ).hasRow( 2L, // id "egT1YqFWsVk", // uid "15-19 years", // code @@ -135,6 +142,16 @@ public void persist_option_set_with_options_in_data_base_when_call() throws Exce "2014-08-18T12:39:16.000", // lastUpdated 2, // sortOrder "VQ2lai3OfVG" // optionSet + ).hasRow( + 4L, // id + "Z1ILwhy5VDY", // uid + "First option", // code + "First option", // name + "First option", // displayName + "2014-08-18T12:39:16.000", // created + "2014-08-18T12:39:16.000", // lastUpdated + 1, // sortOrder + "TQ2lai3OfVG" // optionSet ).isExhausted(); } @@ -143,7 +160,7 @@ public void persist_option_set_with_options_in_data_base_when_call() throws Exce public void return_option_set_after_call() throws Exception { List optionSetList = executeOptionSetCall(); - assertThat(optionSetList.size()).isEqualTo(1); + assertThat(optionSetList.size()).isEqualTo(2); OptionSet optionSet = optionSetList.get(0); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java index ba6e373c7c..57508f7b70 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/organisationunit/OrganisationUnitCallMockIntegrationShould.java @@ -30,7 +30,6 @@ import android.content.ContentValues; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -43,7 +42,6 @@ import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.IdentifiableObjectStore; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.organisationunit.OrganisationUnitSamples; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.program.ProgramTableInfo; @@ -67,6 +65,8 @@ import java.util.Set; import java.util.concurrent.Callable; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @@ -93,7 +93,7 @@ public OrganisationUnitCallMockIntegrationShould() throws ParseException { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramEndpointCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramEndpointCallMockIntegrationShould.java index 1cb8e091ac..32cded9ebd 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramEndpointCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/program/ProgramEndpointCallMockIntegrationShould.java @@ -30,7 +30,6 @@ import android.content.ContentValues; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -43,7 +42,6 @@ import org.hisp.dhis.android.core.common.BaseNameableObjectModel; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.legendset.LegendSetTableInfo; import org.hisp.dhis.android.core.legendset.LegendTableInfo; @@ -61,6 +59,8 @@ import java.util.List; import java.util.concurrent.Callable; +import androidx.test.runner.AndroidJUnit4; + import static org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel.Columns.UID; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @@ -109,7 +109,7 @@ public class ProgramEndpointCallMockIntegrationShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); @@ -280,7 +280,6 @@ public void persist_tracked_entity_attribute_when_call() throws Exception { TrackedEntityAttributeFields.OPTION_SET, TrackedEntityAttributeFields.VALUE_TYPE, TrackedEntityAttributeFields.EXPRESSION, - TrackedEntityAttributeFields.SEARCH_SCOPE, TrackedEntityAttributeFields.PROGRAM_SCOPE, TrackedEntityAttributeFields.DISPLAY_IN_LIST_NO_PROGRAM, TrackedEntityAttributeFields.GENERATED, @@ -309,7 +308,6 @@ public void persist_tracked_entity_attribute_when_call() throws Exception { null, "TEXT", null, - "SEARCH_ORG_UNITS", 0, // false 1, // true 0, // false diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/relationship/RelationshipStoreIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/relationship/RelationshipStoreIntegrationShould.java index 03ef2ceaf3..3ef7cc8a05 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/relationship/RelationshipStoreIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/relationship/RelationshipStoreIntegrationShould.java @@ -39,7 +39,7 @@ public class RelationshipStoreIntegrationShould extends IdentifiableObjectStoreAbstractIntegrationShould { public RelationshipStoreIntegrationShould() { - super(RelationshipStore.create(DatabaseAdapterFactory.get(false)), + super(RelationshipStoreImpl.create(DatabaseAdapterFactory.get(false)), RelationshipTableInfo.TABLE_INFO, DatabaseAdapterFactory.get(false)); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/systeminfo/SystemInfoCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/systeminfo/SystemInfoCallMockIntegrationShould.java index 3a724233d8..d1b427b28b 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/systeminfo/SystemInfoCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/systeminfo/SystemInfoCallMockIntegrationShould.java @@ -29,7 +29,6 @@ package org.hisp.dhis.android.core.systeminfo; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.arch.db.TableInfo; @@ -37,7 +36,6 @@ import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.data.systeminfo.SystemInfoSamples; import org.junit.After; @@ -47,6 +45,8 @@ import java.io.IOException; +import androidx.test.runner.AndroidJUnit4; + import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @RunWith(AndroidJUnit4.class) @@ -66,7 +66,7 @@ public class SystemInfoCallMockIntegrationShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); dhis2MockServer.enqueueMockResponse("systeminfo/system_info.json"); D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); @@ -75,7 +75,7 @@ public void setUp() throws IOException { @Test public void persist_system_info_when_call() throws Exception { - systemInfoRepository.download().call(); + systemInfoRepository.download().subscribe(); Cursor systemInfoCursor = getCursor(); assertSystemInfoInCursor(systemInfoCursor, systemInfoFromAPI); } @@ -86,7 +86,7 @@ public void update_system_info_when_call() throws Exception { Cursor cursorPreCall = getCursor(); assertSystemInfoInCursor(cursorPreCall, systemInfoFromDB); - systemInfoRepository.download().call(); + systemInfoRepository.download().subscribe(); Cursor cursorPostCall = getCursor(); assertSystemInfoInCursor(cursorPostCall, systemInfoFromAPI); } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/CreateTrackedEntityAttributeUtils.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/CreateTrackedEntityAttributeUtils.java index 30d69a8154..192c203478 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/CreateTrackedEntityAttributeUtils.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/CreateTrackedEntityAttributeUtils.java @@ -60,7 +60,6 @@ public class CreateTrackedEntityAttributeUtils { private static final Integer SORT_ORDER_IN_LIST_NO_PROGRAM = 1; private static final ValueType VALUE_TYPE = ValueType.BOOLEAN; private static final String EXPRESSION = "test_expression"; - private static final TrackedEntityAttributeSearchScope SEARCH_SCOPE = TrackedEntityAttributeSearchScope.SEARCH_ORG_UNITS; private static final Integer PROGRAM_SCOPE = 0; // false private static final Integer DISPLAY_IN_LIST_NO_PROGRAM = 1; // true private static final Integer GENERATED = 0; // false @@ -89,7 +88,6 @@ public static ContentValues create(long id, String uid, String optionSetUid) { values.put(TrackedEntityAttributeFields.OPTION_SET, optionSetUid); values.put(TrackedEntityAttributeFields.VALUE_TYPE, VALUE_TYPE.name()); values.put(TrackedEntityAttributeFields.EXPRESSION, EXPRESSION); - values.put(TrackedEntityAttributeFields.SEARCH_SCOPE, SEARCH_SCOPE.name()); values.put(TrackedEntityAttributeFields.PROGRAM_SCOPE, PROGRAM_SCOPE); values.put(TrackedEntityAttributeFields.DISPLAY_IN_LIST_NO_PROGRAM, DISPLAY_IN_LIST_NO_PROGRAM); values.put(TrackedEntityAttributeFields.GENERATED, GENERATED); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityAttributeModelShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityAttributeModelShould.java index 4e0068024f..74bf574e58 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityAttributeModelShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityAttributeModelShould.java @@ -30,7 +30,6 @@ import android.content.ContentValues; import android.database.MatrixCursor; -import androidx.test.runner.AndroidJUnit4; import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.ValueType; @@ -40,6 +39,8 @@ import java.util.Date; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.AndroidTestUtils.toBoolean; @@ -59,8 +60,6 @@ public class TrackedEntityAttributeModelShould { private static final String OPTION_SET = "test_option_set_uid"; private static final ValueType VALUE_TYPE = ValueType.BOOLEAN; private static final String EXPRESSION = "test_expression"; - private static final TrackedEntityAttributeSearchScope SEARCH_SCOPE = - TrackedEntityAttributeSearchScope.SEARCH_ORG_UNITS; private static final Integer PROGRAM_SCOPE = 0; // false private static final Integer DISPLAY_IN_LIST_NO_PROGRAM = 1; // true private static final Integer GENERATED = 0; // false @@ -96,7 +95,6 @@ public void create_model_when_created_from_database_cursor() { Columns.OPTION_SET, Columns.VALUE_TYPE, Columns.EXPRESSION, - Columns.SEARCH_SCOPE, Columns.PROGRAM_SCOPE, Columns.DISPLAY_IN_LIST_NO_PROGRAM, Columns.GENERATED, @@ -108,7 +106,7 @@ public void create_model_when_created_from_database_cursor() { cursor.addRow(new Object[]{ ID, UID, CODE, NAME, DISPLAY_NAME, dateString, dateString, SHORT_NAME, DISPLAY_SHORT_NAME, DESCRIPTION, DISPLAY_DESCRIPTION, PATTERN, - SORT_ORDER_IN_LIST_NO_PROGRAM, OPTION_SET, VALUE_TYPE, EXPRESSION, SEARCH_SCOPE, + SORT_ORDER_IN_LIST_NO_PROGRAM, OPTION_SET, VALUE_TYPE, EXPRESSION, PROGRAM_SCOPE, DISPLAY_IN_LIST_NO_PROGRAM, GENERATED, DISPLAY_ON_VISIT_SCHEDULE, ORG_UNIT_SCOPE, UNIQUE, INHERIT }); @@ -132,7 +130,6 @@ public void create_model_when_created_from_database_cursor() { assertThat(model.optionSet()).isEqualTo(OPTION_SET); assertThat(model.valueType()).isEqualTo(VALUE_TYPE); assertThat(model.expression()).isEqualTo(EXPRESSION); - assertThat(model.searchScope()).isEqualTo(SEARCH_SCOPE); assertThat(model.programScope()).isEqualTo(toBoolean(PROGRAM_SCOPE)); assertThat(model.displayInListNoProgram()).isEqualTo(toBoolean(DISPLAY_IN_LIST_NO_PROGRAM)); assertThat(model.generated()).isEqualTo(toBoolean(GENERATED)); @@ -161,7 +158,6 @@ public void create_content_values_when_created_from_builder() { .optionSet(OPTION_SET) .valueType(VALUE_TYPE) .expression(EXPRESSION) - .searchScope(SEARCH_SCOPE) .programScope(toBoolean(PROGRAM_SCOPE)) .displayInListNoProgram(toBoolean(DISPLAY_IN_LIST_NO_PROGRAM)) .generated(toBoolean(GENERATED)) @@ -189,7 +185,6 @@ public void create_content_values_when_created_from_builder() { assertThat(contentValues.getAsString(Columns.OPTION_SET)).isEqualTo(OPTION_SET); assertThat(contentValues.getAsString(Columns.VALUE_TYPE)).isEqualTo(VALUE_TYPE.toString()); assertThat(contentValues.getAsString(Columns.EXPRESSION)).isEqualTo(EXPRESSION); - assertThat(contentValues.getAsString(Columns.SEARCH_SCOPE)).isEqualTo(SEARCH_SCOPE.toString()); assertThat(contentValues.getAsBoolean(Columns.PROGRAM_SCOPE)).isEqualTo(toBoolean(PROGRAM_SCOPE)); assertThat(contentValues.getAsBoolean(Columns.DISPLAY_IN_LIST_NO_PROGRAM)) .isEqualTo(toBoolean(DISPLAY_IN_LIST_NO_PROGRAM)); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java index 8c09ff6031..835ba69d9f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCallMockIntegrationShould.java @@ -28,8 +28,6 @@ package org.hisp.dhis.android.core.trackedentity; -import androidx.annotation.NonNull; - import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; @@ -39,6 +37,7 @@ import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.Payload; +import org.hisp.dhis.android.core.common.State; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; @@ -61,6 +60,8 @@ import java.util.Map; import java.util.concurrent.Callable; +import androidx.annotation.NonNull; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -74,7 +75,7 @@ public class TrackedEntityInstanceCallMockIntegrationShould extends AbsStoreTest public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); } @@ -118,6 +119,7 @@ public void remove_data_removed_in_server_after_second_download() trackedEntityInstanceByUidEndPointCall = d2.trackedEntityModule().downloadTrackedEntityInstancesByUid(Lists.newArrayList(teiUid)); + EnrollmentStoreImpl.create(databaseAdapter()).setState("p6xHz0sbDlx", State.TO_DELETE); dhis2MockServer.enqueueMockResponse("trackedentity/tracked_entity_instance_with_removed_data_payload.json"); @@ -162,6 +164,8 @@ private void verifyDownloadedTrackedEntityInstancePayload(String file, String te assertThat(downloadedTei.uid(), is(expectedEnrollmentResponse.uid())); assertThat(downloadedTei.trackedEntityAttributeValues().size(), is(expectedEnrollmentResponse.trackedEntityAttributeValues().size())); + assertThat(downloadedTei.enrollments().size(), + is(expectedEnrollmentResponse.enrollments().size())); } private void verifyDownloadedTrackedEntityInstance(String file, String teiUid) diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCollectionRepositoryMockIntegrationShould.java index ac055b8e7c..bd4b8e962f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCollectionRepositoryMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceCollectionRepositoryMockIntegrationShould.java @@ -28,14 +28,15 @@ package org.hisp.dhis.android.core.trackedentity; -import androidx.test.runner.AndroidJUnit4; - import org.hisp.dhis.android.core.data.database.SyncedDatabaseMockIntegrationShould; +import org.hisp.dhis.android.core.maintenance.D2Error; import org.junit.Test; import org.junit.runner.RunWith; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -78,4 +79,38 @@ public void include_tracked_entity_attribute_values_as_children() { assertThat(tei.trackedEntityAttributeValues().get(0).trackedEntityAttribute(), is("lZGmxYbs97q")); assertThat(tei.trackedEntityAttributeValues().get(0).value(), is("4081507")); } + + @Test + public void include_relationships_as_children() { + TrackedEntityInstance tei = d2.trackedEntityModule().trackedEntityInstances + .withRelationships().uid("nWrB0TfWlvh").get(); + assertThat(tei.relationships().size(), is(2)); + assertThat(tei.relationships().get(0).uid(), is("AJOytZW7OaI")); + } + + @Test + public void include_relationship_items_in_relationships_as_children() { + TrackedEntityInstance tei = d2.trackedEntityModule().trackedEntityInstances + .withRelationships().uid("nWrB0TfWlvh").get(); + assertThat(tei.relationships().size(), is(2)); + assertThat(tei.relationships().get(0).from().elementUid(), is("nWrB0TfWlvh")); + assertThat(tei.relationships().get(0).to().elementUid(), is("nWrB0TfWlvh")); + } + + @Test + public void add_tracked_entity_instances_to_the_repository() throws D2Error { + List trackedEntityInstances1 = d2.trackedEntityModule().trackedEntityInstances.get(); + assertThat(trackedEntityInstances1.size(), is(2)); + + String teiUid = d2.trackedEntityModule().trackedEntityInstances.add( + TrackedEntityInstanceCreateProjection.create("DiszpKrYNg8", "nEenWmSyUEp")); + + List trackedEntityInstances2 = d2.trackedEntityModule().trackedEntityInstances.get(); + assertThat(trackedEntityInstances2.size(), is(3)); + + TrackedEntityInstance trackedEntityInstance = d2.trackedEntityModule().trackedEntityInstances.uid(teiUid).get(); + assertThat(trackedEntityInstance.uid(), is(teiUid)); + + d2.trackedEntityModule().trackedEntityInstances.uid(teiUid).delete(); + } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallMockIntegrationShould.java index a32b8df6b4..566ae7165e 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallMockIntegrationShould.java @@ -28,25 +28,37 @@ package org.hisp.dhis.android.core.trackedentity; -import androidx.test.runner.AndroidJUnit4; +import com.google.common.collect.Lists; import org.hisp.dhis.android.core.D2; +import org.hisp.dhis.android.core.common.D2CallExecutor; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.common.State; +import org.hisp.dhis.android.core.common.UidsHelper; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; +import org.hisp.dhis.android.core.data.relationship.RelationshipSamples; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; +import org.hisp.dhis.android.core.data.trackedentity.TrackedEntityDataValueSamples; +import org.hisp.dhis.android.core.data.trackedentity.TrackedEntityInstanceSamples; import org.hisp.dhis.android.core.enrollment.Enrollment; import org.hisp.dhis.android.core.enrollment.EnrollmentStoreImpl; import org.hisp.dhis.android.core.event.Event; import org.hisp.dhis.android.core.event.EventStoreImpl; +import org.hisp.dhis.android.core.maintenance.D2Error; +import org.hisp.dhis.android.core.maintenance.ForeignKeyCleanerImpl; import org.hisp.dhis.android.core.organisationunit.OrganisationUnit; import org.hisp.dhis.android.core.organisationunit.OrganisationUnitStore; import org.hisp.dhis.android.core.program.Program; import org.hisp.dhis.android.core.program.ProgramStage; import org.hisp.dhis.android.core.program.ProgramStageStore; -import org.hisp.dhis.android.core.utils.CodeGenerator; -import org.hisp.dhis.android.core.utils.CodeGeneratorImpl; +import org.hisp.dhis.android.core.relationship.Relationship; +import org.hisp.dhis.android.core.relationship.RelationshipConstraintType; +import org.hisp.dhis.android.core.relationship.RelationshipItem; +import org.hisp.dhis.android.core.relationship.RelationshipItemStoreImpl; +import org.hisp.dhis.android.core.relationship.RelationshipItemTrackedEntityInstance; +import org.hisp.dhis.android.core.relationship.RelationshipStoreImpl; +import org.hisp.dhis.android.core.relationship.RelationshipType; +import org.hisp.dhis.android.core.relationship.RelationshipTypeStore; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -57,6 +69,8 @@ import java.util.Collections; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; @RunWith(AndroidJUnit4.class) @@ -65,8 +79,6 @@ public class TrackedEntityInstancePostCallMockIntegrationShould extends AbsStore private Dhis2MockServer dhis2MockServer; private D2 d2; - private CodeGenerator codeGenerator = new CodeGeneratorImpl(); - private TrackedEntityInstancePostCall trackedEntityInstancePostCall; @Override @@ -74,7 +86,7 @@ public class TrackedEntityInstancePostCallMockIntegrationShould extends AbsStore public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); trackedEntityInstancePostCall = getD2DIComponent(d2).trackedEntityInstancePostCall(); @@ -92,22 +104,179 @@ public void tearDown() throws IOException { public void build_payload_with_different_enrollments() throws Exception { givenAMetadataInDatabase(); - String teiId = codeGenerator.generate(); - String enrollment1Id = codeGenerator.generate(); - String enrollment2Id = codeGenerator.generate(); + storeTrackedEntityInstance(); + + List instances = trackedEntityInstancePostCall.queryDataToSync(null); + + assertThat(instances.size()).isEqualTo(1); + for (TrackedEntityInstance instance : instances) { + assertThat(instance.enrollments().size()).isEqualTo(2); + for (Enrollment enrollment : instance.enrollments()) { + assertThat(enrollment.events().size()).isEqualTo(1); + for (Event event : enrollment.events()) { + assertThat(event.trackedEntityDataValues().size()).isEqualTo(1); + } + } + } + } + + @Test + public void build_payload_with_the_enrollments_events_and_values_set_for_upload_update_or_delete() throws Exception { + givenAMetadataInDatabase(); + + storeTrackedEntityInstance(); + + List instances = trackedEntityInstancePostCall.queryDataToSync(null); + assertThat(instances.size()).isEqualTo(1); + for (TrackedEntityInstance instance : instances) { + assertThat(instance.enrollments().size()).isEqualTo(2); + for (Enrollment enrollment : instance.enrollments()) { + assertThat(enrollment.events().size()).isEqualTo(1); + for (Event event : enrollment.events()) { + assertThat(event.trackedEntityDataValues().size()).isEqualTo(1); + } + } + } + + EnrollmentStoreImpl.create(databaseAdapter()).setState("enrollment3Id", State.TO_POST); + instances = trackedEntityInstancePostCall.queryDataToSync(null); + assertThat(instances.size()).isEqualTo(1); + for (TrackedEntityInstance instance : instances) { + assertThat(instance.enrollments().size()).isEqualTo(3); + for (Enrollment enrollment : instance.enrollments()) { + if (enrollment.uid().equals("enrollment3Id")) { + assertThat(enrollment.events().size()).isEqualTo(0); + } else { + assertThat(enrollment.events().size()).isEqualTo(1); + } + } + } + + EventStoreImpl.create(databaseAdapter()).setState("event3Id", State.TO_POST); + instances = trackedEntityInstancePostCall.queryDataToSync(null); + assertThat(instances.size()).isEqualTo(1); + for (TrackedEntityInstance instance : instances) { + assertThat(instance.enrollments().size()).isEqualTo(3); + for (Enrollment enrollment : instance.enrollments()) { + assertThat(enrollment.events().size()).isEqualTo(1); + for (Event event : enrollment.events()) { + assertThat(event.trackedEntityDataValues().size()).isEqualTo(1); + } + } + } + } + + @Test + public void handle_import_conflicts_correctly() throws Exception { + givenAMetadataInDatabase(); + + storeTrackedEntityInstance(); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_import_conflicts_2.json"); + + d2.trackedEntityModule().trackedEntityInstances.upload().call(); + + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(3); + } + + @Test + public void delete_old_import_conflicts() throws Exception { + givenAMetadataInDatabase(); + + storeTrackedEntityInstance(); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_import_conflicts_2.json"); + d2.trackedEntityModule().trackedEntityInstances.upload().call(); + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(3); + + + TrackedEntityInstanceStoreImpl.create(databaseAdapter()).setState("teiId", State.TO_POST); + EnrollmentStoreImpl.create(databaseAdapter()).setState("enrollment1Id", State.TO_POST); + EnrollmentStoreImpl.create(databaseAdapter()).setState("enrollment2Id", State.TO_POST); + EventStoreImpl.create(databaseAdapter()).setState("event1Id", State.TO_POST); + EventStoreImpl.create(databaseAdapter()).setState("event2Id", State.TO_POST); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_import_conflicts_3.json"); + d2.trackedEntityModule().trackedEntityInstances.upload().call(); + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(1); + } + + @Test + public void handle_tei_deletions() throws Exception { + givenAMetadataInDatabase(); + + storeTrackedEntityInstance(); + + TrackedEntityInstanceStoreImpl.create(databaseAdapter()).setState("teiId", State.TO_DELETE); + + dhis2MockServer.enqueueMockResponse("imports/web_response_with_import_conflicts_2.json"); + + d2.trackedEntityModule().trackedEntityInstances.upload().call(); + + assertThat(d2.trackedEntityModule().trackedEntityInstances.count()).isEqualTo(0); + assertThat(d2.enrollmentModule().enrollments.count()).isEqualTo(0); + assertThat(d2.eventModule().events.count()).isEqualTo(0); + assertThat(d2.importModule().trackerImportConflicts.count()).isEqualTo(0); + } + + @Test + public void recreate_teis_with_filters_and_relationships() throws Exception { + givenAMetadataInDatabase(); + + String tei1 = "tei1"; + String tei2 = "tei2"; + String tei3 = "tei3"; + String tei4 = "tei4"; + String tei5 = "tei5"; + + storeSimpleTrackedEntityInstance(tei1, State.TO_POST); + storeSimpleTrackedEntityInstance(tei2, State.TO_POST); + storeSimpleTrackedEntityInstance(tei3, State.TO_POST); + storeSimpleTrackedEntityInstance(tei4, State.TO_POST); + storeSimpleTrackedEntityInstance(tei5, State.SYNCED); + + storeRelationship("relationship1", tei1, tei2); + storeRelationship("relationship2", tei2, tei3); + storeRelationship("relationship3", tei1, tei5); + storeRelationship("relationship4", tei5, tei4); + + List instances = trackedEntityInstancePostCall.queryDataToSync( + d2.trackedEntityModule().trackedEntityInstances.byUid().eq(tei1) + .byState().in(State.TO_POST, State.TO_UPDATE, State.TO_DELETE).get()); + + assertThat(instances.size()).isEqualTo(3); + assertThat(UidsHelper.getUidsList(instances).containsAll(Lists.newArrayList(tei1, tei2, tei3))).isEqualTo(true); + } + + private void givenAMetadataInDatabase() throws Exception { + dhis2MockServer.enqueueMetadataResponses(); + d2.syncMetaData().call(); + } + + private void storeTrackedEntityInstance() { + String teiId = "teiId"; + String enrollment1Id = "enrollment1Id"; + String enrollment2Id = "enrollment2Id"; + String enrollment3Id = "enrollment3Id"; + String event1Id = "event1Id"; + String event2Id = "event2Id"; + String event3Id = "event3Id"; OrganisationUnit orgUnit = OrganisationUnitStore.create(databaseAdapter()).selectFirst(); TrackedEntityType teiType = TrackedEntityTypeStore.create(databaseAdapter()).selectFirst(); Program program = d2.programModule().programs.one().get(); ProgramStage programStage = ProgramStageStore.create(databaseAdapter()).selectFirst(); + TrackedEntityDataValue dataValue1 = TrackedEntityDataValueSamples.get().toBuilder().event(event1Id).build(); + Event event1 = Event.builder() - .uid(codeGenerator.generate()) + .uid(event1Id) .enrollment(enrollment1Id) .organisationUnit(orgUnit.uid()) .program(program.uid()) .programStage(programStage.uid()) .state(State.TO_POST) + .trackedEntityDataValues(Collections.singletonList(dataValue1)) .build(); Enrollment enrollment1 = Enrollment.builder() @@ -119,13 +288,16 @@ public void build_payload_with_different_enrollments() throws Exception { .events(Collections.singletonList(event1)) .build(); + TrackedEntityDataValue dataValue2 = TrackedEntityDataValueSamples.get().toBuilder().event(event2Id).build(); + Event event2 = Event.builder() - .uid(codeGenerator.generate()) + .uid(event2Id) .enrollment(enrollment2Id) .organisationUnit(orgUnit.uid()) .program(program.uid()) .programStage(programStage.uid()) .state(State.TO_POST) + .trackedEntityDataValues(Collections.singletonList(dataValue2)) .build(); Enrollment enrollment2 = Enrollment.builder() @@ -137,33 +309,92 @@ public void build_payload_with_different_enrollments() throws Exception { .events(Collections.singletonList(event2)) .build(); + TrackedEntityDataValue dataValue3 = TrackedEntityDataValueSamples.get().toBuilder().event(event3Id).build(); + + Event event3 = Event.builder() + .uid(event3Id) + .enrollment(enrollment3Id) + .organisationUnit(orgUnit.uid()) + .program(program.uid()) + .programStage(programStage.uid()) + .state(State.ERROR) + .trackedEntityDataValues(Collections.singletonList(dataValue3)) + .build(); + + Enrollment enrollment3 = Enrollment.builder() + .uid(enrollment3Id) + .program(program.uid()) + .organisationUnit(orgUnit.uid()) + .state(State.SYNCED) + .trackedEntityInstance(teiId) + .events(Collections.singletonList(event3)) + .build(); + TrackedEntityInstance tei = TrackedEntityInstance.builder() .uid(teiId) .trackedEntityType(teiType.uid()) .organisationUnit(orgUnit.uid()) .state(State.TO_POST) - .enrollments(Arrays.asList(enrollment1, enrollment2)) + .enrollments(Arrays.asList(enrollment1, enrollment2, enrollment3)) .build(); TrackedEntityInstanceStoreImpl.create(databaseAdapter()).insert(tei); EnrollmentStoreImpl.create(databaseAdapter()).insert(enrollment1); EnrollmentStoreImpl.create(databaseAdapter()).insert(enrollment2); + EnrollmentStoreImpl.create(databaseAdapter()).insert(enrollment3); EventStoreImpl.create(databaseAdapter()).insert(event1); EventStoreImpl.create(databaseAdapter()).insert(event2); + EventStoreImpl.create(databaseAdapter()).insert(event3); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue1); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue2); + TrackedEntityDataValueStoreImpl.create(databaseAdapter()).insert(dataValue3); - List instances = trackedEntityInstancePostCall.queryDataToSync(); + assertThat(d2.trackedEntityModule().trackedEntityInstances.count()).isEqualTo(1); + } - assertThat(instances.size()).isEqualTo(1); - for (TrackedEntityInstance instance : instances) { - assertThat(instance.enrollments().size()).isEqualTo(2); - for (Enrollment enrollment : instance.enrollments()) { - assertThat(enrollment.events().size()).isEqualTo(1); - } - } + private void storeSimpleTrackedEntityInstance(String teiUid, State state) { + OrganisationUnit orgUnit = OrganisationUnitStore.create(databaseAdapter()).selectFirst(); + TrackedEntityType teiType = TrackedEntityTypeStore.create(databaseAdapter()).selectFirst(); + + TrackedEntityInstanceStoreImpl.create(databaseAdapter()).insert( + TrackedEntityInstanceSamples.get().toBuilder() + .uid(teiUid) + .trackedEntityType(teiType.uid()) + .organisationUnit(orgUnit.uid()) + .state(state) + .build()); } - private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMetadataResponses(); - d2.syncMetaData().call(); + private void storeRelationship(String relationshipUid, String fromUid, String toUid) throws D2Error { + + RelationshipType relationshipType = RelationshipTypeStore.create(databaseAdapter()).selectFirst(); + final D2CallExecutor executor = D2CallExecutor.create(d2.databaseAdapter()); + + executor.executeD2CallTransactionally(() -> { + + RelationshipStoreImpl.create(databaseAdapter()).insert( + RelationshipSamples.get230(relationshipUid, fromUid, toUid).toBuilder() + .relationshipType(relationshipType.uid()).build()); + RelationshipItemStoreImpl.create(databaseAdapter()).insert( + RelationshipItem.builder() + .relationship(Relationship.builder().uid(relationshipUid).build()) + .relationshipItemType(RelationshipConstraintType.FROM) + .trackedEntityInstance( + RelationshipItemTrackedEntityInstance.builder().trackedEntityInstance(fromUid).build()) + .build() + ); + RelationshipItemStoreImpl.create(databaseAdapter()).insert( + RelationshipItem.builder() + .relationship(Relationship.builder().uid(relationshipUid).build()) + .relationshipItemType(RelationshipConstraintType.TO) + .trackedEntityInstance( + RelationshipItemTrackedEntityInstance.builder().trackedEntityInstance(toUid).build()) + .build() + ); + + ForeignKeyCleanerImpl.create(d2.databaseAdapter()).cleanForeignKeyErrors(); + + return null; + }); } } \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallRealIntegrationShould.java index 446a2a2c3c..c94cb4a824 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstancePostCallRealIntegrationShould.java @@ -201,7 +201,7 @@ public void pull_event_after_push_tracked_entity_instance_with_that_event() thro //@Test public void post_a_tei() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(4, true).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(4, true, false).asObservable().subscribe(); TrackedEntityInstance tei = trackedEntityInstanceStore.selectFirst(); @@ -227,7 +227,7 @@ public void post_a_tei() throws Exception { //@Test public void post_more_than_one_tei() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(4, true).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(4, true, false).asObservable().subscribe(); TrackedEntityInstance tei = trackedEntityInstanceStore.selectFirst(); @@ -247,11 +247,41 @@ public void post_more_than_one_tei() throws Exception { assertThat(teiList.size() == 1).isTrue(); } + //@Test + public void post_teis_filtering_what_to_post() throws Exception { + downloadMetadata(); + d2.trackedEntityModule().downloadTrackedEntityInstances(4, true, false).asObservable().subscribe(); + + TrackedEntityInstance tei = trackedEntityInstanceStore.selectFirst(); + + String newUid1 = codeGenerator.generate(); + String newUid2 = codeGenerator.generate(); + + insertATei(newUid1, tei, tei.featureType()); + insertATei(newUid2, tei, tei.featureType()); + + d2.trackedEntityModule().trackedEntityInstances.byUid().eq(newUid1).upload().call(); + + d2.wipeModule().wipeEverything(); + downloadMetadata(); + + List teiList = d2.trackedEntityModule().downloadTrackedEntityInstancesByUid(Lists.newArrayList(newUid1)).call(); + assertThat(teiList.size() == 1).isTrue(); + + boolean teiDownloadedSuccessfully = true; + try { + d2.trackedEntityModule().downloadTrackedEntityInstancesByUid(Lists.newArrayList(newUid2)).call(); + } catch (Exception e) { + teiDownloadedSuccessfully = false; + } + assertThat(teiDownloadedSuccessfully).isFalse(); + } + /* Set Dhis2 server to 2.30 or up*/ //@Test public void post_one_tei_and_delete_it() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(1, true).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(1, true, false).asObservable().subscribe(); TrackedEntityInstance tei = trackedEntityInstanceStore.selectFirst(); @@ -282,7 +312,7 @@ public void post_one_tei_and_delete_it() throws Exception { //@Test public void post_new_relationship_to_client_created_tei() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(5, true).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(5, true, false).asObservable().subscribe(); TrackedEntityInstance teiA = trackedEntityInstanceStore.selectFirst(); RelationshipType relationshipType = d2.relationshipModule().relationshipTypes.get().iterator().next(); @@ -330,7 +360,7 @@ public void post_new_relationship_to_client_created_tei() throws Exception { public void create_tei_to_tei_relationship() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(5, false).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(5, false, false).asObservable().subscribe(); List trackedEntityInstances = trackedEntityInstanceStore.selectAll(); assertThat(trackedEntityInstances.size() >= 5).isTrue(); @@ -349,7 +379,7 @@ public void create_tei_to_tei_relationship() throws Exception { public void create_and_delete_tei_to_tei_relationship() throws Exception { downloadMetadata(); - d2.trackedEntityModule().downloadTrackedEntityInstances(10, false).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(10, false, false).asObservable().subscribe(); List trackedEntityInstances = trackedEntityInstanceStore.selectAll(); assertThat(trackedEntityInstances.size() == 10).isTrue(); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceStoreShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceStoreShould.java index 35b851d481..d4e68f8362 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceStoreShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/TrackedEntityInstanceStoreShould.java @@ -31,7 +31,6 @@ import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteConstraintException; -import androidx.test.runner.AndroidJUnit4; import org.hisp.dhis.android.core.common.BaseDataModel; import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; @@ -51,6 +50,8 @@ import java.util.Date; import java.util.List; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @@ -180,7 +181,7 @@ public void return_list_of_tracked_entity_instance_when_query() throws Exception // verify that tei was successfully inserted into database assertThatCursor(cursor).hasRow(UID).isExhausted(); - List trackedEntityInstances = trackedEntityInstanceStore.queryTrackedEntityInstancesToPost(); + List trackedEntityInstances = trackedEntityInstanceStore.queryTrackedEntityInstancesToSync(); List teiUids = new ArrayList<>(); for (TrackedEntityInstance trackedEntityInstance : trackedEntityInstances) { diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/api/TrackedEntityInstanceAPIShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/api/TrackedEntityInstanceAPIShould.java index 63fc94ecfd..66548b1344 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/api/TrackedEntityInstanceAPIShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/api/TrackedEntityInstanceAPIShould.java @@ -126,11 +126,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { // Check server status Payload serverValidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); try { - executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + executor.executeObjectCall(trackedEntityInstanceService.getTrackedEntityInstanceAsCall(invalidTEI.uid(), + TrackedEntityInstanceFields.allFields, true, true)); Assert.fail("Should not reach that line"); } catch (D2Error e) { assertThat(e.httpErrorCode()).isEqualTo(404); @@ -166,11 +167,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { // Check server status Payload serverValidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); try { - executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + executor.executeObjectCall(trackedEntityInstanceService.getTrackedEntityInstanceAsCall(invalidTEI.uid(), + TrackedEntityInstanceFields.allFields, true, true)); Assert.fail("Should not reach that line"); } catch (D2Error e) { assertThat(e.httpErrorCode()).isEqualTo(404); @@ -206,10 +208,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { // TODO Check server status Payload serverValidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverInvalidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); } @@ -241,10 +245,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { } Payload serverValidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverInvalidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI.items().get(0).enrollments()).isNotEmpty(); assertThat(serverInvalidTEI.items().get(0).enrollments()).isEmpty(); @@ -280,10 +286,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { } Payload serverValidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverInvalidTEI = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverInvalidTEI.items().get(0).enrollments().size()).isEqualTo(1); @@ -318,10 +326,12 @@ else if (validTEI2.uid().equals(importSummary.reference())) { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI1.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI1.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverValidTEI2 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI2.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI2.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); @@ -360,10 +370,12 @@ else if (validTEI2.uid().equals(importSummary.reference())) { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI1.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI1.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverValidTEI2 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI2.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI2.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverValidTEI1.items().get(0).enrollments().get(0).events()).isEmpty(); @@ -403,10 +415,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverValidTEI2 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverValidTEI1.items().get(0).enrollments().get(0).events().size()).isEqualTo(1); @@ -446,10 +460,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverValidTEI2 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverValidTEI1.items().get(0).enrollments().get(0).events().size()).isEqualTo(1); @@ -492,10 +508,12 @@ else if (invalidTEI.uid().equals(importSummary.reference())) { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(validTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(validTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); Payload serverValidTEI2 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(invalidTEI.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverValidTEI1.items().get(0).enrollments().get(0).events().size()).isEqualTo(1); @@ -532,7 +550,8 @@ public void event_in_completed_enrollment() throws Exception { } Payload serverValidTEI1 = executor.executeObjectCall(trackedEntityInstanceService - .getTrackedEntityInstance(completedEnrollment.uid(), TrackedEntityInstanceFields.allFields, true)); + .getTrackedEntityInstanceAsCall(completedEnrollment.uid(), TrackedEntityInstanceFields.allFields, + true, true)); assertThat(serverValidTEI1.items().get(0).enrollments().size()).isEqualTo(1); assertThat(serverValidTEI1.items().get(0).enrollments().get(0) @@ -547,4 +566,4 @@ public void event_in_completed_enrollment() throws Exception { private void login() throws Exception { d2.userModule().logIn(RealServerMother.user, RealServerMother.password).call(); } -} +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java similarity index 93% rename from core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java rename to core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java index 2ecd0b00bb..d93f3e5118 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryAndDownloadRealIntegrationShould.java @@ -26,14 +26,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.hisp.dhis.android.core; +package org.hisp.dhis.android.core.trackedentity.search; +import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.api.OuMode; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.server.RealServerMother; import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstance; -import org.hisp.dhis.android.core.trackedentity.search.TrackedEntityInstanceQuery; import org.junit.Before; import java.io.IOException; @@ -71,7 +71,8 @@ public void query_and_download_tracked_entity_instances() throws Exception { d2.syncMetaData().call(); TrackedEntityInstanceQuery query = queryBuilder.build(); - List queriedTeis = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queriedTeis = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queriedTeis).isNotEmpty(); Set uids = new HashSet<>(queriedTeis.size()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCallRealIntegrationShould.java similarity index 93% rename from core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryCallRealIntegrationShould.java rename to core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCallRealIntegrationShould.java index 76853607c5..31d9097486 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/TrackedEntityInstanceQueryCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCallRealIntegrationShould.java @@ -26,18 +26,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.hisp.dhis.android.core; +package org.hisp.dhis.android.core.trackedentity.search; import com.google.common.collect.Lists; +import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.api.OuMode; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.server.RealServerMother; -import org.hisp.dhis.android.core.maintenance.D2Error; -import org.hisp.dhis.android.core.maintenance.D2ErrorCode; import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstance; -import org.hisp.dhis.android.core.trackedentity.search.TrackedEntityInstanceQuery; import org.junit.Before; import java.io.IOException; @@ -71,7 +69,8 @@ public void setUp() throws IOException { //@Test public void query_tracked_entity_instances_no_filter() throws Exception { login(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(queryBuilder.build()).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().get(); assertThat(queryResponse).isNotEmpty(); } @@ -79,8 +78,9 @@ public void query_tracked_entity_instances_no_filter() throws Exception { public void query_tracked_entity_instances_filter_name() throws Exception { login(); - TrackedEntityInstanceQuery query = queryBuilder.query("jorge").build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + TrackedEntityInstanceQuery query = queryBuilder.query(QueryFilter.create("jorge")).build(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -91,7 +91,8 @@ public void query_tracked_entity_instances_filter_program_start_date() throws Ex Calendar cal = Calendar.getInstance(); cal.add(Calendar.YEAR, -1); TrackedEntityInstanceQuery query = queryBuilder.programStartDate(cal.getTime()).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -101,7 +102,8 @@ public void query_tracked_entity_instances_filter_program_end_date() throws Exce Calendar cal = Calendar.getInstance(); TrackedEntityInstanceQuery query = queryBuilder.programEndDate(cal.getTime()).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -109,11 +111,12 @@ public void query_tracked_entity_instances_filter_program_end_date() throws Exce public void query_tracked_entity_instances_one_attribute() throws Exception { login(); - List attributeList = new ArrayList<>(1); - attributeList.add("w75KJ2mc4zz:like:jorge"); + List attributeList = new ArrayList<>(1); + attributeList.add(QueryItem.create("w75KJ2mc4zz", QueryFilter.create(QueryOperator.LIKE, "john"))); TrackedEntityInstanceQuery query = queryBuilder.attribute(attributeList).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -121,12 +124,14 @@ public void query_tracked_entity_instances_one_attribute() throws Exception { public void query_tracked_entity_instances_two_attributes() throws Exception { login(); - List attributeList = new ArrayList<>(2); - attributeList.add("w75KJ2mc4zz:like:Filona"); - attributeList.add("zDhUuAYrxNC:like:Ryder"); + List attributeList = new ArrayList<>(2); + + attributeList.add(QueryItem.create("w75KJ2mc4zz", QueryFilter.create(QueryOperator.LIKE, "Filona"))); + attributeList.add(QueryItem.create("zDhUuAYrxNC", QueryFilter.create(QueryOperator.LIKE, "Ryder"))); TrackedEntityInstanceQuery query = queryBuilder.attribute(attributeList).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -134,11 +139,12 @@ public void query_tracked_entity_instances_two_attributes() throws Exception { public void use_attribute_to_reduce_attributes_returned() throws Exception { login(); - List attributeList = new ArrayList<>(1); - attributeList.add("w75KJ2mc4zz"); + List attributeList = new ArrayList<>(1); + attributeList.add(QueryItem.create("w75KJ2mc4zz")); TrackedEntityInstanceQuery query = queryBuilder.attribute(attributeList).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -146,11 +152,12 @@ public void use_attribute_to_reduce_attributes_returned() throws Exception { public void query_tracked_entity_instances_one_filter() throws Exception { login(); - List filterList = new ArrayList<>(1); - filterList.add("w75KJ2mc4zz:like:jorge"); + List filterList = new ArrayList<>(1); + filterList.add(QueryItem.create("w75KJ2mc4zz", QueryFilter.create(QueryOperator.LIKE, "jorge"))); TrackedEntityInstanceQuery query = queryBuilder.filter(filterList).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -158,12 +165,13 @@ public void query_tracked_entity_instances_one_filter() throws Exception { public void query_tracked_entity_instances_two_filters() throws Exception { login(); - List filterList = new ArrayList<>(2); - filterList.add("w75KJ2mc4zz:like:Filona"); - filterList.add("zDhUuAYrxNC:like:Ryder"); + List filterList = new ArrayList<>(2); + filterList.add(QueryItem.create("w75KJ2mc4zz", QueryFilter.create(QueryOperator.LIKE, "Filona"))); + filterList.add(QueryItem.create("zDhUuAYrxNC", QueryFilter.create(QueryOperator.LIKE, "Ryder"))); TrackedEntityInstanceQuery query = queryBuilder.filter(filterList).build(); - List queryResponse = d2.trackedEntityModule().queryTrackedEntityInstances(query).call(); + List queryResponse = + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(query).get(); assertThat(queryResponse).isNotEmpty(); } @@ -512,10 +520,11 @@ public void throw_exception_for_too_long_list_of_org_units() throws Exception { queryBuilder.orgUnits(orgUnits); try { - d2.trackedEntityModule().queryTrackedEntityInstances(queryBuilder.build()).call(); + d2.trackedEntityModule().trackedEntityInstanceQuery.onlineOnly().query(queryBuilder.build()).get(); fail("D2Error was expected but was not thrown"); - } catch (D2Error d2e) { - assertThat(d2e.errorCode() == D2ErrorCode.TOO_MANY_ORG_UNITS).isTrue(); + } catch (Exception d2e) { + // TODO + //assertThat(d2e.errorCode() == D2ErrorCode.TOO_MANY_ORG_UNITS).isTrue(); } } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java new file mode 100644 index 0000000000..39825e3ad4 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/trackedentity/search/TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.core.trackedentity.search; + +import com.jraska.livedata.TestObserver; + +import org.hisp.dhis.android.core.data.database.SyncedDatabaseMockIntegrationShould; +import org.hisp.dhis.android.core.trackedentity.TrackedEntityInstance; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule; +import androidx.lifecycle.LiveData; +import androidx.paging.PagedList; +import androidx.test.runner.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +public class TrackedEntityInstanceQueryCollectionRepositoryMockIntegrationShould + extends SyncedDatabaseMockIntegrationShould { + + @Rule + public TestRule rule = new InstantTaskExecutorRule(); + + @Test + public void get_offline_initial_objects() throws InterruptedException { + LiveData> liveData = d2.trackedEntityModule().trackedEntityInstanceQuery + .offlineOnly().getPaged(2); + + TestObserver.test(liveData) + .awaitValue() + .assertHasValue() + .assertValue(pagedList -> pagedList.size() == 2); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java index 95c292c1ba..fa6e87e91f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserAuthenticateCallMockIntegrationShould.java @@ -29,14 +29,12 @@ package org.hisp.dhis.android.core.user; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import org.hisp.dhis.android.core.D2; import org.hisp.dhis.android.core.common.BaseIdentifiableObject; import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.resource.Resource; import org.hisp.dhis.android.core.resource.ResourceTableInfo; @@ -48,6 +46,8 @@ import java.io.IOException; import java.util.concurrent.Callable; +import androidx.test.runner.AndroidJUnit4; + import static com.google.common.truth.Truth.assertThat; import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; import static org.hisp.dhis.android.core.utils.UserUtils.base64; @@ -90,7 +90,7 @@ public class UserAuthenticateCallMockIntegrationShould extends AbsStoreTestCase public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java index 8e5d8d385b..c21b1a57ae 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/user/UserCallMockIntegrationShould.java @@ -30,7 +30,6 @@ import android.content.ContentValues; import android.database.Cursor; -import androidx.test.runner.AndroidJUnit4; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; @@ -40,7 +39,6 @@ import org.hisp.dhis.android.core.common.BaseIdentifiableObjectModel; import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.hisp.dhis.android.core.program.CreateProgramUtils; import org.hisp.dhis.android.core.program.ProgramTableInfo; @@ -52,6 +50,8 @@ import java.io.IOException; import java.util.concurrent.Callable; +import androidx.test.runner.AndroidJUnit4; + import static org.hisp.dhis.android.core.data.database.CursorAssert.assertThatCursor; @RunWith(AndroidJUnit4.class) @@ -64,7 +64,7 @@ public class UserCallMockIntegrationShould extends AbsStoreTestCase { @Before public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); dhis2MockServer.enqueueMockResponse("user/user.json"); D2 d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallMockIntegrationShould.java index acd0d9f3ef..cd92ca3053 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallMockIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallMockIntegrationShould.java @@ -32,7 +32,6 @@ import org.hisp.dhis.android.core.common.D2Factory; import org.hisp.dhis.android.core.data.database.AbsStoreTestCase; import org.hisp.dhis.android.core.data.database.DatabaseAssert; -import org.hisp.dhis.android.core.data.file.ResourcesFileReader; import org.hisp.dhis.android.core.data.server.Dhis2MockServer; import org.junit.After; import org.junit.Before; @@ -50,7 +49,8 @@ public class WipeDBCallMockIntegrationShould extends AbsStoreTestCase { public void setUp() throws IOException { super.setUp(); - dhis2MockServer = new Dhis2MockServer(new ResourcesFileReader()); + dhis2MockServer = new Dhis2MockServer(); + dhis2MockServer.setRequestDispatcher(); d2 = D2Factory.create(dhis2MockServer.getBaseEndpoint(), databaseAdapter()); } @@ -92,17 +92,14 @@ public void have_empty_database_when_wipe_db_after_sync_data() throws Exception } private void givenALoginInDatabase() throws Exception { - dhis2MockServer.enqueueLoginResponses(); d2.userModule().logIn("user", "password").call(); } private void givenAMetadataInDatabase() throws Exception { - dhis2MockServer.enqueueMetadataResponses(); d2.syncMetaData().call(); } - private void givenAEventInDatabase() throws Exception { - dhis2MockServer.enqueueMockResponse("event/events.json"); - d2.eventModule().downloadSingleEvents(1, false); + private void givenAEventInDatabase() { + d2.eventModule().downloadSingleEvents(1, false, false); } } diff --git a/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallRealIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallRealIntegrationShould.java index 96a9a0dccb..5572b9ef0f 100644 --- a/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallRealIntegrationShould.java +++ b/core/src/androidTest/java/org/hisp/dhis/android/core/wipe/WipeDBCallRealIntegrationShould.java @@ -105,7 +105,7 @@ public void do_not_have_data_when_wipe_data_after_sync() throws Exception { d2.syncMetaData().call(); - d2.trackedEntityModule().downloadTrackedEntityInstances(5, false).call(); + d2.trackedEntityModule().downloadTrackedEntityInstances(5, false, false).asObservable().subscribe(); TrackedEntityInstanceStore trackedEntityInstanceStore = TrackedEntityInstanceStoreImpl.create(databaseAdapter()); diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/imports/TrackerImportConflictCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/imports/TrackerImportConflictCollectionRepositoryMockIntegrationShould.java new file mode 100644 index 0000000000..6f57470599 --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/imports/TrackerImportConflictCollectionRepositoryMockIntegrationShould.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.testapp.imports; + +import org.hisp.dhis.android.core.common.BaseIdentifiableObject; +import org.hisp.dhis.android.core.data.database.SyncedDatabaseMockIntegrationShould; +import org.hisp.dhis.android.core.imports.ImportStatus; +import org.hisp.dhis.android.core.imports.TrackerImportConflict; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.text.ParseException; +import java.util.List; + +import androidx.test.runner.AndroidJUnit4; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +@RunWith(AndroidJUnit4.class) +public class TrackerImportConflictCollectionRepositoryMockIntegrationShould + extends SyncedDatabaseMockIntegrationShould { + + @Test + public void find_all() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts.get(); + assertThat(trackerImportConflicts.size(), is(2)); + } + + @Test + public void filter_by_conflict() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byConflict().eq("conflict").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_value() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byValue().eq("value").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_tracked_entity_instance() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byTrackedEntityInstanceUid().eq("nWrB0TfWlvh").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_enrollment() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byEnrollmentUid().eq("enroll2").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_event() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byEventUid().eq("event2").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_tale_reference() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byTableReference().eq("table_reference").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_error_code() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byErrorCode().eq("error_code").get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_status() { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byStatus().eq(ImportStatus.SUCCESS).get(); + assertThat(trackerImportConflicts.size(), is(1)); + } + + @Test + public void filter_by_created() throws ParseException { + List trackerImportConflicts = d2.importModule().trackerImportConflicts + .byCreated().eq(BaseIdentifiableObject.parseDate("2017-11-29T11:27:46.935")).get(); + assertThat(trackerImportConflicts.size(), is(2)); + } +} \ No newline at end of file diff --git a/core/src/androidTest/java/org/hisp/dhis/android/testapp/option/OptionCollectionRepositoryMockIntegrationShould.java b/core/src/androidTest/java/org/hisp/dhis/android/testapp/option/OptionCollectionRepositoryMockIntegrationShould.java new file mode 100644 index 0000000000..5fc28f120c --- /dev/null +++ b/core/src/androidTest/java/org/hisp/dhis/android/testapp/option/OptionCollectionRepositoryMockIntegrationShould.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.hisp.dhis.android.testapp.option; + +import org.hisp.dhis.android.core.data.database.SyncedDatabaseMockIntegrationShould; +import org.hisp.dhis.android.core.option.Option; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.List; + +import androidx.test.runner.AndroidJUnit4; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +@RunWith(AndroidJUnit4.class) +public class OptionCollectionRepositoryMockIntegrationShould extends SyncedDatabaseMockIntegrationShould { + + @Test + public void find_all() { + List