test: add unit tests for use cases and ViewModel, add Compose UI test
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
package com.radiola.ui.stations
|
||||||
|
|
||||||
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
|
import androidx.compose.ui.test.onNodeWithText
|
||||||
|
import com.radiola.ui.theme.RadiolaTheme
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class StationsScreenTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val composeTestRule = createComposeRule()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun stationsScreen_showsTitle() {
|
||||||
|
composeTestRule.setContent {
|
||||||
|
RadiolaTheme {
|
||||||
|
StationsScreen(onStationClick = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
composeTestRule.onNodeWithText("Радио").assertIsDisplayed()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.radiola.domain.usecase
|
||||||
|
|
||||||
|
import com.radiola.domain.model.DeeplinkService
|
||||||
|
import com.radiola.domain.model.Track
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class SearchTrackInServiceUseCaseTest {
|
||||||
|
|
||||||
|
private val useCase = SearchTrackInServiceUseCase()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke returns correct Yandex Music URL`() {
|
||||||
|
val track = Track("Artist", "Song", null, "Record")
|
||||||
|
val url = useCase(track, DeeplinkService.YANDEX)
|
||||||
|
|
||||||
|
assertTrue(url.startsWith("https://music.yandex.ru/search"))
|
||||||
|
assertTrue(url.contains("Artist"))
|
||||||
|
assertTrue(url.contains("Song"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke returns correct Spotify URL`() {
|
||||||
|
val track = Track("Artist", "Song", null, "Record")
|
||||||
|
val url = useCase(track, DeeplinkService.SPOTIFY)
|
||||||
|
|
||||||
|
assertTrue(url.startsWith("https://open.spotify.com/search"))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.radiola.domain.usecase
|
||||||
|
|
||||||
|
import com.radiola.domain.model.Station
|
||||||
|
import com.radiola.domain.repository.FavoritesRepository
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class ToggleFavoriteUseCaseTest {
|
||||||
|
|
||||||
|
private val favoritesRepository: FavoritesRepository = mockk(relaxed = true)
|
||||||
|
private val useCase = ToggleFavoriteUseCase(favoritesRepository)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke adds favorite when not favorite`() = runTest {
|
||||||
|
val station = Station(1, "Record", "rr", "", "", "", emptyList(), 0)
|
||||||
|
coEvery { favoritesRepository.isFavorite(station.id) } returns flowOf(false)
|
||||||
|
|
||||||
|
useCase(station)
|
||||||
|
|
||||||
|
coVerify { favoritesRepository.addFavorite(station) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `invoke removes favorite when already favorite`() = runTest {
|
||||||
|
val station = Station(1, "Record", "rr", "", "", "", emptyList(), 0)
|
||||||
|
coEvery { favoritesRepository.isFavorite(station.id) } returns flowOf(true)
|
||||||
|
|
||||||
|
useCase(station)
|
||||||
|
|
||||||
|
coVerify { favoritesRepository.removeFavorite(station.id) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package com.radiola.ui.stations
|
||||||
|
|
||||||
|
import com.radiola.domain.model.Station
|
||||||
|
import com.radiola.domain.usecase.GetStationsUseCase
|
||||||
|
import com.radiola.domain.usecase.PlayStationUseCase
|
||||||
|
import com.radiola.domain.usecase.ToggleFavoriteUseCase
|
||||||
|
import io.mockk.coVerify
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||||
|
import kotlinx.coroutines.test.advanceUntilIdle
|
||||||
|
import kotlinx.coroutines.test.resetMain
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import kotlinx.coroutines.test.setMain
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
class StationsViewModelTest {
|
||||||
|
|
||||||
|
private val testDispatcher = StandardTestDispatcher()
|
||||||
|
private val getStationsUseCase: GetStationsUseCase = mockk()
|
||||||
|
private val playStationUseCase: PlayStationUseCase = mockk(relaxed = true)
|
||||||
|
private val toggleFavoriteUseCase: ToggleFavoriteUseCase = mockk(relaxed = true)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
Dispatchers.setMain(testDispatcher)
|
||||||
|
every { getStationsUseCase() } returns flowOf(
|
||||||
|
listOf(
|
||||||
|
Station(1, "Record", "rr", "", "", "Trans", listOf("trans"), 0),
|
||||||
|
Station(2, "Deep", "deep", "", "", "House", listOf("house"), 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
Dispatchers.resetMain()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `stations filtered by search query`() = runTest {
|
||||||
|
val viewModel = StationsViewModel(getStationsUseCase, playStationUseCase, toggleFavoriteUseCase)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
viewModel.onSearchQueryChange("Record")
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
assertEquals(1, viewModel.stations.value.size)
|
||||||
|
assertEquals("Record", viewModel.stations.value[0].name)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `playStation calls use case`() = runTest {
|
||||||
|
val viewModel = StationsViewModel(getStationsUseCase, playStationUseCase, toggleFavoriteUseCase)
|
||||||
|
val station = Station(1, "Record", "rr", "", "", "", emptyList(), 0)
|
||||||
|
|
||||||
|
viewModel.playStation(station)
|
||||||
|
advanceUntilIdle()
|
||||||
|
|
||||||
|
coVerify { playStationUseCase(station) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user