Add unit tests
This commit is contained in:
2
.github/workflows/check.yml
vendored
2
.github/workflows/check.yml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: ./gradlew check coverageReport sonar --no-daemon --no-configuration-cache --no-build-cache
|
||||
run: ./gradlew check coverageReport sonar --no-configuration-cache
|
||||
|
||||
- name: Publish test reports
|
||||
uses: mikepenz/action-junit-report@v3
|
||||
|
||||
2
.github/workflows/sign.yml
vendored
2
.github/workflows/sign.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
echo "storePassword=$MEALIENT_KEY_STORE_PASSWORD" >> keystore.properties
|
||||
echo "keyAlias=$MEALIENT_KEY_ALIAS" >> keystore.properties
|
||||
echo "keyPassword=$MEALIENT_KEY_PASSWORD" >> keystore.properties
|
||||
./gradlew build coverageReport sonar uploadToAppSweepRelease --no-daemon --no-configuration-cache --no-build-cache
|
||||
./gradlew build coverageReport sonar uploadToAppSweepRelease --no-configuration-cache
|
||||
cp app/build/outputs/apk/release/*.apk mealient-release.apk
|
||||
|
||||
- name: Upload signed APK
|
||||
|
||||
@@ -42,7 +42,8 @@ android {
|
||||
buildTypes {
|
||||
getByName("debug") {
|
||||
ext["enableCrashlytics"] = false
|
||||
isTestCoverageEnabled = true
|
||||
enableUnitTestCoverage = true
|
||||
enableAndroidTestCoverage = true
|
||||
}
|
||||
getByName("release") {
|
||||
isMinifyEnabled = true
|
||||
|
||||
@@ -13,6 +13,7 @@ import gq.kirmanak.mealient.datasource.runCatchingExceptCancel
|
||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||
import gq.kirmanak.mealient.extensions.*
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@@ -22,6 +23,7 @@ class MealieDataSourceWrapper @Inject constructor(
|
||||
private val authRepo: AuthRepo,
|
||||
private val v0Source: MealieDataSourceV0,
|
||||
private val v1Source: MealieDataSourceV1,
|
||||
private val logger: Logger,
|
||||
) : AddRecipeDataSource, RecipeDataSource {
|
||||
|
||||
override suspend fun addRecipe(
|
||||
@@ -68,9 +70,11 @@ class MealieDataSourceWrapper @Inject constructor(
|
||||
val version = serverInfoRepo.getVersion()
|
||||
return runCatchingExceptCancel { block(authHeader, url, version) }.getOrElse {
|
||||
if (it is NetworkError.Unauthorized) {
|
||||
logger.e { "Unauthorized, trying to invalidate token" }
|
||||
authRepo.invalidateAuthHeader()
|
||||
// Trying again with new authentication header
|
||||
val newHeader = authRepo.getAuthHeader()
|
||||
logger.e { "New token ${if (newHeader == authHeader) "matches" else "doesn't match"} old token" }
|
||||
if (newHeader == authHeader) throw it else block(newHeader, url, version)
|
||||
} else {
|
||||
throw it
|
||||
|
||||
@@ -8,10 +8,10 @@ import gq.kirmanak.mealient.database.AppDb
|
||||
import gq.kirmanak.mealient.database.recipe.RecipeDao
|
||||
import gq.kirmanak.mealient.database.recipe.entity.FullRecipeEntity
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.extensions.recipeEntity
|
||||
import gq.kirmanak.mealient.extensions.toRecipeEntity
|
||||
import gq.kirmanak.mealient.extensions.toRecipeIngredientEntity
|
||||
import gq.kirmanak.mealient.extensions.toRecipeInstructionEntity
|
||||
import gq.kirmanak.mealient.extensions.toRecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@@ -29,7 +29,7 @@ class RecipeStorageImpl @Inject constructor(
|
||||
logger.v { "saveRecipes() called with $recipes" }
|
||||
|
||||
for (recipe in recipes) {
|
||||
val recipeSummaryEntity = recipe.recipeEntity()
|
||||
val recipeSummaryEntity = recipe.toRecipeSummaryEntity()
|
||||
recipeDao.insertRecipe(recipeSummaryEntity)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ fun GetRecipeSummaryResponseV1.toRecipeSummaryInfo() = RecipeSummaryInfo(
|
||||
imageId = remoteId,
|
||||
)
|
||||
|
||||
fun RecipeSummaryInfo.recipeEntity() = RecipeSummaryEntity(
|
||||
fun RecipeSummaryInfo.toRecipeSummaryEntity() = RecipeSummaryEntity(
|
||||
remoteId = remoteId,
|
||||
name = name,
|
||||
slug = slug,
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package gq.kirmanak.mealient.data.add.impl
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeDataSource
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||
import gq.kirmanak.mealient.datastore.recipe.AddRecipeStorage
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_DRAFT
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AddRecipeRepoTest {
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var dataSource: AddRecipeDataSource
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: AddRecipeStorage
|
||||
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
private lateinit var subject: AddRecipeRepo
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
subject = AddRecipeRepoImpl(dataSource, storage, logger)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when clear expect storage clear`() = runTest {
|
||||
subject.clear()
|
||||
coVerify { storage.clear() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipe expect then reads storage`() = runTest {
|
||||
every { storage.updates } returns flowOf(PORRIDGE_RECIPE_DRAFT)
|
||||
coEvery { dataSource.addRecipe(any()) } returns "porridge"
|
||||
subject.saveRecipe()
|
||||
verify { storage.updates }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipe expect addRecipe with stored value`() = runTest {
|
||||
every { storage.updates } returns flowOf(PORRIDGE_RECIPE_DRAFT)
|
||||
coEvery { dataSource.addRecipe(any()) } returns "porridge"
|
||||
subject.saveRecipe()
|
||||
coVerify { dataSource.addRecipe(eq(PORRIDGE_ADD_RECIPE_INFO)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipe expect result from dataSource`() = runTest {
|
||||
every { storage.updates } returns flowOf(PORRIDGE_RECIPE_DRAFT)
|
||||
val expected = "porridge"
|
||||
coEvery { dataSource.addRecipe(any()) } returns expected
|
||||
assertThat(subject.saveRecipe()).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when preserve expect save to storage`() = runTest {
|
||||
subject.preserve(PORRIDGE_ADD_RECIPE_INFO)
|
||||
coVerify { storage.save(eq(PORRIDGE_RECIPE_DRAFT)) }
|
||||
}
|
||||
}
|
||||
@@ -10,9 +10,10 @@ import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V0
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_TOKEN
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -34,8 +35,7 @@ class AuthRepoImplTest {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: AuthStorage
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: AuthRepo
|
||||
|
||||
@@ -53,7 +53,7 @@ class AuthRepoImplTest {
|
||||
|
||||
@Test
|
||||
fun `when authenticate successfully then saves to storage`() = runTest {
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
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)
|
||||
@@ -104,7 +104,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 { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||
subject.invalidateAuthHeader()
|
||||
|
||||
@@ -14,9 +14,9 @@ import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -32,8 +32,7 @@ class AuthStorageImplTest : HiltRobolectricTest() {
|
||||
@ApplicationContext
|
||||
lateinit var context: Context
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: AuthStorage
|
||||
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
package gq.kirmanak.mealient.data.baseurl
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.datasource.NetworkError
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V0
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class ServerInfoRepoTest {
|
||||
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
private lateinit var subject: ServerInfoRepo
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: ServerInfoStorage
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var dataSource: VersionDataSource
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
subject = ServerInfoRepoImpl(storage, dataSource, logger)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage returns null url expect getUrl return null`() = runTest {
|
||||
coEvery { storage.getBaseURL() } returns null
|
||||
assertThat(subject.getUrl()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage returns url value expect getUrl return value`() = runTest {
|
||||
val expected = TEST_BASE_URL
|
||||
coEvery { storage.getBaseURL() } returns expected
|
||||
assertThat(subject.getUrl()).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException::class)
|
||||
fun `when storage returns null url expect requireUrl to throw`() = runTest {
|
||||
coEvery { storage.getBaseURL() } returns null
|
||||
subject.requireUrl()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when getUrl expect storage is accessed`() = runTest {
|
||||
coEvery { storage.getBaseURL() } returns null
|
||||
subject.getUrl()
|
||||
coVerify { storage.getBaseURL() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when requireUrl expect storage is accessed`() = runTest {
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
subject.requireUrl()
|
||||
coVerify { storage.getBaseURL() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storeBaseUrl expect call to storage`() = runTest {
|
||||
subject.storeBaseURL(TEST_BASE_URL, TEST_VERSION)
|
||||
coVerify { storage.storeBaseURL(TEST_BASE_URL, TEST_VERSION) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage is empty expect getVersion to call data source`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VERSION_INFO_V0
|
||||
subject.getVersion()
|
||||
coVerify { dataSource.getVersionInfo(eq(TEST_BASE_URL)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage is empty and data source has value expect getVersion to save it`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VersionInfo(TEST_VERSION)
|
||||
subject.getVersion()
|
||||
coVerify { storage.storeServerVersion(TEST_VERSION) }
|
||||
}
|
||||
|
||||
@Test(expected = NetworkError.NotMealie::class)
|
||||
fun `when data source has invalid value expect getVersion to throw`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VersionInfo("v2.0.0")
|
||||
subject.getVersion()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when data source has invalid value expect getVersion not to save`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VersionInfo("v2.0.0")
|
||||
subject.runCatching { getVersion() }
|
||||
coVerify(inverse = true) { storage.storeServerVersion(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage has value expect getVersion to not get URL`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns TEST_VERSION
|
||||
subject.getVersion()
|
||||
coVerify(inverse = true) { storage.getBaseURL() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage has value expect getVersion to not call data source`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns TEST_VERSION
|
||||
subject.getVersion()
|
||||
coVerify(inverse = true) { dataSource.getVersionInfo(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage has v0 value expect getVersion to return parsed`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns "v0.5.6"
|
||||
assertThat(subject.getVersion()).isEqualTo(ServerVersion.V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storage has v1 value expect getVersion to return parsed`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns "v1.0.0-beta05"
|
||||
assertThat(subject.getVersion()).isEqualTo(ServerVersion.V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when data source has valid v0 value expect getVersion to return it`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VersionInfo("v0.5.6")
|
||||
assertThat(subject.getVersion()).isEqualTo(ServerVersion.V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when data source has valid v1 value expect getVersion to return it`() = runTest {
|
||||
coEvery { storage.getServerVersion() } returns null
|
||||
coEvery { storage.getBaseURL() } returns TEST_BASE_URL
|
||||
coEvery { dataSource.getVersionInfo(eq(TEST_BASE_URL)) } returns VersionInfo("v1.0.0-beta05")
|
||||
assertThat(subject.getVersion()).isEqualTo(ServerVersion.V1)
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
|
||||
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
@@ -15,7 +17,7 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class ServerInfoStorageImplTest {
|
||||
class ServerInfoStorageTest {
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var preferencesStorage: PreferencesStorage
|
||||
@@ -34,26 +36,43 @@ class ServerInfoStorageImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when getBaseURL and preferences storage empty then null`() = runTest {
|
||||
fun `when preferences storage empty expect getBaseURL return null`() = runTest {
|
||||
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns null
|
||||
assertThat(subject.getBaseURL()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when getBaseUrl and preferences storage has value then value`() = runTest {
|
||||
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns "baseUrl"
|
||||
assertThat(subject.getBaseURL()).isEqualTo("baseUrl")
|
||||
fun `when preferences storage has value expect getBaseUrl return value`() = runTest {
|
||||
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns TEST_BASE_URL
|
||||
assertThat(subject.getBaseURL()).isEqualTo(TEST_BASE_URL)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storeBaseURL then calls preferences storage`() = runTest {
|
||||
subject.storeBaseURL("baseUrl", "v0.5.6")
|
||||
fun `when storeBaseURL expect call to preferences storage`() = runTest {
|
||||
subject.storeBaseURL(TEST_BASE_URL, TEST_VERSION)
|
||||
coVerify {
|
||||
preferencesStorage.baseUrlKey
|
||||
preferencesStorage.storeValues(
|
||||
eq(Pair(baseUrlKey, "baseUrl")),
|
||||
eq(Pair(serverVersionKey, "v0.5.6")),
|
||||
eq(Pair(baseUrlKey, TEST_BASE_URL)),
|
||||
eq(Pair(serverVersionKey, TEST_VERSION)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when preference storage is empty expect getServerVersion return null`() = runTest {
|
||||
coEvery { preferencesStorage.getValue(eq(serverVersionKey)) } returns null
|
||||
assertThat(subject.getServerVersion()).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when preference storage has value expect getServerVersion return value`() = runTest {
|
||||
coEvery { preferencesStorage.getValue(eq(serverVersionKey)) } returns TEST_VERSION
|
||||
assertThat(subject.getServerVersion()).isEqualTo(TEST_VERSION)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when storeServerVersion then calls preferences storage`() = runTest {
|
||||
subject.storeServerVersion(TEST_VERSION)
|
||||
coVerify { preferencesStorage.storeValues(eq(Pair(serverVersionKey, TEST_VERSION))) }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,30 @@
|
||||
package gq.kirmanak.mealient.data.network
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.auth.AuthRepo
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.datasource.NetworkError
|
||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||
import gq.kirmanak.mealient.datasource.v0.models.GetRecipeResponseV0
|
||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_AUTH_HEADER
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerifyAll
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V0
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V1
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_REQUEST_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_CREATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_UPDATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V1
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
@@ -37,30 +48,153 @@ class MealieDataSourceWrapperTest {
|
||||
|
||||
lateinit var subject: MealieDataSourceWrapper
|
||||
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
subject = MealieDataSourceWrapper(serverInfoRepo, authRepo, v0Source, v1Source)
|
||||
subject = MealieDataSourceWrapper(serverInfoRepo, authRepo, v0Source, v1Source, logger)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when withAuthHeader fails with Unauthorized then invalidates auth`() = runTest {
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
||||
fun `when makeCall fails with Unauthorized expect it to invalidate token`() = runTest {
|
||||
val slug = "porridge"
|
||||
coEvery {
|
||||
v0Source.requestRecipeInfo(any(), isNull(), any())
|
||||
} throws NetworkError.Unauthorized(IOException())
|
||||
coEvery {
|
||||
v0Source.requestRecipeInfo(any(), eq(TEST_AUTH_HEADER), any())
|
||||
} returns PORRIDGE_RECIPE_RESPONSE_V0
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
|
||||
coEvery {
|
||||
v0Source.requestRecipeInfo(eq(TEST_BASE_URL), isNull(), eq("cake"))
|
||||
} throws NetworkError.Unauthorized(IOException())
|
||||
val successResponse = mockk<GetRecipeResponseV0>(relaxed = true)
|
||||
coEvery {
|
||||
v0Source.requestRecipeInfo(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq("cake"))
|
||||
} returns successResponse
|
||||
subject.requestRecipeInfo("cake")
|
||||
coVerifyAll {
|
||||
|
||||
subject.requestRecipeInfo(slug)
|
||||
|
||||
coVerifySequence {
|
||||
authRepo.getAuthHeader()
|
||||
authRepo.invalidateAuthHeader()
|
||||
authRepo.getAuthHeader()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when server version v1 expect requestRecipeInfo to call v1`() = runTest {
|
||||
val slug = "porridge"
|
||||
coEvery {
|
||||
v1Source.requestRecipeInfo(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq(slug))
|
||||
} returns PORRIDGE_RECIPE_RESPONSE_V1
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
|
||||
val actual = subject.requestRecipeInfo(slug)
|
||||
|
||||
coVerify { v1Source.requestRecipeInfo(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq(slug)) }
|
||||
|
||||
assertThat(actual).isEqualTo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when server version v1 expect requestRecipes to call v1`() = runTest {
|
||||
coEvery {
|
||||
v1Source.requestRecipes(any(), any(), any(), any())
|
||||
} returns listOf(PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1)
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
|
||||
val actual = subject.requestRecipes(40, 10)
|
||||
|
||||
val page = 5 // 0-9 (1), 10-19 (2), 20-29 (3), 30-39 (4), 40-49 (5)
|
||||
val perPage = 10
|
||||
coVerify {
|
||||
v1Source.requestRecipes(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq(page), eq(perPage))
|
||||
}
|
||||
|
||||
assertThat(actual).isEqualTo(listOf(RECIPE_SUMMARY_PORRIDGE_V1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when server version v0 expect requestRecipes to call v0`() = runTest {
|
||||
coEvery {
|
||||
v0Source.requestRecipes(any(), any(), any(), any())
|
||||
} returns listOf(PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0)
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
|
||||
val start = 40
|
||||
val limit = 10
|
||||
val actual = subject.requestRecipes(start, limit)
|
||||
|
||||
coVerify {
|
||||
v0Source.requestRecipes(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq(start), eq(limit))
|
||||
}
|
||||
|
||||
assertThat(actual).isEqualTo(listOf(RECIPE_SUMMARY_PORRIDGE_V0))
|
||||
}
|
||||
|
||||
@Test(expected = IOException::class)
|
||||
fun `when request fails expect addRecipe to rethrow`() = runTest {
|
||||
coEvery { v0Source.addRecipe(any(), any(), any()) } throws IOException()
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
subject.addRecipe(PORRIDGE_ADD_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when server version v0 expect addRecipe to call v0`() = runTest {
|
||||
val slug = "porridge"
|
||||
|
||||
coEvery { v0Source.addRecipe(any(), any(), any()) } returns slug
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V0
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
|
||||
val actual = subject.addRecipe(PORRIDGE_ADD_RECIPE_INFO)
|
||||
|
||||
coVerify {
|
||||
v0Source.addRecipe(
|
||||
eq(TEST_BASE_URL),
|
||||
eq(TEST_AUTH_HEADER),
|
||||
eq(PORRIDGE_ADD_RECIPE_REQUEST_V0),
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(actual).isEqualTo(slug)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when server version v1 expect addRecipe to call v1`() = runTest {
|
||||
val slug = "porridge"
|
||||
|
||||
coEvery { v1Source.createRecipe(any(), any(), any()) } returns slug
|
||||
coEvery {
|
||||
v1Source.updateRecipe(any(), any(), any(), any())
|
||||
} returns PORRIDGE_RECIPE_RESPONSE_V1
|
||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION_V1
|
||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||
coEvery { authRepo.getAuthHeader() } returns TEST_AUTH_HEADER
|
||||
|
||||
val actual = subject.addRecipe(PORRIDGE_ADD_RECIPE_INFO)
|
||||
|
||||
coVerifySequence {
|
||||
v1Source.createRecipe(
|
||||
eq(TEST_BASE_URL),
|
||||
eq(TEST_AUTH_HEADER),
|
||||
eq(PORRIDGE_CREATE_RECIPE_REQUEST_V1),
|
||||
)
|
||||
|
||||
v1Source.updateRecipe(
|
||||
eq(TEST_BASE_URL),
|
||||
eq(TEST_AUTH_HEADER),
|
||||
eq(slug),
|
||||
eq(PORRIDGE_UPDATE_RECIPE_REQUEST_V1),
|
||||
)
|
||||
}
|
||||
|
||||
assertThat(actual).isEqualTo(slug)
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,16 @@ import gq.kirmanak.mealient.database.AppDb
|
||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.BREAD_INGREDIENT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_BREAD_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_PORRIDGE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.GET_CAKE_RESPONSE
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.GET_PORRIDGE_RESPONSE
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_CAKE
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -61,16 +61,16 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
@Test
|
||||
fun `when saveRecipeInfo then saves recipe info`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")
|
||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when saveRecipeInfo with two then saves second`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE))
|
||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
||||
subject.saveRecipeInfo(GET_PORRIDGE_RESPONSE)
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE_V0))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
subject.saveRecipeInfo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("2")
|
||||
assertThat(actual).isEqualTo(FULL_PORRIDGE_INFO_ENTITY)
|
||||
}
|
||||
@@ -78,8 +78,8 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites ingredients`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
||||
val newRecipe = GET_CAKE_RESPONSE.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeIngredients
|
||||
val expected = listOf(CAKE_BREAD_RECIPE_INGREDIENT_ENTITY.copy(localId = 3))
|
||||
@@ -89,8 +89,8 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
||||
@Test
|
||||
fun `when saveRecipeInfo secondly then overwrites instructions`() = runTest {
|
||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
||||
val newRecipe = GET_CAKE_RESPONSE.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
||||
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
||||
subject.saveRecipeInfo(newRecipe)
|
||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeInstructions
|
||||
val expected = listOf(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY.copy(localId = 3))
|
||||
|
||||
@@ -3,6 +3,7 @@ package gq.kirmanak.mealient.data.recipes.impl
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.impl.annotations.MockK
|
||||
@@ -19,8 +20,7 @@ class RecipeImageUrlProviderImplTest {
|
||||
@MockK
|
||||
lateinit var serverInfoRepo: ServerInfoRepo
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
||||
@@ -7,8 +7,9 @@ import gq.kirmanak.mealient.data.recipes.db.RecipeStorage
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.GET_CAKE_RESPONSE
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
@@ -19,7 +20,7 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class RecipeRepoImplTest {
|
||||
class RecipeRepoTest {
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: RecipeStorage
|
||||
@@ -33,8 +34,7 @@ class RecipeRepoImplTest {
|
||||
@MockK
|
||||
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: RecipeRepo
|
||||
|
||||
@@ -45,26 +45,32 @@ class RecipeRepoImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when loadRecipeInfo then loads recipe`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns GET_CAKE_RESPONSE
|
||||
fun `when loadRecipeInfo expect return value from data source`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns CAKE_FULL_RECIPE_INFO
|
||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||
val actual = subject.loadRecipeInfo("1", "cake")
|
||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when loadRecipeInfo then saves to DB`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns GET_CAKE_RESPONSE
|
||||
fun `when loadRecipeInfo expect call to storage`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns CAKE_FULL_RECIPE_INFO
|
||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||
subject.loadRecipeInfo("1", "cake")
|
||||
coVerify { storage.saveRecipeInfo(eq(GET_CAKE_RESPONSE)) }
|
||||
coVerify { storage.saveRecipeInfo(eq(CAKE_FULL_RECIPE_INFO)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when loadRecipeInfo with error then loads from DB`() = runTest {
|
||||
fun `when data source fails expect loadRecipeInfo return value from storage`() = runTest {
|
||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } throws RuntimeException()
|
||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||
val actual = subject.loadRecipeInfo("1", "cake")
|
||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when clearLocalData expect call to storage`() = runTest {
|
||||
subject.clearLocalData()
|
||||
coVerify { storage.clearAllLocalData() }
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import gq.kirmanak.mealient.data.recipes.network.RecipeDataSource
|
||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
@@ -39,8 +40,7 @@ class RecipesRemoteMediatorTest {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package gq.kirmanak.mealient.extensions
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_RECIPE_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MILK_RECIPE_INGREDIENT_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_RECIPE_INSTRUCTION_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_REQUEST_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_CREATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_FULL_RECIPE_INFO
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_DRAFT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_UPDATE_RECIPE_REQUEST_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_PORRIDGE_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.SUGAR_INGREDIENT
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_INFO_V1
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_RESPONSE_V0
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.VERSION_RESPONSE_V1
|
||||
import org.junit.Test
|
||||
|
||||
class ModelMappingsTest {
|
||||
|
||||
@Test
|
||||
fun `when toAddRecipeRequest then fills fields correctly`() {
|
||||
assertThat(PORRIDGE_RECIPE_DRAFT.toAddRecipeInfo()).isEqualTo(PORRIDGE_ADD_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when toDraft then fills fields correctly`() {
|
||||
assertThat(PORRIDGE_ADD_RECIPE_INFO.toDraft()).isEqualTo(PORRIDGE_RECIPE_DRAFT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when full recipe info to entity expect correct entity`() {
|
||||
assertThat(CAKE_FULL_RECIPE_INFO.toRecipeEntity()).isEqualTo(CAKE_RECIPE_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ingredient info to entity expect correct entity`() {
|
||||
val actual = SUGAR_INGREDIENT.toRecipeIngredientEntity("1")
|
||||
assertThat(actual).isEqualTo(CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when instruction info to entity expect correct entity`() {
|
||||
val actual = MIX_INSTRUCTION.toRecipeInstructionEntity("1")
|
||||
assertThat(actual).isEqualTo(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary v0 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0.toRecipeSummaryInfo()
|
||||
assertThat(actual).isEqualTo(RECIPE_SUMMARY_PORRIDGE_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary v1 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1.toRecipeSummaryInfo()
|
||||
assertThat(actual).isEqualTo(RECIPE_SUMMARY_PORRIDGE_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when summary info to entity expect correct entity`() {
|
||||
val actual = RECIPE_SUMMARY_PORRIDGE_V0.toRecipeSummaryEntity()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_RECIPE_SUMMARY_ENTITY)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when version response v0 to info expect correct info`() {
|
||||
assertThat(VERSION_RESPONSE_V0.toVersionInfo()).isEqualTo(VERSION_INFO_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when version response v1 to info expect correct info`() {
|
||||
assertThat(VERSION_RESPONSE_V1.toVersionInfo()).isEqualTo(VERSION_INFO_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe ingredient response v0 to info expect correct info`() {
|
||||
val actual = MILK_RECIPE_INGREDIENT_RESPONSE_V0.toRecipeIngredientInfo()
|
||||
assertThat(actual).isEqualTo(MILK_RECIPE_INGREDIENT_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe ingredient response v1 to info expect correct info`() {
|
||||
val actual = MILK_RECIPE_INGREDIENT_RESPONSE_V1.toRecipeIngredientInfo()
|
||||
assertThat(actual).isEqualTo(MILK_RECIPE_INGREDIENT_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe instruction response v0 to info expect correct info`() {
|
||||
val actual = MIX_RECIPE_INSTRUCTION_RESPONSE_V0.toRecipeInstructionInfo()
|
||||
assertThat(actual).isEqualTo(MIX_RECIPE_INSTRUCTION_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe instruction response v1 to info expect correct info`() {
|
||||
val actual = MIX_RECIPE_INSTRUCTION_RESPONSE_V1.toRecipeInstructionInfo()
|
||||
assertThat(actual).isEqualTo(MIX_RECIPE_INSTRUCTION_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe response v0 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_RESPONSE_V0.toFullRecipeInfo()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when recipe response v1 to info expect correct info`() {
|
||||
val actual = PORRIDGE_RECIPE_RESPONSE_V1.toFullRecipeInfo()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_FULL_RECIPE_INFO)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to request v0 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV0Request()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_ADD_RECIPE_REQUEST_V0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to create request v1 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV1CreateRequest()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_CREATE_RECIPE_REQUEST_V1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when add recipe info to update request v1 expect correct request`() {
|
||||
val actual = PORRIDGE_ADD_RECIPE_INFO.toV1UpdateRequest()
|
||||
assertThat(actual).isEqualTo(PORRIDGE_UPDATE_RECIPE_REQUEST_V1)
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package gq.kirmanak.mealient.extensions
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
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.datastore.recipe.AddRecipeDraft
|
||||
import org.junit.Test
|
||||
|
||||
class RemoteToLocalMappingsTest {
|
||||
|
||||
@Test
|
||||
fun `when toAddRecipeRequest then fills fields correctly`() {
|
||||
val input = AddRecipeDraft(
|
||||
recipeName = "Recipe name",
|
||||
recipeDescription = "Recipe description",
|
||||
recipeYield = "Recipe yield",
|
||||
recipeInstructions = listOf("Recipe instruction 1", "Recipe instruction 2"),
|
||||
recipeIngredients = listOf("Recipe ingredient 1", "Recipe ingredient 2"),
|
||||
isRecipePublic = false,
|
||||
areCommentsDisabled = true,
|
||||
)
|
||||
|
||||
val expected = AddRecipeInfo(
|
||||
name = "Recipe name",
|
||||
description = "Recipe description",
|
||||
recipeYield = "Recipe yield",
|
||||
recipeIngredient = listOf(
|
||||
AddRecipeIngredientInfo(note = "Recipe ingredient 1"),
|
||||
AddRecipeIngredientInfo(note = "Recipe ingredient 2")
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
AddRecipeInstructionInfo(text = "Recipe instruction 1"),
|
||||
AddRecipeInstructionInfo(text = "Recipe instruction 2")
|
||||
),
|
||||
settings = AddRecipeSettingsInfo(
|
||||
public = false,
|
||||
disableComments = true,
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(input.toAddRecipeInfo()).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when toDraft then fills fields correctly`() {
|
||||
val request = AddRecipeInfo(
|
||||
name = "Recipe name",
|
||||
description = "Recipe description",
|
||||
recipeYield = "Recipe yield",
|
||||
recipeIngredient = listOf(
|
||||
AddRecipeIngredientInfo(note = "Recipe ingredient 1"),
|
||||
AddRecipeIngredientInfo(note = "Recipe ingredient 2")
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
AddRecipeInstructionInfo(text = "Recipe instruction 1"),
|
||||
AddRecipeInstructionInfo(text = "Recipe instruction 2")
|
||||
),
|
||||
settings = AddRecipeSettingsInfo(
|
||||
public = false,
|
||||
disableComments = true,
|
||||
)
|
||||
)
|
||||
|
||||
val expected = AddRecipeDraft(
|
||||
recipeName = "Recipe name",
|
||||
recipeDescription = "Recipe description",
|
||||
recipeYield = "Recipe yield",
|
||||
recipeInstructions = listOf("Recipe instruction 1", "Recipe instruction 2"),
|
||||
recipeIngredients = listOf("Recipe ingredient 1", "Recipe ingredient 2"),
|
||||
isRecipePublic = false,
|
||||
areCommentsDisabled = true,
|
||||
)
|
||||
|
||||
assertThat(request.toDraft()).isEqualTo(expected)
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ object AuthImplTestData {
|
||||
const val TEST_TOKEN = "TEST_TOKEN"
|
||||
const val TEST_AUTH_HEADER = "Bearer TEST_TOKEN"
|
||||
const val TEST_VERSION = "v0.5.6"
|
||||
val TEST_SERVER_VERSION = ServerVersion.V0
|
||||
val TEST_SERVER_VERSION_V0 = ServerVersion.V0
|
||||
val TEST_SERVER_VERSION_V1 = ServerVersion.V1
|
||||
}
|
||||
34
app/src/test/java/gq/kirmanak/mealient/test/FakeLogger.kt
Normal file
34
app/src/test/java/gq/kirmanak/mealient/test/FakeLogger.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package gq.kirmanak.mealient.test
|
||||
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.logging.MessageSupplier
|
||||
|
||||
class FakeLogger : Logger {
|
||||
override fun v(throwable: Throwable?, tag: String?, messageSupplier: MessageSupplier) {
|
||||
print("V", throwable, messageSupplier)
|
||||
}
|
||||
|
||||
override fun d(throwable: Throwable?, tag: String?, messageSupplier: MessageSupplier) {
|
||||
print("D", throwable, messageSupplier)
|
||||
}
|
||||
|
||||
override fun i(throwable: Throwable?, tag: String?, messageSupplier: MessageSupplier) {
|
||||
print("I", throwable, messageSupplier)
|
||||
}
|
||||
|
||||
override fun w(throwable: Throwable?, tag: String?, messageSupplier: MessageSupplier) {
|
||||
print("W", throwable, messageSupplier)
|
||||
}
|
||||
|
||||
override fun e(throwable: Throwable?, tag: String?, messageSupplier: MessageSupplier) {
|
||||
print("E", throwable, messageSupplier)
|
||||
}
|
||||
|
||||
private fun print(
|
||||
level: String,
|
||||
throwable: Throwable?,
|
||||
messageSupplier: MessageSupplier,
|
||||
) {
|
||||
println("$level ${messageSupplier()}. ${throwable?.stackTraceToString().orEmpty()}")
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,15 @@ 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.baseurl.VersionInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.FullRecipeInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeIngredientInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeInstructionInfo
|
||||
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
||||
import gq.kirmanak.mealient.database.recipe.entity.*
|
||||
import gq.kirmanak.mealient.datasource.v0.models.*
|
||||
import gq.kirmanak.mealient.datasource.v1.models.*
|
||||
import gq.kirmanak.mealient.datastore.recipe.AddRecipeDraft
|
||||
import kotlinx.datetime.LocalDate
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
|
||||
@@ -23,7 +27,7 @@ object RecipeImplTestData {
|
||||
imageId = "cake",
|
||||
)
|
||||
|
||||
val RECIPE_SUMMARY_PORRIDGE = RecipeSummaryInfo(
|
||||
val RECIPE_SUMMARY_PORRIDGE_V0 = RecipeSummaryInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
@@ -33,7 +37,17 @@ object RecipeImplTestData {
|
||||
imageId = "porridge",
|
||||
)
|
||||
|
||||
val TEST_RECIPE_SUMMARIES = listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE)
|
||||
val RECIPE_SUMMARY_PORRIDGE_V1 = RecipeSummaryInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
imageId = "2",
|
||||
)
|
||||
|
||||
val TEST_RECIPE_SUMMARIES = listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE_V0)
|
||||
|
||||
val CAKE_RECIPE_SUMMARY_ENTITY = RecipeSummaryEntity(
|
||||
remoteId = "1",
|
||||
@@ -55,7 +69,7 @@ object RecipeImplTestData {
|
||||
imageId = "porridge",
|
||||
)
|
||||
|
||||
private val SUGAR_INGREDIENT = RecipeIngredientInfo(
|
||||
val SUGAR_INGREDIENT = RecipeIngredientInfo(
|
||||
note = "2 oz of white sugar",
|
||||
)
|
||||
|
||||
@@ -79,7 +93,7 @@ object RecipeImplTestData {
|
||||
text = "Boil the ingredients"
|
||||
)
|
||||
|
||||
val GET_CAKE_RESPONSE = FullRecipeInfo(
|
||||
val CAKE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||
remoteId = "1",
|
||||
name = "Cake",
|
||||
recipeYield = "4 servings",
|
||||
@@ -87,7 +101,7 @@ object RecipeImplTestData {
|
||||
recipeInstructions = listOf(MIX_INSTRUCTION, BAKE_INSTRUCTION)
|
||||
)
|
||||
|
||||
val GET_PORRIDGE_RESPONSE = FullRecipeInfo(
|
||||
val PORRIDGE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
@@ -96,30 +110,26 @@ object RecipeImplTestData {
|
||||
)
|
||||
|
||||
val MIX_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
localId = 1,
|
||||
recipeId = "1",
|
||||
text = "Mix the ingredients",
|
||||
)
|
||||
|
||||
private val BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
localId = 2,
|
||||
recipeId = "1",
|
||||
text = "Bake the ingredients",
|
||||
)
|
||||
|
||||
private val CAKE_RECIPE_ENTITY = RecipeEntity(
|
||||
val CAKE_RECIPE_ENTITY = RecipeEntity(
|
||||
remoteId = "1",
|
||||
recipeYield = "4 servings"
|
||||
)
|
||||
|
||||
private val CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
localId = 1,
|
||||
val CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
recipeId = "1",
|
||||
note = "2 oz of white sugar",
|
||||
)
|
||||
|
||||
val CAKE_BREAD_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
localId = 2,
|
||||
recipeId = "1",
|
||||
note = "2 oz of white bread",
|
||||
)
|
||||
@@ -143,25 +153,21 @@ object RecipeImplTestData {
|
||||
)
|
||||
|
||||
private val PORRIDGE_MILK_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
localId = 4,
|
||||
recipeId = "2",
|
||||
note = "2 oz of white milk",
|
||||
)
|
||||
|
||||
private val PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||
localId = 3,
|
||||
recipeId = "2",
|
||||
note = "2 oz of white sugar",
|
||||
)
|
||||
|
||||
private val PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
localId = 3,
|
||||
recipeId = "2",
|
||||
text = "Mix the ingredients"
|
||||
)
|
||||
|
||||
private val PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||
localId = 4,
|
||||
recipeId = "2",
|
||||
text = "Boil the ingredients"
|
||||
)
|
||||
@@ -179,20 +185,177 @@ object RecipeImplTestData {
|
||||
)
|
||||
)
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_INFO = AddRecipeIngredientInfo("2 oz of white sugar")
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_INFO = AddRecipeIngredientInfo("2 oz of white milk")
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_INFO = AddRecipeInstructionInfo("Boil the ingredients")
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_INFO = AddRecipeInstructionInfo("Mix the ingredients")
|
||||
|
||||
val ADD_RECIPE_INFO_SETTINGS = AddRecipeSettingsInfo(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_ADD_RECIPE_INFO = AddRecipeInfo(
|
||||
name = "Porridge",
|
||||
description = "Tasty breakfast",
|
||||
recipeYield = "5 servings",
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredient = listOf(
|
||||
AddRecipeIngredientInfo("Milk"),
|
||||
AddRecipeIngredientInfo("Sugar"),
|
||||
AddRecipeIngredientInfo("Salt"),
|
||||
AddRecipeIngredientInfo("Porridge"),
|
||||
MILK_ADD_RECIPE_INGREDIENT_INFO,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_INFO,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
AddRecipeInstructionInfo("Mix"),
|
||||
AddRecipeInstructionInfo("Cook"),
|
||||
MIX_ADD_RECIPE_INSTRUCTION_INFO,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_INFO,
|
||||
),
|
||||
settings = AddRecipeSettingsInfo(disableComments = false, public = true),
|
||||
settings = ADD_RECIPE_INFO_SETTINGS,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_DRAFT = AddRecipeDraft(
|
||||
recipeName = "Porridge",
|
||||
recipeDescription = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf("Mix the ingredients", "Boil the ingredients"),
|
||||
recipeIngredients = listOf("2 oz of white milk", "2 oz of white sugar"),
|
||||
isRecipePublic = true,
|
||||
areCommentsDisabled = false,
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_RESPONSE_V0 = GetRecipeSummaryResponseV0(
|
||||
remoteId = 2,
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_SUMMARY_RESPONSE_V1 = GetRecipeSummaryResponseV1(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
slug = "porridge",
|
||||
description = "A tasty porridge",
|
||||
dateAdded = LocalDate.parse("2021-11-12"),
|
||||
dateUpdated = LocalDateTime.parse("2021-10-13T17:35:23"),
|
||||
)
|
||||
|
||||
val VERSION_RESPONSE_V0 = VersionResponseV0("v0.5.6")
|
||||
|
||||
val VERSION_INFO_V0 = VersionInfo("v0.5.6")
|
||||
|
||||
val VERSION_RESPONSE_V1 = VersionResponseV1("v1.0.0-beta05")
|
||||
|
||||
val VERSION_INFO_V1 = VersionInfo("v1.0.0-beta05")
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_RESPONSE_V0 = GetRecipeIngredientResponseV0("2 oz of white milk")
|
||||
|
||||
val SUGAR_RECIPE_INGREDIENT_RESPONSE_V0 = GetRecipeIngredientResponseV0("2 oz of white sugar")
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_RESPONSE_V1 = GetRecipeIngredientResponseV1("2 oz of white milk")
|
||||
|
||||
val SUGAR_RECIPE_INGREDIENT_RESPONSE_V1 = GetRecipeIngredientResponseV1("2 oz of white sugar")
|
||||
|
||||
val MILK_RECIPE_INGREDIENT_INFO = RecipeIngredientInfo("2 oz of white milk")
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_RESPONSE_V0 = GetRecipeInstructionResponseV0("Mix the ingredients")
|
||||
|
||||
val BOIL_RECIPE_INSTRUCTION_RESPONSE_V0 = GetRecipeInstructionResponseV0("Boil the ingredients")
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_RESPONSE_V1 = GetRecipeInstructionResponseV1("Mix the ingredients")
|
||||
|
||||
val BOIL_RECIPE_INSTRUCTION_RESPONSE_V1 = GetRecipeInstructionResponseV1("Boil the ingredients")
|
||||
|
||||
val MIX_RECIPE_INSTRUCTION_INFO = RecipeInstructionInfo("Mix the ingredients")
|
||||
|
||||
val PORRIDGE_RECIPE_RESPONSE_V0 = GetRecipeResponseV0(
|
||||
remoteId = 2,
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredients = listOf(
|
||||
SUGAR_RECIPE_INGREDIENT_RESPONSE_V0,
|
||||
MILK_RECIPE_INGREDIENT_RESPONSE_V0,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_RECIPE_INSTRUCTION_RESPONSE_V0,
|
||||
BOIL_RECIPE_INSTRUCTION_RESPONSE_V0
|
||||
),
|
||||
)
|
||||
|
||||
val PORRIDGE_RECIPE_RESPONSE_V1 = GetRecipeResponseV1(
|
||||
remoteId = "2",
|
||||
name = "Porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeIngredients = listOf(
|
||||
SUGAR_RECIPE_INGREDIENT_RESPONSE_V1,
|
||||
MILK_RECIPE_INGREDIENT_RESPONSE_V1,
|
||||
),
|
||||
recipeInstructions = listOf(
|
||||
MIX_RECIPE_INSTRUCTION_RESPONSE_V1,
|
||||
BOIL_RECIPE_INSTRUCTION_RESPONSE_V1
|
||||
),
|
||||
)
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V0 = AddRecipeInstructionV0("Mix the ingredients")
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V0 = AddRecipeInstructionV0("Boil the ingredients")
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V0 = AddRecipeIngredientV0("2 oz of white sugar")
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_REQUEST_V0 = AddRecipeIngredientV0("2 oz of white milk")
|
||||
|
||||
val ADD_RECIPE_REQUEST_SETTINGS_V0 = AddRecipeSettingsV0(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_ADD_RECIPE_REQUEST_V0 = AddRecipeRequestV0(
|
||||
name = "Porridge",
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf(
|
||||
MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V0,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V0,
|
||||
),
|
||||
recipeIngredient = listOf(
|
||||
MILK_ADD_RECIPE_INGREDIENT_REQUEST_V0,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V0,
|
||||
),
|
||||
settings = ADD_RECIPE_REQUEST_SETTINGS_V0
|
||||
)
|
||||
|
||||
val MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V1 = AddRecipeInstructionV1(
|
||||
id = "1",
|
||||
text = "Mix the ingredients",
|
||||
ingredientReferences = emptyList()
|
||||
)
|
||||
|
||||
val BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V1 = AddRecipeInstructionV1(
|
||||
id = "2",
|
||||
text = "Boil the ingredients",
|
||||
ingredientReferences = emptyList()
|
||||
)
|
||||
|
||||
val SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V1 = AddRecipeIngredientV1(
|
||||
id = "3",
|
||||
note = "2 oz of white sugar"
|
||||
)
|
||||
|
||||
val MILK_ADD_RECIPE_INGREDIENT_REQUEST_V1 = AddRecipeIngredientV1(
|
||||
id = "4",
|
||||
note = "2 oz of white milk"
|
||||
)
|
||||
|
||||
val ADD_RECIPE_REQUEST_SETTINGS_V1 = AddRecipeSettingsV1(disableComments = false, public = true)
|
||||
|
||||
val PORRIDGE_CREATE_RECIPE_REQUEST_V1 = CreateRecipeRequestV1(name = "Porridge")
|
||||
|
||||
val PORRIDGE_UPDATE_RECIPE_REQUEST_V1 = UpdateRecipeRequestV1(
|
||||
description = "A tasty porridge",
|
||||
recipeYield = "3 servings",
|
||||
recipeInstructions = listOf(
|
||||
MIX_ADD_RECIPE_INSTRUCTION_REQUEST_V1,
|
||||
BOIL_ADD_RECIPE_INSTRUCTION_REQUEST_V1,
|
||||
),
|
||||
recipeIngredient = listOf(
|
||||
MILK_ADD_RECIPE_INGREDIENT_REQUEST_V1,
|
||||
SUGAR_ADD_RECIPE_INGREDIENT_REQUEST_V1,
|
||||
),
|
||||
settings = ADD_RECIPE_REQUEST_SETTINGS_V1
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package gq.kirmanak.mealient.ui.add
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RecipeImplTestData.PORRIDGE_ADD_RECIPE_INFO
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
@@ -28,8 +29,7 @@ class AddRecipeViewModelTest {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var addRecipeRepo: AddRecipeRepo
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: AddRecipeViewModel
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import gq.kirmanak.mealient.data.baseurl.VersionInfo
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import gq.kirmanak.mealient.test.RobolectricTest
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
@@ -26,8 +27,7 @@ class BaseURLViewModelTest : RobolectricTest() {
|
||||
@MockK
|
||||
lateinit var versionDataSource: VersionDataSource
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: BaseURLViewModel
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package gq.kirmanak.mealient.ui.disclaimer
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
||||
import gq.kirmanak.mealient.logging.Logger
|
||||
import gq.kirmanak.mealient.test.FakeLogger
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -18,8 +19,7 @@ class DisclaimerViewModelTest {
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var storage: DisclaimerStorage
|
||||
|
||||
@MockK(relaxUnitFun = true)
|
||||
lateinit var logger: Logger
|
||||
private val logger: Logger = FakeLogger()
|
||||
|
||||
lateinit var subject: DisclaimerViewModel
|
||||
|
||||
|
||||
@@ -9,4 +9,22 @@ data class RecipeIngredientEntity(
|
||||
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "local_id") val localId: Long = 0,
|
||||
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
||||
@ColumnInfo(name = "note") val note: String,
|
||||
)
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RecipeIngredientEntity
|
||||
|
||||
if (recipeId != other.recipeId) return false
|
||||
if (note != other.note) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = recipeId.hashCode()
|
||||
result = 31 * result + note.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,22 @@ data class RecipeInstructionEntity(
|
||||
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "local_id") val localId: Long = 0,
|
||||
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
||||
@ColumnInfo(name = "text") val text: String,
|
||||
)
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as RecipeInstructionEntity
|
||||
|
||||
if (recipeId != other.recipeId) return false
|
||||
if (text != other.text) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = recipeId.hashCode()
|
||||
result = 31 * result + text.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,47 @@ data class UpdateRecipeRequestV1(
|
||||
data class AddRecipeIngredientV1(
|
||||
@SerialName("referenceId") val id: String,
|
||||
@SerialName("note") val note: String,
|
||||
)
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AddRecipeIngredientV1
|
||||
|
||||
if (note != other.note) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return note.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AddRecipeInstructionV1(
|
||||
@SerialName("id") val id: String,
|
||||
@SerialName("text") val text: String = "",
|
||||
@SerialName("ingredientReferences") val ingredientReferences: List<String>,
|
||||
)
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as AddRecipeInstructionV1
|
||||
|
||||
if (text != other.text) return false
|
||||
if (ingredientReferences != other.ingredientReferences) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = text.hashCode()
|
||||
result = 31 * result + ingredientReferences.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class AddRecipeSettingsV1(
|
||||
|
||||
Reference in New Issue
Block a user