|
|
|
@ -19,22 +19,26 @@ import mozilla.components.concept.sync.AccountObserver
|
|
|
|
|
import mozilla.components.service.fxa.SyncEngine
|
|
|
|
|
import mozilla.components.service.fxa.manager.FxaAccountManager
|
|
|
|
|
import mozilla.components.service.fxa.manager.SyncEnginesStorage
|
|
|
|
|
import mozilla.components.support.test.any
|
|
|
|
|
import org.junit.After
|
|
|
|
|
import org.junit.Assert.assertFalse
|
|
|
|
|
import org.junit.Assert.assertTrue
|
|
|
|
|
import org.junit.Before
|
|
|
|
|
import org.junit.Test
|
|
|
|
|
import org.mozilla.fenix.R
|
|
|
|
|
import org.mozilla.fenix.settings.SyncPreference
|
|
|
|
|
import org.mozilla.fenix.settings.SyncPreferenceView
|
|
|
|
|
import org.mozilla.fenix.settings.logins.fragment.SavedLoginsAuthFragmentDirections
|
|
|
|
|
|
|
|
|
|
class LoginsSyncPreferenceViewTest {
|
|
|
|
|
class SyncPreferenceViewTest {
|
|
|
|
|
|
|
|
|
|
@MockK private lateinit var syncLoginsPreference: Preference
|
|
|
|
|
@MockK private lateinit var syncPreference: SyncPreference
|
|
|
|
|
@MockK private lateinit var lifecycleOwner: LifecycleOwner
|
|
|
|
|
@MockK private lateinit var accountManager: FxaAccountManager
|
|
|
|
|
@MockK(relaxed = true) private lateinit var navController: NavController
|
|
|
|
|
private lateinit var accountObserver: CapturingSlot<AccountObserver>
|
|
|
|
|
private lateinit var clickListener: CapturingSlot<Preference.OnPreferenceClickListener>
|
|
|
|
|
private lateinit var preferenceChangeListener: CapturingSlot<Preference.OnPreferenceChangeListener>
|
|
|
|
|
private lateinit var widgetVisibilitySlot: CapturingSlot<Boolean>
|
|
|
|
|
|
|
|
|
|
@Before
|
|
|
|
|
fun setup() {
|
|
|
|
@ -42,17 +46,29 @@ class LoginsSyncPreferenceViewTest {
|
|
|
|
|
mockkConstructor(SyncEnginesStorage::class)
|
|
|
|
|
|
|
|
|
|
accountObserver = slot()
|
|
|
|
|
clickListener = slot()
|
|
|
|
|
preferenceChangeListener = slot()
|
|
|
|
|
widgetVisibilitySlot = slot()
|
|
|
|
|
|
|
|
|
|
val context = mockk<Context> {
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins_reconnect) } returns "Reconnect"
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins_sign_in) } returns "Sign in to Sync"
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins_on) } returns "On"
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins_off) } returns "Off"
|
|
|
|
|
every { getString(R.string.pref_key_credit_cards_sync_cards_across_devices) } returns "pref_key_credit_cards_sync_cards_across_devices"
|
|
|
|
|
every { getString(R.string.preferences_credit_cards_sync_cards_across_devices) } returns "Sync cards across devices"
|
|
|
|
|
every { getString(R.string.preferences_credit_cards_sync_cards) } returns "Sync cards"
|
|
|
|
|
|
|
|
|
|
every { getString(R.string.pref_key_sync_logins) } returns "pref_key_sync_logins"
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins) } returns "Sync logins"
|
|
|
|
|
every { getString(R.string.preferences_passwords_sync_logins_across_devices) } returns "Sync logins across devices"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
every { syncLoginsPreference.summary = any() } just Runs
|
|
|
|
|
every { syncLoginsPreference.onPreferenceClickListener = capture(clickListener) } just Runs
|
|
|
|
|
every { syncLoginsPreference.context } returns context
|
|
|
|
|
syncPreference = mockk {
|
|
|
|
|
every { isSwitchWidgetVisible = any() } just Runs
|
|
|
|
|
every { key } returns "pref_key_sync_logins"
|
|
|
|
|
every { isChecked = any() } just Runs
|
|
|
|
|
every { title = any() } just Runs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
every { syncPreference.title = any() } just Runs
|
|
|
|
|
every { syncPreference.onPreferenceChangeListener = capture(preferenceChangeListener) } just Runs
|
|
|
|
|
every { syncPreference.context } returns context
|
|
|
|
|
every { accountManager.register(capture(accountObserver), owner = lifecycleOwner) } just Runs
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().getStatus() } returns emptyMap()
|
|
|
|
|
}
|
|
|
|
@ -66,11 +82,12 @@ class LoginsSyncPreferenceViewTest {
|
|
|
|
|
fun `needs reauth ui on init`() {
|
|
|
|
|
every { accountManager.authenticatedAccount() } returns mockk()
|
|
|
|
|
every { accountManager.accountNeedsReauth() } returns true
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify { syncLoginsPreference.summary = "Reconnect" }
|
|
|
|
|
assertTrue(clickListener.captured.onPreferenceClick(syncLoginsPreference))
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify { syncPreference.isSwitchWidgetVisible = false }
|
|
|
|
|
verify { syncPreference.title = notLoggedInTitle }
|
|
|
|
|
assertFalse(preferenceChangeListener.captured.onPreferenceChange(syncPreference, any()))
|
|
|
|
|
verify {
|
|
|
|
|
navController.navigate(
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
|
|
|
|
@ -82,20 +99,29 @@ class LoginsSyncPreferenceViewTest {
|
|
|
|
|
fun `needs reauth ui on init even if null account`() {
|
|
|
|
|
every { accountManager.authenticatedAccount() } returns null
|
|
|
|
|
every { accountManager.accountNeedsReauth() } returns true
|
|
|
|
|
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify { syncLoginsPreference.summary = "Reconnect" }
|
|
|
|
|
verify { syncPreference.isSwitchWidgetVisible = false }
|
|
|
|
|
verify { syncPreference.title = notLoggedInTitle }
|
|
|
|
|
assertFalse(preferenceChangeListener.captured.onPreferenceChange(syncPreference, any()))
|
|
|
|
|
verify {
|
|
|
|
|
navController.navigate(
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `needs login if account does not exist`() {
|
|
|
|
|
every { accountManager.authenticatedAccount() } returns null
|
|
|
|
|
every { accountManager.accountNeedsReauth() } returns false
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify { syncLoginsPreference.summary = "Sign in to Sync" }
|
|
|
|
|
assertTrue(clickListener.captured.onPreferenceClick(syncLoginsPreference))
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify { syncPreference.isSwitchWidgetVisible = false }
|
|
|
|
|
verify { syncPreference.title = notLoggedInTitle }
|
|
|
|
|
assertFalse(preferenceChangeListener.captured.onPreferenceChange(syncPreference, any()))
|
|
|
|
|
verify {
|
|
|
|
|
navController.navigate(
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment()
|
|
|
|
@ -104,59 +130,62 @@ class LoginsSyncPreferenceViewTest {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `show status for existing account`() {
|
|
|
|
|
fun `GIVEN LoginScreen and syncLogins true WHEN updateSyncPreferenceStatus THEN setStatus false`() {
|
|
|
|
|
every { accountManager.authenticatedAccount() } returns mockk()
|
|
|
|
|
every { accountManager.accountNeedsReauth() } returns false
|
|
|
|
|
createView()
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().getStatus() } returns mapOf(
|
|
|
|
|
SyncEngine.Passwords to true
|
|
|
|
|
)
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().setStatus(any(), any()) } just Runs
|
|
|
|
|
|
|
|
|
|
verify { syncLoginsPreference.summary = "Off" }
|
|
|
|
|
assertTrue(clickListener.captured.onPreferenceClick(syncLoginsPreference))
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify {
|
|
|
|
|
navController.navigate(
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment()
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
verify { syncPreference.isSwitchWidgetVisible = true }
|
|
|
|
|
verify { syncPreference.isChecked = true }
|
|
|
|
|
verify { syncPreference.title = loggedInTitle }
|
|
|
|
|
assertTrue(preferenceChangeListener.captured.onPreferenceChange(syncPreference, false))
|
|
|
|
|
verify { anyConstructed<SyncEnginesStorage>().setStatus(any(), false) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
fun `show status for existing account with passwords`() {
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().getStatus() } returns mapOf(
|
|
|
|
|
SyncEngine.Passwords to true
|
|
|
|
|
)
|
|
|
|
|
fun `GIVEN LoginScreen and syncLogins false WHEN updateSyncPreferenceStatus THEN setStatus true`() {
|
|
|
|
|
every { accountManager.authenticatedAccount() } returns mockk()
|
|
|
|
|
every { accountManager.accountNeedsReauth() } returns false
|
|
|
|
|
createView()
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().getStatus() } returns mapOf(
|
|
|
|
|
SyncEngine.Passwords to false
|
|
|
|
|
)
|
|
|
|
|
every { anyConstructed<SyncEnginesStorage>().setStatus(any(), any()) } just Runs
|
|
|
|
|
|
|
|
|
|
verify { syncLoginsPreference.summary = "On" }
|
|
|
|
|
assertTrue(clickListener.captured.onPreferenceClick(syncLoginsPreference))
|
|
|
|
|
createView()
|
|
|
|
|
|
|
|
|
|
verify {
|
|
|
|
|
navController.navigate(
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment()
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
verify { syncPreference.isSwitchWidgetVisible = true }
|
|
|
|
|
verify { syncPreference.isChecked = false }
|
|
|
|
|
verify { syncPreference.title = loggedInTitle }
|
|
|
|
|
assertTrue(preferenceChangeListener.captured.onPreferenceChange(syncPreference, true))
|
|
|
|
|
verify { anyConstructed<SyncEnginesStorage>().setStatus(any(), true) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun createView() = SyncPreferenceView(
|
|
|
|
|
syncPreference = syncLoginsPreference,
|
|
|
|
|
syncPreference = syncPreference,
|
|
|
|
|
lifecycleOwner = lifecycleOwner,
|
|
|
|
|
accountManager = accountManager,
|
|
|
|
|
syncEngine = SyncEngine.Passwords,
|
|
|
|
|
loggedOffTitle = notLoggedInTitle,
|
|
|
|
|
loggedInTitle = loggedInTitle,
|
|
|
|
|
onSignInToSyncClicked = {
|
|
|
|
|
val directions =
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToTurnOnSyncFragment()
|
|
|
|
|
navController.navigate(directions)
|
|
|
|
|
},
|
|
|
|
|
onSyncStatusClicked = {
|
|
|
|
|
val directions =
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountSettingsFragment()
|
|
|
|
|
navController.navigate(directions)
|
|
|
|
|
},
|
|
|
|
|
onReconnectClicked = {
|
|
|
|
|
val directions =
|
|
|
|
|
SavedLoginsAuthFragmentDirections.actionGlobalAccountProblemFragment()
|
|
|
|
|
navController.navigate(directions)
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
companion object {
|
|
|
|
|
const val notLoggedInTitle: String = "Sync logins across devices"
|
|
|
|
|
const val loggedInTitle: String = "Sync logins"
|
|
|
|
|
}
|
|
|
|
|
}
|