You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iceraven-browser/app/src/test/java/org/mozilla/fenix/perf/StartupPathProviderTest.kt

204 lines
7.4 KiB
Kotlin

/* 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.perf
import android.content.Intent
import androidx.lifecycle.Lifecycle
import io.mockk.MockKAnnotations
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.perf.StartupPathProvider.StartupPath
class StartupPathProviderTest {
private lateinit var provider: StartupPathProvider
private lateinit var callbacks: StartupPathProvider.StartupPathLifecycleObserver
@MockK private lateinit var intent: Intent
@Before
fun setUp() {
MockKAnnotations.init(this)
provider = StartupPathProvider()
callbacks = provider.getTestCallbacks()
}
@Test
fun `WHEN attach is called THEN the provider is registered to the lifecycle`() {
val lifecycle = mockk<Lifecycle>(relaxed = true)
provider.attachOnActivityOnCreate(lifecycle, null)
verify { lifecycle.addObserver(any()) }
}
@Test
fun `WHEN calling attach THEN the intent is passed to on intent received`() {
// With this test, we're basically saying, "attach..." does the same thing as
// "onIntentReceived" so we don't need to duplicate all the tests we run for
// "onIntentReceived".
val spyProvider = spyk(provider)
every { spyProvider.onIntentReceived(intent) } returns Unit
spyProvider.attachOnActivityOnCreate(mockk(relaxed = true), intent)
verify { spyProvider.onIntentReceived(intent) }
}
@Test
fun `GIVEN no intent is received and the activity is not started WHEN getting the start up path THEN it is not set`() {
assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity)
}
@Test
fun `GIVEN a main intent is received but the activity is not started yet WHEN getting the start up path THEN main is returned`() {
every { intent.action } returns Intent.ACTION_MAIN
provider.onIntentReceived(intent)
assertEquals(StartupPath.MAIN, provider.startupPathForActivity)
}
@Test
fun `GIVEN a main intent is received and the app is started WHEN getting the start up path THEN it is main`() {
every { intent.action } returns Intent.ACTION_MAIN
callbacks.onCreate(mockk())
provider.onIntentReceived(intent)
callbacks.onStart(mockk())
assertEquals(StartupPath.MAIN, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched from the homescreen WHEN getting the start up path THEN it is main`() {
// There's technically more to a homescreen Intent but it's fine for now.
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
assertEquals(StartupPath.MAIN, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched by app link WHEN getting the start up path THEN it is view`() {
// There's technically more to a homescreen Intent but it's fine for now.
every { intent.action } returns Intent.ACTION_VIEW
launchApp(intent)
assertEquals(StartupPath.VIEW, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched by a send action WHEN getting the start up path THEN it is unknown`() {
every { intent.action } returns Intent.ACTION_SEND
launchApp(intent)
assertEquals(StartupPath.UNKNOWN, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched by a null intent (is this possible) WHEN getting the start up path THEN it is not set`() {
callbacks.onCreate(mockk())
provider.onIntentReceived(null)
callbacks.onStart(mockk())
callbacks.onResume(mockk())
assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched to the homescreen and stopped WHEN getting the start up path THEN it is not set`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
stopLaunchedApp()
assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched to the homescreen, stopped, and relaunched warm from app link WHEN getting the start up path THEN it is view`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
stopLaunchedApp()
every { intent.action } returns Intent.ACTION_VIEW
startStoppedApp(intent)
assertEquals(StartupPath.VIEW, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched to the homescreen, stopped, and relaunched warm from the app switcher WHEN getting the start up path THEN it is not set`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
stopLaunchedApp()
startStoppedAppFromAppSwitcher()
assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched to the homescreen, paused, and resumed WHEN getting the start up path THEN it returns the initial intent value`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
callbacks.onPause(mockk())
callbacks.onResume(mockk())
assertEquals(StartupPath.MAIN, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched with an intent and receives an intent while the activity is foregrounded WHEN getting the start up path THEN it returns the initial intent value`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
every { intent.action } returns Intent.ACTION_VIEW
receiveIntentInForeground(intent)
assertEquals(StartupPath.MAIN, provider.startupPathForActivity)
}
@Test
fun `GIVEN the app is launched, stopped, started from the app switcher and receives an intent in the foreground WHEN getting the start up path THEN it returns not set`() {
every { intent.action } returns Intent.ACTION_MAIN
launchApp(intent)
stopLaunchedApp()
startStoppedAppFromAppSwitcher()
every { intent.action } returns Intent.ACTION_VIEW
receiveIntentInForeground(intent)
assertEquals(StartupPath.NOT_SET, provider.startupPathForActivity)
}
private fun launchApp(intent: Intent) {
callbacks.onCreate(mockk())
provider.onIntentReceived(intent)
callbacks.onStart(mockk())
callbacks.onResume(mockk())
}
private fun stopLaunchedApp() {
callbacks.onPause(mockk())
callbacks.onStop(mockk())
}
private fun startStoppedApp(intent: Intent) {
callbacks.onStart(mockk())
provider.onIntentReceived(intent)
callbacks.onResume(mockk())
}
private fun startStoppedAppFromAppSwitcher() {
// What makes the app switcher case special is it starts the app without an intent.
callbacks.onStart(mockk())
callbacks.onResume(mockk())
}
private fun receiveIntentInForeground(intent: Intent) {
// To my surprise, the app is paused before receiving an intent on Pixel 2.
callbacks.onPause(mockk())
provider.onIntentReceived(intent)
callbacks.onResume(mockk())
}
}