diff --git a/opensrp-reveal/build.gradle b/opensrp-reveal/build.gradle index e666aaf25b..89ed54c41a 100644 --- a/opensrp-reveal/build.gradle +++ b/opensrp-reveal/build.gradle @@ -53,8 +53,8 @@ android { applicationId "org.smartregister.reveal" minSdkVersion 18 targetSdkVersion 28 - versionCode 32 - versionName "5.3.24" + versionCode 33 + versionName "5.3.25" multiDexEnabled true buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l" buildConfigField "boolean", "TIME_CHECK", "false" @@ -151,7 +151,7 @@ android { buildConfigField "int", "OPENMRS_UNIQUE_ID_INITIAL_BATCH_SIZE", '250' buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '100' buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2' - buildConfigField "long", "SYNC_INTERVAL_IN_MINUTES", '15' + buildConfigField "long", "SYNC_INTERVAL_IN_MINUTES", '480' buildConfigField "org.smartregister.reveal.util.Country", "BUILD_COUNTRY", "org.smartregister.reveal.util.Country.ZAMBIA" buildConfigField "long", "PULL_UNIQUE_IDS_MINUTES", '15' buildConfigField "String", "ADMIN_PASSWORD_NOT_NEAR_STRUCTURES", '"AdminPass1"' @@ -170,7 +170,7 @@ android { buildConfigField "int", "OPENMRS_UNIQUE_ID_INITIAL_BATCH_SIZE", '250' buildConfigField "int", "OPENMRS_UNIQUE_ID_BATCH_SIZE", '100' buildConfigField "int", "OPENMRS_UNIQUE_ID_SOURCE", '2' - buildConfigField "long", "SYNC_INTERVAL_IN_MINUTES", '15' + buildConfigField "long", "SYNC_INTERVAL_IN_MINUTES", '480' buildConfigField "org.smartregister.reveal.util.Country", "BUILD_COUNTRY", "org.smartregister.reveal.util.Country.THAILAND_EN" buildConfigField "long", "PULL_UNIQUE_IDS_MINUTES", '15' buildConfigField "String", "ADMIN_PASSWORD_NOT_NEAR_STRUCTURES", '"AdminPass1"' diff --git a/opensrp-reveal/src/main/java/org/smartregister/reveal/interactor/LoginInteractor.java b/opensrp-reveal/src/main/java/org/smartregister/reveal/interactor/LoginInteractor.java index b5da7d9091..ffbcf83310 100644 --- a/opensrp-reveal/src/main/java/org/smartregister/reveal/interactor/LoginInteractor.java +++ b/opensrp-reveal/src/main/java/org/smartregister/reveal/interactor/LoginInteractor.java @@ -22,14 +22,13 @@ public LoginInteractor(BaseLoginContract.Presenter loginPresenter) { @Override protected void scheduleJobsPeriodically() { LocationTaskServiceJob.scheduleJob(LocationTaskServiceJob.TAG, - BuildConfig.SYNC_INTERVAL_IN_MINUTES, getFlexValue((int) BuildConfig.SYNC_INTERVAL_IN_MINUTES)); + Utils.getSyncInterval(), getFlexValue((int) Utils.getSyncInterval())); PullUniqueIdsServiceJob.scheduleJob(SyncServiceJob.TAG, BuildConfig.PULL_UNIQUE_IDS_MINUTES, getFlexValue((int) BuildConfig.PULL_UNIQUE_IDS_MINUTES)); DocumentConfigurationServiceJob - .scheduleJob(DocumentConfigurationServiceJob.TAG, BuildConfig.SYNC_INTERVAL_IN_MINUTES, - getFlexValue((int) BuildConfig.SYNC_INTERVAL_IN_MINUTES)); + .scheduleJob(DocumentConfigurationServiceJob.TAG, Utils.getSyncInterval(), getFlexValue((int) Utils.getSyncInterval())); } @Override diff --git a/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Constants.java b/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Constants.java index a5a71d31c4..7d7e58731d 100644 --- a/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Constants.java +++ b/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Constants.java @@ -69,6 +69,9 @@ public interface Constants { List MACEPA_PROVINCES = Arrays.asList("Western", "Southern", "Lusaka"); String ACTIONS = "actions"; + String THAILAND_SYNC_INTERVAL = "720"; + + int SYNC_BACK_OFF_DELAY = 5000; interface CONFIGURATION { String LOGIN = "login"; @@ -106,6 +109,7 @@ interface CONFIGURATION { String COMMUNITY_HEALTH_WORKERS = "community_health_workers"; String CODE = "code"; String NAME = "name"; + String SYNC_INTERVAL_IN_MINUTES = "sync_interval_in_minutes"; String MDA_CORDINATORS = "mda_coordinators"; diff --git a/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Utils.java b/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Utils.java index 06e99b5635..bd26d5c2a2 100644 --- a/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Utils.java +++ b/opensrp-reveal/src/main/java/org/smartregister/reveal/util/Utils.java @@ -190,6 +190,18 @@ public static Float getLocationBuffer() { return Float.valueOf(getGlobalConfig(CONFIGURATION.LOCATION_BUFFER_RADIUS_IN_METRES, BuildConfig.MY_LOCATION_BUFFER + "")); } + public static long getSyncInterval() { + return Long.parseLong(getGlobalConfig(CONFIGURATION.SYNC_INTERVAL_IN_MINUTES, getDefaultSyncInterval())); + } + + private static String getDefaultSyncInterval() { + if (BuildConfig.BUILD_COUNTRY == Country.THAILAND || BuildConfig.BUILD_COUNTRY == Country.THAILAND_EN) { + return Constants.THAILAND_SYNC_INTERVAL; + } else { + return BuildConfig.SYNC_INTERVAL_IN_MINUTES + ""; + } + } + public static Float getPixelsPerDPI(Resources resources) { return TypedValue.applyDimension( diff --git a/opensrp-reveal/src/main/java/org/smartregister/reveal/view/ListTasksActivity.java b/opensrp-reveal/src/main/java/org/smartregister/reveal/view/ListTasksActivity.java index 73aea5d990..4e3cfa38a5 100644 --- a/opensrp-reveal/src/main/java/org/smartregister/reveal/view/ListTasksActivity.java +++ b/opensrp-reveal/src/main/java/org/smartregister/reveal/view/ListTasksActivity.java @@ -10,6 +10,7 @@ import android.graphics.Color; import android.location.Location; import android.os.Bundle; +import android.os.Handler; import android.text.Editable; import android.text.TextWatcher; import android.view.Gravity; @@ -30,7 +31,6 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; import com.mapbox.android.core.permissions.PermissionsManager; import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; @@ -83,6 +83,7 @@ import org.smartregister.reveal.util.Country; import org.smartregister.reveal.util.RevealJsonFormUtils; import org.smartregister.reveal.util.RevealMapHelper; +import org.smartregister.util.NetworkUtils; import java.util.Arrays; import java.util.List; @@ -115,6 +116,7 @@ import static org.smartregister.reveal.util.Constants.RequestCode.REQUEST_CODE_FILTER_TASKS; import static org.smartregister.reveal.util.Constants.RequestCode.REQUEST_CODE_GET_JSON; import static org.smartregister.reveal.util.Constants.RequestCode.REQUEST_CODE_TASK_LISTS; +import static org.smartregister.reveal.util.Constants.SYNC_BACK_OFF_DELAY; import static org.smartregister.reveal.util.Constants.VERTICAL_OFFSET; import static org.smartregister.reveal.util.FamilyConstants.Intent.START_REGISTRATION; import static org.smartregister.reveal.util.Utils.displayDistanceScale; @@ -158,7 +160,9 @@ public class ListTasksActivity extends BaseMapActivity implements ListTaskContra private boolean hasRequestedLocation; - private Snackbar syncProgressSnackbar; + private boolean startedToastShown; + + private boolean completedToastShown; private BaseDrawerContract.View drawerView; @@ -216,8 +220,6 @@ protected void onCreate(Bundle savedInstanceState) { initializeCardViews(); initializeToolbar(); - - syncProgressSnackbar = Snackbar.make(rootView, getString(org.smartregister.R.string.syncing), Snackbar.LENGTH_INDEFINITE); } private void initializeCardViews() { @@ -844,8 +846,10 @@ public void onDestroy() { @Override public void onSyncStart() { - if (SyncStatusBroadcastReceiver.getInstance().isSyncing()) { - syncProgressSnackbar.show(); + if (SyncStatusBroadcastReceiver.getInstance().isSyncing() && !startedToastShown) { + displayToast(R.string.sync_started); + startedToastShown = true; + completedToastShown = false; } toggleProgressBarView(true); } @@ -853,17 +857,22 @@ public void onSyncStart() { @Override public void onSyncInProgress(FetchStatus fetchStatus) { if (FetchStatus.fetched.equals(fetchStatus)) { - syncProgressSnackbar.show(); return; } - syncProgressSnackbar.dismiss(); - if (fetchStatus.equals(FetchStatus.fetchedFailed)) { - Snackbar.make(rootView, org.smartregister.R.string.sync_failed, Snackbar.LENGTH_SHORT).show(); + if (completedToastShown) return; + //To cover against consecutive sync starts firing, turn the flag off with delay + new Handler().postDelayed(() -> startedToastShown = false, SYNC_BACK_OFF_DELAY); + boolean isNetworkAvailable = NetworkUtils.isNetworkAvailable(); + if (fetchStatus.equals(FetchStatus.fetchedFailed) && isNetworkAvailable) { + displayToast(org.smartregister.R.string.sync_failed); } else if (fetchStatus.equals(FetchStatus.nothingFetched)) { - Snackbar.make(rootView, org.smartregister.R.string.sync_complete, Snackbar.LENGTH_SHORT).show(); + displayToast(org.smartregister.R.string.sync_complete); } else if (fetchStatus.equals(FetchStatus.noConnection)) { - Snackbar.make(rootView, org.smartregister.R.string.sync_failed_no_internet, Snackbar.LENGTH_SHORT).show(); + displayToast(org.smartregister.R.string.sync_failed_no_internet); + } else if (fetchStatus.equals(FetchStatus.fetchedFailed) && !isNetworkAvailable) { + displayToast(org.smartregister.R.string.sync_failed_no_internet); } + completedToastShown = true; } @Override @@ -889,7 +898,6 @@ public void onResume() { listTaskPresenter.onResume(); if (SyncStatusBroadcastReceiver.getInstance().isSyncing()) { - syncProgressSnackbar.show(); toggleProgressBarView(true); } } diff --git a/opensrp-reveal/src/main/res/values-th/strings.xml b/opensrp-reveal/src/main/res/values-th/strings.xml index 20526ce3d5..09dbb7cf3d 100644 --- a/opensrp-reveal/src/main/res/values-th/strings.xml +++ b/opensrp-reveal/src/main/res/values-th/strings.xml @@ -293,5 +293,6 @@ เปลี่ยนคำเป็น “แก้ไข” กำลังดาวน์โหลด กำลังดาวน์โหลด: %,.2f %% + เริ่มการซิงค์แล้ว diff --git a/opensrp-reveal/src/main/res/values/strings.xml b/opensrp-reveal/src/main/res/values/strings.xml index 01a1950f3a..1620063169 100644 --- a/opensrp-reveal/src/main/res/values/strings.xml +++ b/opensrp-reveal/src/main/res/values/strings.xml @@ -428,6 +428,7 @@ Start P2P Sync Events + Sync Started Done Locations Plans diff --git a/opensrp-reveal/src/test/java/org/smartregister/reveal/util/UtilsTest.java b/opensrp-reveal/src/test/java/org/smartregister/reveal/util/UtilsTest.java index a90e5ea068..05cf721b52 100644 --- a/opensrp-reveal/src/test/java/org/smartregister/reveal/util/UtilsTest.java +++ b/opensrp-reveal/src/test/java/org/smartregister/reveal/util/UtilsTest.java @@ -14,6 +14,7 @@ import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; import org.smartregister.domain.Obs; import org.smartregister.reveal.BuildConfig; import org.smartregister.reveal.R; @@ -279,6 +280,35 @@ public void testGetCoordsFromGeometryReturnsCorrectValuesFromMultiPolygon() { } + @Test + public void testGetSyncIntervalDefaultForThailand() throws Exception { + RevealApplication revealApplication = initRevealApplicationMock(); + + when(revealApplication.getServerConfigs()).thenReturn(new HashMap<>()); + Whitebox.setInternalState(BuildConfig.class, BuildConfig.BUILD_COUNTRY, Country.THAILAND); + assertEquals(Utils.getSyncInterval(), 720); + + Whitebox.setInternalState(BuildConfig.class, BuildConfig.BUILD_COUNTRY, Country.THAILAND_EN); + assertEquals(Utils.getSyncInterval(), 720); + } + + @Test + public void testGetSyncIntervalDefaultForOthers() throws Exception { + RevealApplication revealApplication = initRevealApplicationMock(); + when(revealApplication.getServerConfigs()).thenReturn(new HashMap<>()); + Whitebox.setInternalState(BuildConfig.class, BuildConfig.BUILD_COUNTRY, Country.ZAMBIA); + assertEquals(Utils.getSyncInterval(), 480); + } + + @Test + public void testGetSyncIntervalFromGlobalConfig() throws Exception { + RevealApplication revealApplication = initRevealApplicationMock(); + Map globalConfigs= new HashMap<>(); + globalConfigs.put(Constants.CONFIGURATION.SYNC_INTERVAL_IN_MINUTES, "80"); + when(revealApplication.getServerConfigs()).thenReturn(globalConfigs); + assertEquals(Utils.getSyncInterval(), 80); + } + @Test public void testShowWhenTrueCheckVisible() { View view = mock(View.class); diff --git a/opensrp-reveal/src/test/java/org/smartregister/reveal/view/ListTasksActivityTest.java b/opensrp-reveal/src/test/java/org/smartregister/reveal/view/ListTasksActivityTest.java index 326341570d..f1e9113e97 100644 --- a/opensrp-reveal/src/test/java/org/smartregister/reveal/view/ListTasksActivityTest.java +++ b/opensrp-reveal/src/test/java/org/smartregister/reveal/view/ListTasksActivityTest.java @@ -5,6 +5,8 @@ import android.content.Intent; import android.graphics.Color; import android.location.Location; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -15,7 +17,6 @@ import androidx.appcompat.app.AlertDialog; -import com.google.android.material.snackbar.Snackbar; import com.mapbox.geojson.Feature; import com.mapbox.geojson.FeatureCollection; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -41,6 +42,8 @@ import org.robolectric.Robolectric; import org.robolectric.shadows.ShadowAlertDialog; import org.robolectric.shadows.ShadowApplication; +import org.robolectric.shadows.ShadowConnectivityManager; +import org.robolectric.shadows.ShadowNetworkInfo; import org.robolectric.shadows.ShadowProgressDialog; import org.robolectric.shadows.ShadowToast; import org.smartregister.Context; @@ -660,6 +663,15 @@ public void testShowProgressDialog() { assertEquals(listTasksActivity.getString(R.string.saving_title), ShadowApplication.getInstance().getLatestDialog().getTitle()); } + @Test + public void testShowProgressDialogWithFormatArgs() { + listTasksActivity.showProgressDialog(R.string.saving_title, R.string.family_name_format, "Name"); + ProgressDialog progressDialog = (ProgressDialog) ShadowProgressDialog.getLatestDialog(); + assertNotNull(progressDialog); + assertTrue(progressDialog.isShowing()); + assertEquals(listTasksActivity.getString(R.string.saving_title), ShadowApplication.getInstance().getLatestDialog().getTitle()); + } + @Test public void testHideProgressDialog() { listTasksActivity.showProgressDialog(R.string.saving_title, R.string.saving_message); @@ -711,54 +723,64 @@ public void testOnSyncStart() { listTasksActivity = spy(listTasksActivity); doNothing().when(listTasksActivity).toggleProgressBarView(true); listTasksActivity.onSyncStart(); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertTrue(snackbar.isShown()); + assertEquals(listTasksActivity.getString(R.string.sync_started), ShadowToast.getTextOfLatestToast()); } @Test - public void testOnSyncInProgressFetchedDataSnackBarIsStillShown() { + public void testOnSyncInProgressFetchedDataToastIsNotShown() { init(listTasksActivity); listTasksActivity.onSyncInProgress(FetchStatus.fetched); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertTrue(snackbar.isShown()); + assertEquals(0, ShadowToast.shownToastCount()); } + @Test + public void testOnConsecutiveSyncCompletedToastIsShownOnce() { + init(listTasksActivity); + listTasksActivity.onSyncInProgress(FetchStatus.nothingFetched); + listTasksActivity.onSyncInProgress(FetchStatus.nothingFetched); + assertEquals(1, ShadowToast.shownToastCount()); + } @Test - public void testOnSyncInProgressFetchFailedSnackBarIsDismissed() { + public void testOnSyncInProgressFetchFailedToastWithFailedIsShown() { init(listTasksActivity); listTasksActivity.onSyncInProgress(FetchStatus.fetchedFailed); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertFalse(snackbar.isShown()); - + assertEquals(listTasksActivity.getString(R.string.sync_failed), ShadowToast.getTextOfLatestToast()); + } + @Test + public void testOnSyncInProgressFetchFailedWithNoNetwork() { + ConnectivityManager connectivityManager = (ConnectivityManager)listTasksActivity.getSystemService("connectivity"); + ShadowConnectivityManager shadowConnectivityManager = shadowOf(connectivityManager); + NetworkInfo networkInfo = ShadowNetworkInfo.newInstance(NetworkInfo.DetailedState.DISCONNECTED, ConnectivityManager.TYPE_WIFI, 0, true, NetworkInfo.State.DISCONNECTED); + shadowConnectivityManager.setActiveNetworkInfo(networkInfo); + init(listTasksActivity); + listTasksActivity.onSyncInProgress(FetchStatus.fetchedFailed); + assertEquals(listTasksActivity.getString(R.string.sync_failed_no_internet), ShadowToast.getTextOfLatestToast()); } @Test - public void testOnSyncInProgressNothingFetchedSnackBarIsDismissed() { + public void testOnSyncInProgressNothingFetchedSyncCompletedIsShown() { init(listTasksActivity); listTasksActivity.onSyncInProgress(FetchStatus.nothingFetched); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertFalse(snackbar.isShown()); + assertEquals(listTasksActivity.getString(R.string.sync_complete), ShadowToast.getTextOfLatestToast()); } @Test - public void testOnSyncInProgressNoConnectionSnackBarIsDismissed() { + public void testOnSyncInProgressNoConnectionCheckConnectionIsShown() { init(listTasksActivity); listTasksActivity.onSyncInProgress(FetchStatus.noConnection); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertFalse(snackbar.isShown()); + assertEquals(listTasksActivity.getString(R.string.sync_failed_no_internet), ShadowToast.getTextOfLatestToast()); } @Test - public void testOnSyncCompleteSnackBarIsDismissed() { + public void testOnSyncCompleteToastCompleteIsShown() { init(listTasksActivity); listTasksActivity = spy(listTasksActivity); doNothing().when(listTasksActivity).toggleProgressBarView(false); listTasksActivity.onSyncComplete(FetchStatus.nothingFetched); - Snackbar snackbar = Whitebox.getInternalState(listTasksActivity, "syncProgressSnackbar"); - assertFalse(snackbar.isShown()); + assertEquals(listTasksActivity.getString(R.string.sync_complete), ShadowToast.getTextOfLatestToast()); } @Test @@ -790,6 +812,20 @@ public void testOnDrawerClosed() { verify(listTaskPresenter).onDrawerClosed(); } + @Test + public void testToggleProgressBarView() { + Whitebox.setInternalState(listTasksActivity, "drawerView", drawerView); + listTasksActivity.toggleProgressBarView(true); + verify(drawerView).toggleProgressBarView(true); + } + + @Test + public void testSetOperationalArea() { + Whitebox.setInternalState(listTasksActivity, "drawerView", drawerView); + listTasksActivity.setOperationalArea(""); + verify(drawerView).setOperationalArea(""); + } + @Test public void testFocusOnUserLocation() { Whitebox.setInternalState(listTasksActivity, "kujakuMapView", kujakuMapView); @@ -1010,14 +1046,6 @@ public void testToggleProgressView() { verify(drawerView).toggleProgressBarView(true); } - @Test - public void testSetOperationalArea() { - Whitebox.setInternalState(listTasksActivity, "drawerView", drawerView); - listTasksActivity.setOperationalArea("operational area"); - verify(drawerView).setOperationalArea("operational area"); - } - - @Test public void testDisplayEditCDDTaskCompleteDialog(){ Whitebox.setInternalState(listTasksActivity, "listTaskPresenter", listTaskPresenter);