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:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_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
|
- name: Publish test reports
|
||||||
uses: mikepenz/action-junit-report@v3
|
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 "storePassword=$MEALIENT_KEY_STORE_PASSWORD" >> keystore.properties
|
||||||
echo "keyAlias=$MEALIENT_KEY_ALIAS" >> keystore.properties
|
echo "keyAlias=$MEALIENT_KEY_ALIAS" >> keystore.properties
|
||||||
echo "keyPassword=$MEALIENT_KEY_PASSWORD" >> 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
|
cp app/build/outputs/apk/release/*.apk mealient-release.apk
|
||||||
|
|
||||||
- name: Upload signed APK
|
- name: Upload signed APK
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ android {
|
|||||||
buildTypes {
|
buildTypes {
|
||||||
getByName("debug") {
|
getByName("debug") {
|
||||||
ext["enableCrashlytics"] = false
|
ext["enableCrashlytics"] = false
|
||||||
isTestCoverageEnabled = true
|
enableUnitTestCoverage = true
|
||||||
|
enableAndroidTestCoverage = true
|
||||||
}
|
}
|
||||||
getByName("release") {
|
getByName("release") {
|
||||||
isMinifyEnabled = true
|
isMinifyEnabled = true
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import gq.kirmanak.mealient.datasource.runCatchingExceptCancel
|
|||||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
||||||
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
import gq.kirmanak.mealient.datasource.v1.MealieDataSourceV1
|
||||||
import gq.kirmanak.mealient.extensions.*
|
import gq.kirmanak.mealient.extensions.*
|
||||||
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -22,6 +23,7 @@ class MealieDataSourceWrapper @Inject constructor(
|
|||||||
private val authRepo: AuthRepo,
|
private val authRepo: AuthRepo,
|
||||||
private val v0Source: MealieDataSourceV0,
|
private val v0Source: MealieDataSourceV0,
|
||||||
private val v1Source: MealieDataSourceV1,
|
private val v1Source: MealieDataSourceV1,
|
||||||
|
private val logger: Logger,
|
||||||
) : AddRecipeDataSource, RecipeDataSource {
|
) : AddRecipeDataSource, RecipeDataSource {
|
||||||
|
|
||||||
override suspend fun addRecipe(
|
override suspend fun addRecipe(
|
||||||
@@ -68,9 +70,11 @@ class MealieDataSourceWrapper @Inject constructor(
|
|||||||
val version = serverInfoRepo.getVersion()
|
val version = serverInfoRepo.getVersion()
|
||||||
return runCatchingExceptCancel { block(authHeader, url, version) }.getOrElse {
|
return runCatchingExceptCancel { block(authHeader, url, version) }.getOrElse {
|
||||||
if (it is NetworkError.Unauthorized) {
|
if (it is NetworkError.Unauthorized) {
|
||||||
|
logger.e { "Unauthorized, trying to invalidate token" }
|
||||||
authRepo.invalidateAuthHeader()
|
authRepo.invalidateAuthHeader()
|
||||||
// Trying again with new authentication header
|
// Trying again with new authentication header
|
||||||
val newHeader = authRepo.getAuthHeader()
|
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)
|
if (newHeader == authHeader) throw it else block(newHeader, url, version)
|
||||||
} else {
|
} else {
|
||||||
throw it
|
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.RecipeDao
|
||||||
import gq.kirmanak.mealient.database.recipe.entity.FullRecipeEntity
|
import gq.kirmanak.mealient.database.recipe.entity.FullRecipeEntity
|
||||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
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.toRecipeEntity
|
||||||
import gq.kirmanak.mealient.extensions.toRecipeIngredientEntity
|
import gq.kirmanak.mealient.extensions.toRecipeIngredientEntity
|
||||||
import gq.kirmanak.mealient.extensions.toRecipeInstructionEntity
|
import gq.kirmanak.mealient.extensions.toRecipeInstructionEntity
|
||||||
|
import gq.kirmanak.mealient.extensions.toRecipeSummaryEntity
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -29,7 +29,7 @@ class RecipeStorageImpl @Inject constructor(
|
|||||||
logger.v { "saveRecipes() called with $recipes" }
|
logger.v { "saveRecipes() called with $recipes" }
|
||||||
|
|
||||||
for (recipe in recipes) {
|
for (recipe in recipes) {
|
||||||
val recipeSummaryEntity = recipe.recipeEntity()
|
val recipeSummaryEntity = recipe.toRecipeSummaryEntity()
|
||||||
recipeDao.insertRecipe(recipeSummaryEntity)
|
recipeDao.insertRecipe(recipeSummaryEntity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ fun GetRecipeSummaryResponseV1.toRecipeSummaryInfo() = RecipeSummaryInfo(
|
|||||||
imageId = remoteId,
|
imageId = remoteId,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun RecipeSummaryInfo.recipeEntity() = RecipeSummaryEntity(
|
fun RecipeSummaryInfo.toRecipeSummaryEntity() = RecipeSummaryEntity(
|
||||||
remoteId = remoteId,
|
remoteId = remoteId,
|
||||||
name = name,
|
name = name,
|
||||||
slug = slug,
|
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_AUTH_HEADER
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
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_TOKEN
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import io.mockk.*
|
import io.mockk.*
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -34,8 +35,7 @@ class AuthRepoImplTest {
|
|||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var storage: AuthStorage
|
lateinit var storage: AuthStorage
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: AuthRepo
|
lateinit var subject: AuthRepo
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ class AuthRepoImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when authenticate successfully then saves to storage`() = runTest {
|
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 { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||||
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
coEvery { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||||
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
subject.authenticate(TEST_USERNAME, TEST_PASSWORD)
|
||||||
@@ -104,7 +104,7 @@ class AuthRepoImplTest {
|
|||||||
fun `when invalidate with credentials then calls authenticate`() = runTest {
|
fun `when invalidate with credentials then calls authenticate`() = runTest {
|
||||||
coEvery { storage.getEmail() } returns TEST_USERNAME
|
coEvery { storage.getEmail() } returns TEST_USERNAME
|
||||||
coEvery { storage.getPassword() } returns TEST_PASSWORD
|
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 { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||||
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
coEvery { dataSource.authenticate(eq(TEST_USERNAME), eq(TEST_PASSWORD)) } returns TEST_TOKEN
|
||||||
subject.invalidateAuthHeader()
|
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_AUTH_HEADER
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_PASSWORD
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_USERNAME
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
import gq.kirmanak.mealient.test.HiltRobolectricTest
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.impl.annotations.MockK
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -32,8 +32,7 @@ class AuthStorageImplTest : HiltRobolectricTest() {
|
|||||||
@ApplicationContext
|
@ApplicationContext
|
||||||
lateinit var context: Context
|
lateinit var context: Context
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: AuthStorage
|
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 com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
|
import gq.kirmanak.mealient.data.baseurl.impl.ServerInfoStorageImpl
|
||||||
import gq.kirmanak.mealient.data.storage.PreferencesStorage
|
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.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
@@ -15,7 +17,7 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class ServerInfoStorageImplTest {
|
class ServerInfoStorageTest {
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var preferencesStorage: PreferencesStorage
|
lateinit var preferencesStorage: PreferencesStorage
|
||||||
@@ -34,26 +36,43 @@ class ServerInfoStorageImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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
|
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns null
|
||||||
assertThat(subject.getBaseURL()).isNull()
|
assertThat(subject.getBaseURL()).isNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when getBaseUrl and preferences storage has value then value`() = runTest {
|
fun `when preferences storage has value expect getBaseUrl return value`() = runTest {
|
||||||
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns "baseUrl"
|
coEvery { preferencesStorage.getValue(eq(baseUrlKey)) } returns TEST_BASE_URL
|
||||||
assertThat(subject.getBaseURL()).isEqualTo("baseUrl")
|
assertThat(subject.getBaseURL()).isEqualTo(TEST_BASE_URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when storeBaseURL then calls preferences storage`() = runTest {
|
fun `when storeBaseURL expect call to preferences storage`() = runTest {
|
||||||
subject.storeBaseURL("baseUrl", "v0.5.6")
|
subject.storeBaseURL(TEST_BASE_URL, TEST_VERSION)
|
||||||
coVerify {
|
coVerify {
|
||||||
preferencesStorage.baseUrlKey
|
|
||||||
preferencesStorage.storeValues(
|
preferencesStorage.storeValues(
|
||||||
eq(Pair(baseUrlKey, "baseUrl")),
|
eq(Pair(baseUrlKey, TEST_BASE_URL)),
|
||||||
eq(Pair(serverVersionKey, "v0.5.6")),
|
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
|
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.auth.AuthRepo
|
||||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.datasource.NetworkError
|
import gq.kirmanak.mealient.datasource.NetworkError
|
||||||
import gq.kirmanak.mealient.datasource.v0.MealieDataSourceV0
|
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.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_AUTH_HEADER
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V0
|
||||||
import io.mockk.MockKAnnotations
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_SERVER_VERSION_V1
|
||||||
import io.mockk.coEvery
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import io.mockk.coVerifyAll
|
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.impl.annotations.MockK
|
||||||
import io.mockk.mockk
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@@ -37,30 +48,153 @@ class MealieDataSourceWrapperTest {
|
|||||||
|
|
||||||
lateinit var subject: MealieDataSourceWrapper
|
lateinit var subject: MealieDataSourceWrapper
|
||||||
|
|
||||||
|
private val logger: Logger = FakeLogger()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockKAnnotations.init(this)
|
MockKAnnotations.init(this)
|
||||||
subject = MealieDataSourceWrapper(serverInfoRepo, authRepo, v0Source, v1Source)
|
subject = MealieDataSourceWrapper(serverInfoRepo, authRepo, v0Source, v1Source, logger)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when withAuthHeader fails with Unauthorized then invalidates auth`() = runTest {
|
fun `when makeCall fails with Unauthorized expect it to invalidate token`() = runTest {
|
||||||
coEvery { serverInfoRepo.getVersion() } returns TEST_SERVER_VERSION
|
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 { serverInfoRepo.requireUrl() } returns TEST_BASE_URL
|
||||||
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
|
coEvery { authRepo.getAuthHeader() } returns null andThen TEST_AUTH_HEADER
|
||||||
coEvery {
|
|
||||||
v0Source.requestRecipeInfo(eq(TEST_BASE_URL), isNull(), eq("cake"))
|
subject.requestRecipeInfo(slug)
|
||||||
} throws NetworkError.Unauthorized(IOException())
|
|
||||||
val successResponse = mockk<GetRecipeResponseV0>(relaxed = true)
|
coVerifySequence {
|
||||||
coEvery {
|
|
||||||
v0Source.requestRecipeInfo(eq(TEST_BASE_URL), eq(TEST_AUTH_HEADER), eq("cake"))
|
|
||||||
} returns successResponse
|
|
||||||
subject.requestRecipeInfo("cake")
|
|
||||||
coVerifyAll {
|
|
||||||
authRepo.getAuthHeader()
|
authRepo.getAuthHeader()
|
||||||
authRepo.invalidateAuthHeader()
|
authRepo.invalidateAuthHeader()
|
||||||
authRepo.getAuthHeader()
|
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.HiltRobolectricTest
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.BREAD_INGREDIENT
|
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_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.CAKE_RECIPE_SUMMARY_ENTITY
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.FULL_CAKE_INFO_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.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_CAKE_RECIPE_INSTRUCTION_ENTITY
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.MIX_INSTRUCTION
|
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.PORRIDGE_RECIPE_SUMMARY_ENTITY
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.RECIPE_SUMMARY_CAKE
|
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 gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -61,16 +61,16 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `when saveRecipeInfo then saves recipe info`() = runTest {
|
fun `when saveRecipeInfo then saves recipe info`() = runTest {
|
||||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")
|
val actual = appDb.recipeDao().queryFullRecipeInfo("1")
|
||||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when saveRecipeInfo with two then saves second`() = runTest {
|
fun `when saveRecipeInfo with two then saves second`() = runTest {
|
||||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE))
|
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE, RECIPE_SUMMARY_PORRIDGE_V0))
|
||||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||||
subject.saveRecipeInfo(GET_PORRIDGE_RESPONSE)
|
subject.saveRecipeInfo(PORRIDGE_FULL_RECIPE_INFO)
|
||||||
val actual = appDb.recipeDao().queryFullRecipeInfo("2")
|
val actual = appDb.recipeDao().queryFullRecipeInfo("2")
|
||||||
assertThat(actual).isEqualTo(FULL_PORRIDGE_INFO_ENTITY)
|
assertThat(actual).isEqualTo(FULL_PORRIDGE_INFO_ENTITY)
|
||||||
}
|
}
|
||||||
@@ -78,8 +78,8 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `when saveRecipeInfo secondly then overwrites ingredients`() = runTest {
|
fun `when saveRecipeInfo secondly then overwrites ingredients`() = runTest {
|
||||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||||
val newRecipe = GET_CAKE_RESPONSE.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeIngredients = listOf(BREAD_INGREDIENT))
|
||||||
subject.saveRecipeInfo(newRecipe)
|
subject.saveRecipeInfo(newRecipe)
|
||||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeIngredients
|
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeIngredients
|
||||||
val expected = listOf(CAKE_BREAD_RECIPE_INGREDIENT_ENTITY.copy(localId = 3))
|
val expected = listOf(CAKE_BREAD_RECIPE_INGREDIENT_ENTITY.copy(localId = 3))
|
||||||
@@ -89,8 +89,8 @@ class RecipeStorageImplTest : HiltRobolectricTest() {
|
|||||||
@Test
|
@Test
|
||||||
fun `when saveRecipeInfo secondly then overwrites instructions`() = runTest {
|
fun `when saveRecipeInfo secondly then overwrites instructions`() = runTest {
|
||||||
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
subject.saveRecipes(listOf(RECIPE_SUMMARY_CAKE))
|
||||||
subject.saveRecipeInfo(GET_CAKE_RESPONSE)
|
subject.saveRecipeInfo(CAKE_FULL_RECIPE_INFO)
|
||||||
val newRecipe = GET_CAKE_RESPONSE.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
val newRecipe = CAKE_FULL_RECIPE_INFO.copy(recipeInstructions = listOf(MIX_INSTRUCTION))
|
||||||
subject.saveRecipeInfo(newRecipe)
|
subject.saveRecipeInfo(newRecipe)
|
||||||
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeInstructions
|
val actual = appDb.recipeDao().queryFullRecipeInfo("1")?.recipeInstructions
|
||||||
val expected = listOf(MIX_CAKE_RECIPE_INSTRUCTION_ENTITY.copy(localId = 3))
|
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 com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
import gq.kirmanak.mealient.data.baseurl.ServerInfoRepo
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
@@ -19,8 +20,7 @@ class RecipeImageUrlProviderImplTest {
|
|||||||
@MockK
|
@MockK
|
||||||
lateinit var serverInfoRepo: ServerInfoRepo
|
lateinit var serverInfoRepo: ServerInfoRepo
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
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.data.recipes.network.RecipeDataSource
|
||||||
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
import gq.kirmanak.mealient.database.recipe.entity.RecipeSummaryEntity
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
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.FULL_CAKE_INFO_ENTITY
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.GET_CAKE_RESPONSE
|
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
@@ -19,7 +20,7 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
class RecipeRepoImplTest {
|
class RecipeRepoTest {
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var storage: RecipeStorage
|
lateinit var storage: RecipeStorage
|
||||||
@@ -33,8 +34,7 @@ class RecipeRepoImplTest {
|
|||||||
@MockK
|
@MockK
|
||||||
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: RecipeRepo
|
lateinit var subject: RecipeRepo
|
||||||
|
|
||||||
@@ -45,26 +45,32 @@ class RecipeRepoImplTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when loadRecipeInfo then loads recipe`() = runTest {
|
fun `when loadRecipeInfo expect return value from data source`() = runTest {
|
||||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns GET_CAKE_RESPONSE
|
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns CAKE_FULL_RECIPE_INFO
|
||||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||||
val actual = subject.loadRecipeInfo("1", "cake")
|
val actual = subject.loadRecipeInfo("1", "cake")
|
||||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when loadRecipeInfo then saves to DB`() = runTest {
|
fun `when loadRecipeInfo expect call to storage`() = runTest {
|
||||||
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns GET_CAKE_RESPONSE
|
coEvery { dataSource.requestRecipeInfo(eq("cake")) } returns CAKE_FULL_RECIPE_INFO
|
||||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||||
subject.loadRecipeInfo("1", "cake")
|
subject.loadRecipeInfo("1", "cake")
|
||||||
coVerify { storage.saveRecipeInfo(eq(GET_CAKE_RESPONSE)) }
|
coVerify { storage.saveRecipeInfo(eq(CAKE_FULL_RECIPE_INFO)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@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 { dataSource.requestRecipeInfo(eq("cake")) } throws RuntimeException()
|
||||||
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
coEvery { storage.queryRecipeInfo(eq("1")) } returns FULL_CAKE_INFO_ENTITY
|
||||||
val actual = subject.loadRecipeInfo("1", "cake")
|
val actual = subject.loadRecipeInfo("1", "cake")
|
||||||
assertThat(actual).isEqualTo(FULL_CAKE_INFO_ENTITY)
|
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.database.recipe.entity.RecipeSummaryEntity
|
||||||
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
import gq.kirmanak.mealient.datasource.NetworkError.Unauthorized
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
import gq.kirmanak.mealient.test.RecipeImplTestData.TEST_RECIPE_SUMMARIES
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
@@ -39,8 +40,7 @@ class RecipesRemoteMediatorTest {
|
|||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
lateinit var pagingSourceFactory: InvalidatingPagingSourceFactory<Int, RecipeSummaryEntity>
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
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_TOKEN = "TEST_TOKEN"
|
||||||
const val TEST_AUTH_HEADER = "Bearer TEST_TOKEN"
|
const val TEST_AUTH_HEADER = "Bearer TEST_TOKEN"
|
||||||
const val TEST_VERSION = "v0.5.6"
|
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.AddRecipeIngredientInfo
|
||||||
import gq.kirmanak.mealient.data.add.AddRecipeInstructionInfo
|
import gq.kirmanak.mealient.data.add.AddRecipeInstructionInfo
|
||||||
import gq.kirmanak.mealient.data.add.AddRecipeSettingsInfo
|
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.FullRecipeInfo
|
||||||
import gq.kirmanak.mealient.data.recipes.network.RecipeIngredientInfo
|
import gq.kirmanak.mealient.data.recipes.network.RecipeIngredientInfo
|
||||||
import gq.kirmanak.mealient.data.recipes.network.RecipeInstructionInfo
|
import gq.kirmanak.mealient.data.recipes.network.RecipeInstructionInfo
|
||||||
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
import gq.kirmanak.mealient.data.recipes.network.RecipeSummaryInfo
|
||||||
import gq.kirmanak.mealient.database.recipe.entity.*
|
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.LocalDate
|
||||||
import kotlinx.datetime.LocalDateTime
|
import kotlinx.datetime.LocalDateTime
|
||||||
|
|
||||||
@@ -23,7 +27,7 @@ object RecipeImplTestData {
|
|||||||
imageId = "cake",
|
imageId = "cake",
|
||||||
)
|
)
|
||||||
|
|
||||||
val RECIPE_SUMMARY_PORRIDGE = RecipeSummaryInfo(
|
val RECIPE_SUMMARY_PORRIDGE_V0 = RecipeSummaryInfo(
|
||||||
remoteId = "2",
|
remoteId = "2",
|
||||||
name = "Porridge",
|
name = "Porridge",
|
||||||
slug = "porridge",
|
slug = "porridge",
|
||||||
@@ -33,7 +37,17 @@ object RecipeImplTestData {
|
|||||||
imageId = "porridge",
|
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(
|
val CAKE_RECIPE_SUMMARY_ENTITY = RecipeSummaryEntity(
|
||||||
remoteId = "1",
|
remoteId = "1",
|
||||||
@@ -55,7 +69,7 @@ object RecipeImplTestData {
|
|||||||
imageId = "porridge",
|
imageId = "porridge",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val SUGAR_INGREDIENT = RecipeIngredientInfo(
|
val SUGAR_INGREDIENT = RecipeIngredientInfo(
|
||||||
note = "2 oz of white sugar",
|
note = "2 oz of white sugar",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -79,7 +93,7 @@ object RecipeImplTestData {
|
|||||||
text = "Boil the ingredients"
|
text = "Boil the ingredients"
|
||||||
)
|
)
|
||||||
|
|
||||||
val GET_CAKE_RESPONSE = FullRecipeInfo(
|
val CAKE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||||
remoteId = "1",
|
remoteId = "1",
|
||||||
name = "Cake",
|
name = "Cake",
|
||||||
recipeYield = "4 servings",
|
recipeYield = "4 servings",
|
||||||
@@ -87,7 +101,7 @@ object RecipeImplTestData {
|
|||||||
recipeInstructions = listOf(MIX_INSTRUCTION, BAKE_INSTRUCTION)
|
recipeInstructions = listOf(MIX_INSTRUCTION, BAKE_INSTRUCTION)
|
||||||
)
|
)
|
||||||
|
|
||||||
val GET_PORRIDGE_RESPONSE = FullRecipeInfo(
|
val PORRIDGE_FULL_RECIPE_INFO = FullRecipeInfo(
|
||||||
remoteId = "2",
|
remoteId = "2",
|
||||||
name = "Porridge",
|
name = "Porridge",
|
||||||
recipeYield = "3 servings",
|
recipeYield = "3 servings",
|
||||||
@@ -96,30 +110,26 @@ object RecipeImplTestData {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val MIX_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
val MIX_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||||
localId = 1,
|
|
||||||
recipeId = "1",
|
recipeId = "1",
|
||||||
text = "Mix the ingredients",
|
text = "Mix the ingredients",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
private val BAKE_CAKE_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||||
localId = 2,
|
|
||||||
recipeId = "1",
|
recipeId = "1",
|
||||||
text = "Bake the ingredients",
|
text = "Bake the ingredients",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CAKE_RECIPE_ENTITY = RecipeEntity(
|
val CAKE_RECIPE_ENTITY = RecipeEntity(
|
||||||
remoteId = "1",
|
remoteId = "1",
|
||||||
recipeYield = "4 servings"
|
recipeYield = "4 servings"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
val CAKE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||||
localId = 1,
|
|
||||||
recipeId = "1",
|
recipeId = "1",
|
||||||
note = "2 oz of white sugar",
|
note = "2 oz of white sugar",
|
||||||
)
|
)
|
||||||
|
|
||||||
val CAKE_BREAD_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
val CAKE_BREAD_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||||
localId = 2,
|
|
||||||
recipeId = "1",
|
recipeId = "1",
|
||||||
note = "2 oz of white bread",
|
note = "2 oz of white bread",
|
||||||
)
|
)
|
||||||
@@ -143,25 +153,21 @@ object RecipeImplTestData {
|
|||||||
)
|
)
|
||||||
|
|
||||||
private val PORRIDGE_MILK_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
private val PORRIDGE_MILK_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||||
localId = 4,
|
|
||||||
recipeId = "2",
|
recipeId = "2",
|
||||||
note = "2 oz of white milk",
|
note = "2 oz of white milk",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
private val PORRIDGE_SUGAR_RECIPE_INGREDIENT_ENTITY = RecipeIngredientEntity(
|
||||||
localId = 3,
|
|
||||||
recipeId = "2",
|
recipeId = "2",
|
||||||
note = "2 oz of white sugar",
|
note = "2 oz of white sugar",
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
private val PORRIDGE_MIX_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||||
localId = 3,
|
|
||||||
recipeId = "2",
|
recipeId = "2",
|
||||||
text = "Mix the ingredients"
|
text = "Mix the ingredients"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
private val PORRIDGE_BOIL_RECIPE_INSTRUCTION_ENTITY = RecipeInstructionEntity(
|
||||||
localId = 4,
|
|
||||||
recipeId = "2",
|
recipeId = "2",
|
||||||
text = "Boil the ingredients"
|
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(
|
val PORRIDGE_ADD_RECIPE_INFO = AddRecipeInfo(
|
||||||
name = "Porridge",
|
name = "Porridge",
|
||||||
description = "Tasty breakfast",
|
description = "A tasty porridge",
|
||||||
recipeYield = "5 servings",
|
recipeYield = "3 servings",
|
||||||
recipeIngredient = listOf(
|
recipeIngredient = listOf(
|
||||||
AddRecipeIngredientInfo("Milk"),
|
MILK_ADD_RECIPE_INGREDIENT_INFO,
|
||||||
AddRecipeIngredientInfo("Sugar"),
|
SUGAR_ADD_RECIPE_INGREDIENT_INFO,
|
||||||
AddRecipeIngredientInfo("Salt"),
|
|
||||||
AddRecipeIngredientInfo("Porridge"),
|
|
||||||
),
|
),
|
||||||
recipeInstructions = listOf(
|
recipeInstructions = listOf(
|
||||||
AddRecipeInstructionInfo("Mix"),
|
MIX_ADD_RECIPE_INSTRUCTION_INFO,
|
||||||
AddRecipeInstructionInfo("Cook"),
|
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 com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
import gq.kirmanak.mealient.data.add.AddRecipeRepo
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
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_ADD_RECIPE_INFO
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
@@ -28,8 +29,7 @@ class AddRecipeViewModelTest {
|
|||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var addRecipeRepo: AddRecipeRepo
|
lateinit var addRecipeRepo: AddRecipeRepo
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: AddRecipeViewModel
|
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.logging.Logger
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_BASE_URL
|
||||||
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
import gq.kirmanak.mealient.test.AuthImplTestData.TEST_VERSION
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import gq.kirmanak.mealient.test.RobolectricTest
|
import gq.kirmanak.mealient.test.RobolectricTest
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
@@ -26,8 +27,7 @@ class BaseURLViewModelTest : RobolectricTest() {
|
|||||||
@MockK
|
@MockK
|
||||||
lateinit var versionDataSource: VersionDataSource
|
lateinit var versionDataSource: VersionDataSource
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: BaseURLViewModel
|
lateinit var subject: BaseURLViewModel
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package gq.kirmanak.mealient.ui.disclaimer
|
|||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
import gq.kirmanak.mealient.data.disclaimer.DisclaimerStorage
|
||||||
import gq.kirmanak.mealient.logging.Logger
|
import gq.kirmanak.mealient.logging.Logger
|
||||||
|
import gq.kirmanak.mealient.test.FakeLogger
|
||||||
import io.mockk.MockKAnnotations
|
import io.mockk.MockKAnnotations
|
||||||
import io.mockk.impl.annotations.MockK
|
import io.mockk.impl.annotations.MockK
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
@@ -18,8 +19,7 @@ class DisclaimerViewModelTest {
|
|||||||
@MockK(relaxUnitFun = true)
|
@MockK(relaxUnitFun = true)
|
||||||
lateinit var storage: DisclaimerStorage
|
lateinit var storage: DisclaimerStorage
|
||||||
|
|
||||||
@MockK(relaxUnitFun = true)
|
private val logger: Logger = FakeLogger()
|
||||||
lateinit var logger: Logger
|
|
||||||
|
|
||||||
lateinit var subject: DisclaimerViewModel
|
lateinit var subject: DisclaimerViewModel
|
||||||
|
|
||||||
|
|||||||
@@ -9,4 +9,22 @@ data class RecipeIngredientEntity(
|
|||||||
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "local_id") val localId: Long = 0,
|
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "local_id") val localId: Long = 0,
|
||||||
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
||||||
@ColumnInfo(name = "note") val note: 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,
|
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "local_id") val localId: Long = 0,
|
||||||
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
@ColumnInfo(name = "recipe_id") val recipeId: String,
|
||||||
@ColumnInfo(name = "text") val text: 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(
|
data class AddRecipeIngredientV1(
|
||||||
@SerialName("referenceId") val id: String,
|
@SerialName("referenceId") val id: String,
|
||||||
@SerialName("note") val note: 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
|
@Serializable
|
||||||
data class AddRecipeInstructionV1(
|
data class AddRecipeInstructionV1(
|
||||||
@SerialName("id") val id: String,
|
@SerialName("id") val id: String,
|
||||||
@SerialName("text") val text: String = "",
|
@SerialName("text") val text: String = "",
|
||||||
@SerialName("ingredientReferences") val ingredientReferences: List<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
|
@Serializable
|
||||||
data class AddRecipeSettingsV1(
|
data class AddRecipeSettingsV1(
|
||||||
|
|||||||
Reference in New Issue
Block a user