mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-11 13:11:01 +00:00
Add tests for onboarding viewholders (#11522)
This commit is contained in:
parent
cf94906e9d
commit
67ce5ad5d9
@ -5,12 +5,14 @@
|
||||
package org.mozilla.fenix.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.appcompat.content.res.AppCompatResources.getDrawable
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import kotlinx.android.synthetic.main.onboarding_automatic_signin.view.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.service.fxa.manager.SignInWithShareableAccountResult
|
||||
import mozilla.components.service.fxa.sharing.ShareableAccount
|
||||
@ -20,42 +22,18 @@ import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
|
||||
class OnboardingAutomaticSignInViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
class OnboardingAutomaticSignInViewHolder(
|
||||
view: View,
|
||||
private val scope: CoroutineScope = MainScope()
|
||||
) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
private lateinit var shareableAccount: ShareableAccount
|
||||
private val headerText = view.header_text
|
||||
|
||||
init {
|
||||
view.turn_on_sync_button.setOnClickListener {
|
||||
it.context.components.analytics.metrics.track(Event.OnboardingAutoSignIn)
|
||||
|
||||
it.turn_on_sync_button.text = it.context.getString(
|
||||
R.string.onboarding_firefox_account_signing_in
|
||||
)
|
||||
it.turn_on_sync_button.isEnabled = false
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
val result = view.context.components.backgroundServices.accountManager
|
||||
.signInWithShareableAccountAsync(shareableAccount).await()
|
||||
when (result) {
|
||||
SignInWithShareableAccountResult.Failure -> {
|
||||
// Failed to sign-in (e.g. bad credentials). Allow to try again.
|
||||
it.turn_on_sync_button.text = it.context.getString(
|
||||
R.string.onboarding_firefox_account_auto_signin_confirm
|
||||
)
|
||||
it.turn_on_sync_button.isEnabled = true
|
||||
FenixSnackbar.make(
|
||||
view = it,
|
||||
duration = Snackbar.LENGTH_SHORT,
|
||||
isDisplayedWithBrowserToolbar = false
|
||||
).setText(
|
||||
it.context.getString(R.string.onboarding_firefox_account_automatic_signin_failed)
|
||||
).show()
|
||||
}
|
||||
SignInWithShareableAccountResult.WillRetry, SignInWithShareableAccountResult.Success -> {
|
||||
// We consider both of these as a 'success'.
|
||||
}
|
||||
}
|
||||
scope.launch {
|
||||
onClick(it.turn_on_sync_button)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -69,6 +47,34 @@ class OnboardingAutomaticSignInViewHolder(view: View) : RecyclerView.ViewHolder(
|
||||
headerText.putCompoundDrawablesRelativeWithIntrinsicBounds(start = icon)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal suspend fun onClick(button: Button) {
|
||||
val context = button.context
|
||||
context.components.analytics.metrics.track(Event.OnboardingAutoSignIn)
|
||||
|
||||
button.text = context.getString(R.string.onboarding_firefox_account_signing_in)
|
||||
button.isEnabled = false
|
||||
|
||||
val accountManager = context.components.backgroundServices.accountManager
|
||||
when (accountManager.signInWithShareableAccountAsync(shareableAccount).await()) {
|
||||
SignInWithShareableAccountResult.Failure -> {
|
||||
// Failed to sign-in (e.g. bad credentials). Allow to try again.
|
||||
button.text = context.getString(R.string.onboarding_firefox_account_auto_signin_confirm)
|
||||
button.isEnabled = true
|
||||
FenixSnackbar.make(
|
||||
view = button,
|
||||
duration = Snackbar.LENGTH_SHORT,
|
||||
isDisplayedWithBrowserToolbar = false
|
||||
).setText(
|
||||
context.getString(R.string.onboarding_firefox_account_automatic_signin_failed)
|
||||
).show()
|
||||
}
|
||||
SignInWithShareableAccountResult.WillRetry, SignInWithShareableAccountResult.Success -> {
|
||||
// We consider both of these as a 'success'.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val LAYOUT_ID = R.layout.onboarding_automatic_signin
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import mozilla.components.feature.pwa.WebAppShortcutManager
|
||||
class TestCore(context: Context) : Core(context) {
|
||||
|
||||
override val engine = mockk<Engine>(relaxed = true) {
|
||||
every { this@mockk getProperty "settings" } returns mockk<Settings>()
|
||||
every { this@mockk getProperty "settings" } returns mockk<Settings>(relaxed = true)
|
||||
}
|
||||
override val sessionManager = SessionManager(engine)
|
||||
override val store = mockk<BrowserStore>()
|
||||
|
@ -0,0 +1,105 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkObject
|
||||
import io.mockk.unmockkObject
|
||||
import io.mockk.verify
|
||||
import kotlinx.android.synthetic.main.onboarding_automatic_signin.view.*
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import mozilla.components.service.fxa.manager.SignInWithShareableAccountResult
|
||||
import mozilla.components.service.fxa.sharing.ShareableAccount
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.components.BackgroundServices
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingAutomaticSignInViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var backgroundServices: BackgroundServices
|
||||
private lateinit var snackbar: FenixSnackbar
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingAutomaticSignInViewHolder.LAYOUT_ID, null)
|
||||
snackbar = mockk(relaxed = true)
|
||||
mockkObject(FenixSnackbar.Companion)
|
||||
|
||||
backgroundServices = testContext.components.backgroundServices
|
||||
every { FenixSnackbar.make(any(), any(), any(), any()) } returns snackbar
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
unmockkObject(FenixSnackbar.Companion)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind updates header text`() {
|
||||
val holder = OnboardingAutomaticSignInViewHolder(view)
|
||||
holder.bind(mockk {
|
||||
every { email } returns "email@example.com"
|
||||
})
|
||||
assertEquals(
|
||||
"You are signed in as email@example.com on another Firefox browser on this phone. Would you like to sign in with this account?",
|
||||
view.header_text.text
|
||||
)
|
||||
assertTrue(view.turn_on_sync_button.isEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sign in on click`() = runBlocking {
|
||||
val account = mockk<ShareableAccount> {
|
||||
every { email } returns "email@example.com"
|
||||
}
|
||||
every {
|
||||
backgroundServices.accountManager.signInWithShareableAccountAsync(account)
|
||||
} returns CompletableDeferred(SignInWithShareableAccountResult.Success)
|
||||
|
||||
val holder = OnboardingAutomaticSignInViewHolder(view, scope = this)
|
||||
holder.bind(account)
|
||||
holder.onClick(view.turn_on_sync_button)
|
||||
|
||||
assertEquals("Signing in…", view.turn_on_sync_button.text)
|
||||
assertFalse(view.turn_on_sync_button.isEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `show error if sign in fails`() = runBlockingTest {
|
||||
val account = mockk<ShareableAccount> {
|
||||
every { email } returns "email@example.com"
|
||||
}
|
||||
every {
|
||||
backgroundServices.accountManager.signInWithShareableAccountAsync(account)
|
||||
} returns CompletableDeferred(SignInWithShareableAccountResult.Failure)
|
||||
|
||||
val holder = OnboardingAutomaticSignInViewHolder(view, scope = this)
|
||||
holder.bind(account)
|
||||
holder.onClick(view.turn_on_sync_button)
|
||||
|
||||
assertEquals("Yes, sign me in", view.turn_on_sync_button.text)
|
||||
assertTrue(view.turn_on_sync_button.isEnabled)
|
||||
verify { snackbar.setText("Failed to sign-in") }
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.android.synthetic.main.onboarding_finish.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.home.sessioncontrol.OnboardingInteractor
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingFinishViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var interactor: OnboardingInteractor
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingFinishViewHolder.LAYOUT_ID, null)
|
||||
interactor = mockk(relaxed = true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `call interactor on click`() {
|
||||
OnboardingFinishViewHolder(view, interactor)
|
||||
|
||||
view.finish_button.performClick()
|
||||
verify { interactor.onStartBrowsingClicked() }
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.onboarding_header.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingHeaderViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingHeaderViewHolder.LAYOUT_ID, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind header text`() {
|
||||
OnboardingHeaderViewHolder(view)
|
||||
|
||||
assertEquals("Welcome to Firefox Preview!", view.header_text.text)
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.Navigation
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.android.synthetic.main.onboarding_manual_signin.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.home.HomeFragmentDirections
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingManualSignInViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var navController: NavController
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingManualSignInViewHolder.LAYOUT_ID, null)
|
||||
navController = mockk(relaxed = true)
|
||||
|
||||
mockkStatic(Navigation::class)
|
||||
every { Navigation.findNavController(view) } returns navController
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
unmockkStatic(Navigation::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind header text`() {
|
||||
OnboardingManualSignInViewHolder(view).bind()
|
||||
|
||||
assertEquals("Get the most out of Firefox Preview.", view.header_text.text)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `navigate on click`() {
|
||||
OnboardingManualSignInViewHolder(view)
|
||||
view.turn_on_sync_button.performClick()
|
||||
|
||||
verify { navController.navigate(HomeFragmentDirections.actionGlobalTurnOnSync()) }
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import kotlinx.android.synthetic.main.onboarding_section_header.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingSectionHeaderViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingSectionHeaderViewHolder.LAYOUT_ID, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bind text`() {
|
||||
val holder = OnboardingSectionHeaderViewHolder(view)
|
||||
holder.bind { "Hello world" }
|
||||
|
||||
assertEquals(
|
||||
"Hello world",
|
||||
view.section_header_text.text
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/* 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.home.sessioncontrol.viewholders.onboarding
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.android.synthetic.main.onboarding_toolbar_position_picker.view.*
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class OnboardingToolbarPositionPickerViewHolderTest {
|
||||
|
||||
private lateinit var view: View
|
||||
private lateinit var settings: Settings
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
view = LayoutInflater.from(testContext)
|
||||
.inflate(OnboardingToolbarPositionPickerViewHolder.LAYOUT_ID, null)
|
||||
settings = mockk(relaxed = true)
|
||||
|
||||
Settings.instance = settings
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
Settings.instance = null
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `bottom illustration should select corresponding radio button`() {
|
||||
every { settings.shouldUseBottomToolbar } returns false
|
||||
OnboardingToolbarPositionPickerViewHolder(view)
|
||||
assertTrue(view.toolbar_top_radio_button.isChecked)
|
||||
assertFalse(view.toolbar_bottom_radio_button.isChecked)
|
||||
|
||||
view.toolbar_bottom_image.performClick()
|
||||
assertFalse(view.toolbar_top_radio_button.isChecked)
|
||||
assertTrue(view.toolbar_bottom_radio_button.isChecked)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `top illustration should select corresponding radio button`() {
|
||||
every { settings.shouldUseBottomToolbar } returns true
|
||||
OnboardingToolbarPositionPickerViewHolder(view)
|
||||
assertFalse(view.toolbar_top_radio_button.isChecked)
|
||||
assertTrue(view.toolbar_bottom_radio_button.isChecked)
|
||||
|
||||
view.toolbar_top_image.performClick()
|
||||
assertTrue(view.toolbar_top_radio_button.isChecked)
|
||||
assertFalse(view.toolbar_bottom_radio_button.isChecked)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user