mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 08:01:20 +02:00
Dev: add simple automated UI test setup (#1027)
## Description This PR is mostly a proof-of-concept for setting up automated UI testing. The tests use Roboelectric so they can run without an emulator. There is also a sample instrumented test for running on emulators or devices for future tests. It adds two basic automated UI tests for adding a server. These are sort integration tests because they use the actual implementations for the view model and services like `ServerRepository` and `JellyfinServerDao`. Also, moves the bulk of `MainActivity`'s compose code into a function for future tests. ### Related issues N/A ### Testing Local testing ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
8935067c5a
commit
0004701296
19 changed files with 990 additions and 163 deletions
|
|
@ -9,10 +9,12 @@ import androidx.lifecycle.map
|
|||
import com.github.damontecres.wholphin.data.model.JellyfinServer
|
||||
import com.github.damontecres.wholphin.data.model.JellyfinUser
|
||||
import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||
import com.github.damontecres.wholphin.services.hilt.IoDispatcher
|
||||
import com.github.damontecres.wholphin.ui.setValueOnMain
|
||||
import com.github.damontecres.wholphin.ui.toServerString
|
||||
import com.github.damontecres.wholphin.util.EqualityMutableLiveData
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
|
|
@ -41,6 +43,7 @@ class ServerRepository
|
|||
val serverDao: JellyfinServerDao,
|
||||
val apiClient: ApiClient,
|
||||
val userPreferencesDataStore: DataStore<AppPreferences>,
|
||||
@param:IoDispatcher private val ioDispatcher: CoroutineDispatcher,
|
||||
) {
|
||||
private var _current = EqualityMutableLiveData<CurrentUser?>(null)
|
||||
val current: LiveData<CurrentUser?> = _current
|
||||
|
|
@ -57,7 +60,7 @@ class ServerRepository
|
|||
* The current user is removed
|
||||
*/
|
||||
suspend fun addAndChangeServer(server: JellyfinServer) {
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
serverDao.addOrUpdateServer(server)
|
||||
}
|
||||
apiClient.update(baseUrl = server.url, accessToken = null)
|
||||
|
|
@ -71,7 +74,7 @@ class ServerRepository
|
|||
server: JellyfinServer,
|
||||
user: JellyfinUser,
|
||||
): CurrentUser? =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
if (server.id != user.serverId) {
|
||||
throw IllegalStateException("User is not part of the server")
|
||||
}
|
||||
|
|
@ -126,7 +129,7 @@ class ServerRepository
|
|||
return null
|
||||
}
|
||||
val serverAndUsers =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
serverDao.getServer(serverId)
|
||||
}
|
||||
if (serverAndUsers != null) {
|
||||
|
|
@ -149,7 +152,7 @@ class ServerRepository
|
|||
}
|
||||
|
||||
suspend fun fetchLastUsedServer(serverId: UUID?): JellyfinServer? =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
serverId?.let { serverDao.getServer(serverId)?.server }
|
||||
}
|
||||
|
||||
|
|
@ -163,7 +166,7 @@ class ServerRepository
|
|||
suspend fun changeUser(
|
||||
serverUrl: String,
|
||||
authenticationResult: AuthenticationResult,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
) = withContext(ioDispatcher) {
|
||||
val accessToken = authenticationResult.accessToken
|
||||
if (accessToken != null) {
|
||||
val authedUser = authenticationResult.user
|
||||
|
|
@ -213,7 +216,7 @@ class ServerRepository
|
|||
}
|
||||
apiClient.update(accessToken = null)
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
serverDao.deleteUser(user.serverId, user.id)
|
||||
}
|
||||
}
|
||||
|
|
@ -233,7 +236,7 @@ class ServerRepository
|
|||
}
|
||||
apiClient.update(baseUrl = null, accessToken = null)
|
||||
}
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
serverDao.deleteServer(server.id)
|
||||
}
|
||||
}
|
||||
|
|
@ -252,7 +255,7 @@ class ServerRepository
|
|||
suspend fun setUserPin(
|
||||
user: JellyfinUser,
|
||||
pin: String?,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
) = withContext(ioDispatcher) {
|
||||
val newUser = user.copy(pin = pin)
|
||||
val updatedUser = serverDao.addOrUpdateUser(newUser)
|
||||
if (currentUser.value?.id == updatedUser.id && currentServer.value?.id == user.serverId) {
|
||||
|
|
@ -265,7 +268,7 @@ class ServerRepository
|
|||
}
|
||||
|
||||
suspend fun authorizeQuickConnect(code: String): Boolean =
|
||||
withContext(Dispatchers.IO) {
|
||||
withContext(ioDispatcher) {
|
||||
val userId = currentUser.value?.id
|
||||
if (userId == null) {
|
||||
Timber.e("No user logged in for Quick Connect authorization")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue