Handle server info inside of AuthDataSource
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
package gq.kirmanak.mealient.data.add
|
||||
|
||||
data class AddRecipeInfo(
|
||||
val name: String = "",
|
||||
val description: String = "",
|
||||
val recipeYield: String = "",
|
||||
val recipeIngredient: List<AddRecipeIngredientInfo> = emptyList(),
|
||||
val recipeInstructions: List<AddRecipeInstructionInfo> = emptyList(),
|
||||
val settings: AddRecipeSettingsInfo = AddRecipeSettingsInfo(),
|
||||
val name: String,
|
||||
val description: String,
|
||||
val recipeYield: String,
|
||||
val recipeIngredient: List<AddRecipeIngredientInfo>,
|
||||
val recipeInstructions: List<AddRecipeInstructionInfo>,
|
||||
val settings: AddRecipeSettingsInfo,
|
||||
)
|
||||
|
||||
data class AddRecipeSettingsInfo(
|
||||
val disableComments: Boolean = false,
|
||||
val public: Boolean = true,
|
||||
val disableComments: Boolean,
|
||||
val public: Boolean,
|
||||
)
|
||||
|
||||
data class AddRecipeIngredientInfo(
|
||||
val note: String = "",
|
||||
val note: String,
|
||||
)
|
||||
|
||||
data class AddRecipeInstructionInfo(
|
||||
val text: String = "",
|
||||
val text: String,
|
||||
)
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
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,
|
||||
serverVersion: ServerVersion,
|
||||
): String
|
||||
suspend fun authenticate(username: String, password: String): String
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package gq.kirmanak.mealient.data.auth.impl
|
||||
|
||||
import gq.kirmanak.mealient.data.auth.AuthDataSource
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerVersion
|
||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||
@@ -9,6 +10,7 @@ import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class AuthDataSourceImpl @Inject constructor(
|
||||
private val serverInfoRepo: ServerInfoRepo,
|
||||
private val v0Source: MealieDataSourceV0,
|
||||
private val v1Source: MealieDataSourceV1,
|
||||
) : AuthDataSource {
|
||||
@@ -16,10 +18,11 @@ class AuthDataSourceImpl @Inject constructor(
|
||||
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)
|
||||
): String {
|
||||
val baseUrl = serverInfoRepo.requireUrl()
|
||||
return when (serverInfoRepo.getVersion()) {
|
||||
ServerVersion.V0 -> v0Source.authenticate(baseUrl, username, password)
|
||||
ServerVersion.V1 -> v1Source.authenticate(baseUrl, username, password)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ 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.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.datasource.runCatchingExceptCancel
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -15,7 +14,6 @@ import javax.inject.Singleton
|
||||
class AuthRepoImpl @Inject constructor(
|
||||
private val authStorage: AuthStorage,
|
||||
private val authDataSource: AuthDataSource,
|
||||
private val serverInfoRepo: ServerInfoRepo,
|
||||
private val logger: Logger,
|
||||
) : AuthRepo {
|
||||
|
||||
@@ -24,11 +22,9 @@ class AuthRepoImpl @Inject constructor(
|
||||
|
||||
override suspend fun authenticate(email: String, password: String) {
|
||||
logger.v { "authenticate() called with: email = $email, password = $password" }
|
||||
val version = serverInfoRepo.getVersion()
|
||||
val url = serverInfoRepo.requireUrl()
|
||||
authDataSource.authenticate(email, password, url, version)
|
||||
.let { AUTH_HEADER_FORMAT.format(it) }
|
||||
.let { authStorage.setAuthHeader(it) }
|
||||
val token = authDataSource.authenticate(email, password)
|
||||
val header = AUTH_HEADER_FORMAT.format(token)
|
||||
authStorage.setAuthHeader(header)
|
||||
authStorage.setEmail(email)
|
||||
authStorage.setPassword(password)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class AuthRepoImplTest {
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
subject = AuthRepoImpl(storage, dataSource, serverInfoRepo, logger)
|
||||
subject = AuthRepoImpl(storage, dataSource, logger)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,14 +54,7 @@ class AuthRepoImplTest {
|
||||
@Test
|
||||
fun `when authenticate successfully then saves to storage`() = runTest {
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
||||
coEvery {
|
||||
dataSource.authenticate(
|
||||
eq(TEST_USERNAME),
|
||||
eq(TEST_PASSWORD),
|
||||
eq(TEST_BASE_URL),
|
||||
eq(TEST_SERVER_VERSION),
|
||||
)
|
||||
} returns TEST_TOKEN
|
||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
||||
coVerifyAll {
|
||||
@@ -74,7 +67,7 @@ class AuthRepoImplTest {
|
||||
|
||||
@Test
|
||||
fun `when authenticate fails then does not change storage`() = runTest {
|
||||
coEvery { dataSource.authenticate(any(), any(), any(), any()) } throws RuntimeException()
|
||||
coEvery { dataSource.authenticate(any(), any()) } throws RuntimeException()
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
runCatchingExceptCancel { subject.authenticate("invalid", "") }
|
||||
confirmVerified(storage)
|
||||
@@ -113,17 +106,9 @@ class AuthRepoImplTest {
|
||||
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery {
|
||||
dataSource.authenticate(
|
||||
eq(TEST_USERNAME), eq(TEST_PASSWORD), eq(TEST_BASE_URL), eq(TEST_SERVER_VERSION)
|
||||
)
|
||||
} returns TEST_TOKEN
|
||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||
subject.invalidateAuthHeader()
|
||||
coVerifyAll {
|
||||
dataSource.authenticate(
|
||||
eq(TEST_USERNAME), eq(TEST_PASSWORD), eq(TEST_BASE_URL), eq(TEST_SERVER_VERSION)
|
||||
)
|
||||
}
|
||||
coVerifyAll { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,7 +116,7 @@ class AuthRepoImplTest {
|
||||
coEvery { storage.getEmail() } returns "invalid"
|
||||
coEvery { storage.getPassword() } returns ""
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.authenticate(any(), any(), any(), any()) } throws RuntimeException()
|
||||
coEvery { dataSource.authenticate(any(), any()) } throws RuntimeException()
|
||||
subject.invalidateAuthHeader()
|
||||
coVerify { storage.setEmail(null) }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package gq.kirmanak.mealient.test
|
||||
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeIngredientInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeInstructionInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeSettingsInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeIngredientInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeInstructionInfo
|
||||
@@ -174,4 +178,21 @@ object RecipeImplTestData {
|
||||
PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY,
|
||||
)
|
||||
)
|
||||
|
||||
val PORRIDGE_ADD_RECIPE_INFO = AddRecipeInfo(
|
||||
name = "Porridge",
|
||||
description = "Tasty breakfast",
|
||||
recipeYield = "5 servings",
|
||||
recipeIngredient = listOf(
|
||||
AddRecipeIngredientInfo("Milk"),
|
||||
AddRecipeIngredientInfo("Sugar"),
|
||||
AddRecipeIngredientInfo("Salt"),
|
||||
AddRecipeIngredientInfo("Porridge"),
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
AddRecipeInstructionInfo("Mix"),
|
||||
AddRecipeInstructionInfo("Cook"),
|
||||
),
|
||||
settings = AddRecipeSettingsInfo(disableComments = false, public = true),
|
||||
)
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package gq.kirmanak.mealient.ui.add
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeInfo
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
@@ -61,21 +61,21 @@ class AddRecipeViewModelTest {
|
||||
|
||||
@Test
|
||||
fun `when preserve then doesn't update UI`() {
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(AddRecipeInfo())
|
||||
subject.preserve(AddRecipeInfo())
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(PORRIDGE_ADD_RECIPE_INFO)
|
||||
subject.preserve(PORRIDGE_ADD_RECIPE_INFO)
|
||||
coVerify(inverse = true) { addRecipeRepo.addRecipeRequestFlow }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when preservedAddRecipeRequest without loadPreservedRequest then empty`() = runTest {
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(AddRecipeInfo())
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(PORRIDGE_ADD_RECIPE_INFO)
|
||||
val actual = withTimeoutOrNull(10) { subject.preservedAddRecipeRequest.firstOrNull() }
|
||||
assertThat(actual).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when loadPreservedRequest then updates preservedAddRecipeRequest`() = runTest {
|
||||
val expected = AddRecipeInfo()
|
||||
val expected = PORRIDGE_ADD_RECIPE_INFO
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(expected)
|
||||
subject.loadPreservedRequest()
|
||||
assertThat(subject.preservedAddRecipeRequest.first()).isSameInstanceAs(expected)
|
||||
@@ -83,7 +83,7 @@ class AddRecipeViewModelTest {
|
||||
|
||||
@Test
|
||||
fun `when clear then updates preservedAddRecipeRequest`() = runTest {
|
||||
val expected = AddRecipeInfo()
|
||||
val expected = PORRIDGE_ADD_RECIPE_INFO
|
||||
coEvery { addRecipeRepo.addRecipeRequestFlow } returns flowOf(expected)
|
||||
subject.clear()
|
||||
assertThat(subject.preservedAddRecipeRequest.first()).isSameInstanceAs(expected)
|
||||
|
||||
Reference in New Issue
Block a user