Coverage Summary for Class: AppConfigDoc (com.georgeci.moneysurfer.data.remote)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| AppConfigDoc |
100%
(1/1)
|
0%
(0/28)
|
100%
(5/5)
|
43.4%
(69/159)
|
| AppConfigDoc$Companion |
100%
(1/1)
|
|
100%
(1/1)
|
100%
(4/4)
|
| Total |
100%
(2/2)
|
0%
(0/28)
|
100%
(6/6)
|
44.8%
(73/163)
|
package com.georgeci.moneysurfer.data.remote
import dev.gitlive.firebase.firestore.FirebaseFirestore
import kotlinx.serialization.Serializable
import org.koin.core.annotation.Single
/** `appConfig/mobile` — the server-owned version gate, as it sits on the wire. */
@Serializable
data class AppConfigDoc(
val minSupportedAppVersionCode: Int = 0,
val latestAppVersionCode: Int = 0,
val forceUpdate: Boolean = false,
val message: String? = null,
)
/**
* The one read behind the app-version gate.
*
* A seam rather than a direct `firestore` call inside the repository, for the reason
* [AccountDeletionRemoteSource] and [UserConfigRemoteSource][com.georgeci.moneysurfer.data.sync.UserConfigRemoteSource]
* exist: what is worth testing is the decision around the read — how a missing document, an
* unreachable server and each combination of version fields resolve — and gitlive's client cannot
* be constructed off Android.
*/
fun interface AppConfigRemoteSource {
/** The gate document, or null when it has never been published. Throws on a failed read. */
suspend fun fetchMobile(): AppConfigDoc?
}
@Single(binds = [AppConfigRemoteSource::class])
class FirebaseAppConfigRemoteSource(
private val firestore: FirebaseFirestore,
) : AppConfigRemoteSource {
override suspend fun fetchMobile(): AppConfigDoc? {
val snapshot = firestore.collection(APP_CONFIG_COLLECTION).document(MOBILE_DOCUMENT).get()
return if (snapshot.exists) snapshot.data(AppConfigDoc.serializer()) else null
}
private companion object {
const val APP_CONFIG_COLLECTION = "appConfig"
const val MOBILE_DOCUMENT = "mobile"
}
}