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

Fix select all not updating checkbox state in the overdue search screen #4143

Merged
merged 1 commit into from Aug 3, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -12,6 +12,7 @@
- Remove overdue search v1 implementation
- Bump flipper to v0.156.0
- Bump jgit version
- Fix select all not updating checkbox state in the overdue search screen
- [In Progress: 27 Apr 2022] Migrate `BloodPressureHistoryScreenEffectHandler` to use view effect

## 2022-08-01-8350
Expand Down
@@ -1,7 +1,5 @@
package org.simple.clinic.home.overdue.search

import androidx.paging.PagingData
import org.simple.clinic.home.overdue.OverdueAppointment
import java.time.LocalDate
import java.util.UUID

Expand Down Expand Up @@ -45,8 +43,3 @@ object OpenSelectShareFormatDialog : OverdueSearchViewEffect()
object OpenShareInProgressDialog : OverdueSearchViewEffect()

object ShowNoInternetConnectionDialog : OverdueSearchViewEffect()

data class SetOverdueSearchPagingData(
val overdueSearchResults: PagingData<OverdueAppointment>,
val selectedOverdueAppointments: Set<UUID>
) : OverdueSearchViewEffect()
Expand Up @@ -7,6 +7,7 @@ import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.reactivex.ObservableTransformer
import kotlinx.coroutines.CoroutineScope
import org.simple.clinic.facility.Facility
import org.simple.clinic.overdue.AppointmentRepository
import org.simple.clinic.overdue.OverdueAppointmentSelector
Expand All @@ -25,13 +26,15 @@ class OverdueSearchEffectHandler @AssistedInject constructor(
private val overdueAppointmentSelector: OverdueAppointmentSelector,
private val overdueDownloadScheduler: OverdueDownloadScheduler,
private val patientRepository: PatientRepository,
@Assisted private val viewEffectsConsumer: Consumer<OverdueSearchViewEffect>
@Assisted private val viewEffectsConsumer: Consumer<OverdueSearchViewEffect>,
@Assisted private val pagingCacheScope: () -> CoroutineScope
) {

@AssistedFactory
interface Factory {
fun create(
viewEffectsConsumer: Consumer<OverdueSearchViewEffect>
viewEffectsConsumer: Consumer<OverdueSearchViewEffect>,
pagingCacheScope: () -> CoroutineScope
): OverdueSearchEffectHandler
}

Expand Down Expand Up @@ -65,7 +68,8 @@ class OverdueSearchEffectHandler @AssistedInject constructor(
)
},
pageSize = overdueSearchConfig.pagingLoadSize,
enablePlaceholders = false
enablePlaceholders = false,
cacheScope = pagingCacheScope.invoke()
)
}
.map(::OverdueSearchResultsLoaded)
Expand Down
@@ -1,8 +1,10 @@
package org.simple.clinic.home.overdue.search

import android.os.Parcelable
import androidx.paging.PagingData
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.simple.clinic.home.overdue.OverdueAppointment
import java.util.UUID

@Parcelize
Expand All @@ -11,7 +13,9 @@ data class OverdueSearchModel(
@IgnoredOnParcel
val selectedOverdueAppointments: Set<UUID> = emptySet(),
val villageAndPatientNames: List<String>?,
val searchInputs: List<String>
val searchInputs: List<String>,
@IgnoredOnParcel
val overdueSearchResults: PagingData<OverdueAppointment> = PagingData.empty()
) : Parcelable {

val hasSearchInputs: Boolean
Expand All @@ -27,7 +31,8 @@ data class OverdueSearchModel(
overdueSearchProgressState = null,
selectedOverdueAppointments = emptySet(),
villageAndPatientNames = null,
searchInputs = emptyList()
searchInputs = emptyList(),
overdueSearchResults = PagingData.empty()
)
}
}
Expand All @@ -47,4 +52,8 @@ data class OverdueSearchModel(
fun overdueSearchInputsChanged(searchInputs: List<String>): OverdueSearchModel {
return copy(searchInputs = searchInputs)
}

fun overdueSearchResultsLoaded(overdueSearchResults: PagingData<OverdueAppointment>): OverdueSearchModel {
return copy(overdueSearchResults = overdueSearchResults)
}
}
Expand Up @@ -10,6 +10,7 @@ import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.paging.LoadState
import androidx.paging.PagingData
import androidx.recyclerview.widget.RecyclerView
Expand Down Expand Up @@ -169,7 +170,8 @@ class OverdueSearchScreen : BaseScreen<

override fun createEffectHandler(viewEffectsConsumer: Consumer<OverdueSearchViewEffect>) = effectHandlerFactory
.create(
viewEffectsConsumer = viewEffectsConsumer
viewEffectsConsumer = viewEffectsConsumer,
pagingCacheScope = { lifecycleScope }
)
.build()

Expand Down
@@ -1,5 +1,9 @@
package org.simple.clinic.home.overdue.search

import androidx.paging.PagingData
import org.simple.clinic.home.overdue.OverdueAppointment
import java.util.UUID

interface OverdueSearchUi {
fun hideSearchResults()
fun hideProgress()
Expand All @@ -12,4 +16,5 @@ interface OverdueSearchUi {
fun showSelectedOverdueAppointmentCount(selectedOverdueAppointments: Int)
fun hideSelectedOverdueAppointmentCount()
fun setOverdueSearchSuggestions(searchSuggestions: List<String>)
fun setOverdueSearchResultsPagingData(overdueSearchResults: PagingData<OverdueAppointment>, selectedAppointments: Set<UUID>)
}
@@ -1,7 +1,5 @@
package org.simple.clinic.home.overdue.search

import androidx.paging.PagingData
import org.simple.clinic.home.overdue.OverdueAppointment
import java.util.UUID

interface OverdueSearchUiActions {
Expand All @@ -11,8 +9,4 @@ interface OverdueSearchUiActions {
fun openSelectShareFormatDialog()
fun openShareInProgressDialog()
fun showNoInternetConnectionDialog()
fun setOverdueSearchResultsPagingData(
overdueSearchResults: PagingData<OverdueAppointment>,
selectedOverdueAppointments: Set<UUID>
)
}
Expand Up @@ -38,6 +38,8 @@ class OverdueSearchUiRenderer(
// No-op
}
}

ui.setOverdueSearchResultsPagingData(model.overdueSearchResults, model.selectedOverdueAppointments)
}

private fun renderOverdueListSelectedCount(selectedOverdueAppointments: Set<UUID>) {
Expand Down
Expand Up @@ -18,10 +18,7 @@ class OverdueSearchUpdate(

override fun update(model: OverdueSearchModel, event: OverdueSearchEvent): Next<OverdueSearchModel, OverdueSearchEffect> {
return when (event) {
is OverdueSearchResultsLoaded -> dispatch(SetOverdueSearchPagingData(
overdueSearchResults = event.overdueAppointments,
selectedOverdueAppointments = model.selectedOverdueAppointments
))
is OverdueSearchResultsLoaded -> next(model.overdueSearchResultsLoaded(event.overdueAppointments))
is CallPatientClicked -> dispatch(OpenContactPatientSheet(event.patientUuid))
is OverduePatientClicked -> dispatch(OpenPatientSummary(event.patientUuid))
is OverdueSearchLoadStateChanged -> next(model.loadStateChanged(event.overdueSearchProgressState))
Expand Down
Expand Up @@ -15,10 +15,6 @@ class OverdueSearchViewEffectHandler(
OpenSelectShareFormatDialog -> uiActions.openSelectShareFormatDialog()
OpenShareInProgressDialog -> uiActions.openShareInProgressDialog()
ShowNoInternetConnectionDialog -> uiActions.showNoInternetConnectionDialog()
is SetOverdueSearchPagingData -> uiActions.setOverdueSearchResultsPagingData(
overdueSearchResults = viewEffect.overdueSearchResults,
selectedOverdueAppointments = viewEffect.selectedOverdueAppointments
)
}.exhaustive()
}
}
13 changes: 11 additions & 2 deletions app/src/main/java/org/simple/clinic/util/PagerFactory.kt
Expand Up @@ -4,8 +4,10 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.PagingSource
import androidx.paging.rxjava2.cachedIn
import androidx.paging.rxjava2.observable
import io.reactivex.Observable
import kotlinx.coroutines.CoroutineScope
import javax.inject.Inject

typealias PagingSourceFactory<K, V> = () -> PagingSource<K, V>
Expand All @@ -16,15 +18,22 @@ class PagerFactory @Inject constructor() {
sourceFactory: PagingSourceFactory<K, V>,
pageSize: Int,
enablePlaceholders: Boolean,
initialKey: K? = null
initialKey: K? = null,
cacheScope: CoroutineScope? = null
): Observable<PagingData<V>> {
return Pager(
val pagingData = Pager(
config = PagingConfig(
pageSize = pageSize,
enablePlaceholders = enablePlaceholders
),
initialKey = initialKey,
pagingSourceFactory = sourceFactory
).observable

return if (cacheScope != null) {
pagingData.cachedIn(cacheScope)
} else {
pagingData
}
}
}
Expand Up @@ -12,11 +12,11 @@ import com.nhaarman.mockitokotlin2.whenever
import io.reactivex.Observable
import org.junit.After
import org.junit.Test
import org.simple.sharedTestCode.TestData
import org.simple.clinic.mobius.EffectHandlerTestCase
import org.simple.clinic.util.PagerFactory
import org.simple.clinic.util.PagingSourceFactory
import org.simple.clinic.util.scheduler.TestSchedulersProvider
import org.simple.sharedTestCode.TestData
import java.util.UUID

class DrugSearchEffectHandlerTest {
Expand Down Expand Up @@ -59,7 +59,8 @@ class DrugSearchEffectHandlerTest {
sourceFactory = any<PagingSourceFactory<Int, Drug>>(),
pageSize = eq(drugsSearchResultsPageSize),
enablePlaceholders = eq(false),
initialKey = eq(null)
initialKey = eq(null),
cacheScope = eq(null)
)) doReturn Observable.just(searchResults)

// when
Expand Down
Expand Up @@ -127,7 +127,8 @@ class OverdueEffectHandlerTest {
sourceFactory = any<PagingSourceFactory<Int, OverdueAppointment_Old>>(),
pageSize = eq(overdueAppointmentsConfig.overdueAppointmentsLoadSize),
enablePlaceholders = eq(true),
initialKey = eq(null)
initialKey = eq(null),
cacheScope = eq(null)
)) doReturn Observable.just(overdueAppointments)

// when
Expand Down
Expand Up @@ -93,7 +93,8 @@ class OverdueLogicTest {
sourceFactory = any<PagingSourceFactory<Int, OverdueAppointment_Old>>(),
pageSize = eq(10),
enablePlaceholders = eq(true),
initialKey = eq(null)
initialKey = eq(null),
cacheScope = eq(null)
)) doReturn Observable.just(overdueAppointments)

whenever(overdueAppointmentSelector.selectedAppointmentIdsStream) doReturn Observable.just(emptySet())
Expand Down
Expand Up @@ -10,6 +10,7 @@ import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
import com.nhaarman.mockitokotlin2.verifyZeroInteractions
import com.nhaarman.mockitokotlin2.whenever
import io.reactivex.Observable
import kotlinx.coroutines.test.TestScope
import org.junit.After
import org.junit.Test
import org.simple.clinic.home.overdue.OverdueAppointment
Expand Down Expand Up @@ -40,6 +41,7 @@ class OverdueSearchEffectHandlerTest {
private val overdueAppointmentSelector = mock<OverdueAppointmentSelector>()
private val overdueDownloadScheduler = mock<OverdueDownloadScheduler>()
private val patientRepository = mock<PatientRepository>()
private val pagingCacheScope = TestScope()
private val effectHandler = OverdueSearchEffectHandler(
schedulersProvider = TestSchedulersProvider.trampoline(),
appointmentRepository = appointmentRepository,
Expand All @@ -49,7 +51,8 @@ class OverdueSearchEffectHandlerTest {
overdueAppointmentSelector = overdueAppointmentSelector,
overdueDownloadScheduler = overdueDownloadScheduler,
patientRepository = patientRepository,
viewEffectsConsumer = viewEffectHandler::handle
viewEffectsConsumer = viewEffectHandler::handle,
pagingCacheScope = { pagingCacheScope }
).build()
private val effectHandlerTestCase = EffectHandlerTestCase(effectHandler)

Expand Down Expand Up @@ -108,7 +111,8 @@ class OverdueSearchEffectHandlerTest {
sourceFactory = any<PagingSourceFactory<Int, OverdueAppointment>>(),
pageSize = eq(pagingLoadSize),
enablePlaceholders = eq(false),
initialKey = eq(null)
initialKey = eq(null),
cacheScope = any()
)) doReturn Observable.just(expectedPagingData)

// when
Expand Down Expand Up @@ -297,61 +301,4 @@ class OverdueSearchEffectHandlerTest {
effectHandlerTestCase.assertOutgoingEvents(VillagesAndPatientNamesLoaded(villagesAndPatientNames))
verifyZeroInteractions(uiActions)
}

@Test
fun `when set overdue search paging data effect is received, then set overdue search paging data`() {
// give
val selectedOverdueAppointments = setOf(
UUID.fromString("931d4406-78d1-4cdf-aad5-d8f4a9e18f38")
)
val searchResults = PagingData.from(listOf(
TestData.overdueAppointment(
patientUuid = UUID.fromString("92fc941d-a6f5-427f-a9f3-0e703373d03e"),
appointmentUuid = UUID.fromString("931d4406-78d1-4cdf-aad5-d8f4a9e18f38"),
name = "Anish Acharya"
)
))

// when
effectHandlerTestCase.dispatch(SetOverdueSearchPagingData(
overdueSearchResults = searchResults,
selectedOverdueAppointments = selectedOverdueAppointments
))

verify(uiActions).setOverdueSearchResultsPagingData(
overdueSearchResults = searchResults,
selectedOverdueAppointments = selectedOverdueAppointments
)
verifyNoMoreInteractions(uiActions)
}

@Test
fun `when search overdue patients effect is received, then search for overdue patients`() {
// given
val searchInputs = listOf(
"Babri",
"Narwar",
"Anandh"
)
val since = LocalDate.parse("2018-01-01")

val searchResults = PagingData.from(listOf(
TestData.overdueAppointment(appointmentUuid = UUID.fromString("0da6d783-0ba8-4c06-8a29-815d013bda6d"))
))

whenever(pagerFactory.createPager(
sourceFactory = any<PagingSourceFactory<Int, OverdueAppointment>>(),
pageSize = eq(pagingLoadSize),
enablePlaceholders = eq(false),
initialKey = eq(null)
)) doReturn Observable.just(searchResults)

// when
effectHandlerTestCase.dispatch(SearchOverduePatients(searchInputs, since))

// then
verifyZeroInteractions(uiActions)

effectHandlerTestCase.assertOutgoingEvents(OverdueSearchResultsLoaded(searchResults))
}
}