[fenix] For https://github.com/mozilla-mobile/fenix/issues/12801 - Extra debug menu trigger, disable if already triggered
parent
1df7dce5d0
commit
fb7c801b38
@ -0,0 +1,71 @@
|
||||
/* 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.about
|
||||
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.OnLifecycleEvent
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* Triggers the "secret" debug menu when logoView is tapped 5 times.
|
||||
*/
|
||||
class SecretDebugMenuTrigger(
|
||||
logoView: View,
|
||||
private val settings: Settings
|
||||
) : View.OnClickListener, LifecycleObserver {
|
||||
|
||||
private var secretDebugMenuClicks = 0
|
||||
private var lastDebugMenuToast: Toast? = null
|
||||
|
||||
init {
|
||||
if (!settings.showSecretDebugMenuThisSession) {
|
||||
logoView.setOnClickListener(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the [secretDebugMenuClicks] counter.
|
||||
*/
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
fun clearClickCounter() {
|
||||
secretDebugMenuClicks = 0
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
// Because the user will mostly likely tap the logo in rapid succession,
|
||||
// we ensure only 1 toast is shown at any given time.
|
||||
lastDebugMenuToast?.cancel()
|
||||
secretDebugMenuClicks += 1
|
||||
when (secretDebugMenuClicks) {
|
||||
in 2 until SECRET_DEBUG_MENU_CLICKS -> {
|
||||
val clicksLeft = SECRET_DEBUG_MENU_CLICKS - secretDebugMenuClicks
|
||||
val toast = Toast.makeText(
|
||||
v.context,
|
||||
v.context.getString(R.string.about_debug_menu_toast_progress, clicksLeft),
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
toast.show()
|
||||
lastDebugMenuToast = toast
|
||||
}
|
||||
SECRET_DEBUG_MENU_CLICKS -> {
|
||||
Toast.makeText(
|
||||
v.context,
|
||||
R.string.about_debug_menu_toast_done,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
settings.showSecretDebugMenuThisSession = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// Number of clicks on the app logo to enable the "secret" debug menu.
|
||||
private const val SECRET_DEBUG_MENU_CLICKS = 5
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/* 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.about
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import io.mockk.CapturingSlot
|
||||
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.mockkStatic
|
||||
import io.mockk.slot
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class SecretDebugMenuTriggerTest {
|
||||
|
||||
@MockK private lateinit var logoView: View
|
||||
@MockK private lateinit var context: Context
|
||||
@MockK private lateinit var settings: Settings
|
||||
@MockK(relaxUnitFun = true) private lateinit var toast: Toast
|
||||
private lateinit var clickListener: CapturingSlot<View.OnClickListener>
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
MockKAnnotations.init(this)
|
||||
mockkStatic(Toast::class)
|
||||
clickListener = slot()
|
||||
|
||||
every { logoView.setOnClickListener(capture(clickListener)) } just Runs
|
||||
every { logoView.context } returns context
|
||||
every {
|
||||
context.getString(R.string.about_debug_menu_toast_progress, any())
|
||||
} returns "Debug menu: x click(s) left to enable"
|
||||
every { settings.showSecretDebugMenuThisSession } returns false
|
||||
every { settings.showSecretDebugMenuThisSession = any() } just Runs
|
||||
every { Toast.makeText(context, any<Int>(), any()) } returns toast
|
||||
every { Toast.makeText(context, any<String>(), any()) } returns toast
|
||||
}
|
||||
|
||||
@After
|
||||
fun teardown() {
|
||||
unmockkStatic(Toast::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toast is not displayed on first click`() {
|
||||
SecretDebugMenuTrigger(logoView, settings)
|
||||
clickListener.captured.onClick(logoView)
|
||||
|
||||
verify(inverse = true) { Toast.makeText(context, any<String>(), any()) }
|
||||
verify(inverse = true) { toast.show() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toast is displayed on second click`() {
|
||||
SecretDebugMenuTrigger(logoView, settings)
|
||||
clickListener.captured.onClick(logoView)
|
||||
clickListener.captured.onClick(logoView)
|
||||
|
||||
verify { context.getString(R.string.about_debug_menu_toast_progress, 3) }
|
||||
verify { Toast.makeText(context, any<String>(), Toast.LENGTH_SHORT) }
|
||||
verify { toast.show() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clearClickCounter resets counter`() {
|
||||
val trigger = SecretDebugMenuTrigger(logoView, settings)
|
||||
|
||||
clickListener.captured.onClick(logoView)
|
||||
trigger.clearClickCounter()
|
||||
|
||||
clickListener.captured.onClick(logoView)
|
||||
|
||||
verify(inverse = true) { Toast.makeText(context, any<String>(), any()) }
|
||||
verify(inverse = true) { toast.show() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toast is displayed on fifth click`() {
|
||||
SecretDebugMenuTrigger(logoView, settings)
|
||||
clickListener.captured.onClick(logoView)
|
||||
clickListener.captured.onClick(logoView)
|
||||
clickListener.captured.onClick(logoView)
|
||||
clickListener.captured.onClick(logoView)
|
||||
clickListener.captured.onClick(logoView)
|
||||
|
||||
verify { Toast.makeText(
|
||||
context,
|
||||
R.string.about_debug_menu_toast_done,
|
||||
Toast.LENGTH_LONG
|
||||
) }
|
||||
verify { toast.show() }
|
||||
verify { settings.showSecretDebugMenuThisSession = true }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `don't register click listener if menu is already shown`() {
|
||||
every { settings.showSecretDebugMenuThisSession } returns true
|
||||
SecretDebugMenuTrigger(logoView, settings)
|
||||
|
||||
verify(inverse = true) { logoView.setOnClickListener(any()) }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue