Add RxStore and StoryViewerPage forward navigation.

This commit is contained in:
Alex Hart
2022-04-01 09:27:09 -03:00
committed by Cody Henthorne
parent 11c3ea769e
commit 3e42c044b8
8 changed files with 300 additions and 37 deletions

View File

@@ -0,0 +1,129 @@
package org.thoughtcrime.securesms.stories.viewer.page
import android.app.Application
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.plugins.RxJavaPlugins
import io.reactivex.rxjava3.schedulers.TestScheduler
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
@RunWith(RobolectricTestRunner::class)
@Config(application = Application::class)
class StoryViewerPageViewModelTest {
private val repository: StoryViewerPageRepository = mock()
private val testScheduler = TestScheduler()
@Before
fun setUp() {
RxJavaPlugins.setInitComputationSchedulerHandler { testScheduler }
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
}
@After
fun tearDown() {
RxJavaPlugins.reset()
}
@Test
fun `Given no initial story and 3 records all viewed, when I initialize, then I expect storyIndex to be 0`() {
// GIVEN
val storyPosts = createStoryPosts(3) { true }
whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts))
// WHEN
val testSubject = createTestSubject()
// THEN
testScheduler.triggerActions()
val testSubscriber = testSubject.state.test()
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 0 }
}
@Test
fun `Given no initial story and 3 records all not viewed, when I initialize, then I expect storyIndex to be 0`() {
// GIVEN
val storyPosts = createStoryPosts(3) { false }
whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts))
// WHEN
val testSubject = createTestSubject()
// THEN
testScheduler.triggerActions()
val testSubscriber = testSubject.state.test()
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 0 }
}
@Test
fun `Given no initial story and 3 records with 2nd is not viewed, when I initialize, then I expect storyIndex to be 1`() {
// GIVEN
val storyPosts = createStoryPosts(3) { it % 2 != 0 }
whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts))
// WHEN
val testSubject = createTestSubject()
// THEN
testScheduler.triggerActions()
val testSubscriber = testSubject.state.test()
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 1 }
}
@Test
fun `Given no initial story and 3 records with 1st and 3rd not viewed, when I goToNext, then I expect storyIndex to be 2`() {
// GIVEN
val storyPosts = createStoryPosts(3) { it % 2 == 0 }
whenever(repository.getStoryPostsFor(any())).thenReturn(Observable.just(storyPosts))
// WHEN
val testSubject = createTestSubject()
testScheduler.triggerActions()
testSubject.goToNextPost()
testScheduler.triggerActions()
// THEN
val testSubscriber = testSubject.state.test()
testSubscriber.assertValueAt(0) { it.selectedPostIndex == 2 }
}
private fun createTestSubject(): StoryViewerPageViewModel {
return StoryViewerPageViewModel(
RecipientId.from(1),
-1L,
repository
)
}
private fun createStoryPosts(count: Int, isViewed: (Int) -> Boolean = { false }): List<StoryPost> {
return (1..count).map {
StoryPost(
id = it.toLong(),
sender = Recipient.UNKNOWN,
group = null,
distributionList = null,
viewCount = 0,
replyCount = 0,
dateInMilliseconds = it.toLong(),
content = StoryPost.Content.TextContent(mock(), it.toLong(), false, 0),
conversationMessage = mock(),
allowsReplies = true,
hasSelfViewed = isViewed(it)
)
}
}
}

View File

@@ -0,0 +1,70 @@
package org.thoughtcrime.securesms.util.rx
import io.reactivex.rxjava3.plugins.RxJavaPlugins
import io.reactivex.rxjava3.schedulers.TestScheduler
import org.junit.After
import org.junit.Before
import org.junit.Test
class RxStoreTest {
private val testScheduler = TestScheduler()
@Before
fun setUp() {
RxJavaPlugins.setInitComputationSchedulerHandler { testScheduler }
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
}
@After
fun tearDown() {
RxJavaPlugins.reset()
}
@Test
fun `Given an initial state, when I observe, then I expect my initial state`() {
// GIVEN
val testSubject = RxStore(1)
// WHEN
val subscriber = testSubject.stateFlowable.test()
testScheduler.triggerActions()
// THEN
subscriber.assertValueAt(0, 1)
subscriber.assertNotComplete()
}
@Test
fun `Given immediate observation, when I update, then I expect both states`() {
// GIVEN
val testSubject = RxStore(1)
// WHEN
val subscriber = testSubject.stateFlowable.test()
testSubject.update { 2 }
testScheduler.triggerActions()
// THEN
subscriber.assertValueAt(0, 1)
subscriber.assertValueAt(1, 2)
subscriber.assertNotComplete()
}
@Test
fun `Given late observation after several updates, when I observe, then I expect latest state`() {
// GIVEN
val testSubject = RxStore(1)
testSubject.update { 2 }
// WHEN
testScheduler.triggerActions()
val subscriber = testSubject.stateFlowable.test()
testScheduler.triggerActions()
// THEN
subscriber.assertValueAt(0, 2)
subscriber.assertNotComplete()
}
}