adding missing image gallery reducer tests
This commit is contained in:
parent
42761c0899
commit
6492afe063
|
@ -39,6 +39,8 @@ class ReducerTestScope<S, E>(
|
||||||
private val expectTestScope: ExpectTestScope
|
private val expectTestScope: ExpectTestScope
|
||||||
) : ExpectTestScope by expectTestScope, Reducer<S> {
|
) : ExpectTestScope by expectTestScope, Reducer<S> {
|
||||||
|
|
||||||
|
private var invalidateCapturedState: Boolean = false
|
||||||
|
private val actionSideEffects = mutableMapOf<Action, () -> S>()
|
||||||
private var manualState: S? = null
|
private var manualState: S? = null
|
||||||
private var capturedResult: S? = null
|
private var capturedResult: S? = null
|
||||||
|
|
||||||
|
@ -47,6 +49,10 @@ class ReducerTestScope<S, E>(
|
||||||
override val coroutineScope = CoroutineScope(UnconfinedTestDispatcher())
|
override val coroutineScope = CoroutineScope(UnconfinedTestDispatcher())
|
||||||
override fun dispatch(action: Action) {
|
override fun dispatch(action: Action) {
|
||||||
actionCaptures.add(action)
|
actionCaptures.add(action)
|
||||||
|
|
||||||
|
if (actionSideEffects.containsKey(action)) {
|
||||||
|
setState(actionSideEffects.getValue(action).invoke(), invalidateCapturedState = true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getState() = manualState ?: reducerFactory.initialState()
|
override fun getState() = manualState ?: reducerFactory.initialState()
|
||||||
|
@ -54,15 +60,20 @@ class ReducerTestScope<S, E>(
|
||||||
private val reducer: Reducer<S> = reducerFactory.create(reducerScope)
|
private val reducer: Reducer<S> = reducerFactory.create(reducerScope)
|
||||||
|
|
||||||
override fun reduce(action: Action) = reducer.reduce(action).also {
|
override fun reduce(action: Action) = reducer.reduce(action).also {
|
||||||
capturedResult = it
|
capturedResult = if (invalidateCapturedState) manualState else it
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setState(state: S) {
|
fun actionSideEffect(action: Action, handler: () -> S) {
|
||||||
|
actionSideEffects[action] = handler
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setState(state: S, invalidateCapturedState: Boolean = false) {
|
||||||
manualState = state
|
manualState = state
|
||||||
|
this.invalidateCapturedState = invalidateCapturedState
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setState(block: (S) -> S) {
|
fun setState(block: (S) -> S) {
|
||||||
manualState = block(reducerScope.getState())
|
setState(block(reducerScope.getState()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertInitialState(expected: S) {
|
fun assertInitialState(expected: S) {
|
||||||
|
|
|
@ -46,7 +46,6 @@ fun imageGalleryReducer(
|
||||||
parent = ImageGalleryPage.Routes.folders,
|
parent = ImageGalleryPage.Routes.folders,
|
||||||
state = ImageGalleryPage.Files(Lce.Loading(), action.folder)
|
state = ImageGalleryPage.Files(Lce.Loading(), action.folder)
|
||||||
)
|
)
|
||||||
|
|
||||||
dispatch(PageAction.GoTo(page))
|
dispatch(PageAction.GoTo(page))
|
||||||
|
|
||||||
jobBag.replace(ImageGalleryPage.Files::class, coroutineScope.launch {
|
jobBag.replace(ImageGalleryPage.Files::class, coroutineScope.launch {
|
||||||
|
|
|
@ -1,54 +1,123 @@
|
||||||
package app.dapk.st.messenger.gallery.state
|
package app.dapk.st.messenger.gallery.state
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import app.dapk.st.core.Lce
|
import app.dapk.st.core.Lce
|
||||||
|
import app.dapk.st.core.page.PageAction
|
||||||
|
import app.dapk.st.core.page.PageContainer
|
||||||
|
import app.dapk.st.core.page.PageStateChange
|
||||||
import app.dapk.st.design.components.SpiderPage
|
import app.dapk.st.design.components.SpiderPage
|
||||||
import app.dapk.st.messenger.gallery.FetchMediaFoldersUseCase
|
import app.dapk.st.messenger.gallery.FetchMediaFoldersUseCase
|
||||||
import app.dapk.st.messenger.gallery.FetchMediaUseCase
|
import app.dapk.st.messenger.gallery.FetchMediaUseCase
|
||||||
import app.dapk.st.core.page.PageContainer
|
import app.dapk.st.messenger.gallery.Folder
|
||||||
|
import app.dapk.st.messenger.gallery.Media
|
||||||
import app.dapk.state.Combined2
|
import app.dapk.state.Combined2
|
||||||
import fake.FakeJobBag
|
import fake.FakeJobBag
|
||||||
|
import fake.FakeUri
|
||||||
|
import io.mockk.coEvery
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
import test.assertOnlyDispatches
|
||||||
|
import test.delegateReturn
|
||||||
|
import test.expect
|
||||||
import test.testReducer
|
import test.testReducer
|
||||||
|
|
||||||
private const val A_ROOM_NAME = "a room name"
|
private const val A_ROOM_NAME = "a room name"
|
||||||
|
private val A_FOLDER = Folder(
|
||||||
|
bucketId = "a-bucket-id",
|
||||||
|
title = "a title",
|
||||||
|
thumbnail = FakeUri().instance,
|
||||||
|
)
|
||||||
|
private val A_MEDIA_RESULT = listOf(aMedia())
|
||||||
|
private val A_FOLDERS_RESULT = listOf(aFolder())
|
||||||
|
private val AN_INITIAL_FILES_PAGE = SpiderPage(
|
||||||
|
route = ImageGalleryPage.Routes.files,
|
||||||
|
label = "Send to $A_ROOM_NAME",
|
||||||
|
parent = ImageGalleryPage.Routes.folders,
|
||||||
|
state = ImageGalleryPage.Files(Lce.Loading(), A_FOLDER)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val AN_INITIAL_FOLDERS_PAGE = SpiderPage(
|
||||||
|
route = ImageGalleryPage.Routes.folders,
|
||||||
|
label = "Send to $A_ROOM_NAME",
|
||||||
|
parent = null,
|
||||||
|
state = ImageGalleryPage.Folders(Lce.Loading())
|
||||||
|
)
|
||||||
|
|
||||||
class ImageGalleryReducerTest {
|
class ImageGalleryReducerTest {
|
||||||
|
|
||||||
private val fakeJobBag = FakeJobBag()
|
private val fakeJobBag = FakeJobBag()
|
||||||
|
private val fakeFetchMediaFoldersUseCase = FakeFetchMediaFoldersUseCase()
|
||||||
|
private val fakeFetchMediaUseCase = FakeFetchMediaUseCase()
|
||||||
|
|
||||||
private val runReducerTest = testReducer { _: (Unit) -> Unit ->
|
private val runReducerTest = testReducer { _: (Unit) -> Unit ->
|
||||||
imageGalleryReducer(
|
imageGalleryReducer(
|
||||||
A_ROOM_NAME,
|
A_ROOM_NAME,
|
||||||
FakeFetchMediaFoldersUseCase().instance,
|
fakeFetchMediaFoldersUseCase.instance,
|
||||||
FakeFetchMediaUseCase().instance,
|
fakeFetchMediaUseCase.instance,
|
||||||
fakeJobBag.instance,
|
fakeJobBag.instance,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `initial state is folders page`() = runReducerTest {
|
fun `initial state is folders page`() = runReducerTest {
|
||||||
assertInitialState(
|
assertInitialState(pageState(AN_INITIAL_FOLDERS_PAGE))
|
||||||
Combined2(
|
}
|
||||||
state1 = PageContainer(
|
|
||||||
SpiderPage(
|
@Test
|
||||||
route = ImageGalleryPage.Routes.folders,
|
fun `when Visible, then updates Folders content`() = runReducerTest {
|
||||||
label = "Send to $A_ROOM_NAME",
|
fakeJobBag.instance.expect { it.replace(ImageGalleryPage.Folders::class, any()) }
|
||||||
parent = null,
|
fakeFetchMediaFoldersUseCase.givenFolders().returns(A_FOLDERS_RESULT)
|
||||||
state = ImageGalleryPage.Folders(Lce.Loading())
|
|
||||||
)
|
reduce(ImageGalleryActions.Visible)
|
||||||
),
|
|
||||||
state2 = Unit
|
assertOnlyDispatches(
|
||||||
|
PageStateChange.UpdatePage(AN_INITIAL_FOLDERS_PAGE.state.copy(content = Lce.Content(A_FOLDERS_RESULT)))
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `when SelectFolder, then goes to Folder page and fetches content`() = runReducerTest {
|
||||||
|
fakeJobBag.instance.expect { it.replace(ImageGalleryPage.Files::class, any()) }
|
||||||
|
fakeFetchMediaUseCase.givenMedia(A_FOLDER.bucketId).returns(A_MEDIA_RESULT)
|
||||||
|
val goToFolderPage = PageAction.GoTo(AN_INITIAL_FILES_PAGE)
|
||||||
|
actionSideEffect(goToFolderPage) { pageState(goToFolderPage.page) }
|
||||||
|
|
||||||
|
reduce(ImageGalleryActions.SelectFolder(A_FOLDER))
|
||||||
|
|
||||||
|
assertOnlyDispatches(
|
||||||
|
goToFolderPage,
|
||||||
|
PageStateChange.UpdatePage(goToFolderPage.page.state.copy(content = Lce.Content(A_MEDIA_RESULT)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <P> pageState(page: SpiderPage<out P>) = Combined2(PageContainer(page), Unit)
|
||||||
|
|
||||||
class FakeFetchMediaFoldersUseCase {
|
class FakeFetchMediaFoldersUseCase {
|
||||||
val instance = mockk<FetchMediaFoldersUseCase>()
|
val instance = mockk<FetchMediaFoldersUseCase>()
|
||||||
|
|
||||||
|
fun givenFolders() = coEvery { instance.fetchFolders() }.delegateReturn()
|
||||||
}
|
}
|
||||||
|
|
||||||
class FakeFetchMediaUseCase {
|
class FakeFetchMediaUseCase {
|
||||||
val instance = mockk<FetchMediaUseCase>()
|
val instance = mockk<FetchMediaUseCase>()
|
||||||
|
|
||||||
|
fun givenMedia(bucketId: String) = coEvery { instance.getMediaInBucket(bucketId) }.delegateReturn()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun aMedia(
|
||||||
|
id: Long = 1L,
|
||||||
|
uri: Uri = FakeUri().instance,
|
||||||
|
mimeType: String = "image/png",
|
||||||
|
width: Int = 100,
|
||||||
|
height: Int = 250,
|
||||||
|
size: Long = 1000L,
|
||||||
|
dateModifiedEpochMillis: Long = 5000L,
|
||||||
|
) = Media(id, uri, mimeType, width, height, size, dateModifiedEpochMillis)
|
||||||
|
|
||||||
|
fun aFolder(
|
||||||
|
bucketId: String = "a-bucket-id",
|
||||||
|
title: String = "a title",
|
||||||
|
thumbnail: Uri = FakeUri().instance,
|
||||||
|
) = Folder(bucketId, title, thumbnail)
|
Loading…
Reference in New Issue