For #4231 added unit tests for most recent apps
parent
fdbf63fb97
commit
9d972fa1d0
|
@ -45,7 +45,7 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(
|
||||
By.text("SHARE A LINK")
|
||||
By.text("ALL ACTIONS")
|
||||
), waitingTime
|
||||
)
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class LibrarySubMenusMultipleSelectionToolbarRobot {
|
|||
|
||||
mDevice.waitNotNull(
|
||||
Until.findObject(
|
||||
By.text("SHARE A LINK")
|
||||
By.text("ALL ACTIONS")
|
||||
), waitingTime
|
||||
)
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class ThreeDotMenuMainRobot {
|
|||
fun verifyReaderViewAppearance(visible: Boolean) = assertReaderViewAppearanceButton(visible)
|
||||
fun clickShareButton() {
|
||||
shareButton().click()
|
||||
mDevice.waitNotNull(Until.findObject(By.text("SHARE A LINK")), waitingTime)
|
||||
mDevice.waitNotNull(Until.findObject(By.text("ALL ACTIONS")), waitingTime)
|
||||
}
|
||||
|
||||
fun verifyShareTabButton() = assertShareTabButton()
|
||||
|
@ -293,7 +293,7 @@ private fun assertSendToDeviceTitle() = SendToDeviceTitle()
|
|||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
|
||||
|
||||
private fun ShareALinkTitle() =
|
||||
onView(allOf(withText(R.string.share_link_all_apps_subheader), withResourceName("apps_link_header")))
|
||||
onView(allOf(withText("ALL ACTIONS"), withResourceName("apps_link_header")))
|
||||
|
||||
private fun assertShareALinkTitle() = ShareALinkTitle()
|
||||
|
||||
|
|
|
@ -31,12 +31,13 @@ import org.mozilla.fenix.share.listadapters.SyncShareOption
|
|||
class ShareViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
companion object {
|
||||
private const val RECENT_APPS_LIMIT = 6
|
||||
internal const val RECENT_APPS_LIMIT = 6
|
||||
}
|
||||
|
||||
private val connectivityManager by lazy { application.getSystemService<ConnectivityManager>() }
|
||||
private val fxaAccountManager = application.components.backgroundServices.accountManager
|
||||
private val recentAppsStorage = RecentAppsStorage(application.applicationContext)
|
||||
@VisibleForTesting
|
||||
internal var recentAppsStorage = RecentAppsStorage(application.applicationContext)
|
||||
|
||||
private val devicesListLiveData = MutableLiveData<List<SyncShareOption>>(emptyList())
|
||||
private val appsListLiveData = MutableLiveData<List<AppShareOption>>(emptyList())
|
||||
|
@ -131,8 +132,9 @@ class ShareViewModel(application: Application) : AndroidViewModel(application) {
|
|||
connectivityManager?.unregisterNetworkCallback(networkCallback)
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@WorkerThread
|
||||
private fun getIntentActivities(shareIntent: Intent, context: Context): List<ResolveInfo>? {
|
||||
fun getIntentActivities(shareIntent: Intent, context: Context): List<ResolveInfo>? {
|
||||
return context.packageManager.queryIntentActivities(shareIntent, 0)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import io.mockk.slot
|
|||
import io.mockk.verify
|
||||
import io.mockk.verifyOrder
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.ObsoleteCoroutinesApi
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import mozilla.components.browser.session.Session
|
||||
import mozilla.components.feature.session.SessionUseCases
|
||||
import mozilla.components.feature.sitepermissions.SitePermissions
|
||||
|
@ -42,16 +42,17 @@ import org.mozilla.fenix.utils.Settings
|
|||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@UseExperimental(ObsoleteCoroutinesApi::class)
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
class DefaultQuickSettingsControllerTest {
|
||||
private val context = testContext
|
||||
private val store = mockk<QuickSettingsFragmentStore>()
|
||||
private val coroutinesScope = GlobalScope
|
||||
private val coroutinesScope = TestCoroutineScope()
|
||||
private val navController = mockk<NavController>(relaxed = true)
|
||||
private val browserSession = mockk<Session>()
|
||||
private val sitePermissions = SitePermissions(origin = "", savedAt = 123)
|
||||
private val sitePermissions: SitePermissions = SitePermissions(origin = "", savedAt = 123)
|
||||
private val appSettings = mockk<Settings>(relaxed = true)
|
||||
private val permissionStorage = mockk<PermissionStorage>(relaxed = true)
|
||||
private val reload = mockk<SessionUseCases.ReloadUrlUseCase>(relaxed = true)
|
||||
|
@ -121,9 +122,8 @@ class DefaultQuickSettingsControllerTest {
|
|||
// We want to verify that the Status is toggled and this event is passed to Controller also.
|
||||
assertThat(sitePermissions.camera).isSameAs(NO_DECISION)
|
||||
verifyOrder {
|
||||
sitePermissions.toggle(capture(toggledFeature)).also {
|
||||
controller.handlePermissionsChange(it)
|
||||
}
|
||||
val permission = sitePermissions.toggle(capture(toggledFeature))
|
||||
controller.handlePermissionsChange(permission)
|
||||
}
|
||||
// We should also modify View's state. Not necessarily as the last operation.
|
||||
verify {
|
||||
|
|
|
@ -22,11 +22,15 @@ import io.mockk.slot
|
|||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import io.mockk.verifyOrder
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.TestCoroutineScope
|
||||
import mozilla.components.concept.engine.prompt.ShareData
|
||||
import mozilla.components.concept.sync.Device
|
||||
import mozilla.components.concept.sync.DeviceType
|
||||
import mozilla.components.concept.sync.TabData
|
||||
import mozilla.components.feature.accounts.push.SendTabUseCases
|
||||
import mozilla.components.feature.share.RecentAppsStorage
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
@ -44,6 +48,7 @@ import org.robolectric.annotation.Config
|
|||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
@ExperimentalCoroutinesApi
|
||||
class ShareControllerTest {
|
||||
// Need a valid context to retrieve Strings for example, but we also need it to return our "metrics"
|
||||
private val context: Context = spyk(testContext)
|
||||
|
@ -58,12 +63,15 @@ class ShareControllerTest {
|
|||
TabData("title1", "url1")
|
||||
)
|
||||
private val textToShare = "${shareData[0].title} ${shareData[0].url}\n\n${shareData[1].title} ${shareData[1].url}"
|
||||
private val testCoroutineScope = TestCoroutineScope()
|
||||
private val sendTabUseCases = mockk<SendTabUseCases>(relaxed = true)
|
||||
private val snackbar = mockk<FenixSnackbar>(relaxed = true)
|
||||
private val navController = mockk<NavController>(relaxed = true)
|
||||
private val dismiss = mockk<(ShareController.Result) -> Unit>(relaxed = true)
|
||||
private val recentAppStorage = mockk<RecentAppsStorage>(relaxed = true)
|
||||
private val controller = DefaultShareController(
|
||||
context, shareData, sendTabUseCases, snackbar, navController, dismiss
|
||||
context, shareData, sendTabUseCases, snackbar, navController,
|
||||
recentAppStorage, testCoroutineScope, dismiss
|
||||
)
|
||||
|
||||
@Before
|
||||
|
@ -79,7 +87,7 @@ class ShareControllerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `handleShareToApp should start a new sharing activity and close this`() {
|
||||
fun `handleShareToApp should start a new sharing activity and close this`() = runBlocking {
|
||||
val appPackageName = "package"
|
||||
val appClassName = "activity"
|
||||
val appShareOption = AppShareOption("app", mockk(), appPackageName, appClassName)
|
||||
|
@ -88,8 +96,10 @@ class ShareControllerTest {
|
|||
// needed for capturing the actual Intent used the `slot` one doesn't have this flag so we
|
||||
// need to use an Activity Context.
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(activityContext, shareData, mockk(), mockk(), mockk(), dismiss)
|
||||
val testController = DefaultShareController(activityContext, shareData, mockk(), mockk(), mockk(),
|
||||
recentAppStorage, testCoroutineScope, dismiss)
|
||||
every { activityContext.startActivity(capture(shareIntent)) } just Runs
|
||||
every { recentAppStorage.updateRecentApp(appShareOption.packageName) } just Runs
|
||||
|
||||
testController.handleShareToApp(appShareOption)
|
||||
|
||||
|
@ -104,6 +114,7 @@ class ShareControllerTest {
|
|||
assertThat(shareIntent.captured.component!!.className).isEqualTo(appClassName)
|
||||
}
|
||||
verifyOrder {
|
||||
recentAppStorage.updateRecentApp(appShareOption.packageName)
|
||||
activityContext.startActivity(shareIntent.captured)
|
||||
dismiss(ShareController.Result.SUCCESS)
|
||||
}
|
||||
|
@ -119,7 +130,8 @@ class ShareControllerTest {
|
|||
// needed for capturing the actual Intent used the `slot` one doesn't have this flag so we
|
||||
// need to use an Activity Context.
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(activityContext, shareData, mockk(), snackbar, mockk(), dismiss)
|
||||
val testController = DefaultShareController(activityContext, shareData, mockk(), snackbar,
|
||||
mockk(), mockk(), testCoroutineScope, dismiss)
|
||||
every { activityContext.startActivity(capture(shareIntent)) } throws SecurityException()
|
||||
every { activityContext.getString(R.string.share_error_snackbar) } returns "Cannot share to this app"
|
||||
|
||||
|
@ -242,7 +254,14 @@ class ShareControllerTest {
|
|||
@Test
|
||||
fun `getSuccessMessage should return different strings depending on the number of shared tabs`() {
|
||||
val controllerWithOneSharedTab = DefaultShareController(
|
||||
context, listOf(ShareData(url = "url0", title = "title0")), mockk(), mockk(), mockk(), mockk()
|
||||
context,
|
||||
listOf(ShareData(url = "url0", title = "title0")),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk()
|
||||
)
|
||||
val controllerWithMoreSharedTabs = controller
|
||||
val expectedTabSharedMessage = context.getString(R.string.sync_sent_tab_snackbar)
|
||||
|
|
|
@ -11,12 +11,19 @@ import android.content.pm.ResolveInfo
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.net.ConnectivityManager
|
||||
import androidx.core.content.getSystemService
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.TestCoroutineDispatcher
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import mozilla.components.feature.share.RecentApp
|
||||
import mozilla.components.feature.share.RecentAppsStorage
|
||||
import mozilla.components.service.fxa.manager.FxaAccountManager
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import org.junit.Assert.assertEquals
|
||||
|
@ -27,6 +34,7 @@ import org.mozilla.fenix.TestApplication
|
|||
import org.mozilla.fenix.ext.application
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.isOnline
|
||||
import org.mozilla.fenix.share.ShareViewModel.Companion.RECENT_APPS_LIMIT
|
||||
import org.mozilla.fenix.share.listadapters.AppShareOption
|
||||
import org.mozilla.fenix.share.listadapters.SyncShareOption
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
@ -34,6 +42,7 @@ import org.robolectric.annotation.Config
|
|||
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@Config(application = TestApplication::class)
|
||||
@ExperimentalCoroutinesApi
|
||||
class ShareViewModelTest {
|
||||
|
||||
private val packageName = "org.mozilla.fenix"
|
||||
|
@ -67,10 +76,38 @@ class ShareViewModelTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `loadDevicesAndApps registers networkCallback`() = runBlocking {
|
||||
fun `loadDevicesAndApps`() = runBlockingTest {
|
||||
mockkStatic(Dispatchers::class)
|
||||
every {
|
||||
Dispatchers.IO
|
||||
} returns TestCoroutineDispatcher()
|
||||
viewModel = spyk(viewModel)
|
||||
val drawable: Drawable = mockk()
|
||||
val appOptions = ArrayList<AppShareOption>()
|
||||
val appElement = AppShareOption("Label", drawable, "Package", "Activity")
|
||||
appOptions.add(appElement)
|
||||
|
||||
val recentAppOptions = ArrayList<RecentApp>()
|
||||
val appEntity: RecentApp = mockk()
|
||||
every { appEntity.packageName } returns "Package"
|
||||
recentAppOptions.add(appEntity)
|
||||
val storage: RecentAppsStorage = mockk(relaxed = true)
|
||||
viewModel.recentAppsStorage = storage
|
||||
|
||||
every { viewModel.buildAppsList(any(), any()) } returns appOptions
|
||||
every { storage.updateDatabaseWithNewApps(appOptions.map { app -> app.packageName }) } just Runs
|
||||
every { storage.getRecentAppsUpTo(RECENT_APPS_LIMIT) } returns recentAppOptions
|
||||
|
||||
viewModel.loadDevicesAndApps()
|
||||
|
||||
verify { connectivityManager.registerNetworkCallback(any(), eq(viewModel.networkCallback)) }
|
||||
verify {
|
||||
connectivityManager.registerNetworkCallback(
|
||||
any(),
|
||||
any<ConnectivityManager.NetworkCallback>()
|
||||
)
|
||||
}
|
||||
assertEquals(1, viewModel.recentAppsList.value?.size)
|
||||
assertEquals(0, viewModel.appsList.value?.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -115,7 +152,10 @@ class ShareViewModelTest {
|
|||
every { fxaAccountManager.authenticatedAccount() } returns mockk()
|
||||
every { fxaAccountManager.accountNeedsReauth() } returns true
|
||||
|
||||
assertEquals(listOf(SyncShareOption.Reconnect), viewModel.buildDeviceList(fxaAccountManager))
|
||||
assertEquals(
|
||||
listOf(SyncShareOption.Reconnect),
|
||||
viewModel.buildDeviceList(fxaAccountManager)
|
||||
)
|
||||
}
|
||||
|
||||
private fun createResolveInfo(
|
||||
|
|
Loading…
Reference in New Issue