Add beta version usecase tests
This commit is contained in:
parent
58470e2dcd
commit
167c3f81c4
|
@ -16,6 +16,5 @@ class ApplicationPreferences(
|
|||
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class ApplicationVersion(val value: Int)
|
||||
data class ApplicationVersion(val value: Int)
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@ class BetaVersionUpgradeUseCase(
|
|||
}
|
||||
|
||||
private suspend fun hasChangedVersion(): Boolean {
|
||||
val previousVersion = applicationPreferences.readVersion()?.value
|
||||
val readVersion = applicationPreferences.readVersion()
|
||||
val previousVersion = readVersion?.value
|
||||
val currentVersion = buildMeta.versionCode
|
||||
return when (previousVersion) {
|
||||
null -> false
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package app.dapk.st.home
|
||||
|
||||
import app.dapk.st.core.BuildMeta
|
||||
import app.dapk.st.domain.ApplicationPreferences
|
||||
import app.dapk.st.domain.ApplicationVersion
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
import org.junit.Test
|
||||
import test.delegateReturn
|
||||
import test.expect
|
||||
|
||||
class BetaVersionUpgradeUseCaseTest {
|
||||
|
||||
private val buildMeta = BuildMeta(versionName = "a-version-name", versionCode = 100, isDebug = false)
|
||||
private val fakeApplicationPreferences = FakeApplicationPreferences()
|
||||
|
||||
private val useCase = BetaVersionUpgradeUseCase(
|
||||
fakeApplicationPreferences.instance,
|
||||
buildMeta
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `given same stored version, when hasVersionChanged then is false`() = runTest {
|
||||
fakeApplicationPreferences.givenVersion().returns(ApplicationVersion(buildMeta.versionCode))
|
||||
|
||||
val result = useCase.hasVersionChanged()
|
||||
|
||||
result shouldBeEqualTo false
|
||||
}
|
||||
|
||||
// Should be impossible
|
||||
@Test
|
||||
fun `given higher stored version, when hasVersionChanged then is false`() = runTest {
|
||||
fakeApplicationPreferences.givenVersion().returns(ApplicationVersion(buildMeta.versionCode + 1))
|
||||
|
||||
val result = useCase.hasVersionChanged()
|
||||
|
||||
result shouldBeEqualTo false
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given lower stored version, when hasVersionChanged then is true`() = runTest {
|
||||
fakeApplicationPreferences.givenVersion().returns(ApplicationVersion(buildMeta.versionCode - 1))
|
||||
|
||||
val result = useCase.hasVersionChanged()
|
||||
|
||||
result shouldBeEqualTo true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given version has changed, when waiting, then blocks until notified of upgrade`() = runTest {
|
||||
fakeApplicationPreferences.givenVersion().returns(ApplicationVersion(buildMeta.versionCode - 1))
|
||||
fakeApplicationPreferences.instance.expect { it.setVersion(ApplicationVersion(buildMeta.versionCode)) }
|
||||
|
||||
val waitUntilReady = async { useCase.waitUnitReady() }
|
||||
async { useCase.notifyUpgraded() }
|
||||
waitUntilReady.await()
|
||||
}
|
||||
}
|
||||
|
||||
private class FakeApplicationPreferences {
|
||||
val instance = mockk<ApplicationPreferences>()
|
||||
|
||||
fun givenVersion() = coEvery { instance.readVersion() }.delegateReturn()
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
package app.dapk.st.home.state
|
||||
|
||||
import app.dapk.st.directory.state.ComponentLifecycle
|
||||
import app.dapk.st.directory.state.DirectorySideEffect
|
||||
import app.dapk.st.domain.StoreCleaner
|
||||
import app.dapk.st.engine.Me
|
||||
import app.dapk.st.home.BetaVersionUpgradeUseCase
|
||||
import app.dapk.st.matrix.common.HomeServerUrl
|
||||
import app.dapk.st.profile.state.ProfileAction
|
||||
import fake.FakeChatEngine
|
||||
import fake.FakeJobBag
|
||||
import fixture.aRoomId
|
||||
import fixture.aRoomInvite
|
||||
import fixture.aUserId
|
||||
import io.mockk.mockk
|
||||
import org.junit.Test
|
||||
import test.*
|
||||
|
||||
private val A_ME = Me(aUserId(), displayName = null, avatarUrl = null, homeServerUrl = HomeServerUrl("ignored"))
|
||||
private val A_SIGNED_IN_STATE = HomeScreenState.SignedIn(
|
||||
HomeScreenState.Page.Directory,
|
||||
me = A_ME,
|
||||
invites = 0,
|
||||
)
|
||||
|
||||
class HomeReducerTest {
|
||||
|
||||
private val fakeStoreCleaner = FakeStoreCleaner()
|
||||
private val fakeChatEngine = FakeChatEngine()
|
||||
private val fakeBetaVersionUpgradeUseCase = FakeBetaVersionUpgradeUseCase()
|
||||
private val fakeJobBag = FakeJobBag()
|
||||
|
||||
private val runReducerTest = testReducer { fakeEventSource ->
|
||||
homeReducer(
|
||||
fakeChatEngine,
|
||||
fakeStoreCleaner,
|
||||
fakeBetaVersionUpgradeUseCase.instance,
|
||||
fakeJobBag.instance,
|
||||
fakeEventSource,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state is loading`() = runReducerTest {
|
||||
assertInitialState(HomeScreenState.Loading)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when UpdateState, then replaces state`() = runReducerTest {
|
||||
reduce(HomeAction.UpdateState(HomeScreenState.SignedOut))
|
||||
|
||||
assertOnlyStateChange(HomeScreenState.SignedOut)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn, when UpdateInviteCount, then updates invite count`() = runReducerTest {
|
||||
setState(A_SIGNED_IN_STATE)
|
||||
|
||||
reduce(HomeAction.UpdateInvitesCount(invitesCount = 90))
|
||||
|
||||
assertOnlyStateChange(A_SIGNED_IN_STATE.copy(invites = 90))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ScrollToTop, then forwards to directory scroll event`() = runReducerTest {
|
||||
reduce(HomeAction.ScrollToTop)
|
||||
|
||||
assertOnlyDispatches(DirectorySideEffect.ScrollToTop)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ClearCache, then clears store cache, upgrades and relaunches`() = runReducerTest {
|
||||
fakeStoreCleaner.expect { it.cleanCache(removeCredentials = false) }
|
||||
fakeBetaVersionUpgradeUseCase.instance.expect { it.notifyUpgraded() }
|
||||
|
||||
reduce(HomeAction.ClearCache)
|
||||
|
||||
assertOnlyEvents(HomeEvent.Relaunch)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn and invites update, when Visible, then show content and update on invite changes`() = runReducerTest {
|
||||
fakeChatEngine.givenIsSignedIn().returns(true)
|
||||
|
||||
reduce(HomeAction.LifecycleVisible)
|
||||
|
||||
assertEvents(HomeEvent.OnShowContent)
|
||||
assertDispatches(HomeAction.InitialHome)
|
||||
assertNoStateChange()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedOut and invites update, when Visible, then show content and update on invite changes`() = runReducerTest {
|
||||
fakeChatEngine.givenIsSignedIn().returns(false)
|
||||
|
||||
reduce(HomeAction.LifecycleVisible)
|
||||
|
||||
assertOnlyDispatches(HomeAction.UpdateState(HomeScreenState.SignedOut))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn, when InitialHome, then updates me state and listens to invite changes`() = runReducerTest {
|
||||
setState(A_SIGNED_IN_STATE)
|
||||
fakeChatEngine.givenMe(forceRefresh = false).returns(A_ME)
|
||||
givenInvites(count = 5)
|
||||
|
||||
reduce(HomeAction.InitialHome)
|
||||
|
||||
assertOnlyDispatches(
|
||||
HomeAction.UpdateToSignedIn(A_ME),
|
||||
HomeAction.UpdateInvitesCount(5)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn, when UpdateToSignedIn, then updates me state`() = runReducerTest {
|
||||
setState(A_SIGNED_IN_STATE)
|
||||
val expectedMe = A_ME.copy(aUserId("another-user"))
|
||||
|
||||
reduce(HomeAction.UpdateToSignedIn(expectedMe))
|
||||
|
||||
assertOnlyStateChange(A_SIGNED_IN_STATE.copy(me = expectedMe))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given Loading, when UpdateToSignedIn, then set SignedIn and updates me state`() = runReducerTest {
|
||||
setState(HomeScreenState.Loading)
|
||||
val expectedMe = A_ME.copy(aUserId("another-user"))
|
||||
|
||||
reduce(HomeAction.UpdateToSignedIn(expectedMe))
|
||||
|
||||
assertOnlyStateChange(A_SIGNED_IN_STATE.copy(me = expectedMe))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedOut, when UpdateToSignedIn, then set SignedIn and updates me state`() = runReducerTest {
|
||||
setState(HomeScreenState.SignedOut)
|
||||
val expectedMe = A_ME.copy(aUserId("another-user"))
|
||||
|
||||
reduce(HomeAction.UpdateToSignedIn(expectedMe))
|
||||
|
||||
assertOnlyStateChange(A_SIGNED_IN_STATE.copy(me = expectedMe))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when LoggedIn, then emit show content and fetch initial home`() = runReducerTest {
|
||||
setState(HomeScreenState.SignedOut)
|
||||
givenInvites(count = 0)
|
||||
|
||||
reduce(HomeAction.LoggedIn)
|
||||
|
||||
assertDispatches(HomeAction.InitialHome)
|
||||
assertEvents(HomeEvent.OnShowContent)
|
||||
assertNoStateChange()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedOut, when ChangePage, then does nothing`() = runReducerTest {
|
||||
setState(HomeScreenState.SignedOut)
|
||||
|
||||
reduce(HomeAction.ChangePage(HomeScreenState.Page.Directory))
|
||||
|
||||
assertNoChanges()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given Loading, when ChangePage, then does nothing`() = runReducerTest {
|
||||
setState(HomeScreenState.Loading)
|
||||
|
||||
reduce(HomeAction.ChangePage(HomeScreenState.Page.Directory))
|
||||
|
||||
assertNoChanges()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn, when ChangePage to same page, then does nothing`() = runReducerTest {
|
||||
val page = HomeScreenState.Page.Directory
|
||||
setState(A_SIGNED_IN_STATE.copy(page = page))
|
||||
|
||||
reduce(HomeAction.ChangePage(page))
|
||||
|
||||
assertNoChanges()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given SignedIn, when ChangePage to different page, then updates page and emits side effect`() = runReducerTest {
|
||||
val expectedPage = HomeScreenState.Page.Profile
|
||||
setState(A_SIGNED_IN_STATE.copy(page = HomeScreenState.Page.Directory))
|
||||
|
||||
reduce(HomeAction.ChangePage(expectedPage))
|
||||
|
||||
assertStateChange(A_SIGNED_IN_STATE.copy(page = expectedPage))
|
||||
assertDispatches(HomeAction.ChangePageSideEffect(expectedPage))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ChangePageSide is Directory, then does nothing`() = runReducerTest {
|
||||
reduce(HomeAction.ChangePageSideEffect(HomeScreenState.Page.Directory))
|
||||
|
||||
assertNoChanges()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when ChangePageSide is Profile, then mark directory gone and resets profile`() = runReducerTest {
|
||||
reduce(HomeAction.ChangePageSideEffect(HomeScreenState.Page.Profile))
|
||||
|
||||
assertOnlyDispatches(
|
||||
ComponentLifecycle.OnGone,
|
||||
ProfileAction.Reset
|
||||
)
|
||||
}
|
||||
|
||||
private fun givenInvites(count: Int) {
|
||||
fakeJobBag.instance.expect { it.replace("invites-count", any()) }
|
||||
val invites = List(count) { aRoomInvite(roomId = aRoomId(it.toString())) }
|
||||
fakeChatEngine.givenInvites().emits(invites)
|
||||
}
|
||||
}
|
||||
|
||||
class FakeStoreCleaner : StoreCleaner by mockk()
|
||||
|
||||
class FakeBetaVersionUpgradeUseCase {
|
||||
val instance = mockk<BetaVersionUpgradeUseCase>()
|
||||
}
|
Loading…
Reference in New Issue