|
|
|
@ -7,186 +7,177 @@ package org.mozilla.fenix.home
|
|
|
|
|
import android.graphics.Bitmap
|
|
|
|
|
import android.widget.ImageView
|
|
|
|
|
import androidx.core.view.isVisible
|
|
|
|
|
import io.mockk.Called
|
|
|
|
|
import io.mockk.Runs
|
|
|
|
|
import io.mockk.coEvery
|
|
|
|
|
import io.mockk.coVerify
|
|
|
|
|
import io.mockk.every
|
|
|
|
|
import io.mockk.just
|
|
|
|
|
import io.mockk.mockk
|
|
|
|
|
import io.mockk.spyk
|
|
|
|
|
import io.mockk.verify
|
|
|
|
|
import kotlinx.coroutines.CoroutineDispatcher
|
|
|
|
|
import kotlinx.coroutines.cancel
|
|
|
|
|
import mozilla.components.support.test.ext.joinBlocking
|
|
|
|
|
import mozilla.components.support.test.libstate.ext.waitUntilIdle
|
|
|
|
|
import mozilla.components.support.test.rule.MainCoroutineRule
|
|
|
|
|
import mozilla.components.support.test.rule.runTestOnMain
|
|
|
|
|
import org.junit.Assert.assertEquals
|
|
|
|
|
import org.junit.Assert.assertNotNull
|
|
|
|
|
import org.junit.Assert.assertNull
|
|
|
|
|
import org.junit.Rule
|
|
|
|
|
import org.junit.Assert.assertTrue
|
|
|
|
|
import org.junit.Ignore
|
|
|
|
|
import org.junit.Test
|
|
|
|
|
import org.junit.runner.RunWith
|
|
|
|
|
import org.mozilla.fenix.components.AppStore
|
|
|
|
|
import org.mozilla.fenix.components.appstate.AppAction.WallpaperAction.UpdateCurrentWallpaper
|
|
|
|
|
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
|
|
|
|
import org.mozilla.fenix.utils.Settings
|
|
|
|
|
import org.mozilla.fenix.wallpapers.Wallpaper
|
|
|
|
|
import org.mozilla.fenix.wallpapers.WallpapersUseCases
|
|
|
|
|
|
|
|
|
|
@RunWith(FenixRobolectricTestRunner::class)
|
|
|
|
|
class WallpapersObserverTest {
|
|
|
|
|
@get:Rule
|
|
|
|
|
val coroutinesTestRule = MainCoroutineRule()
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `WHEN the observer is created THEN start observing the store`() {
|
|
|
|
|
val appStore: AppStore = mockk(relaxed = true) {
|
|
|
|
|
every { observeManually(any()) } answers { mockk(relaxed = true) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val observer = getObserver(appStore)
|
|
|
|
|
val observer = WallpapersObserver(appStore, mockk(), mockk())
|
|
|
|
|
|
|
|
|
|
assertNotNull(observer.observeWallpapersStoreSubscription)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN a certain wallpaper is chosen WHEN the state is updated with that wallpaper THEN load it it`() = runTestOnMain {
|
|
|
|
|
fun `WHEN asked to apply the wallpaper THEN show it`() {
|
|
|
|
|
val appStore = AppStore()
|
|
|
|
|
val settings: Settings = mockk { every { currentWallpaperName } returns "Test" }
|
|
|
|
|
val wallpaper: Wallpaper = mockk { every { name } returns "Test" }
|
|
|
|
|
val observer = spyk(
|
|
|
|
|
getObserver(appStore, settings, mockk(relaxed = true), mockk(relaxed = true)),
|
|
|
|
|
)
|
|
|
|
|
val observer = spyk(WallpapersObserver(appStore, mockk(), mockk())) {
|
|
|
|
|
every { showWallpaper(any()) } just Runs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore the call on the real instance and call again "observeWallpaperUpdates"
|
|
|
|
|
// on the spy to be able to verify the "showWallpaper" call in the spy.
|
|
|
|
|
observer.observeWallpaperUpdates()
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper)).joinBlocking()
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
observer.applyCurrentWallpaper()
|
|
|
|
|
|
|
|
|
|
verify { observer.showWallpaper(any()) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN the store was observed for updates WHEN the lifecycle owner is destroyed THEN stop observing the store`() {
|
|
|
|
|
val observer = WallpapersObserver(mockk(relaxed = true), mockk(), mockk())
|
|
|
|
|
observer.observeWallpapersStoreSubscription = mockk(relaxed = true)
|
|
|
|
|
observer.wallpapersScope = mockk {
|
|
|
|
|
every { cancel() } just Runs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
coVerify { observer.loadWallpaper(any()) }
|
|
|
|
|
coVerify { observer.applyCurrentWallpaper() }
|
|
|
|
|
observer.onDestroy(mockk())
|
|
|
|
|
|
|
|
|
|
verify { observer.wallpapersScope.cancel() }
|
|
|
|
|
verify { observer.observeWallpapersStoreSubscription!!.unsubscribe() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN a certain wallpaper is chosen WHEN the state updated with another wallpaper THEN avoid loading it`() = runTestOnMain {
|
|
|
|
|
fun `WHEN the wallpaper is updated THEN show the wallpaper`() {
|
|
|
|
|
val appStore = AppStore()
|
|
|
|
|
val settings: Settings = mockk { every { currentWallpaperName } returns "Test" }
|
|
|
|
|
val otherWallpaper: Wallpaper = mockk { every { name } returns "Other" }
|
|
|
|
|
val observer = spyk(
|
|
|
|
|
getObserver(appStore, settings, mockk(relaxed = true), mockk(relaxed = true)),
|
|
|
|
|
)
|
|
|
|
|
val observer = spyk(WallpapersObserver(appStore, mockk(relaxed = true), mockk(relaxed = true))) {
|
|
|
|
|
every { showWallpaper(any()) } just Runs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore the call on the real instance and call again "observeWallpaperUpdates"
|
|
|
|
|
// on the spy to be able to verify the "showWallpaper" call in the spy.
|
|
|
|
|
observer.observeWallpaperUpdates()
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(otherWallpaper)).joinBlocking()
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
|
|
|
|
|
coVerify(exactly = 0) { observer.loadWallpaper(any()) }
|
|
|
|
|
coVerify(exactly = 0) { observer.applyCurrentWallpaper() }
|
|
|
|
|
val newWallpaper: Wallpaper = mockk(relaxed = true)
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(newWallpaper))
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
verify { observer.showWallpaper(newWallpaper) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN a wallpaper is SHOWN WHEN the wallpaper is updated to the current one THEN don't try showing the same wallpaper again`() {
|
|
|
|
|
@Ignore("Intermittent test: https://github.com/mozilla-mobile/fenix/issues/26760")
|
|
|
|
|
fun `WHEN the wallpaper is updated to a new one THEN show the wallpaper`() {
|
|
|
|
|
val appStore = AppStore()
|
|
|
|
|
val settings: Settings = mockk { every { currentWallpaperName } returns "Test" }
|
|
|
|
|
val wallpaper: Wallpaper = mockk { every { name } returns "Test" }
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk { coEvery { loadBitmap(any()) } returns null }
|
|
|
|
|
val observer = spyk(getObserver(appStore, settings, wallpapersUseCases, mockk(relaxed = true))) {
|
|
|
|
|
coEvery { loadWallpaper(any()) } just Runs
|
|
|
|
|
coEvery { applyCurrentWallpaper() } just Runs
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk {
|
|
|
|
|
coEvery { loadBitmap(any()) } returns null
|
|
|
|
|
}
|
|
|
|
|
val observer = spyk(WallpapersObserver(appStore, wallpapersUseCases, mockk(relaxed = true))) {
|
|
|
|
|
every { showWallpaper(any()) } just Runs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ignore the call on the real instance and call again "observeWallpaperUpdates"
|
|
|
|
|
// on the spy to be able to verify the "showWallpaper" call in the spy.
|
|
|
|
|
observer.observeWallpaperUpdates()
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper)).joinBlocking()
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
coVerify(exactly = 1) { observer.loadWallpaper(any()) }
|
|
|
|
|
coVerify(exactly = 1) { observer.applyCurrentWallpaper() }
|
|
|
|
|
verify { observer.showWallpaper(Wallpaper.Default) }
|
|
|
|
|
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper)).joinBlocking()
|
|
|
|
|
val wallpaper: Wallpaper = mockk(relaxed = true)
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper))
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
coVerify(exactly = 1) { observer.loadWallpaper(any()) }
|
|
|
|
|
coVerify(exactly = 1) { observer.applyCurrentWallpaper() }
|
|
|
|
|
verify { observer.showWallpaper(wallpaper) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN the store was observed for updates WHEN the lifecycle owner is destroyed THEN stop observing the store`() {
|
|
|
|
|
val observer = getObserver(mockk(relaxed = true))
|
|
|
|
|
observer.observeWallpapersStoreSubscription = mockk(relaxed = true)
|
|
|
|
|
observer.wallpapersScope = mockk {
|
|
|
|
|
every { cancel() } just Runs
|
|
|
|
|
fun `WHEN the wallpaper is updated to the current one THEN don't try showing the same wallpaper again`() {
|
|
|
|
|
val appStore = AppStore()
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk {
|
|
|
|
|
coEvery { loadBitmap(any()) } returns null
|
|
|
|
|
}
|
|
|
|
|
val observer = spyk(WallpapersObserver(appStore, wallpapersUseCases, mockk(relaxed = true))) {
|
|
|
|
|
every { showWallpaper(any()) } just Runs
|
|
|
|
|
}
|
|
|
|
|
// Ignore the call on the real instance and call again "observeWallpaperUpdates"
|
|
|
|
|
// on the spy to be able to verify the "showWallpaper" call in the spy.
|
|
|
|
|
observer.observeWallpaperUpdates()
|
|
|
|
|
|
|
|
|
|
observer.onDestroy(mockk())
|
|
|
|
|
val wallpaper: Wallpaper = mockk(relaxed = true)
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper))
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
verify { observer.showWallpaper(wallpaper) }
|
|
|
|
|
|
|
|
|
|
verify { observer.wallpapersScope.cancel() }
|
|
|
|
|
verify { observer.observeWallpapersStoreSubscription!!.unsubscribe() }
|
|
|
|
|
appStore.dispatch(UpdateCurrentWallpaper(wallpaper))
|
|
|
|
|
appStore.waitUntilIdle()
|
|
|
|
|
verify(exactly = 1) { observer.showWallpaper(wallpaper) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN a wallpaper image is available WHEN asked to apply the current wallpaper THEN show set it to the wallpaper ImageView`() = runTestOnMain {
|
|
|
|
|
val imageView: ImageView = mockk(relaxed = true)
|
|
|
|
|
val observer = getObserver(wallpaperImageView = imageView)
|
|
|
|
|
val image: Bitmap = mockk()
|
|
|
|
|
observer.currentWallpaperImage = image
|
|
|
|
|
observer.isWallpaperLoaded.complete(Unit)
|
|
|
|
|
fun `GIVEN no wallpaper is provided WHEN asked to show the wallpaper THEN show the current one`() {
|
|
|
|
|
val wallpaper: Wallpaper = mockk()
|
|
|
|
|
val appStore: AppStore = mockk(relaxed = true) {
|
|
|
|
|
every { state.wallpaperState.currentWallpaper } returns wallpaper
|
|
|
|
|
}
|
|
|
|
|
val observer = spyk(WallpapersObserver(appStore, mockk(relaxed = true), mockk(relaxed = true)))
|
|
|
|
|
|
|
|
|
|
observer.applyCurrentWallpaper()
|
|
|
|
|
observer.showWallpaper()
|
|
|
|
|
|
|
|
|
|
verify { imageView.setImageBitmap(image) }
|
|
|
|
|
verify { imageView.isVisible = true }
|
|
|
|
|
verify { observer.showWallpaper(wallpaper) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun `GIVEN no wallpaper image is available WHEN asked to apply the current wallpaper THEN hide the wallpaper ImageView`() = runTestOnMain {
|
|
|
|
|
val imageView: ImageView = mockk()
|
|
|
|
|
val observer = getObserver(wallpaperImageView = imageView)
|
|
|
|
|
observer.isWallpaperLoaded.complete(Unit)
|
|
|
|
|
fun `GiVEN the current wallpaper is the default one WHEN showing it THEN hide the wallpaper view`() {
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk()
|
|
|
|
|
val wallpaperView: ImageView = mockk(relaxed = true)
|
|
|
|
|
val observer = WallpapersObserver(mockk(relaxed = true), wallpapersUseCases, wallpaperView)
|
|
|
|
|
|
|
|
|
|
observer.applyCurrentWallpaper()
|
|
|
|
|
observer.showWallpaper(Wallpaper.Default)
|
|
|
|
|
|
|
|
|
|
verify { imageView.isVisible = false }
|
|
|
|
|
verify(exactly = 0) { imageView.setImageBitmap(any()) }
|
|
|
|
|
verify { wallpaperView.isVisible = false }
|
|
|
|
|
verify { wallpapersUseCases wasNot Called }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN the default wallpaper WHEN asked to load it THEN cache that the current image is null`() = runTestOnMain {
|
|
|
|
|
val observer = getObserver()
|
|
|
|
|
observer.currentWallpaperImage = mockk()
|
|
|
|
|
fun `GiVEN the current wallpaper is different than the default one WHEN showing it THEN load it's bitmap in the visible wallpaper view`() {
|
|
|
|
|
val wallpaper: Wallpaper = mockk()
|
|
|
|
|
val bitmap: Bitmap = mockk()
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk {
|
|
|
|
|
coEvery { loadBitmap(any()) } returns bitmap
|
|
|
|
|
}
|
|
|
|
|
val wallpaperView: ImageView = mockk(relaxed = true)
|
|
|
|
|
val observer = WallpapersObserver(mockk(relaxed = true), wallpapersUseCases, wallpaperView)
|
|
|
|
|
|
|
|
|
|
observer.loadWallpaper(Wallpaper.Default)
|
|
|
|
|
observer.showWallpaper(wallpaper)
|
|
|
|
|
|
|
|
|
|
assertNull(observer.currentWallpaperImage)
|
|
|
|
|
verify { wallpaperView.isVisible = true }
|
|
|
|
|
verify { wallpaperView.setImageBitmap(bitmap) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `GIVEN a custom wallpaper WHEN asked to load it THEN cache it's bitmap`() = runTestOnMain {
|
|
|
|
|
val bitmap: Bitmap = mockk()
|
|
|
|
|
val wallpaper: Wallpaper = mockk()
|
|
|
|
|
val usecases: WallpapersUseCases = mockk {
|
|
|
|
|
coEvery { loadBitmap(wallpaper) } returns bitmap
|
|
|
|
|
}
|
|
|
|
|
val observer = getObserver(wallpapersUseCases = usecases)
|
|
|
|
|
fun `GIVEN the observer THEN use the main thread for showing the wallpaper`() {
|
|
|
|
|
val wallpapersUseCases: WallpapersUseCases = mockk()
|
|
|
|
|
val wallpaperView: ImageView = mockk(relaxed = true)
|
|
|
|
|
|
|
|
|
|
observer.loadWallpaper(wallpaper)
|
|
|
|
|
val observer = WallpapersObserver(mockk(relaxed = true), wallpapersUseCases, wallpaperView)
|
|
|
|
|
|
|
|
|
|
assertEquals(bitmap, observer.currentWallpaperImage)
|
|
|
|
|
// Check that the context that would be used is Dispatchers.Main.immediate
|
|
|
|
|
// Unfortunately I could not also test that this is actually used when "showWallpaper" is called.
|
|
|
|
|
assertTrue(observer.wallpapersScope.toString().contains("Dispatchers.Main.immediate"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun getObserver(
|
|
|
|
|
appStore: AppStore = mockk(relaxed = true),
|
|
|
|
|
settings: Settings = mockk(),
|
|
|
|
|
wallpapersUseCases: WallpapersUseCases = mockk(),
|
|
|
|
|
wallpaperImageView: ImageView = mockk(),
|
|
|
|
|
backgroundWorkDispatcher: CoroutineDispatcher = coroutinesTestRule.testDispatcher,
|
|
|
|
|
) = WallpapersObserver(
|
|
|
|
|
appStore = appStore,
|
|
|
|
|
settings = settings,
|
|
|
|
|
wallpapersUseCases = wallpapersUseCases,
|
|
|
|
|
wallpaperImageView = wallpaperImageView,
|
|
|
|
|
backgroundWorkDispatcher = backgroundWorkDispatcher,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|