Skip to content

Commit

Permalink
domain tests
Browse files Browse the repository at this point in the history
  • Loading branch information
RubyLichtenstein committed Sep 26, 2023
1 parent 058ab10 commit aae0a45
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 34 deletions.
1 change: 1 addition & 0 deletions domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")

testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")
testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
testImplementation("org.junit.jupiter:junit-jupiter-params:$junitVersion")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.rubylichtenstein.domain.common

import com.rubylichtenstein.domain.common.AsyncResult
import com.rubylichtenstein.domain.common.asAsyncResult
import com.rubylichtenstein.domain.common.mapSuccess
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.toList
Expand Down Expand Up @@ -54,4 +51,11 @@ class AsyncResultTest {
val result = flow.drop(1).first()
assertTrue(result is AsyncResult.Error && result.exception?.message == "Error")
}

@Test
fun `asAsyncResult emits Error`() = runTest {
val flow = flow { emit(AsyncResult.Error(Exception("Error"))) }.toList()
val result = flow.first()
assertTrue(result.exception?.message == "Error")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.rubylichtenstein.domain.favorites

import com.rubylichtenstein.domain.common.AsyncResult
import com.rubylichtenstein.domain.common.asAsyncResult
import com.rubylichtenstein.domain.images.DogImageEntity
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map

class FakeFavoritesRepository(
initialDogImages: List<DogImageEntity>
) : FavoritesRepository {

private val _images = MutableStateFlow(initialDogImages)

override val favoriteImagesFlow: Flow<AsyncResult<List<DogImageEntity>>> =
_images.map { images ->
images.filter { it.isFavorite }
}.asAsyncResult()

override suspend fun updateFavoriteStatus(url: String, isFavorite: Boolean) {
val currentImages = _images.value.toMutableList()

// Find the image with the given URL
val imageIndex = currentImages.indexOfFirst { it.url == url }

if (imageIndex != -1) {
// Update the isFavorite status of the image
val updatedImage = currentImages[imageIndex].copy(isFavorite = isFavorite)
currentImages[imageIndex] = updatedImage
}

_images.value = currentImages
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.rubylichtenstein.domain.favorites

import app.cash.turbine.test
import com.rubylichtenstein.domain.common.AsyncResult
import com.rubylichtenstein.domain.images.DogImageEntity
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class GetFavoriteImagesUseCaseTest {

private lateinit var useCase: GetFavoriteImagesUseCase
private lateinit var fakeFavoritesRepository: FakeFavoritesRepository

@BeforeEach
fun setUp() {
val element1 = DogImageEntity(
url = "sampleUrl1.com",
isFavorite = false,
breedName = "Dog",
breedKey = "dog"
)

val element2 = DogImageEntity(
url = "sampleUrl2.com",
isFavorite = true,
breedName = "Dog",
breedKey = "dog"
)

val images = listOf(
element1,
element2
)

fakeFavoritesRepository = FakeFavoritesRepository(images)
useCase = GetFavoriteImagesUseCase(fakeFavoritesRepository)
}

@Test
fun `when invoke is called, it should return favorite images from the repository`() = runTest {
useCase.invoke().test {
Assertions.assertEquals(AsyncResult.Loading, awaitItem())
val initialState = awaitItem() as AsyncResult.Success
Assertions.assertEquals(1, initialState.data.size)
Assertions.assertEquals("sampleUrl2.com", initialState.data[0].url)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,12 @@ package com.rubylichtenstein.domain.favorites

import app.cash.turbine.test
import com.rubylichtenstein.domain.common.AsyncResult
import com.rubylichtenstein.domain.common.asAsyncResult
import com.rubylichtenstein.domain.images.DogImageEntity
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test


class FakeFavoritesRepository(
initialDogImages: List<DogImageEntity>
) : FavoritesRepository {

private val _images = MutableStateFlow(initialDogImages)

override val favoriteImagesFlow: Flow<AsyncResult<List<DogImageEntity>>> =
_images.map { images ->
images.filter { it.isFavorite }
}.asAsyncResult()

override suspend fun updateFavoriteStatus(url: String, isFavorite: Boolean) {
val currentImages = _images.value.toMutableList()

// Find the image with the given URL
val imageIndex = currentImages.indexOfFirst { it.url == url }

if (imageIndex != -1) {
// Update the isFavorite status of the image
val updatedImage = currentImages[imageIndex].copy(isFavorite = isFavorite)
currentImages[imageIndex] = updatedImage
}

_images.value = currentImages
}
}

class ToggleFavoriteUseCaseTest {

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.rubylichtenstein.domain.images

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class DogImageEntityKtTest {

@Test
fun `when subBreed is null, only breed should be returned`() {
// Given
val breed = "golden"
val subBreed: String? = null

// When
val result = buildBreedKey(subBreed, breed)

// Then
assertEquals(breed, result)
}

@Test
fun `when subBreed is not null, breed and subBreed should be concatenated with a slash`() {
// Given
val breed = "golden"
val subBreed = "retriever"

// When
val result = buildBreedKey(subBreed, breed)

// Then
assertEquals("$breed/$subBreed", result)
}

@Test
fun `when breed is empty and subBreed is not null, only slash and subBreed should be returned`() {
// Given
val breed = ""
val subBreed = "retriever"

// When
val result = buildBreedKey(subBreed, breed)

// Then
assertEquals("/$subBreed", result)
}

@Test
fun `when both breed and subBreed are empty, only a slash should be returned`() {
// Given
val breed = ""
val subBreed = ""

// When
val result = buildBreedKey(subBreed, breed)

// Then
assertEquals("/", result)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.rubylichtenstein.domain.images

import com.rubylichtenstein.domain.common.AsyncResult
import com.rubylichtenstein.domain.common.asAsyncResult
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.map

class FakeImagesRepository(
initialDogImages: List<DogImageEntity>
) : ImagesRepository {

private val _images = MutableStateFlow(initialDogImages)

override fun getImagesByBreed(breedKey: String): Flow<AsyncResult<List<DogImageEntity>>> {
return _images.map { images ->
images.filter { it.breedKey == breedKey }
}.asAsyncResult()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.rubylichtenstein.domain.images

import app.cash.turbine.test
import com.rubylichtenstein.domain.common.AsyncResult
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test

class GetBreedImagesUseCaseTest {
private lateinit var useCase: GetBreedImagesUseCase
private lateinit var fakeImagesRepository: FakeImagesRepository

@BeforeEach
fun setUp() {
val element1 = DogImageEntity(
url = "sampleUrl1.com",
isFavorite = false,
breedName = "Dog",
breedKey = "Dog"
)

val element2 = DogImageEntity(
url = "sampleUrl2.com",
isFavorite = true,
breedName = "Dog",
breedKey = "Dog"
)

val images = listOf(
element1,
element2
)

fakeImagesRepository = FakeImagesRepository(images)
useCase = GetBreedImagesUseCase(fakeImagesRepository)
}

@Test
operator fun invoke() = runTest {
useCase.invoke("Dog").test {
Assertions.assertEquals(AsyncResult.Loading, awaitItem())
val initialState = awaitItem() as AsyncResult.Success
Assertions.assertEquals(2, initialState.data.size)
}
}
}

0 comments on commit aae0a45

Please sign in to comment.