From 94c030c04ddc6a9774f8380801ea28fbe01fcada Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Sun, 30 Oct 2022 13:40:43 +0100 Subject: [PATCH] Handle server info inside of AuthDataSource --- .../mealient/data/add/AddRecipeInfo.kt | 20 +++++++------- .../mealient/data/auth/AuthDataSource.kt | 9 +------ .../data/auth/impl/AuthDataSourceImpl.kt | 13 +++++---- .../mealient/data/auth/impl/AuthRepoImpl.kt | 10 +++---- .../data/auth/impl/AuthRepoImplTest.kt | 27 +++++-------------- .../mealient/test/RecipeImplTestData.kt | 21 +++++++++++++++ .../mealient/ui/add/AddRecipeViewModelTest.kt | 12 ++++----- 7 files changed, 55 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/add/AddRecipeInfo.kt b/app/src/main/java/gq/kirmanak/mealient/data/add/AddRecipeInfo.kt index a6283e3..bb51ac6 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/add/AddRecipeInfo.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/add/AddRecipeInfo.kt @@ -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 = emptyList(), - val recipeInstructions: List = emptyList(), - val settings: AddRecipeSettingsInfo = AddRecipeSettingsInfo(), + val name: String, + val description: String, + val recipeYield: String, + val recipeIngredient: List, + val recipeInstructions: List, + 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, ) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/AuthDataSource.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/AuthDataSource.kt index c6a29f1..576ccab 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/AuthDataSource.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/AuthDataSource.kt @@ -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 } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt index 2e5f3fc..f42444b 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt @@ -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) + } } } \ No newline at end of file diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImpl.kt index 2108a00..e963a62 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImpl.kt @@ -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) } diff --git a/app/src/test/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImplTest.kt b/app/src/test/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImplTest.kt index 8fde756..e3f5b80 100644 --- a/app/src/test/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImplTest.kt +++ b/app/src/test/java/gq/kirmanak/mealient/data/auth/impl/AuthRepoImplTest.kt @@ -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) } } diff --git a/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt b/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt index 049d6ad..e9c5bb3 100644 --- a/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt +++ b/app/src/test/java/gq/kirmanak/mealient/test/RecipeImplTestData.kt @@ -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), + ) } \ No newline at end of file diff --git a/app/src/test/java/gq/kirmanak/mealient/ui/add/AddRecipeViewModelTest.kt b/app/src/test/java/gq/kirmanak/mealient/ui/add/AddRecipeViewModelTest.kt index 898b2f1..d3efb46 100644 --- a/app/src/test/java/gq/kirmanak/mealient/ui/add/AddRecipeViewModelTest.kt +++ b/app/src/test/java/gq/kirmanak/mealient/ui/add/AddRecipeViewModelTest.kt @@ -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)