[fenix] For https://github.com/mozilla-mobile/fenix/issues/4125: Migrate Sign in to Sync to Libstate
parent
059ee1671d
commit
8391e933be
@ -0,0 +1,62 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings.account
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.nav
|
||||
|
||||
interface AccountSettingsUserActions {
|
||||
|
||||
/**
|
||||
* Called whenever the "Sync now" button is tapped
|
||||
*/
|
||||
fun onSyncNow()
|
||||
|
||||
/**
|
||||
* Called whenever user sets a new device name
|
||||
* @param newDeviceName the device name to change to
|
||||
* @return Boolean indicating whether the new device name has been accepted or not
|
||||
*/
|
||||
fun onChangeDeviceName(newDeviceName: String): Boolean
|
||||
|
||||
/**
|
||||
* Called whenever the "Sign out" button is tapped
|
||||
*/
|
||||
fun onSignOut()
|
||||
}
|
||||
|
||||
class AccountSettingsInteractor(
|
||||
private val navController: NavController,
|
||||
private val syncNow: () -> Unit,
|
||||
private val checkValidName: (String) -> Boolean,
|
||||
private val setDeviceName: (String) -> Unit,
|
||||
private val store: AccountSettingsStore
|
||||
) : AccountSettingsUserActions {
|
||||
|
||||
override fun onSyncNow() {
|
||||
syncNow.invoke()
|
||||
}
|
||||
|
||||
override fun onChangeDeviceName(newDeviceName: String): Boolean {
|
||||
val isValidName = checkValidName.invoke(newDeviceName)
|
||||
if (!isValidName) {
|
||||
return false
|
||||
}
|
||||
// Optimistically set the device name to what user requested.
|
||||
store.dispatch(AccountSettingsAction.UpdateDeviceName(newDeviceName))
|
||||
|
||||
setDeviceName.invoke(newDeviceName)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSignOut() {
|
||||
val directions = AccountSettingsFragmentDirections.actionAccountSettingsFragmentToSignOutFragment()
|
||||
navController.nav(
|
||||
R.id.accountSettingsFragment,
|
||||
directions
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings.account
|
||||
|
||||
import mozilla.components.lib.state.Action
|
||||
import mozilla.components.lib.state.State
|
||||
import mozilla.components.lib.state.Store
|
||||
|
||||
/**
|
||||
* The [Store] for holding the [AccountSettingsState] and applying [AccountAction]s.
|
||||
*/
|
||||
class AccountSettingsStore(
|
||||
initialState: AccountSettingsState
|
||||
) : Store<AccountSettingsState, AccountSettingsAction>(
|
||||
initialState,
|
||||
::accountStateReducer
|
||||
)
|
||||
|
||||
sealed class LastSyncTime {
|
||||
object Never : LastSyncTime()
|
||||
data class Failed(val lastSync: Long) : LastSyncTime()
|
||||
data class Success(val lastSync: Long) : LastSyncTime()
|
||||
}
|
||||
|
||||
/**
|
||||
* The state for the Account Settings Screen
|
||||
*/
|
||||
data class AccountSettingsState(
|
||||
val lastSyncedDate: LastSyncTime,
|
||||
val deviceName: String
|
||||
) : State
|
||||
|
||||
/**
|
||||
* Actions to dispatch through the `SearchStore` to modify `SearchState` through the reducer.
|
||||
*/
|
||||
sealed class AccountSettingsAction : Action {
|
||||
data class SyncFailed(val time: Long) : AccountSettingsAction()
|
||||
data class SyncEnded(val time: Long) : AccountSettingsAction()
|
||||
data class UpdateDeviceName(val name: String) : AccountSettingsAction()
|
||||
}
|
||||
|
||||
/**
|
||||
* The SearchState Reducer.
|
||||
*/
|
||||
fun accountStateReducer(state: AccountSettingsState, action: AccountSettingsAction): AccountSettingsState {
|
||||
return when (action) {
|
||||
is AccountSettingsAction.SyncFailed -> state.copy(lastSyncedDate = LastSyncTime.Failed(action.time))
|
||||
is AccountSettingsAction.SyncEnded -> state.copy(lastSyncedDate = LastSyncTime.Success(action.time))
|
||||
is AccountSettingsAction.UpdateDeviceName -> state.copy(deviceName = action.name)
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.settings
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.settings.account.AccountSettingsAction
|
||||
import org.mozilla.fenix.settings.account.AccountSettingsFragmentDirections
|
||||
import org.mozilla.fenix.settings.account.AccountSettingsInteractor
|
||||
import org.mozilla.fenix.settings.account.AccountSettingsStore
|
||||
|
||||
class AccountSettingsInteractorTest {
|
||||
|
||||
@Test
|
||||
fun onSyncNow() {
|
||||
var ranSyncNow = false
|
||||
|
||||
val interactor = AccountSettingsInteractor(
|
||||
mockk(),
|
||||
{ ranSyncNow = true },
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk()
|
||||
)
|
||||
|
||||
interactor.onSyncNow()
|
||||
|
||||
assertEquals(ranSyncNow, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onChangeDeviceName() {
|
||||
val store: AccountSettingsStore = mockk(relaxed = true)
|
||||
|
||||
val interactor = AccountSettingsInteractor(
|
||||
mockk(),
|
||||
mockk(),
|
||||
{ true },
|
||||
{},
|
||||
store
|
||||
)
|
||||
|
||||
interactor.onChangeDeviceName("New Name")
|
||||
|
||||
verify { store.dispatch(AccountSettingsAction.UpdateDeviceName("New Name")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onSignOut() {
|
||||
val navController: NavController = mockk(relaxed = true)
|
||||
every { navController.currentDestination } returns NavDestination("").apply { id = R.id.accountSettingsFragment }
|
||||
|
||||
val interactor = AccountSettingsInteractor(
|
||||
navController,
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk()
|
||||
)
|
||||
|
||||
interactor.onSignOut()
|
||||
|
||||
verify {
|
||||
navController.navigate(AccountSettingsFragmentDirections.actionAccountSettingsFragmentToSignOutFragment())
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue