Unverified Commit 3f7205e3 authored by Tiger Oakes's avatar Tiger Oakes Committed by GitHub
Browse files

Extract IntentProcessorType to its own file and add tests (#7012)

parent 7477de83
Loading
Loading
Loading
Loading
+15 −55
Original line number Diff line number Diff line
@@ -10,52 +10,13 @@ import android.os.Bundle
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import mozilla.components.feature.intent.processing.IntentProcessor
import mozilla.components.support.utils.Browsers
import org.mozilla.fenix.components.IntentProcessors
import org.mozilla.fenix.components.getType
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.shortcut.NewTabShortcutIntentProcessor

enum class IntentProcessorType {
    EXTERNAL_APP, NEW_TAB, OTHER;

    /**
     * The destination activity based on this intent
     */
    val activityClassName: String
        get() = when (this) {
            EXTERNAL_APP -> ExternalAppBrowserActivity::class.java.name
            NEW_TAB -> HomeActivity::class.java.name
            OTHER -> HomeActivity::class.java.name
        }

    /**
     * Should this intent automatically navigate to the browser?
     */
    fun shouldOpenToBrowser(intent: Intent): Boolean = when (this) {
        EXTERNAL_APP -> true
        NEW_TAB -> intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0
        OTHER -> false
    }
}

/**
 * Classifies the [IntentType] based on the [IntentProcessor] that handled the [Intent]
 */
fun IntentProcessor?.getType(intentProcessors: IntentProcessors): IntentProcessorType {
    return when {
        intentProcessors.externalAppIntentProcessors.contains(this) ||
            intentProcessors.customTabIntentProcessor == this ||
            intentProcessors.privateCustomTabIntentProcessor == this -> IntentProcessorType.EXTERNAL_APP
        intentProcessors.intentProcessor == this ||
                intentProcessors.privateIntentProcessor == this -> IntentProcessorType.NEW_TAB
        else -> IntentProcessorType.OTHER
    }
}

/**
 * Processes incoming intents and sends them to the corresponding activity.
 */
@@ -106,9 +67,8 @@ class IntentReceiverActivity : Activity() {
        // Call process for side effects, short on the first that returns true
        intentProcessors.any { it.process(intent) }

        val intentProcessorType = intentProcessors
            .firstOrNull { it.matches(intent) }
            .getType(components.intentProcessors)
        val intentProcessorType =
            components.intentProcessors.getType(intentProcessors.firstOrNull { it.matches(intent) })

        intent.setClassName(applicationContext, intentProcessorType.activityClassName)
        intent.putExtra(HomeActivity.OPEN_TO_BROWSER, intentProcessorType.shouldOpenToBrowser(intent))
+44 −0
Original line number Diff line number Diff line
/* 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.components

import android.content.Intent
import mozilla.components.feature.intent.processing.IntentProcessor
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity

enum class IntentProcessorType {
    EXTERNAL_APP, NEW_TAB, OTHER;

    /**
     * The destination activity based on this intent
     */
    val activityClassName: String
        get() = when (this) {
            EXTERNAL_APP -> ExternalAppBrowserActivity::class.java.name
            NEW_TAB, OTHER -> HomeActivity::class.java.name
        }

    /**
     * Should this intent automatically navigate to the browser?
     */
    fun shouldOpenToBrowser(intent: Intent): Boolean = when (this) {
        EXTERNAL_APP -> true
        NEW_TAB -> intent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0
        OTHER -> false
    }
}

/**
 * Classifies the [IntentProcessorType] based on the [IntentProcessor] that handled the [Intent].
 */
fun IntentProcessors.getType(processor: IntentProcessor?) = when {
    externalAppIntentProcessors.contains(processor) ||
            customTabIntentProcessor == processor ||
            privateCustomTabIntentProcessor == processor -> IntentProcessorType.EXTERNAL_APP
    intentProcessor == processor ||
            privateIntentProcessor == processor -> IntentProcessorType.NEW_TAB
    else -> IntentProcessorType.OTHER
}
+114 −0
Original line number Diff line number Diff line
/* 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.components

import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
import io.mockk.every
import io.mockk.mockk
import mozilla.components.feature.intent.processing.IntentProcessor
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.TestApplication
import org.mozilla.fenix.customtabs.ExternalAppBrowserActivity
import org.mozilla.fenix.ext.components
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(application = TestApplication::class)
class IntentProcessorTypeTest {

    @Test
    fun `should open intent with flag launched from history`() {
        val intent: Intent = mockk()
        every { intent.flags } returns FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

        assertTrue(IntentProcessorType.EXTERNAL_APP.shouldOpenToBrowser(intent))
        assertFalse(IntentProcessorType.NEW_TAB.shouldOpenToBrowser(intent))
        assertFalse(IntentProcessorType.OTHER.shouldOpenToBrowser(intent))
    }

    @Test
    fun `should open intent without flag launched from history`() {
        val intent: Intent = mockk()
        every { intent.flags } returns 0

        assertTrue(IntentProcessorType.EXTERNAL_APP.shouldOpenToBrowser(intent))
        assertTrue(IntentProcessorType.NEW_TAB.shouldOpenToBrowser(intent))
        assertFalse(IntentProcessorType.OTHER.shouldOpenToBrowser(intent))
    }

    @Test
    fun `get type for normal intent processor`() {
        val processor = testContext.components.intentProcessors.intentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.NEW_TAB, type)
        assertEquals(HomeActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for private intent processor`() {
        val processor = testContext.components.intentProcessors.privateIntentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.NEW_TAB, type)
        assertEquals(HomeActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for custom tab intent processor`() {
        val processor = testContext.components.intentProcessors.customTabIntentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.EXTERNAL_APP, type)
        assertEquals(ExternalAppBrowserActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for private custom tab intent processor`() {
        val processor = testContext.components.intentProcessors.privateCustomTabIntentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.EXTERNAL_APP, type)
        assertEquals(ExternalAppBrowserActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for TWA intent processor`() {
        val processor = testContext.components.intentProcessors.privateCustomTabIntentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.EXTERNAL_APP, type)
        assertEquals(ExternalAppBrowserActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for PWA intent processor`() {
        val processor = testContext.components.intentProcessors.privateCustomTabIntentProcessor
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.EXTERNAL_APP, type)
        assertEquals(ExternalAppBrowserActivity::class.java.name, type.activityClassName)
    }

    @Test
    fun `get type for generic intent processor`() {
        val processor = object : IntentProcessor {
            override fun matches(intent: Intent) = true
            override suspend fun process(intent: Intent) = true
        }
        val type = testContext.components.intentProcessors.getType(processor)

        assertEquals(IntentProcessorType.OTHER, type)
        assertEquals(HomeActivity::class.java.name, type.activityClassName)
    }
}