Extract server info repo

This commit is contained in:
Kirill Kamakin
2022-10-29 19:15:57 +02:00
parent 9e9d07db7d
commit cda22215ec
21 changed files with 205 additions and 122 deletions

View File

@@ -1,8 +1,15 @@
package gq.kirmanak.mealient.data.auth
import gq.kirmanak.mealient.data.baseurl.ServerVersion
interface AuthDataSource {
/**
* Tries to acquire authentication token using the provided credentials
*/
suspend fun authenticate(username: String, password: String, baseUrl: String): String
suspend fun authenticate(
username: String,
password: String,
baseUrl: String,
serverVersion: ServerVersion,
): String
}

View File

@@ -1,15 +1,25 @@
package gq.kirmanak.mealient.data.auth.impl
import gq.kirmanak.mealient.data.auth.AuthDataSource
import gq.kirmanak.mealient.data.baseurl.ServerVersion
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AuthDataSourceImpl @Inject constructor(
private val v0Source: MealieDataSourceV0,
private val v1Source: MealieDataSourceV1,
) : AuthDataSource {
override suspend fun authenticate(username: String, password: String, baseUrl: String): String =
v0Source.authenticate(baseUrl, username, password)
override suspend fun authenticate(
username: String,
password: String,
baseUrl: String,
serverVersion: ServerVersion,
): String = when (serverVersion) {
ServerVersion.V0 -> v0Source.authenticate(baseUrl, username, password)
ServerVersion.V1 -> v1Source.authenticate(baseUrl, username, password)
}
}

View File

@@ -3,7 +3,7 @@ package gq.kirmanak.mealient.data.auth.impl
import gq.kirmanak.mealient.data.auth.AuthDataSource
import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.auth.AuthStorage
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
import gq.kirmanak.mealient.logging.Logger
import kotlinx.coroutines.flow.Flow
@@ -15,7 +15,7 @@ import javax.inject.Singleton
class AuthRepoImpl @Inject constructor(
private val authStorage: AuthStorage,
private val authDataSource: AuthDataSource,
private val baseURLStorage: BaseURLStorage,
private val serverInfoRepo: ServerInfoRepo,
private val logger: Logger,
) : AuthRepo {
@@ -24,7 +24,9 @@ class AuthRepoImpl @Inject constructor(
override suspend fun authenticate(email: String, password: String) {
logger.v { "authenticate() called with: email = $email, password = $password" }
authDataSource.authenticate(email, password, baseURLStorage.requireBaseURL())
val version = serverInfoRepo.getVersion()
val url = serverInfoRepo.requireUrl()
authDataSource.authenticate(email, password, url, version)
.let { AUTH_HEADER_FORMAT.format(it) }
.let { authStorage.setAuthHeader(it) }
authStorage.setEmail(email)

View File

@@ -0,0 +1,11 @@
package gq.kirmanak.mealient.data.baseurl
interface ServerInfoRepo {
suspend fun getUrl(): String?
suspend fun requireUrl(): String
suspend fun getVersion(): ServerVersion
}

View File

@@ -0,0 +1,47 @@
package gq.kirmanak.mealient.data.baseurl
import gq.kirmanak.mealient.datasource.NetworkError
import gq.kirmanak.mealient.logging.Logger
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ServerInfoRepoImpl @Inject constructor(
private val serverInfoStorage: ServerInfoStorage,
private val versionDataSource: VersionDataSource,
private val logger: Logger,
) : ServerInfoRepo {
override suspend fun getUrl(): String? {
val result = serverInfoStorage.getBaseURL()
logger.v { "getUrl() returned: $result" }
return result
}
override suspend fun requireUrl(): String {
val result = checkNotNull(getUrl()) { "Server URL was null when it was required" }
logger.v { "requireUrl() returned: $result" }
return result
}
override suspend fun getVersion(): ServerVersion {
var version = serverInfoStorage.getServerVersion()
val serverVersion = if (version == null) {
logger.d { "getVersion: version is null, requesting" }
version = versionDataSource.getVersionInfo(requireUrl()).version
val result = determineServerVersion(version)
serverInfoStorage.storeServerVersion(version)
result
} else {
determineServerVersion(version)
}
logger.v { "getVersion() returned: $serverVersion from $version" }
return serverVersion
}
private fun determineServerVersion(version: String): ServerVersion = when {
version.startsWith("v0") -> ServerVersion.V0
version.startsWith("v1") -> ServerVersion.V1
else -> throw NetworkError.NotMealie(IllegalStateException("Server version is unknown: $version"))
}
}

View File

@@ -1,11 +1,9 @@
package gq.kirmanak.mealient.data.baseurl
interface BaseURLStorage {
interface ServerInfoStorage {
suspend fun getBaseURL(): String?
suspend fun requireBaseURL(): String
suspend fun storeBaseURL(baseURL: String, version: String)
suspend fun storeServerVersion(version: String)

View File

@@ -0,0 +1,3 @@
package gq.kirmanak.mealient.data.baseurl
enum class ServerVersion { V0, V1 }

View File

@@ -0,0 +1,37 @@
package gq.kirmanak.mealient.data.baseurl
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
import gq.kirmanak.mealient.extensions.toVersionInfo
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class VersionDataSourceImpl @Inject constructor(
private val v0Source: MealieDataSourceV0,
private val v1Source: MealieDataSourceV1,
) : VersionDataSource {
override suspend fun getVersionInfo(baseUrl: String): VersionInfo {
val responses = coroutineScope {
val v0Deferred = async {
runCatchingExceptCancel { v0Source.getVersionInfo(baseUrl).toVersionInfo() }
}
val v1Deferred = async {
runCatchingExceptCancel { v1Source.getVersionInfo(baseUrl).toVersionInfo() }
}
listOf(v0Deferred, v1Deferred).awaitAll()
}
val firstSuccess = responses.firstNotNullOfOrNull { it.getOrNull() }
if (firstSuccess == null) {
throw responses.firstNotNullOf { it.exceptionOrNull() }
} else {
return firstSuccess
}
}
}

View File

@@ -1,15 +1,15 @@
package gq.kirmanak.mealient.data.baseurl.impl
import androidx.datastore.preferences.core.Preferences
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.data.storage.PreferencesStorage
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class BaseURLStorageImpl @Inject constructor(
class ServerInfoStorageImpl @Inject constructor(
private val preferencesStorage: PreferencesStorage,
) : BaseURLStorage {
) : ServerInfoStorage {
private val baseUrlKey: Preferences.Key<String>
get() = preferencesStorage.baseUrlKey
@@ -19,10 +19,6 @@ class BaseURLStorageImpl @Inject constructor(
override suspend fun getBaseURL(): String? = getValue(baseUrlKey)
override suspend fun requireBaseURL(): String = checkNotNull(getBaseURL()) {
"Base URL was null when it was required"
}
override suspend fun storeBaseURL(baseURL: String, version: String) {
preferencesStorage.storeValues(
Pair(baseUrlKey, baseURL),

View File

@@ -2,9 +2,8 @@ package gq.kirmanak.mealient.data.network
import gq.kirmanak.mealient.data.add.AddRecipeDataSource
import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
import gq.kirmanak.mealient.data.baseurl.VersionInfo
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
import gq.kirmanak.mealient.data.baseurl.ServerVersion
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
@@ -12,76 +11,52 @@ import gq.kirmanak.mealient.datasource.NetworkError
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
import gq.kirmanak.mealient.datasource.v0.models.AddRecipeRequestV0
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
import gq.kirmanak.mealient.extensions.toFullRecipeInfo
import gq.kirmanak.mealient.extensions.toRecipeSummaryInfo
import gq.kirmanak.mealient.extensions.toVersionInfo
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MealieDataSourceWrapper @Inject constructor(
private val baseURLStorage: BaseURLStorage,
private val serverInfoRepo: ServerInfoRepo,
private val authRepo: AuthRepo,
private val v0source: MealieDataSourceV0,
private val v1Source: MealieDataSourceV1,
) : AddRecipeDataSource, RecipeDataSource, VersionDataSource {
) : AddRecipeDataSource, RecipeDataSource {
override suspend fun addRecipe(recipe: AddRecipeRequestV0): String =
withAuthHeader { token -> v0source.addRecipe(getUrl(), token, recipe) }
override suspend fun getVersionInfo(baseUrl: String): VersionInfo {
val responses = coroutineScope {
val v0Deferred = async {
runCatchingExceptCancel { v0source.getVersionInfo(baseUrl).toVersionInfo() }
}
val v1Deferred = async {
runCatchingExceptCancel { v1Source.getVersionInfo(baseUrl).toVersionInfo() }
}
listOf(v0Deferred, v1Deferred).awaitAll()
}
val firstSuccess = responses.firstNotNullOfOrNull { it.getOrNull() }
if (firstSuccess == null) {
throw responses.firstNotNullOf { it.exceptionOrNull() }
} else {
return firstSuccess
}
override suspend fun addRecipe(recipe: AddRecipeRequestV0): String = withAuthHeader { token ->
v0source.addRecipe(getUrl(), token, recipe)
}
override suspend fun requestRecipes(start: Int, limit: Int): List<RecipeSummaryInfo> =
withAuthHeader { token ->
val url = getUrl()
if (isV1()) {
v1Source.requestRecipes(url, token, start, limit).map { it.toRecipeSummaryInfo() }
} else {
override suspend fun requestRecipes(
start: Int,
limit: Int
): List<RecipeSummaryInfo> = withAuthHeader { token ->
val url = getUrl()
when (getVersion()) {
ServerVersion.V0 -> {
v0source.requestRecipes(url, token, start, limit).map { it.toRecipeSummaryInfo() }
}
}
override suspend fun requestRecipeInfo(slug: String): FullRecipeInfo =
withAuthHeader { token ->
val url = getUrl()
if (isV1()) {
v1Source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
} else {
v0source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
ServerVersion.V1 -> {
// Imagine start is 30 and limit is 15. It means that we already have page 1 and 2, now we need page 3
val page = start / limit + 1
v1Source.requestRecipes(url, token, page, limit).map { it.toRecipeSummaryInfo() }
}
}
private suspend fun getUrl() = baseURLStorage.requireBaseURL()
private suspend fun isV1(): Boolean {
var version = baseURLStorage.getServerVersion()
if (version == null) {
version = getVersionInfo(getUrl()).version
baseURLStorage.storeServerVersion(version)
}
return version.startsWith("v1")
}
override suspend fun requestRecipeInfo(slug: String): FullRecipeInfo = withAuthHeader { token ->
val url = getUrl()
when (getVersion()) {
ServerVersion.V0 -> v0source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
ServerVersion.V1 -> v1Source.requestRecipeInfo(url, token, slug).toFullRecipeInfo()
}
}
private suspend fun getUrl() = serverInfoRepo.requireUrl()
private suspend fun getVersion() = serverInfoRepo.getVersion()
private suspend inline fun <T> withAuthHeader(block: (String?) -> T): T =
runCatching { block(authRepo.getAuthHeader()) }.getOrElse {
if (it is NetworkError.Unauthorized) {

View File

@@ -1,6 +1,6 @@
package gq.kirmanak.mealient.data.recipes.impl
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
import gq.kirmanak.mealient.logging.Logger
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import javax.inject.Inject
@@ -8,7 +8,7 @@ import javax.inject.Singleton
@Singleton
class RecipeImageUrlProviderImpl @Inject constructor(
private val baseURLStorage: BaseURLStorage,
private val serverInfoRepo: ServerInfoRepo,
private val logger: Logger,
) : RecipeImageUrlProvider {
@@ -16,7 +16,7 @@ class RecipeImageUrlProviderImpl @Inject constructor(
logger.v { "generateImageUrl() called with: slug = $slug" }
slug?.takeUnless { it.isBlank() } ?: return null
val imagePath = IMAGE_PATH_FORMAT.format(slug)
val baseUrl = baseURLStorage.getBaseURL()?.takeUnless { it.isEmpty() }
val baseUrl = serverInfoRepo.getUrl()?.takeUnless { it.isEmpty() }
val result = baseUrl?.toHttpUrlOrNull()
?.newBuilder()
?.addPathSegments(imagePath)

View File

@@ -4,10 +4,8 @@ import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
import gq.kirmanak.mealient.data.baseurl.impl.BaseURLStorageImpl
import gq.kirmanak.mealient.data.network.MealieDataSourceWrapper
import gq.kirmanak.mealient.data.baseurl.*
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
import javax.inject.Singleton
@Module
@@ -16,9 +14,13 @@ interface BaseURLModule {
@Binds
@Singleton
fun bindVersionDataSource(mealieDataSourceWrapper: MealieDataSourceWrapper): VersionDataSource
fun bindVersionDataSource(versionDataSourceImpl: VersionDataSourceImpl): VersionDataSource
@Binds
@Singleton
fun bindBaseUrlStorage(baseURLStorageImpl: BaseURLStorageImpl): BaseURLStorage
fun bindBaseUrlStorage(baseURLStorageImpl: ServerInfoStorageImpl): ServerInfoStorage
@Binds
@Singleton
fun bindServerInfoRepo(serverInfoRepoImpl: ServerInfoRepoImpl): ServerInfoRepo
}

View File

@@ -5,7 +5,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
import gq.kirmanak.mealient.extensions.runCatchingExceptCancel
import gq.kirmanak.mealient.logging.Logger
@@ -15,7 +15,7 @@ import javax.inject.Inject
@HiltViewModel
class BaseURLViewModel @Inject constructor(
private val baseURLStorage: BaseURLStorage,
private val serverInfoStorage: ServerInfoStorage,
private val versionDataSource: VersionDataSource,
private val logger: Logger,
) : ViewModel() {
@@ -36,7 +36,7 @@ class BaseURLViewModel @Inject constructor(
val result = runCatchingExceptCancel {
// If it returns proper version info then it must be a Mealie
val version = versionDataSource.getVersionInfo(baseURL).version
baseURLStorage.storeBaseURL(baseURL, version)
serverInfoStorage.storeBaseURL(baseURL, version)
}
logger.i { "checkBaseURL: result is $result" }
_uiState.value = OperationUiState.fromResult(result)

View File

@@ -6,7 +6,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.NavDirections
import dagger.hilt.android.lifecycle.HiltViewModel
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -15,7 +15,7 @@ import javax.inject.Inject
@HiltViewModel
class SplashViewModel @Inject constructor(
private val disclaimerStorage: DisclaimerStorage,
private val baseURLStorage: BaseURLStorage,
private val serverInfoRepo: ServerInfoRepo,
) : ViewModel() {
private val _nextDestination = MutableLiveData<NavDirections>()
val nextDestination: LiveData<NavDirections> = _nextDestination
@@ -25,7 +25,7 @@ class SplashViewModel @Inject constructor(
delay(1000)
_nextDestination.value = when {
!disclaimerStorage.isDisclaimerAccepted() -> SplashFragmentDirections.actionSplashFragmentToDisclaimerFragment()
baseURLStorage.getBaseURL() == null -> SplashFragmentDirections.actionSplashFragmentToBaseURLFragment()
serverInfoRepo.getUrl() == null -> SplashFragmentDirections.actionSplashFragmentToBaseURLFragment()
else -> SplashFragmentDirections.actionSplashFragmentToRecipesFragment()
}
}

View File

@@ -4,7 +4,7 @@ import com.google.common.truth.Truth.assertThat
import gq.kirmanak.mealient.data.auth.AuthDataSource
import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.auth.AuthStorage
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.logging.Logger
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
@@ -27,7 +27,7 @@ class AuthRepoImplTest {
lateinit var dataSource: AuthDataSource
@MockK
lateinit var baseURLStorage: BaseURLStorage
lateinit var serverInfoStorage: ServerInfoStorage
@MockK(relaxUnitFun = true)
lateinit var storage: AuthStorage
@@ -40,7 +40,7 @@ class AuthRepoImplTest {
@Before
fun setUp() {
MockKAnnotations.init(this)
subject = AuthRepoImpl(storage, dataSource, baseURLStorage, logger)
subject = AuthRepoImpl(storage, dataSource, serverInfoStorage, logger)
}
@Test
@@ -58,7 +58,7 @@ class AuthRepoImplTest {
eq(TEST_BASE_URL)
)
} returns TEST_TOKEN
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
coVerifyAll {
storage.setAuthHeader(TEST_AUTH_HEADER)
@@ -71,7 +71,7 @@ class AuthRepoImplTest {
@Test
fun `when authenticate fails then does not change storage`() = runTest {
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
runCatching { subject.authenticate("invalid", "") }
confirmVerified(storage)
}
@@ -107,7 +107,7 @@ class AuthRepoImplTest {
fun `when invalidate with credentials then calls authenticate`() = runTest {
coEvery { storage.getEmail() } returns TEST_USERNAME
coEvery { storage.getPassword() } returns TEST_PASSWORD
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery {
dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD), eq(TEST_BASE_URL))
} returns TEST_TOKEN
@@ -121,7 +121,7 @@ class AuthRepoImplTest {
fun `when invalidate with credentials and auth fails then clears email`() = runTest {
coEvery { storage.getEmail() } returns "invalid"
coEvery { storage.getPassword() } returns ""
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { dataSource.authenticate(any(), any(), any()) } throws RuntimeException()
subject.invalidateAuthHeader()
coVerify { storage.setEmail(null) }

View File

@@ -2,7 +2,7 @@ package gq.kirmanak.mealient.data.baseurl
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.common.truth.Truth.assertThat
import gq.kirmanak.mealient.data.baseurl.impl.BaseURLStorageImpl
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
import gq.kirmanak.mealient.data.storage.PreferencesStorage
import io.mockk.MockKAnnotations
import io.mockk.coEvery
@@ -15,19 +15,19 @@ import org.junit.Before
import org.junit.Test
@OptIn(ExperimentalCoroutinesApi::class)
class BaseURLStorageImplTest {
class ServerInfoStorageImplTest {
@MockK(relaxUnitFun = true)
lateinit var preferencesStorage: PreferencesStorage
lateinit var subject: BaseURLStorage
lateinit var subject: ServerInfoStorage
private val baseUrlKey = stringPreferencesKey("baseUrlKey")
@Before
fun setUp() {
MockKAnnotations.init(this)
subject = BaseURLStorageImpl(preferencesStorage)
subject = ServerInfoStorageImpl(preferencesStorage)
every { preferencesStorage.baseUrlKey } returns baseUrlKey
}

View File

@@ -1,7 +1,7 @@
package gq.kirmanak.mealient.data.network
import gq.kirmanak.mealient.data.auth.AuthRepo
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.datasource.NetworkError
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
@@ -21,7 +21,7 @@ import java.io.IOException
class MealieDataSourceV0WrapperTest {
@MockK
lateinit var baseURLStorage: BaseURLStorage
lateinit var serverInfoStorage: ServerInfoStorage
@MockK(relaxUnitFun = true)
lateinit var authRepo: AuthRepo
@@ -34,12 +34,12 @@ class MealieDataSourceV0WrapperTest {
@Before
fun setUp() {
MockKAnnotations.init(this)
subject = MealieDataSourceWrapper(baseURLStorage, authRepo, mealieDataSourceV0)
subject = MealieDataSourceWrapper(serverInfoStorage, authRepo, mealieDataSourceV0)
}
@Test
fun `when withAuthHeader fails with Unauthorized then invalidates auth`() = runTest {
coEvery { baseURLStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { serverInfoStorage.requireBaseURL() } returns TEST_BASE_URL
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
coEvery {
mealieDataSourceV0.requestRecipeInfo(eq(TEST_BASE_URL), isNull(), eq("cake"))

View File

@@ -1,7 +1,7 @@
package gq.kirmanak.mealient.data.recipes.impl
import com.google.common.truth.Truth.assertThat
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.logging.Logger
import io.mockk.MockKAnnotations
import io.mockk.coEvery
@@ -17,7 +17,7 @@ class RecipeImageUrlProviderImplTest {
lateinit var subject: RecipeImageUrlProvider
@MockK
lateinit var baseURLStorage: BaseURLStorage
lateinit var serverInfoStorage: ServerInfoStorage
@MockK(relaxUnitFun = true)
lateinit var logger: Logger
@@ -25,7 +25,7 @@ class RecipeImageUrlProviderImplTest {
@Before
fun setUp() {
MockKAnnotations.init(this)
subject = RecipeImageUrlProviderImpl(baseURLStorage, logger)
subject = RecipeImageUrlProviderImpl(serverInfoStorage, logger)
prepareBaseURL("https://google.com/")
}
@@ -81,6 +81,6 @@ class RecipeImageUrlProviderImplTest {
}
private fun prepareBaseURL(baseURL: String?) {
coEvery { baseURLStorage.getBaseURL() } returns baseURL
coEvery { serverInfoStorage.getBaseURL() } returns baseURL
}
}

View File

@@ -1,6 +1,6 @@
package gq.kirmanak.mealient.ui.baseurl
import gq.kirmanak.mealient.data.baseurl.BaseURLStorage
import gq.kirmanak.mealient.data.baseurl.ServerInfoStorage
import gq.kirmanak.mealient.data.baseurl.VersionDataSource
import gq.kirmanak.mealient.data.baseurl.VersionInfo
import gq.kirmanak.mealient.logging.Logger
@@ -21,7 +21,7 @@ import org.junit.Test
class BaseURLViewModelTest : RobolectricTest() {
@MockK(relaxUnitFun = true)
lateinit var baseURLStorage: BaseURLStorage
lateinit var serverInfoStorage: ServerInfoStorage
@MockK
lateinit var versionDataSource: VersionDataSource
@@ -34,7 +34,7 @@ class BaseURLViewModelTest : RobolectricTest() {
@Before
fun setUp() {
MockKAnnotations.init(this)
subject = BaseURLViewModel(baseURLStorage, versionDataSource, logger)
subject = BaseURLViewModel(serverInfoStorage, versionDataSource, logger)
}
@Test
@@ -44,6 +44,6 @@ class BaseURLViewModelTest : RobolectricTest() {
} returns VersionInfo(TEST_VERSION)
subject.saveBaseUrl(TEST_BASE_URL)
advanceUntilIdle()
coVerify { baseURLStorage.storeBaseURL(eq(TEST_BASE_URL), eq(TEST_VERSION)) }
coVerify { serverInfoStorage.storeBaseURL(eq(TEST_BASE_URL), eq(TEST_VERSION)) }
}
}