1
0
Fork 0

Add tests for some classes in home/browser (#12837)

master
Tiger Oakes 2020-07-23 11:17:52 -07:00 committed by GitHub
parent 0d77f761e9
commit 9af167ba0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 234 additions and 45 deletions

View File

@ -12,6 +12,7 @@ import mozilla.components.browser.session.SessionManager
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.sessionsOfType
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry import org.mozilla.fenix.search.telemetry.ads.AdsTelemetry
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
@ -44,25 +45,29 @@ class UriOpenedObserver(
session.register(singleSessionObserver, owner) session.register(singleSessionObserver, owner)
} }
private fun saveOpenTabsCount() {
settings.setOpenTabsCount(sessionManager.sessionsOfType(private = false).count())
}
override fun onAllSessionsRemoved() { override fun onAllSessionsRemoved() {
settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) saveOpenTabsCount()
sessionManager.sessions.forEach { sessionManager.sessions.forEach {
it.unregister(singleSessionObserver) it.unregister(singleSessionObserver)
} }
} }
override fun onSessionAdded(session: Session) { override fun onSessionAdded(session: Session) {
settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) saveOpenTabsCount()
session.register(singleSessionObserver, owner) session.register(singleSessionObserver, owner)
} }
override fun onSessionRemoved(session: Session) { override fun onSessionRemoved(session: Session) {
settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) saveOpenTabsCount()
session.unregister(singleSessionObserver) session.unregister(singleSessionObserver)
} }
override fun onSessionsRestored() { override fun onSessionsRestored() {
settings.setOpenTabsCount(sessionManager.sessions.filter { !it.private }.size) saveOpenTabsCount()
sessionManager.sessions.forEach { sessionManager.sessions.forEach {
it.register(singleSessionObserver, owner) it.register(singleSessionObserver, owner)
} }

View File

@ -1,23 +1,32 @@
/* 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.tips package org.mozilla.fenix.home.tips
import android.view.View import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.button_tip_item.view.* import kotlinx.android.synthetic.main.button_tip_item.*
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.tips.Tip import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.TipType import org.mozilla.fenix.components.tips.TipType
import org.mozilla.fenix.ext.addUnderline import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.view.ViewHolder
class ButtonTipViewHolder( class ButtonTipViewHolder(
val view: View, view: View,
val interactor: SessionControlInteractor private val interactor: SessionControlInteractor,
) : RecyclerView.ViewHolder(view) { private val metrics: MetricController = view.context.components.analytics.metrics,
private val settings: Settings = view.context.components.settings
) : ViewHolder(view) {
var tip: Tip? = null var tip: Tip? = null
fun bind(tip: Tip) { fun bind(tip: Tip) {
@ -25,44 +34,39 @@ class ButtonTipViewHolder(
this.tip = tip this.tip = tip
view.apply { metrics.track(Event.TipDisplayed(tip.identifier))
context.components.analytics.metrics.track(Event.TipDisplayed(tip.identifier))
tip_header_text.text = tip.title tip_header_text.text = tip.title
tip_description_text.text = tip.description tip_description_text.text = tip.description
tip_button.text = tip.type.text tip_button.text = tip.type.text
if (tip.learnMoreURL == null) { tip_learn_more.isVisible = tip.learnMoreURL != null
tip_learn_more.visibility = View.GONE if (tip.learnMoreURL != null) {
} else { tip_learn_more.addUnderline()
tip_learn_more.addUnderline()
tip_learn_more.setOnClickListener { tip_learn_more.setOnClickListener {
(context as HomeActivity).openToBrowserAndLoad( (itemView.context as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = tip.learnMoreURL, searchTermOrURL = tip.learnMoreURL,
newTab = true, newTab = true,
from = BrowserDirection.FromHome from = BrowserDirection.FromHome
)
}
}
tip_button.setOnClickListener {
tip.type.action.invoke()
context.components.analytics.metrics.track(
Event.TipPressed(tip.identifier)
) )
} }
}
tip_close.setOnClickListener { tip_button.setOnClickListener {
context.components.analytics.metrics.track(Event.TipClosed(tip.identifier)) tip.type.action.invoke()
metrics.track(Event.TipPressed(tip.identifier))
}
context.settings().preferences tip_close.setOnClickListener {
.edit() metrics.track(Event.TipClosed(tip.identifier))
.putBoolean(tip.identifier, false)
.apply()
interactor.onCloseTip(tip) settings.preferences
} .edit()
.putBoolean(tip.identifier, false)
.apply()
interactor.onCloseTip(tip)
} }
} }

View File

@ -5,7 +5,9 @@
package org.mozilla.fenix.browser package org.mozilla.fenix.browser
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import io.mockk.MockKAnnotations
import io.mockk.every import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify import io.mockk.verify
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
@ -18,15 +20,16 @@ import org.mozilla.fenix.utils.Settings
class UriOpenedObserverTest { class UriOpenedObserverTest {
private val settings: Settings = mockk(relaxed = true) @MockK(relaxed = true) private lateinit var settings: Settings
private val owner: LifecycleOwner = mockk(relaxed = true) @MockK(relaxed = true) private lateinit var owner: LifecycleOwner
private val sessionManager: SessionManager = mockk(relaxed = true) @MockK(relaxed = true) private lateinit var sessionManager: SessionManager
private val metrics: MetricController = mockk() @MockK private lateinit var metrics: MetricController
private val ads: AdsTelemetry = mockk() @MockK private lateinit var ads: AdsTelemetry
private lateinit var observer: UriOpenedObserver private lateinit var observer: UriOpenedObserver
@Before @Before
fun setup() { fun setup() {
MockKAnnotations.init(this)
observer = UriOpenedObserver(settings, owner, sessionManager, metrics, ads) observer = UriOpenedObserver(settings, owner, sessionManager, metrics, ads)
} }
@ -37,6 +40,14 @@ class UriOpenedObserverTest {
@Test @Test
fun `registers single session observer`() { fun `registers single session observer`() {
every { sessionManager.sessions } returns listOf(
mockk {
every { private } returns false
},
mockk {
every { private } returns true
}
)
val session: Session = mockk(relaxed = true) val session: Session = mockk(relaxed = true)
observer.onSessionAdded(session) observer.onSessionAdded(session)
@ -47,6 +58,8 @@ class UriOpenedObserverTest {
observer.onSessionRemoved(session) observer.onSessionRemoved(session)
verify { session.unregister(observer.singleSessionObserver) } verify { session.unregister(observer.singleSessionObserver) }
verify { settings.setOpenTabsCount(1) }
} }
@Test @Test

View File

@ -4,12 +4,16 @@
package org.mozilla.fenix.browser.readermode package org.mozilla.fenix.browser.readermode
import android.content.res.ColorStateList
import android.view.View import android.view.View
import android.widget.Button
import android.widget.RadioButton
import io.mockk.Called import io.mockk.Called
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.spyk import io.mockk.spyk
import io.mockk.verify import io.mockk.verify
import io.mockk.verifyAll
import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
@ -19,6 +23,7 @@ import mozilla.components.support.test.robolectric.testContext
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
@ -77,4 +82,40 @@ class DefaultReaderModeControllerTest {
verify { readerViewFeature.showControls() } verify { readerViewFeature.showControls() }
verify { readerViewControlsBar wasNot Called } verify { readerViewControlsBar wasNot Called }
} }
@Test
fun testShowControlsPrivateTab() {
val controller = DefaultReaderModeController(
featureWrapper,
readerViewControlsBar,
isPrivate = true
)
val decrease = mockk<Button>(relaxUnitFun = true)
val increase = mockk<Button>(relaxUnitFun = true)
val serif = mockk<RadioButton>(relaxUnitFun = true)
val sansSerif = mockk<RadioButton>(relaxUnitFun = true)
every {
readerViewControlsBar.findViewById<Button>(R.id.mozac_feature_readerview_font_size_decrease)
} returns decrease
every {
readerViewControlsBar.findViewById<Button>(R.id.mozac_feature_readerview_font_size_increase)
} returns increase
every {
readerViewControlsBar.findViewById<RadioButton>(R.id.mozac_feature_readerview_font_serif)
} returns serif
every {
readerViewControlsBar.findViewById<RadioButton>(R.id.mozac_feature_readerview_font_sans_serif)
} returns sansSerif
controller.showControls()
verify { readerViewFeature.showControls() }
verifyAll {
decrease.setTextColor(any<ColorStateList>())
increase.setTextColor(any<ColorStateList>())
serif.setTextColor(any<ColorStateList>())
sansSerif.setTextColor(any<ColorStateList>())
}
}
} }

View File

@ -0,0 +1,126 @@
/* 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.tips
import android.content.SharedPreferences
import android.view.LayoutInflater
import androidx.core.view.isGone
import androidx.core.view.isVisible
import io.mockk.MockKAnnotations
import io.mockk.Runs
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.just
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import kotlinx.android.synthetic.main.button_tip_item.*
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.components.tips.Tip
import org.mozilla.fenix.components.tips.TipType
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor
import org.mozilla.fenix.utils.Settings
@RunWith(FenixRobolectricTestRunner::class)
class ButtonTipViewHolderTest {
@MockK private lateinit var activity: HomeActivity
@MockK private lateinit var interactor: SessionControlInteractor
@MockK(relaxed = true) private lateinit var metrics: MetricController
@MockK private lateinit var settings: Settings
@MockK private lateinit var sharedPrefs: SharedPreferences
@MockK private lateinit var sharedPrefsEditor: SharedPreferences.Editor
private lateinit var viewHolder: ButtonTipViewHolder
@Before
fun setup() {
MockKAnnotations.init(this)
val view = spyk(LayoutInflater.from(testContext)
.inflate(ButtonTipViewHolder.LAYOUT_ID, null))
viewHolder = ButtonTipViewHolder(view, interactor, metrics, settings)
every { view.context } returns activity
every { activity.openToBrowserAndLoad(any(), any(), any()) } just Runs
every { interactor.onCloseTip(any()) } just Runs
every { settings.preferences } returns sharedPrefs
every { sharedPrefs.edit() } returns sharedPrefsEditor
every { sharedPrefsEditor.putBoolean(any(), any()) } returns sharedPrefsEditor
every { sharedPrefsEditor.apply() } just Runs
}
@Test
fun `text is displayed based on given tip`() {
viewHolder.bind(defaultTip())
assertEquals("Tip Title", viewHolder.tip_header_text.text)
assertEquals("Tip description", viewHolder.tip_description_text.text)
assertEquals("button", viewHolder.tip_button.text)
verify { metrics.track(Event.TipDisplayed("tipIdentifier")) }
}
@Test
fun `learn more is hidden if learnMoreURL is null`() {
viewHolder.bind(defaultTip(learnMoreUrl = null))
assertTrue(viewHolder.tip_learn_more.isGone)
}
@Test
fun `learn more is visible if learnMoreURL is not null`() {
viewHolder.bind(defaultTip(learnMoreUrl = "https://learnmore.com"))
assertTrue(viewHolder.tip_learn_more.isVisible)
viewHolder.tip_learn_more.performClick()
verify { activity.openToBrowserAndLoad(
searchTermOrURL = "https://learnmore.com",
newTab = true,
from = BrowserDirection.FromHome
) }
}
@Test
fun `tip button invokes tip action`() {
val action = mockk<() -> Unit>(relaxed = true)
viewHolder.bind(defaultTip(action))
viewHolder.tip_button.performClick()
verify { action() }
verify { metrics.track(Event.TipPressed("tipIdentifier")) }
}
@Test
fun `close button invokes onCloseTip`() {
val tip = defaultTip()
viewHolder.bind(tip)
viewHolder.tip_close.performClick()
verify { interactor.onCloseTip(tip) }
verify { metrics.track(Event.TipClosed("tipIdentifier")) }
verify { sharedPrefsEditor.putBoolean("tipIdentifier", false) }
}
private fun defaultTip(
action: () -> Unit = mockk(),
learnMoreUrl: String? = null
) = Tip(
type = TipType.Button("button", action),
identifier = "tipIdentifier",
title = "Tip Title",
description = "Tip description",
learnMoreURL = learnMoreUrl
)
}