mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-11-05 18:30:59 +01:00
Remove dependency on livedata libraries (#1453)
## Description Refactors all usages of `LiveData` into flows in keeping with best practices. This also includes refactoring several `ViewModel`s to combine multiple `LiveData` into a new single `StateFlow`. There are no user facing changes ### Related issues None ### Testing Emulator ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
982d9e6fe8
commit
0b450fc0ff
90 changed files with 2170 additions and 2283 deletions
|
|
@ -5,7 +5,6 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.work.WorkManager
|
||||
import com.github.damontecres.wholphin.data.CurrentUser
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
|
|
@ -14,6 +13,7 @@ import io.mockk.mockk
|
|||
import io.mockk.verify
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
|
|
@ -28,7 +28,7 @@ import org.junit.Test
|
|||
class LatestNextUpSchedulerServiceTest {
|
||||
@get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val currentLiveData = MutableLiveData<CurrentUser?>()
|
||||
private val currentUser = MutableStateFlow<CurrentUser?>(null)
|
||||
private val mockActivity = mockk<AppCompatActivity>(relaxed = true)
|
||||
private val mockServerRepository = mockk<ServerRepository>(relaxed = true)
|
||||
private val mockWorkManager = mockk<WorkManager>(relaxed = true)
|
||||
|
|
@ -38,7 +38,7 @@ class LatestNextUpSchedulerServiceTest {
|
|||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
every { mockActivity.lifecycle } returns lifecycleRegistry
|
||||
every { mockServerRepository.current } returns currentLiveData
|
||||
every { mockServerRepository.current } returns currentUser
|
||||
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ class LatestNextUpSchedulerServiceTest {
|
|||
runTest {
|
||||
createService()
|
||||
|
||||
currentLiveData.value = null
|
||||
currentUser.value = null
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { mockWorkManager.cancelUniqueWork(LatestNextUpWorker.WORK_NAME) }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.github.damontecres.wholphin.services
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.work.ExistingWorkPolicy
|
||||
import androidx.work.OneTimeWorkRequest
|
||||
import androidx.work.WorkInfo
|
||||
|
|
@ -15,6 +14,7 @@ import io.mockk.mockk
|
|||
import io.mockk.verify
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
|
|
@ -98,8 +98,8 @@ class SuggestionServiceTest {
|
|||
@Test
|
||||
fun getSuggestionsFlow_returnsEmpty_whenNoUserLoggedIn() =
|
||||
runTest {
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(null)
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(null)
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
|
||||
val service = createService()
|
||||
val result = service.getSuggestionsFlow(UUID.randomUUID(), BaseItemKind.MOVIE).first()
|
||||
|
|
@ -113,10 +113,10 @@ class SuggestionServiceTest {
|
|||
listOf(WorkInfo.State.RUNNING, WorkInfo.State.ENQUEUED).forEach { state ->
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, parentId, BaseItemKind.MOVIE)
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returns null
|
||||
mockEnqueueOnDemandWork()
|
||||
every { mockWorkManager.getWorkInfosForUniqueWorkFlow(workName) } returns
|
||||
|
|
@ -142,10 +142,10 @@ class SuggestionServiceTest {
|
|||
listOf(WorkInfo.State.SUCCEEDED, WorkInfo.State.FAILED, WorkInfo.State.CANCELLED).forEach { state ->
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, parentId, BaseItemKind.MOVIE)
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returns null
|
||||
mockEnqueueOnDemandWork()
|
||||
every { mockWorkManager.getWorkInfosForUniqueWorkFlow(workName) } returns
|
||||
|
|
@ -163,10 +163,10 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, parentId, BaseItemKind.MOVIE)
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returns null
|
||||
mockEnqueueOnDemandWork()
|
||||
every { mockWorkManager.getWorkInfosForUniqueWorkFlow(workName) } returns flowOf(emptyList())
|
||||
|
|
@ -189,11 +189,11 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, parentId, BaseItemKind.MOVIE)
|
||||
val cachedId = UUID.randomUUID()
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returnsMany
|
||||
listOf(null, CachedSuggestions(listOf(cachedId)))
|
||||
mockEnqueueOnDemandWork()
|
||||
|
|
@ -220,9 +220,9 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returns CachedSuggestions(emptyList())
|
||||
|
||||
val service = createService()
|
||||
|
|
@ -244,10 +244,10 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, parentId, BaseItemKind.MOVIE)
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
coEvery { mockCache.get(userId, parentId, BaseItemKind.MOVIE) } returns null
|
||||
mockEnqueueOnDemandWork()
|
||||
every { mockWorkManager.getWorkInfosForUniqueWorkFlow(SuggestionsWorker.WORK_NAME) } returns
|
||||
|
|
@ -268,10 +268,10 @@ class SuggestionServiceTest {
|
|||
val userId = UUID.randomUUID()
|
||||
val libraryId = UUID.randomUUID()
|
||||
val otherLibraryId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
val workName = SuggestionsWorker.getOnDemandWorkName(userId, libraryId, BaseItemKind.MOVIE)
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
mockEnqueueOnDemandWork()
|
||||
every { mockWorkManager.getWorkInfosForUniqueWorkFlow(workName) } returns flowOf(emptyList())
|
||||
|
||||
|
|
@ -304,9 +304,9 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
|
||||
val cachedId = UUID.randomUUID()
|
||||
coEvery {
|
||||
|
|
@ -339,9 +339,9 @@ class SuggestionServiceTest {
|
|||
runTest {
|
||||
val userId = UUID.randomUUID()
|
||||
val parentId = UUID.randomUUID()
|
||||
val currentUser = MutableLiveData<JellyfinUser?>(mockUser(userId))
|
||||
val currentUser = MutableStateFlow<JellyfinUser?>(mockUser(userId))
|
||||
|
||||
every { mockServerRepository.currentUser } returns currentUser
|
||||
every { mockServerRepository.currentUserFlow } returns currentUser
|
||||
|
||||
val cachedId = UUID.randomUUID()
|
||||
coEvery {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
|||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.work.PeriodicWorkRequest
|
||||
import androidx.work.WorkManager
|
||||
import com.github.damontecres.wholphin.data.CurrentUser
|
||||
|
|
@ -19,6 +18,7 @@ import io.mockk.slot
|
|||
import io.mockk.verify
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
|
|
@ -35,7 +35,7 @@ import java.util.UUID
|
|||
class SuggestionsSchedulerServiceTest {
|
||||
@get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule()
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val currentLiveData = MutableLiveData<CurrentUser?>()
|
||||
private val currentUser = MutableStateFlow<CurrentUser?>(null)
|
||||
private val mockActivity = mockk<AppCompatActivity>(relaxed = true)
|
||||
private val mockServerRepository = mockk<ServerRepository>(relaxed = true)
|
||||
private val mockWorkManager = mockk<WorkManager>(relaxed = true)
|
||||
|
|
@ -45,7 +45,7 @@ class SuggestionsSchedulerServiceTest {
|
|||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
every { mockActivity.lifecycle } returns lifecycleRegistry
|
||||
every { mockServerRepository.current } returns currentLiveData
|
||||
every { mockServerRepository.current } returns currentUser
|
||||
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
}
|
||||
|
||||
|
|
@ -57,8 +57,8 @@ class SuggestionsSchedulerServiceTest {
|
|||
context = mockActivity,
|
||||
serverRepository = mockServerRepository,
|
||||
workManager = mockWorkManager,
|
||||
dispatcher = testDispatcher,
|
||||
).also {
|
||||
it.dispatcher = testDispatcher
|
||||
it.initialDelaySecondsProvider = { 60L }
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ class SuggestionsSchedulerServiceTest {
|
|||
runTest {
|
||||
mockWorkInfos(emptyList())
|
||||
createService()
|
||||
currentLiveData.value =
|
||||
currentUser.value =
|
||||
CurrentUser(
|
||||
user = JellyfinUser(id = UUID.randomUUID(), name = "User", serverId = UUID.randomUUID(), accessToken = "token"),
|
||||
server = JellyfinServer(id = UUID.randomUUID(), name = "Server", url = "http://localhost", version = null),
|
||||
|
|
@ -88,13 +88,13 @@ class SuggestionsSchedulerServiceTest {
|
|||
runTest {
|
||||
mockWorkInfos(emptyList())
|
||||
createService()
|
||||
currentLiveData.value =
|
||||
currentUser.value =
|
||||
CurrentUser(
|
||||
user = JellyfinUser(id = UUID.randomUUID(), name = "User", serverId = UUID.randomUUID(), accessToken = "token"),
|
||||
server = JellyfinServer(id = UUID.randomUUID(), name = "Server", url = "http://localhost", version = null),
|
||||
)
|
||||
advanceUntilIdle()
|
||||
currentLiveData.value = null
|
||||
currentUser.value = null
|
||||
advanceUntilIdle()
|
||||
verify { mockWorkManager.cancelUniqueWork(SuggestionsWorker.WORK_NAME) }
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ class SuggestionsSchedulerServiceTest {
|
|||
} returns mockk()
|
||||
|
||||
createService()
|
||||
currentLiveData.value =
|
||||
currentUser.value =
|
||||
CurrentUser(
|
||||
user = JellyfinUser(id = UUID.randomUUID(), name = "User", serverId = UUID.randomUUID(), accessToken = "token"),
|
||||
server = JellyfinServer(id = UUID.randomUUID(), name = "Server", url = "http://localhost", version = null),
|
||||
|
|
@ -138,7 +138,7 @@ class SuggestionsSchedulerServiceTest {
|
|||
} returns mockk()
|
||||
|
||||
createService()
|
||||
currentLiveData.value =
|
||||
currentUser.value =
|
||||
CurrentUser(
|
||||
user = JellyfinUser(id = UUID.randomUUID(), name = "User", serverId = UUID.randomUUID(), accessToken = "token"),
|
||||
server = JellyfinServer(id = UUID.randomUUID(), name = "Server", url = "http://localhost", version = null),
|
||||
|
|
@ -159,7 +159,7 @@ class SuggestionsSchedulerServiceTest {
|
|||
mockWorkInfos(listOf(workInfo))
|
||||
|
||||
createService()
|
||||
currentLiveData.value =
|
||||
currentUser.value =
|
||||
CurrentUser(
|
||||
user = JellyfinUser(id = userId, name = "User", serverId = UUID.randomUUID(), accessToken = "token"),
|
||||
server = JellyfinServer(id = UUID.randomUUID(), name = "Server", url = "http://localhost", version = null),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.github.damontecres.wholphin.services
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.work.Data
|
||||
import androidx.work.ListenableWorker
|
||||
import androidx.work.WorkerParameters
|
||||
|
|
@ -15,6 +14,7 @@ import io.mockk.every
|
|||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.unmockkObject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
|
|
@ -112,7 +112,7 @@ class SuggestionsWorkerTest {
|
|||
every { mockApi.accessToken } returns null
|
||||
val mockUser = mockk<CurrentUser>()
|
||||
var restored = false
|
||||
every { mockServerRepository.current } answers { MutableLiveData(if (restored) mockUser else null) }
|
||||
every { mockServerRepository.current } answers { MutableStateFlow(if (restored) mockUser else null) }
|
||||
coEvery { mockServerRepository.restoreSession(testServerId, testUserId) } coAnswers {
|
||||
restored = true
|
||||
mockUser
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.github.damontecres.wholphin.test
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import com.github.damontecres.wholphin.data.PlaybackLanguageChoiceDao
|
||||
import com.github.damontecres.wholphin.data.ServerRepository
|
||||
import com.github.damontecres.wholphin.data.model.ItemPlayback
|
||||
|
|
@ -773,20 +772,19 @@ private fun serverRepo(
|
|||
): ServerRepository {
|
||||
val mocked = mockk<ServerRepository>()
|
||||
every { mocked.currentUserDto } returns
|
||||
MutableLiveData(
|
||||
UserDto(
|
||||
id = UUID.randomUUID(),
|
||||
hasPassword = true,
|
||||
hasConfiguredPassword = true,
|
||||
hasConfiguredEasyPassword = true,
|
||||
configuration =
|
||||
DefaultUserConfiguration.copy(
|
||||
audioLanguagePreference = audioLang,
|
||||
subtitleMode = subtitleMode ?: SubtitlePlaybackMode.DEFAULT,
|
||||
subtitleLanguagePreference = subtitleLang,
|
||||
),
|
||||
),
|
||||
UserDto(
|
||||
id = UUID.randomUUID(),
|
||||
hasPassword = true,
|
||||
hasConfiguredPassword = true,
|
||||
hasConfiguredEasyPassword = true,
|
||||
configuration =
|
||||
DefaultUserConfiguration.copy(
|
||||
audioLanguagePreference = audioLang,
|
||||
subtitleMode = subtitleMode ?: SubtitlePlaybackMode.DEFAULT,
|
||||
subtitleLanguagePreference = subtitleLang,
|
||||
),
|
||||
)
|
||||
|
||||
return mocked
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ object TestModule {
|
|||
.addInterceptor {
|
||||
val request = it.request()
|
||||
val newRequest =
|
||||
serverRepository.currentUser.value?.accessToken?.let { token ->
|
||||
serverRepository.currentUser?.accessToken?.let { token ->
|
||||
request
|
||||
.newBuilder()
|
||||
.addHeader(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue