Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update develop update 3.0 #3621

Merged
merged 14 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package org.dhis2.usescases.flow.syncFlow

import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.lifecycle.MutableLiveData
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
Expand All @@ -20,13 +18,13 @@ import org.dhis2.usescases.searchTrackEntity.SearchTEActivity
import org.dhis2.usescases.searchte.robot.searchTeiRobot
import org.dhis2.usescases.teidashboard.robot.eventRobot
import org.dhis2.usescases.teidashboard.robot.teiDashboardRobot
import org.hisp.dhis.android.core.mockwebserver.ResponseController.GET
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import syncFlowRobot
import java.util.UUID
import org.dhis2.usescases.eventsWithoutRegistration.eventCapture.EventCaptureActivity

@RunWith(AndroidJUnit4::class)
class SyncFlowTest : BaseTest() {
Expand All @@ -48,12 +46,16 @@ class SyncFlowTest : BaseTest() {

override fun setUp() {
super.setUp()
setupMockServer()
workInfoStatusLiveData =
ApplicationProvider.getApplicationContext<AppTest>().mutableWorkInfoStatuses
}

@Ignore("failing by a bug - ANDROAPP-6154")
@Test
fun shouldShowErrorWhenTEISyncFails() {
mockWebServerRobot.addResponse(GET, "/api/system/ping", API_PING_RESPONSE_OK)

val teiName = "Lars"
val teiLastName = "Overland"

Expand All @@ -79,12 +81,8 @@ class SyncFlowTest : BaseTest() {
clickOnCompleteButton()
}

teiDashboardRobot(composeTestRule) {
composeTestRule.onNodeWithText("Sync").performClick()
}

syncFlowRobot(composeTestRule) {
waitToDebounce(500)
clickOnEventToSync()
clickOnSyncButton()
workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.RUNNING)))
workInfoStatusLiveData.postValue(arrayListOf(mockedGranularWorkInfo(WorkInfo.State.FAILED)))
Expand All @@ -95,6 +93,8 @@ class SyncFlowTest : BaseTest() {

@Test
fun shouldSuccessfullySyncSavedEvent() {
mockWebServerRobot.addResponse(GET, "/api/system/ping", API_PING_RESPONSE_OK)

prepareMalariaEventIntentAndLaunchActivity(ruleEventWithoutRegistration)

eventWithoutRegistrationRobot(composeTestRule) {
Expand All @@ -118,6 +118,8 @@ class SyncFlowTest : BaseTest() {

@Test
fun shouldShowErrorWhenSyncEventFails() {
mockWebServerRobot.addResponse(GET, "/api/system/ping", API_PING_RESPONSE_OK)

prepareMalariaEventIntentAndLaunchActivity(ruleEventWithoutRegistration)

eventWithoutRegistrationRobot(composeTestRule) {
Expand All @@ -141,6 +143,8 @@ class SyncFlowTest : BaseTest() {

@Test
fun shouldSuccessfullySyncSavedDataSet() {
mockWebServerRobot.addResponse(GET, "/api/system/ping", API_PING_RESPONSE_OK)

prepareFacilityDataSetIntentAndLaunchActivity(ruleDataSet)

dataSetRobot {
Expand Down Expand Up @@ -223,5 +227,6 @@ class SyncFlowTest : BaseTest() {

companion object {
const val LAB_MONITORING_EVENT_DATE = "28/6/2020"
const val API_PING_RESPONSE_OK = "mocks/systeminfo/ping.txt"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,6 @@ class MockedWorkManagerController(private val workInfoStatuses: LiveData<List<Wo

}

override fun syncDataForWorkers(
metadataWorkerTag: String,
dataWorkerTag: String,
workName: String
) {

}

override fun syncMetaDataForWorker(metadataWorkerTag: String, workName: String) {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fun enrollmentRobot(enrollmentRobot: EnrollmentRobot.() -> Unit) {
class EnrollmentRobot : BaseRobot() {

fun clickOnAProgramForEnrollment(composeTestRule: ComposeTestRule, program: String) {
composeTestRule.onNodeWithTag(PROGRAM_TO_ENROLL.format(program))
composeTestRule.onNodeWithTag(PROGRAM_TO_ENROLL.format(program), useUnmergedTree = true)
.performClick()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,22 @@ class GranularSyncModule(
view,
repository,
schedulerProvider,
object : DispatcherProvider {
override fun io() = Dispatchers.IO

override fun computation() = Dispatchers.Default

override fun ui() = Dispatchers.Main
},
provideDispatchers(),
syncContext,
workManagerController,
smsSyncProvider,
)
}

@Provides
fun provideDispatchers() = object : DispatcherProvider {
override fun io() = Dispatchers.IO

override fun computation() = Dispatchers.Default

override fun ui() = Dispatchers.Main
}

@Provides
fun granularSyncRepository(
d2: D2,
Expand All @@ -87,6 +90,7 @@ class GranularSyncModule(
dhisProgramUtils,
periodUtils,
resourceManager,
provideDispatchers(),
)

@Provides
Expand Down
1 change: 1 addition & 0 deletions app/src/dhisUITesting/assets/mocks/systeminfo/ping.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pong
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ class GranularSyncModule(
periodUtils: DhisPeriodUtils,
preferenceProvider: PreferenceProvider,
resourceManager: ResourceManager,
dispatcherProvider: DispatcherProvider,
): GranularSyncRepository = GranularSyncRepository(
d2,
syncContext,
preferenceProvider,
dhisProgramUtils,
periodUtils,
resourceManager,
dispatcherProvider,
)

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import androidx.work.WorkInfo
interface WorkManagerController {

fun syncDataForWorker(workerItem: WorkerItem)
fun syncDataForWorkers(metadataWorkerTag: String, dataWorkerTag: String, workName: String)
fun syncMetaDataForWorker(metadataWorkerTag: String, workName: String)
fun syncDataForWorker(metadataWorkerTag: String, workName: String)
fun beginUniqueWork(workerItem: WorkerItem)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ package org.dhis2.data.service.workManager

import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.work.Constraints
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkInfo
Expand All @@ -56,38 +54,10 @@ class WorkManagerControllerImpl(private val workManager: WorkManager) : WorkMana
}
}

override fun syncDataForWorkers(
metadataWorkerTag: String,
dataWorkerTag: String,
workName: String,
) {
val workerOneBuilder = OneTimeWorkRequest.Builder(SyncMetadataWorker::class.java)
workerOneBuilder
.addTag(metadataWorkerTag)
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)

val workerTwoBuilder = OneTimeWorkRequest.Builder(SyncDataWorker::class.java)
workerTwoBuilder
.addTag(dataWorkerTag)
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)

workManager
.beginUniqueWork(workName, ExistingWorkPolicy.KEEP, workerOneBuilder.build())
.then(workerTwoBuilder.build())
.enqueue()
}

override fun syncMetaDataForWorker(metadataWorkerTag: String, workName: String) {
val workerOneBuilder = OneTimeWorkRequest.Builder(SyncMetadataWorker::class.java)
workerOneBuilder
.addTag(metadataWorkerTag)
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)

workManager
.beginUniqueWork(workName, ExistingWorkPolicy.KEEP, workerOneBuilder.build())
Expand All @@ -98,9 +68,6 @@ class WorkManagerControllerImpl(private val workManager: WorkManager) : WorkMana
val workerTwoBuilder = OneTimeWorkRequest.Builder(SyncDataWorker::class.java)
workerTwoBuilder
.addTag(dataWorkerTag)
.setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)

workManager
.beginUniqueWork(workName, ExistingWorkPolicy.KEEP, workerTwoBuilder.build())
Expand Down Expand Up @@ -163,9 +130,6 @@ class WorkManagerControllerImpl(private val workManager: WorkManager) : WorkMana

syncBuilder.apply {
addTag(workerItem.workerName)
setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)
workerItem.delayInSeconds?.let {
setInitialDelay(it, TimeUnit.SECONDS)
}
Expand Down Expand Up @@ -218,9 +182,6 @@ class WorkManagerControllerImpl(private val workManager: WorkManager) : WorkMana

syncBuilder.apply {
addTag(workerItem.workerName)
setConstraints(
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(),
)
workerItem.data?.let {
setInputData(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,9 @@ public void setProgram(@NonNull Program program) {
private void setUpActivityTitle() {
String activityTitle;
if (eventCreationType == EventCreationType.REFERAL) {
activityTitle = program.displayName() + " - " + getString(R.string.referral);
activityTitle = getString(R.string.referral);
} else {

activityTitle = eventUid == null ?
program.displayName() + " - " +
resourceManager.formatWithEventLabel(R.string.new_event_label, programStageUid, 1, false)
: program.displayName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class DashboardViewModel(

private val selectedEventUid = MutableLiveData<String>()

val updateEnrollment = MutableLiveData(false)
val showStatusErrorMessages = MutableLiveData(StatusChangeResultCode.CHANGED)

private var _showFollowUpBar = MutableStateFlow(false)
Expand Down Expand Up @@ -143,7 +142,7 @@ class DashboardViewModel(
_showStatusBar.value = status
_syncNeeded.value = true
_state.value = State.TO_UPDATE
updateEnrollment.postValue(true)
fetchDashboardModel()
} else {
showStatusErrorMessages.postValue(result)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class TEIDataContracts {

fun showProgramRuleErrorMessage()
fun goToEventInitial(eventCreationType: EventCreationType, programStage: ProgramStage)
fun updateEnrollment(update: Boolean)
fun displayOrgUnitSelectorForNewEvent(programUid: String, programStageUid: String)

fun goToEventDetails(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,6 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View {

with(dashboardViewModel) {
eventUid().observe(viewLifecycleOwner, ::displayGenerateEvent)
updateEnrollment.observe(viewLifecycleOwner) { update ->
updateEnrollment(update)
}
noEnrollmentSelected.observe(viewLifecycleOwner) { noEnrollmentSelected ->
if (noEnrollmentSelected) {
showLegacyCard(dashboardModel.value as DashboardTEIModel)
Expand Down Expand Up @@ -383,7 +380,7 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View {
programStageUid,
),
)
presenter.fetchEvents(true)
presenter.fetchEvents()
},
).show(parentFragmentManager, SCHEDULING_DIALOG)
}
Expand Down Expand Up @@ -458,18 +455,18 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View {

override fun openEventDetails(intent: Intent, options: ActivityOptionsCompat) =
contractHandler.scheduleEvent(intent, options).observe(viewLifecycleOwner) {
updateEnrollment(true)
presenter.fetchEvents()
}

override fun openEventInitial(intent: Intent) =
contractHandler.editEvent(intent).observe(viewLifecycleOwner) {
updateEnrollment(true)
presenter.fetchEvents()
}

override fun openEventCapture(intent: Intent) {
if (dashboardActivity is TeiDashboardMobileActivity) {
contractHandler.editEvent(intent).observe(viewLifecycleOwner) {
updateEnrollment(true)
presenter.fetchEvents()
}
}
if (dashboardActivity is EventCaptureActivity) {
Expand Down Expand Up @@ -570,13 +567,6 @@ class TEIDataFragment : FragmentGlobalAbstract(), TEIDataContracts.View {
dashboardActivity.executeOnUIThread()
}

override fun updateEnrollment(update: Boolean) {
if (update) {
presenter.fetchEvents(update)
dashboardViewModel.updateDashboard()
}
}

companion object {
const val RC_EVENTS_COMPLETED = 1601
const val PREF_COMPLETED_EVENT = "COMPLETED_EVENT"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class TEIDataPresenter(
val intent = Intent(view.context, ProgramStageSelectionActivity::class.java)
intent.putExtras(bundle)
contractHandler.createEvent(intent).observe(view.viewLifecycleOwner()) {
view.updateEnrollment(true)
fetchEvents()
}
}

Expand Down Expand Up @@ -395,10 +395,8 @@ class TEIDataPresenter(
return options?.let { eventCreationOptionsMapper.mapToEventsByStage(it) } ?: emptyList()
}

fun fetchEvents(updateEnrollment: Boolean) {
if (updateEnrollment) {
groupingProcessor.onNext(dashboardRepository.getGrouping())
}
fun fetchEvents() {
groupingProcessor.onNext(dashboardRepository.getGrouping())
}

fun getEnrollment(): Enrollment? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ class GranularSyncPresenter(
workerName = workerName()
}

private val _serverAvailability = MutableLiveData<Boolean>()
val serverAvailability: LiveData<Boolean> = _serverAvailability

private fun loadSyncInfo(forcedState: State? = null) {
viewModelScope.launch(dispatcher.io()) {
val syncState = async {
Expand Down Expand Up @@ -424,4 +427,15 @@ class GranularSyncPresenter(
}
}
}

fun checkServerAvailability() {
viewModelScope.launch {
try {
repository.checkServerAvailability()
_serverAvailability.value = true
} catch (error: RuntimeException) {
_serverAvailability.value = false
}
}
}
}
Loading
Loading