From 16de092daf9b61cd35dea9fc860b6e4619c35af3 Mon Sep 17 00:00:00 2001 From: Nicolas Pomepuy Date: Mon, 9 Dec 2024 12:55:24 +0100 Subject: [PATCH] Mock the network items in espresso --- .../vlc/PhoneScreenhotsInstrumentedTest.kt | 25 ++++++++++++++++++ .../java/org/videolan/resources/Constants.kt | 1 + .../vlc/gui/browser/MainBrowserFragment.kt | 4 ++- .../org/videolan/vlc/gui/helpers/Navigator.kt | 26 +++++++++++++++---- .../videolan/vlc/providers/NetworkProvider.kt | 10 +++++-- .../vlc/viewmodels/browser/BrowserModel.kt | 7 ++--- .../vlc/viewmodels/browser/NetworkModel.kt | 7 ++--- 7 files changed, 66 insertions(+), 14 deletions(-) diff --git a/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt b/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt index fe40268d9..1108ccc88 100644 --- a/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt +++ b/application/app/src/androidTest/java/org/videolan/vlc/PhoneScreenhotsInstrumentedTest.kt @@ -26,6 +26,7 @@ package org.videolan.vlc import android.content.Intent import android.content.pm.ActivityInfo +import android.net.Uri import android.os.SystemClock import android.util.Log import androidx.core.view.get @@ -43,6 +44,7 @@ import org.hamcrest.core.AllOf import org.junit.ClassRule import org.junit.Rule import org.junit.Test +import org.videolan.resources.EXTRA_FOR_ESPRESSO import org.videolan.resources.EXTRA_TARGET import org.videolan.tools.Settings import org.videolan.vlc.gui.MainActivity @@ -167,6 +169,29 @@ class PhoneScreenhotsInstrumentedTest : BaseUITest() { Settings.getInstance(context).edit().putBoolean("auto_rescan", false).putBoolean("audio_resume_card", false).commit() val intent = Intent().apply { putExtra(EXTRA_TARGET, R.id.nav_audio) + putParcelableArrayListExtra( + EXTRA_FOR_ESPRESSO, arrayListOf( + MLServiceLocator.getAbstractMediaWrapper( + Uri.parse("upnp://test/mock"), 0L, 0F, 0L, MediaWrapper.TYPE_ALL, + null, "My NAS", -1, -1, "", + "", -1, "", "", + 0, 0, "/storage/emulated/0/Download/upnp2.png", + 0, 0, 0, + 0, 0L, 0L, + 0L + ), + MLServiceLocator.getAbstractMediaWrapper( + Uri.parse("upnp://test/mock"), 0L, 0F, 0L, MediaWrapper.TYPE_ALL, + null, "My SMB server", -1, -1, "", + "", -1, "", "", + 0, 0, "/storage/emulated/0/Download/upnp1.png", + 0, 0, 0, + 0, 0L, 0L, + 0L + ) + + ) + ) } activityTestRule.launchActivity(intent) activity = activityTestRule.activity diff --git a/application/resources/src/main/java/org/videolan/resources/Constants.kt b/application/resources/src/main/java/org/videolan/resources/Constants.kt index 91dc6c0ef..479d72d8d 100644 --- a/application/resources/src/main/java/org/videolan/resources/Constants.kt +++ b/application/resources/src/main/java/org/videolan/resources/Constants.kt @@ -27,6 +27,7 @@ const val EXTRA_FIRST_RUN = "extra_first_run" const val EXTRA_UPGRADE = "extra_upgrade" const val EXTRA_PARSE = "extra_parse" const val EXTRA_TARGET = "extra_parse" +const val EXTRA_FOR_ESPRESSO = "extra_for_espresso" const val EXTRA_REMOVE_DEVICE = "extra_remove_device" //UI Navigation diff --git a/application/vlc-android/src/org/videolan/vlc/gui/browser/MainBrowserFragment.kt b/application/vlc-android/src/org/videolan/vlc/gui/browser/MainBrowserFragment.kt index c802fbcf3..cca0ef5f5 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/browser/MainBrowserFragment.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/browser/MainBrowserFragment.kt @@ -37,6 +37,8 @@ import kotlinx.coroutines.withContext import org.videolan.medialibrary.interfaces.media.MediaWrapper import org.videolan.medialibrary.media.MediaLibraryItem import org.videolan.medialibrary.media.MediaWrapperImpl +import org.videolan.resources.EXTRA_FOR_ESPRESSO +import org.videolan.resources.util.parcelableList import org.videolan.tools.* import org.videolan.vlc.R import org.videolan.vlc.gui.BaseFragment @@ -163,7 +165,7 @@ class MainBrowserFragment : BaseFragment(), View.OnClickListener, CtxActionRecei super.onCreate(savedInstanceState) localViewModel = getBrowserModel(category = TYPE_FILE, url = null) favoritesViewModel = BrowserFavoritesModel(requireContext()) - networkViewModel = getBrowserModel(category = TYPE_NETWORK, url = null) + networkViewModel = getBrowserModel(category = TYPE_NETWORK, url = null, mocked = arguments?.parcelableList(EXTRA_FOR_ESPRESSO)) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/Navigator.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/Navigator.kt index 3e9482eb4..84f76c2d5 100644 --- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/Navigator.kt +++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/Navigator.kt @@ -24,10 +24,11 @@ package org.videolan.vlc.gui.helpers import android.app.Activity -import android.content.* +import android.content.SharedPreferences import android.os.Bundle import android.view.MenuItem import androidx.core.content.edit +import androidx.core.os.bundleOf import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.lifecycle.DefaultLifecycleObserver @@ -35,11 +36,22 @@ import androidx.lifecycle.LifecycleOwner import com.google.android.material.appbar.AppBarLayout import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.navigation.NavigationBarView -import org.videolan.resources.* -import org.videolan.tools.* +import org.videolan.medialibrary.media.MediaLibraryItem +import org.videolan.resources.EXTRA_FOR_ESPRESSO +import org.videolan.resources.EXTRA_TARGET +import org.videolan.resources.ID_AUDIO +import org.videolan.resources.ID_DIRECTORIES +import org.videolan.resources.ID_VIDEO +import org.videolan.resources.util.parcelableList +import org.videolan.tools.isStarted +import org.videolan.tools.setGone +import org.videolan.tools.setVisible import org.videolan.vlc.BuildConfig import org.videolan.vlc.R -import org.videolan.vlc.gui.* +import org.videolan.vlc.gui.BaseFragment +import org.videolan.vlc.gui.MainActivity +import org.videolan.vlc.gui.MoreFragment +import org.videolan.vlc.gui.PlaylistFragment import org.videolan.vlc.gui.audio.AudioBrowserFragment import org.videolan.vlc.gui.browser.BaseBrowserFragment import org.videolan.vlc.gui.browser.MainBrowserFragment @@ -59,11 +71,13 @@ class Navigator : NavigationBarView.OnItemSelectedListener, DefaultLifecycleObse private lateinit var settings: SharedPreferences override lateinit var navigationView: List override lateinit var appbarLayout: AppBarLayout + private var forExpresso: ArrayList? = null override fun MainActivity.setupNavigation(state: Bundle?) { activity = this this@Navigator.settings = settings + forExpresso = intent.parcelableList(EXTRA_FOR_ESPRESSO) currentFragmentId = intent.getIntExtra(EXTRA_TARGET, 0) if (state !== null) { currentFragment = supportFragmentManager.getFragment(state, "current_fragment") @@ -85,7 +99,9 @@ class Navigator : NavigationBarView.OnItemSelectedListener, DefaultLifecycleObse private fun getNewFragment(id: Int): Fragment { return when (id) { R.id.nav_audio -> AudioBrowserFragment() - R.id.nav_directories -> MainBrowserFragment() + R.id.nav_directories -> MainBrowserFragment().apply { + arguments = bundleOf(EXTRA_FOR_ESPRESSO to forExpresso) + } R.id.nav_playlists -> PlaylistFragment() R.id.nav_more -> MoreFragment() else -> VideoBrowserFragment() diff --git a/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt b/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt index 956253540..1649ea6d7 100644 --- a/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt +++ b/application/vlc-android/src/org/videolan/vlc/providers/NetworkProvider.kt @@ -21,6 +21,8 @@ package org.videolan.vlc.providers import android.content.Context +import android.graphics.Bitmap +import android.net.Uri import androidx.core.net.toUri import androidx.lifecycle.Observer import kotlinx.coroutines.Dispatchers @@ -28,6 +30,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.videolan.libvlc.util.MediaBrowser +import org.videolan.medialibrary.MLServiceLocator import org.videolan.medialibrary.interfaces.Medialibrary import org.videolan.medialibrary.interfaces.media.MediaWrapper import org.videolan.medialibrary.media.DummyItem @@ -38,7 +41,7 @@ import org.videolan.tools.livedata.LiveDataset import org.videolan.vlc.R import java.util.concurrent.atomic.AtomicBoolean -class NetworkProvider(context: Context, dataset: LiveDataset, url: String? = null): BrowserProvider(context, dataset, url, Medialibrary.SORT_FILENAME, false), Observer> { +class NetworkProvider(context: Context, dataset: LiveDataset, url: String? = null, val mocked: ArrayList? = null): BrowserProvider(context, dataset, url, Medialibrary.SORT_FILENAME, false), Observer> { override fun initBrowser() { if (alreadyRunning.getAndSet(true)) { @@ -76,7 +79,10 @@ class NetworkProvider(context: Context, dataset: LiveDataset, override suspend fun browseRootImpl() { dataset.clear() dataset.value = mutableListOf() - if (NetworkMonitor.getInstance(context).lanAllowed) browse() + if (mocked!= null) + dataset.value = mocked.toMutableList() + else + if (NetworkMonitor.getInstance(context).lanAllowed) browse() } override fun fetch() {} diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt index 32a986ebc..0ad96af7b 100644 --- a/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt +++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/BrowserModel.kt @@ -59,6 +59,7 @@ open class BrowserModel( val type: Long, private val showDummyCategory: Boolean, pickerType: PickerType = PickerType.SUBTITLE, + mocked: ArrayList? = null, coroutineContextProvider: CoroutineContextProvider = CoroutineContextProvider() ) : BaseModel( context, coroutineContextProvider), @@ -69,7 +70,7 @@ open class BrowserModel( override val provider: BrowserProvider = when (type) { TYPE_PICKER -> FilePickerProvider(context, dataset, url, pickerType = pickerType) - TYPE_NETWORK -> NetworkProvider(context, dataset, url) + TYPE_NETWORK -> NetworkProvider(context, dataset, url, mocked) TYPE_STORAGE -> StorageProvider(context, dataset, url) else -> FileBrowserProvider(context, dataset, url, showDummyCategory = showDummyCategory, sort = sort, desc = desc) } @@ -178,7 +179,7 @@ open class BrowserModel( } } -fun Fragment.getBrowserModel(category: Long, url: String?, showDummyCategory: Boolean = false) = if (category == TYPE_NETWORK) - ViewModelProvider(this, NetworkModel.Factory(requireContext(), url)).get(NetworkModel::class.java) +fun Fragment.getBrowserModel(category: Long, url: String?, showDummyCategory: Boolean = false, mocked: ArrayList? = null) = if (category == TYPE_NETWORK) + ViewModelProvider(this, NetworkModel.Factory(requireContext(), url, mocked)).get(NetworkModel::class.java) else ViewModelProvider(this, BrowserModel.Factory(requireContext(), url, category, showDummyCategory = showDummyCategory)).get(BrowserModel::class.java) diff --git a/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt b/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt index d30b9821d..6af6affdb 100644 --- a/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt +++ b/application/vlc-android/src/org/videolan/vlc/viewmodels/browser/NetworkModel.kt @@ -26,10 +26,11 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import org.videolan.medialibrary.media.MediaLibraryItem import org.videolan.tools.CoroutineContextProvider import org.videolan.tools.NetworkMonitor -class NetworkModel(context: Context, url: String? = null, coroutineContextProvider: CoroutineContextProvider = CoroutineContextProvider()) : BrowserModel(context, url, TYPE_NETWORK, true, coroutineContextProvider = coroutineContextProvider) { +class NetworkModel(context: Context, url: String? = null, mocked: ArrayList? = null, coroutineContextProvider: CoroutineContextProvider = CoroutineContextProvider()) : BrowserModel(context, url, TYPE_NETWORK,false, mocked = mocked, coroutineContextProvider = coroutineContextProvider) { init { NetworkMonitor.getInstance(context).connectionFlow.onEach { @@ -38,10 +39,10 @@ class NetworkModel(context: Context, url: String? = null, coroutineContextProvid }.launchIn(viewModelScope) } - class Factory(val context: Context, val url: String?): ViewModelProvider.NewInstanceFactory() { + class Factory(val context: Context, val url: String?, val mocked: ArrayList? = null): ViewModelProvider.NewInstanceFactory() { override fun create(modelClass: Class): T { @Suppress("UNCHECKED_CAST") - return NetworkModel(context.applicationContext, url) as T + return NetworkModel(context.applicationContext, url, mocked) as T } } } \ No newline at end of file