Selaa lähdekoodia

Patch up integration tests for file sharing

This requires a lot of dodgy code, unfortunately. A refactor is greatly needed here.

Signed-off-by: Álvaro Brey Vilas <alvaro.brey@nextcloud.com>
Álvaro Brey Vilas 3 vuotta sitten
vanhempi
commit
b367684e21

+ 72 - 3
src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt

@@ -23,7 +23,9 @@
  */
 package com.owncloud.android.ui.fragment
 
+import android.view.View
 import androidx.test.espresso.Espresso.onView
+import androidx.test.espresso.accessibility.AccessibilityChecks
 import androidx.test.espresso.action.ViewActions
 import androidx.test.espresso.assertion.ViewAssertions.matches
 import androidx.test.espresso.intent.rule.IntentsTestRule
@@ -32,6 +34,9 @@ import androidx.test.espresso.matcher.ViewMatchers.isChecked
 import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
 import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
 import androidx.test.espresso.matcher.ViewMatchers.withText
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultBaseUtils.matchesCheckNames
+import com.google.android.apps.common.testing.accessibility.framework.AccessibilityCheckResultUtils.matchesViews
+import com.google.android.material.floatingactionbutton.FloatingActionButton
 import com.nextcloud.client.TestActivity
 import com.owncloud.android.AbstractIT
 import com.owncloud.android.R
@@ -45,8 +50,12 @@ import com.owncloud.android.lib.resources.shares.OCShare.NO_PERMISSION
 import com.owncloud.android.lib.resources.shares.OCShare.READ_PERMISSION_FLAG
 import com.owncloud.android.lib.resources.shares.OCShare.SHARE_PERMISSION_FLAG
 import com.owncloud.android.lib.resources.shares.ShareType
+import com.owncloud.android.ui.activity.FileDisplayActivity
 import com.owncloud.android.ui.fragment.util.SharingMenuHelper
 import com.owncloud.android.utils.ScreenshotTest
+import org.hamcrest.CoreMatchers.`is`
+import org.hamcrest.CoreMatchers.allOf
+import org.hamcrest.CoreMatchers.anyOf
 import org.hamcrest.CoreMatchers.not
 import org.junit.After
 import org.junit.Assert.assertFalse
@@ -68,6 +77,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun before() {
         activity = testActivityRule.launchActivity(null)
         file = OCFile("/test.md").apply {
+            remoteId = "00000001"
             parentId = activity.storageManager.getFileByEncryptedRemotePath("/").fileId
             permissions = OCFile.PERMISSION_CAN_RESHARE
         }
@@ -223,6 +233,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun publicLinkOptionMenuFolderAdvancePermission() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -233,6 +244,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         }
 
         activity.runOnUiThread { sut.showSharingMenuActionSheet(publicShare) }
+        shortSleep()
+        waitForIdleSync()
 
         // check if items are visible
         onView(ViewMatchers.withId(R.id.menu_share_open_in)).check(matches(not(isDisplayed())))
@@ -319,6 +332,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun publicLinkOptionMenuFolderSendNewEmail() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -331,6 +345,17 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         verifySendNewEmail(sut, publicShare)
     }
 
+    private fun setupSecondaryFragment() {
+        val secondary = FileDetailFragment.newInstance(file, user)
+        activity.addSecondaryFragment(secondary, FileDisplayActivity.TAG_LIST_OF_FILES)
+        activity.addView(
+            FloatingActionButton(activity).apply { // needed for some reason
+                visibility = View.GONE
+                id = R.id.fab_main
+            }
+        )
+    }
+
     @Test
     @Suppress("MagicNumber")
     // public link and email are handled the same way
@@ -338,6 +363,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun publicLinkOptionMenuFileAdvancePermission() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -346,7 +372,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
             shareType = ShareType.PUBLIC_LINK
             permissions = 17
         }
-        activity.runOnUiThread { sut.showSharingMenuActionSheet(publicShare) }
+        activity.handler.post { sut.showSharingMenuActionSheet(publicShare) }
+        waitForIdleSync()
 
         // check if items are visible
         onView(ViewMatchers.withId(R.id.menu_share_open_in)).check(matches(isDisplayed()))
@@ -426,6 +453,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun publicLinkOptionMenuFileSendNewEmail() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -448,7 +476,9 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     // for advanced permissions
     fun userOptionMenuFileAdvancePermission() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
+        suppressFDFAccessibilityChecks()
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -459,6 +489,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         }
 
         activity.runOnUiThread { sut.showSharingMenuActionSheet(userShare) }
+        shortSleep()
+        waitForIdleSync()
 
         // check if items are visible
         onView(ViewMatchers.withId(R.id.menu_share_open_in)).check(matches(isDisplayed()))
@@ -470,6 +502,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
 
         // click event
         onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
+        shortSleep()
+        waitForIdleSync()
 
         // validate view shown on screen
         onView(ViewMatchers.withId(R.id.share_process_permission_read_only)).check(matches(isDisplayed()))
@@ -518,6 +552,23 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         onView(ViewMatchers.withId(R.id.share_process_select_exp_date)).check(matches(withText("")))
     }
 
+    private fun suppressFDFAccessibilityChecks() {
+        AccessibilityChecks.enable().apply {
+            setSuppressingResultMatcher(
+                allOf(
+                    anyOf(
+                        matchesCheckNames(`is`("TouchTargetSizeCheck")),
+                        matchesCheckNames(`is`("SpeakableTextPresentCheck")),
+                    ),
+                    anyOf(
+                        matchesViews(ViewMatchers.withId(R.id.favorite)),
+                        matchesViews(ViewMatchers.withId(R.id.last_modification_timestamp))
+                    )
+                )
+            )
+        }
+    }
+
     @Test
     @Suppress("MagicNumber")
     // also applies for
@@ -529,6 +580,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun userOptionMenuFileSendNewEmail() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -552,6 +604,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun userOptionMenuFolderAdvancePermission() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
+        suppressFDFAccessibilityChecks()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -562,6 +616,8 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         }
 
         activity.runOnUiThread { sut.showSharingMenuActionSheet(userShare) }
+        shortSleep()
+        waitForIdleSync()
 
         // check if items are visible
         onView(ViewMatchers.withId(R.id.menu_share_open_in)).check(matches(not(isDisplayed())))
@@ -636,13 +692,23 @@ class FileDetailSharingFragmentIT : AbstractIT() {
         sut: FileDetailSharingFragment,
         userShare: OCShare
     ) {
-        activity.runOnUiThread { sut.showSharingMenuActionSheet(userShare) }
+        activity.handler.post {
+            sut.showSharingMenuActionSheet(userShare)
+        }
+        waitForIdleSync()
         onView(ViewMatchers.withId(R.id.menu_share_advanced_permissions)).perform(ViewActions.click())
     }
 
     // remove the fragment shown
     private fun goBack() {
-        onView(ViewMatchers.withId(R.id.share_process_btn_cancel)).perform(ViewActions.click())
+        activity.handler.post {
+            val processFragment =
+                activity.supportFragmentManager.findFragmentByTag(FileDetailsSharingProcessFragment.TAG) as
+                    FileDetailsSharingProcessFragment
+            processFragment.onBackPressed()
+        }
+        shortSleep()
+        waitForIdleSync()
     }
 
     @Test
@@ -656,6 +722,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     fun userOptionMenuFolderSendNewEmail() {
         val sut = FileDetailSharingFragment.newInstance(file, user)
         activity.addFragment(sut)
+        setupSecondaryFragment()
         shortSleep()
         sut.refreshCapabilitiesFromDB()
 
@@ -677,6 +744,7 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     ) {
         activity.runOnUiThread { sut.showSharingMenuActionSheet(userShare) }
 
+        waitForIdleSync()
         // click event
         onView(ViewMatchers.withId(R.id.menu_share_send_new_email)).perform(ViewActions.click())
 
@@ -776,5 +844,6 @@ class FileDetailSharingFragmentIT : AbstractIT() {
     @After
     fun after() {
         activity.storageManager.cleanShares()
+        activity.finish()
     }
 }

+ 31 - 2
src/debug/java/com/nextcloud/client/TestActivity.kt

@@ -22,11 +22,13 @@
 package com.nextcloud.client
 
 import android.os.Bundle
+import android.view.View
 import androidx.fragment.app.Fragment
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
 import com.nextcloud.client.network.Connectivity
 import com.nextcloud.client.network.ConnectivityService
 import com.owncloud.android.R
+import com.owncloud.android.databinding.TestLayoutBinding
 import com.owncloud.android.datamodel.FileDataStorageManager
 import com.owncloud.android.datamodel.OCFile
 import com.owncloud.android.files.services.FileDownloader
@@ -45,8 +47,11 @@ class TestActivity :
     SwipeRefreshLayout.OnRefreshListener,
     OnEnforceableRefreshListener {
     lateinit var fragment: Fragment
+    lateinit var secondaryFragment: Fragment
+
     private lateinit var storage: FileDataStorageManager
     private lateinit var fileOperation: FileOperationsHelper
+    private lateinit var binding: TestLayoutBinding
 
     private val connectivityServiceMock: ConnectivityService = object : ConnectivityService {
         override fun isInternetWalled(): Boolean {
@@ -61,16 +66,40 @@ class TestActivity :
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
 
-        setContentView(R.layout.test_layout)
+        binding = TestLayoutBinding.inflate(layoutInflater)
+        setContentView(binding.root)
     }
 
     fun addFragment(fragment: Fragment) {
         this.fragment = fragment
         val transaction = supportFragmentManager.beginTransaction()
-        transaction.replace(R.id.root, fragment)
+        transaction.replace(R.id.main_fragment, fragment)
+        transaction.commit()
+    }
+
+    /**
+     * Adds a secondary fragment to the activity with the given tag.
+     *
+     * If you have to use this, your Fragments are coupled, and you should feel bad.
+     */
+    fun addSecondaryFragment(fragment: Fragment, tag: String) {
+        this.secondaryFragment = fragment
+        val transaction = supportFragmentManager.beginTransaction()
+        transaction.replace(R.id.secondary_fragment, fragment, tag)
         transaction.commit()
     }
 
+    /**
+     * Adds a View to the activity.
+     *
+     * If you have to use this, your Fragment is coupled to your Activity and you should feel bad.
+     */
+    fun addView(view: View) {
+        handler.post {
+            binding.rootLayout.addView(view)
+        }
+    }
+
     override fun onBrowsedDownTo(folder: OCFile?) {
         TODO("Not yet implemented")
     }

+ 1 - 0
src/main/java/com/owncloud/android/ui/fragment/FileDetailsSharingProcessFragment.kt

@@ -24,6 +24,7 @@ package com.owncloud.android.ui.fragment
 import android.content.Context
 import android.os.Bundle
 import android.text.TextUtils
+import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup

+ 13 - 3
src/main/res/layout/test_layout.xml

@@ -17,11 +17,21 @@
   You should have received a copy of the GNU Affero General Public
   License along with this program. If not, see <http://www.gnu.org/licenses/>.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/root"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fitsSystemWindows="true"
+    android:id="@+id/root_layout"
     android:orientation="vertical">
 
-</LinearLayout>
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/secondary_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/main_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</FrameLayout>