mirror of
https://github.com/hmalik144/Weather-apps.git
synced 2026-03-18 07:26:04 +00:00
Imperial units (#24)
- change location retrieval accuracy - change location retrieval caching from location provider - expand unit test suite - code refactoring - Imperial units added - UI test for unit change
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
package com.appttude.h_mal.atlas_weather.data
|
||||
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.RepositoryImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.utils.BaseTest
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.InjectMockKs
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.IOException
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class WeatherSourceTest : BaseTest() {
|
||||
|
||||
@InjectMockKs
|
||||
lateinit var weatherSource: WeatherSource
|
||||
|
||||
@MockK
|
||||
lateinit var repository: RepositoryImpl
|
||||
|
||||
@MockK
|
||||
lateinit var locationProvider: LocationProviderImpl
|
||||
|
||||
private lateinit var weatherResponse: WeatherResponse
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
weatherResponse = getTestData("weather_sample.json", WeatherResponse::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocation_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
val fullWeather = FullWeather(weatherResponse).apply {
|
||||
temperatureUnit = "°C"
|
||||
locationString = CURRENT_LOCATION
|
||||
}
|
||||
val entityItem = EntityItem(CURRENT_LOCATION, fullWeather)
|
||||
|
||||
|
||||
// Act
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns latlon
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
}.returns(weatherResponse)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
every { repository.getUnitType() } returns UnitType.METRIC
|
||||
every { repository.saveLastSavedAt(CURRENT_LOCATION) } returns Unit
|
||||
coEvery { repository.saveCurrentWeatherToRoom(entityItem) } returns Unit
|
||||
|
||||
// Assert
|
||||
val result =
|
||||
runBlocking { weatherSource.getWeather(latlon, locationType = LocationType.City) }
|
||||
assertEquals(result, fullWeather)
|
||||
}
|
||||
|
||||
@Test(expected = IOException::class)
|
||||
fun fetchDataForSingleLocation_failedWeatherApi_invalidReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
|
||||
// Act
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
} throws IOException("Unable fetch data")
|
||||
|
||||
// Assert
|
||||
runBlocking { weatherSource.getWeather(latlon) }
|
||||
}
|
||||
|
||||
@Test(expected = IOException::class)
|
||||
fun fetchDataForSingleLocation_failedLocation_invalidReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
|
||||
// Act
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
} returns weatherResponse
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
}.throws(IOException())
|
||||
|
||||
// Assert
|
||||
runBlocking { weatherSource.getWeather(latlon) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun searchAboveFallbackTime_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
val fullWeather = FullWeather(weatherResponse).apply {
|
||||
temperatureUnit = "°C"
|
||||
locationString = CURRENT_LOCATION
|
||||
}
|
||||
val entityItem = EntityItem(CURRENT_LOCATION, fullWeather)
|
||||
|
||||
// Act
|
||||
coEvery { repository.getSingleWeather(CURRENT_LOCATION) }.returns(entityItem)
|
||||
coEvery { repository.saveCurrentWeatherToRoom(entityItem) }.returns(Unit)
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(false)
|
||||
|
||||
// Assert
|
||||
val result = runBlocking { weatherSource.getWeather(latlon) }
|
||||
assertEquals(result, fullWeather)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun forceFetchDataForSingleLocation_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
val fullWeather = FullWeather(weatherResponse).apply {
|
||||
temperatureUnit = "°C"
|
||||
locationString = CURRENT_LOCATION
|
||||
}
|
||||
val entityItem = EntityItem(CURRENT_LOCATION, fullWeather)
|
||||
|
||||
// Act
|
||||
coEvery { repository.loadSingleCurrentWeatherFromRoom(CURRENT_LOCATION) } returns entityItem
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns latlon
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
}.returns(weatherResponse)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
every { repository.getUnitType() } returns UnitType.METRIC
|
||||
every { repository.saveLastSavedAt(CURRENT_LOCATION) } returns Unit
|
||||
coEvery { repository.saveCurrentWeatherToRoom(entityItem) } returns Unit
|
||||
|
||||
// Assert
|
||||
val result = runBlocking {
|
||||
weatherSource.forceFetchWeather(
|
||||
latlon,
|
||||
locationType = LocationType.City
|
||||
)
|
||||
}
|
||||
assertEquals(result, fullWeather)
|
||||
}
|
||||
}
|
||||
@@ -6,21 +6,17 @@ import com.appttude.h_mal.atlas_weather.data.prefs.LOCATION_CONST
|
||||
import com.appttude.h_mal.atlas_weather.data.prefs.PreferenceProvider
|
||||
import com.appttude.h_mal.atlas_weather.data.room.AppDatabase
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.model.types.UnitType
|
||||
import com.appttude.h_mal.atlas_weather.utils.BaseTest
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.doAnswer
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coJustRun
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.justRun
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import retrofit2.Response
|
||||
import java.io.IOException
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
@@ -94,6 +90,7 @@ class RepositoryImplTest : BaseTest() {
|
||||
|
||||
//Act
|
||||
//create a successful retrofit response
|
||||
every { prefs.getUnitsType() } returns (UnitType.METRIC)
|
||||
coEvery { api.getFromApi("", "") }.returns(mockResponse)
|
||||
|
||||
// Assert
|
||||
@@ -110,6 +107,7 @@ class RepositoryImplTest : BaseTest() {
|
||||
|
||||
//Act
|
||||
//create a successful retrofit response
|
||||
every { prefs.getUnitsType() } returns (UnitType.METRIC)
|
||||
coEvery { api.getFromApi(any(), any()) } returns (mockResponse)
|
||||
|
||||
// Assert
|
||||
|
||||
@@ -1,26 +1,31 @@
|
||||
package com.appttude.h_mal.atlas_weather.viewmodel
|
||||
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.appttude.h_mal.atlas_weather.data.WeatherSource
|
||||
import com.appttude.h_mal.atlas_weather.data.location.LocationProviderImpl
|
||||
import com.appttude.h_mal.atlas_weather.data.network.response.forecast.WeatherResponse
|
||||
import com.appttude.h_mal.atlas_weather.data.repository.Repository
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.CURRENT_LOCATION
|
||||
import com.appttude.h_mal.atlas_weather.data.room.entity.EntityItem
|
||||
import com.appttude.h_mal.atlas_weather.model.ViewState
|
||||
import com.appttude.h_mal.atlas_weather.model.types.LocationType
|
||||
import com.appttude.h_mal.atlas_weather.model.weather.FullWeather
|
||||
import com.appttude.h_mal.atlas_weather.utils.BaseTest
|
||||
import com.appttude.h_mal.atlas_weather.utils.getOrAwaitValue
|
||||
import com.appttude.h_mal.atlas_weather.utils.sleep
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.impl.annotations.InjectMockKs
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.RelaxedMockK
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.ArgumentMatchers
|
||||
import org.mockito.ArgumentMatchers.anyList
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import java.io.IOException
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertIs
|
||||
|
||||
|
||||
@@ -32,8 +37,8 @@ class WorldViewModelTest : BaseTest() {
|
||||
@InjectMockKs
|
||||
lateinit var viewModel: WorldViewModel
|
||||
|
||||
@MockK(relaxed = true)
|
||||
lateinit var repository: Repository
|
||||
@RelaxedMockK
|
||||
lateinit var weatherSource: WeatherSource
|
||||
|
||||
@MockK
|
||||
lateinit var locationProvider: LocationProviderImpl
|
||||
@@ -43,30 +48,19 @@ class WorldViewModelTest : BaseTest() {
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockKAnnotations.init(this)
|
||||
|
||||
weatherResponse = getTestData("weather_sample.json", WeatherResponse::class.java)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocation_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val entityItem = EntityItem(CURRENT_LOCATION, FullWeather(weatherResponse).apply {
|
||||
temperatureUnit = "°C"
|
||||
locationString = CURRENT_LOCATION
|
||||
})
|
||||
val latlon = any<Pair<Double, Double>>()
|
||||
|
||||
// Act
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
}.returns(weatherResponse)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
@@ -74,66 +68,209 @@ class WorldViewModelTest : BaseTest() {
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
every { repository.saveLastSavedAt(CURRENT_LOCATION) } returns Unit
|
||||
coEvery { repository.saveCurrentWeatherToRoom(entityItem) } returns Unit
|
||||
|
||||
viewModel.fetchDataForSingleLocation(CURRENT_LOCATION)
|
||||
coEvery {
|
||||
weatherSource.getWeather(
|
||||
latlon,
|
||||
CURRENT_LOCATION,
|
||||
locationType = LocationType.City
|
||||
)
|
||||
} returns FullWeather(weatherResponse)
|
||||
|
||||
// Assert
|
||||
viewModel.uiState.observeForever {
|
||||
println(it.javaClass.name)
|
||||
viewModel.fetchDataForSingleLocation(CURRENT_LOCATION)
|
||||
|
||||
sleep(100)
|
||||
assertIs<ViewState.HasData<*>>(viewModel.uiState.getOrAwaitValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocation_failedLocation_validReturn() {
|
||||
// Arrange
|
||||
val errorMessage = ArgumentMatchers.anyString()
|
||||
|
||||
// Act
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
} throws IOException(errorMessage)
|
||||
|
||||
// Assert
|
||||
viewModel.fetchDataForSingleLocation(CURRENT_LOCATION)
|
||||
sleep(100)
|
||||
val observerResults = viewModel.uiState.getOrAwaitValue()
|
||||
assertIs<ViewState.HasError<*>>(observerResults)
|
||||
assertEquals(observerResults.error as String, errorMessage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocation_failedApi_validReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(weatherResponse.lat, weatherResponse.lon)
|
||||
val errorMessage = ArgumentMatchers.anyString()
|
||||
|
||||
// Act
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns Pair(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon
|
||||
)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
coEvery {
|
||||
weatherSource.getWeather(
|
||||
latlon,
|
||||
CURRENT_LOCATION,
|
||||
locationType = LocationType.City
|
||||
)
|
||||
} throws IOException(errorMessage)
|
||||
|
||||
// Assert
|
||||
viewModel.fetchDataForSingleLocation(CURRENT_LOCATION)
|
||||
sleep(100)
|
||||
val observerResults = viewModel.uiState.getOrAwaitValue()
|
||||
assertIs<ViewState.HasError<*>>(observerResults)
|
||||
assertEquals(observerResults.error as String, errorMessage)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocationSearch_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val latlon = Pair(weatherResponse.lat, weatherResponse.lon)
|
||||
|
||||
// Act
|
||||
every { weatherSource.repository.getSavedLocations() } returns anyList()
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns latlon
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
coEvery {
|
||||
weatherSource.getWeather(
|
||||
latlon,
|
||||
CURRENT_LOCATION,
|
||||
locationType = LocationType.City
|
||||
)
|
||||
} returns FullWeather(weatherResponse).apply { locationString = CURRENT_LOCATION }
|
||||
|
||||
// Assert
|
||||
viewModel.fetchDataForSingleLocationSearch(CURRENT_LOCATION)
|
||||
|
||||
sleep(100)
|
||||
val result = viewModel.uiState.getOrAwaitValue()
|
||||
assertIs<ViewState.HasData<*>>(result)
|
||||
assertEquals(result.data as String, "$CURRENT_LOCATION saved")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocationSearch_locationAlreadyExists_errorReceived() {
|
||||
// Act
|
||||
every { weatherSource.repository.getSavedLocations() } returns listOf(CURRENT_LOCATION)
|
||||
|
||||
// Assert
|
||||
viewModel.fetchDataForSingleLocationSearch(CURRENT_LOCATION)
|
||||
|
||||
sleep(100)
|
||||
val result = viewModel.uiState.getOrAwaitValue()
|
||||
assertIs<ViewState.HasError<*>>(result)
|
||||
assertEquals(result.error as String, "$CURRENT_LOCATION already exists")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocationSearch_retrievedLocationExists_validError() {
|
||||
// Arrange
|
||||
val latlon = Pair(weatherResponse.lat, weatherResponse.lon)
|
||||
val retrievedLocation = anyString()
|
||||
|
||||
// Act
|
||||
every { weatherSource.repository.getSavedLocations() } returns listOf(retrievedLocation)
|
||||
coEvery { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } returns latlon
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
weatherResponse.lat,
|
||||
weatherResponse.lon,
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(CURRENT_LOCATION)
|
||||
coEvery {
|
||||
weatherSource.getWeather(
|
||||
latlon,
|
||||
CURRENT_LOCATION,
|
||||
locationType = LocationType.City
|
||||
)
|
||||
} returns FullWeather(weatherResponse).apply { locationString = retrievedLocation }
|
||||
|
||||
// Assert
|
||||
viewModel.fetchDataForSingleLocationSearch(CURRENT_LOCATION)
|
||||
|
||||
sleep(100)
|
||||
val result = viewModel.uiState.getOrAwaitValue()
|
||||
assertIs<ViewState.HasError<*>>(result)
|
||||
assertEquals(result.error as String, "$retrievedLocation already exists")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchAllLocations_validLocations_validReturn() {
|
||||
// Arrange
|
||||
val listOfPlaces = listOf("Sydney", "London", "Cairo")
|
||||
|
||||
// Act
|
||||
listOfPlaces.forEachIndexed { index, s ->
|
||||
every { weatherSource.repository.isSearchValid(s) } returns true
|
||||
coEvery { locationProvider.getLatLongFromLocationName(s) } returns Pair(
|
||||
index.toDouble(),
|
||||
index.toDouble()
|
||||
)
|
||||
coEvery {
|
||||
locationProvider.getLocationNameFromLatLong(
|
||||
index.toDouble(),
|
||||
index.toDouble(),
|
||||
LocationType.City
|
||||
)
|
||||
}.returns(s)
|
||||
coEvery {
|
||||
weatherSource.getWeather(
|
||||
Pair(index.toDouble(), index.toDouble()),
|
||||
s,
|
||||
LocationType.City
|
||||
)
|
||||
}
|
||||
}
|
||||
coEvery { weatherSource.repository.loadWeatherList() } returns listOfPlaces
|
||||
|
||||
sleep(3000)
|
||||
// Assert
|
||||
viewModel.fetchAllLocations()
|
||||
|
||||
sleep(100)
|
||||
assertIs<ViewState.HasData<*>>(viewModel.uiState.getOrAwaitValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun fetchDataForSingleLocation_invalidLocation_invalidReturn() {
|
||||
fun deleteLocation_validLocations_validReturn() {
|
||||
// Arrange
|
||||
val location = CURRENT_LOCATION
|
||||
val location = anyString()
|
||||
|
||||
// Act
|
||||
every { locationProvider.getLatLongFromLocationName(CURRENT_LOCATION) } throws IOException("Unable to get location")
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(true)
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
}.returns(weatherResponse)
|
||||
|
||||
viewModel.fetchDataForSingleLocation(location)
|
||||
coEvery { weatherSource.repository.deleteSavedWeatherEntry(location) } returns true
|
||||
|
||||
// Assert
|
||||
sleep(300)
|
||||
assertIs<ViewState.HasError<*>>(viewModel.uiState.getOrAwaitValue())
|
||||
}
|
||||
viewModel.deleteLocation(location)
|
||||
|
||||
@Test
|
||||
fun searchAboveFallbackTime_validLocation_validReturn() {
|
||||
// Arrange
|
||||
val entityItem = EntityItem(CURRENT_LOCATION, FullWeather(weatherResponse).apply {
|
||||
temperatureUnit = "°C"
|
||||
locationString = CURRENT_LOCATION
|
||||
})
|
||||
|
||||
// Act
|
||||
coEvery { repository.getSingleWeather(CURRENT_LOCATION) }.returns(entityItem)
|
||||
every { repository.isSearchValid(CURRENT_LOCATION) }.returns(false)
|
||||
coEvery {
|
||||
repository.getWeatherFromApi(
|
||||
weatherResponse.lat.toString(),
|
||||
weatherResponse.lon.toString()
|
||||
)
|
||||
}.returns(weatherResponse)
|
||||
every { repository.saveLastSavedAt(CURRENT_LOCATION) } returns Unit
|
||||
coEvery { repository.saveCurrentWeatherToRoom(entityItem) } returns Unit
|
||||
|
||||
viewModel.fetchDataForSingleLocation(CURRENT_LOCATION)
|
||||
|
||||
// Assert
|
||||
sleep(300)
|
||||
sleep(100)
|
||||
assertIs<ViewState.HasData<*>>(viewModel.uiState.getOrAwaitValue())
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user