浏览代码

Add test for FileMenuFilter that verifies file locking menu items

Signed-off-by: Álvaro Brey Vilas <alvaro.brey@nextcloud.com>
Álvaro Brey Vilas 3 年之前
父节点
当前提交
f50d9f8451
共有 3 个文件被更改,包括 209 次插入2 次删除
  1. 1 0
      app/build.gradle
  2. 6 2
      app/detekt.yml
  3. 202 0
      app/src/androidTest/java/com/owncloud/android/files/FileMenuFilterIT.kt

+ 1 - 0
app/build.gradle

@@ -318,6 +318,7 @@ dependencies {
     // Android JUnit Runner
     androidTestImplementation "androidx.test:runner:$androidxTestVersion"
     androidTestUtil "androidx.test:orchestrator:$androidxTestVersion"
+    androidTestImplementation "androidx.test:core-ktx:$androidxTestVersion"
 
     // Espresso
     androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"

+ 6 - 2
app/detekt.yml

@@ -202,7 +202,9 @@ naming:
     functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
     excludeClassPattern: '$^'
     ignoreOverridden: true
-    excludes: "**/*Test.kt"
+    excludes:
+      - "**/*Test.kt"
+      - "**/*IT.kt"
   FunctionParameterNaming:
     active: true
     parameterPattern: '[a-z][A-Za-z0-9]*'
@@ -324,7 +326,9 @@ style:
     ignoreAnnotation: false
     ignoreNamedArgument: true
     ignoreEnums: false
-    excludes: "**/*Test.kt"
+    excludes:
+      - "**/*Test.kt"
+      - "**/*IT.kt"
   MandatoryBracesIfStatements:
     active: false
   MaxLineLength:

+ 202 - 0
app/src/androidTest/java/com/owncloud/android/files/FileMenuFilterIT.kt

@@ -0,0 +1,202 @@
+/*
+ * Nextcloud Android client application
+ *
+ * @author Álvaro Brey Vilas
+ * Copyright (C) 2022 Álvaro Brey Vilas
+ * Copyright (C) 2022 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+package com.owncloud.android.files
+
+import android.view.Menu
+import androidx.appcompat.view.menu.MenuBuilder
+import androidx.test.core.app.launchActivity
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.nextcloud.client.TestActivity
+import com.nextcloud.client.account.User
+import com.owncloud.android.AbstractIT
+import com.owncloud.android.R
+import com.owncloud.android.datamodel.FileDataStorageManager
+import com.owncloud.android.datamodel.OCFile
+import com.owncloud.android.lib.resources.files.model.FileLockType
+import com.owncloud.android.lib.resources.status.CapabilityBooleanType
+import com.owncloud.android.lib.resources.status.OCCapability
+import com.owncloud.android.ui.activity.ComponentsGetter
+import org.junit.After
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+class FileMenuFilterIT : AbstractIT() {
+
+    @Mock
+    private lateinit var componentsGetter: ComponentsGetter
+
+    @Mock
+    private lateinit var fileDataStorageManager: FileDataStorageManager
+
+    private lateinit var mocks: AutoCloseable
+
+    @Before
+    fun setup() {
+        mocks = MockitoAnnotations.openMocks(this)
+    }
+
+    @After
+    fun tearDown() {
+        mocks.close()
+    }
+
+    @Test
+    fun filter_noLockingCapability_lockItemsInvisible() {
+        val capability = OCCapability().apply {
+            endToEndEncryption = CapabilityBooleanType.UNKNOWN
+        }
+
+        val file = OCFile("/foo.md")
+
+        testLockingVisibilities(
+            capability,
+            file,
+            ExpectedLockVisibilities(lockFile = false, unlockFile = false, lockedBy = false, lockedUntil = false)
+        )
+    }
+
+    @Test
+    fun filter_lockingCapability_fileUnlocked_lockVisible() {
+        val capability = OCCapability().apply {
+            endToEndEncryption = CapabilityBooleanType.UNKNOWN
+            filesLockingVersion = "1.0"
+        }
+
+        val file = OCFile("/foo.md")
+
+        testLockingVisibilities(
+            capability,
+            file,
+            ExpectedLockVisibilities(lockFile = true, unlockFile = false, lockedBy = false, lockedUntil = false)
+        )
+    }
+
+    @Test
+    fun filter_lockingCapability_fileLocked_lockedByAndProps() {
+        val capability = OCCapability().apply {
+            endToEndEncryption = CapabilityBooleanType.UNKNOWN
+            filesLockingVersion = "1.0"
+        }
+
+        val file = OCFile("/foo.md").apply {
+            isLocked = true
+            lockType = FileLockType.MANUAL
+            lockOwnerId = user.accountName.split("@")[0]
+            lockOwnerDisplayName = "TEST"
+            lockTimestamp = 1000 // irrelevant
+            lockTimeout = 1000 // irrelevant
+        }
+
+        testLockingVisibilities(
+            capability,
+            file,
+            ExpectedLockVisibilities(lockFile = false, unlockFile = true, lockedBy = true, lockedUntil = true)
+        )
+    }
+
+    @Test
+    fun filter_lockingCapability_fileLockedByOthers_lockedByAndProps() {
+        val capability = OCCapability().apply {
+            endToEndEncryption = CapabilityBooleanType.UNKNOWN
+            filesLockingVersion = "1.0"
+        }
+
+        val file = OCFile("/foo.md").apply {
+            isLocked = true
+            lockType = FileLockType.MANUAL
+            lockOwnerId = "A_DIFFERENT_USER"
+            lockOwnerDisplayName = "A_DIFFERENT_USER"
+            lockTimestamp = 1000 // irrelevant
+            lockTimeout = 1000 // irrelevant
+        }
+        testLockingVisibilities(
+            capability,
+            file,
+            ExpectedLockVisibilities(lockFile = false, unlockFile = false, lockedBy = true, lockedUntil = true)
+        )
+    }
+
+    private data class ExpectedLockVisibilities(
+        val lockFile: Boolean,
+        val unlockFile: Boolean,
+        val lockedBy: Boolean,
+        val lockedUntil: Boolean
+    )
+
+    private fun configureCapability(capability: OCCapability) {
+        whenever(fileDataStorageManager.getCapability(any<User>())).thenReturn(capability)
+        whenever(fileDataStorageManager.getCapability(any<String>())).thenReturn(capability)
+        whenever(componentsGetter.storageManager).thenReturn(fileDataStorageManager)
+    }
+
+    private fun getMenu(activity: TestActivity): Menu {
+        val inflater = activity.menuInflater
+        val menu = MenuBuilder(activity)
+        inflater.inflate(R.menu.item_file, menu)
+        return menu
+    }
+
+    private fun testLockingVisibilities(
+        capability: OCCapability,
+        file: OCFile,
+        expectedLockVisibilities: ExpectedLockVisibilities
+    ) {
+        configureCapability(capability)
+
+        launchActivity<TestActivity>().use {
+            it.onActivity { activity ->
+                val menu = getMenu(activity)
+
+                val sut = FileMenuFilter(file, componentsGetter, activity, true, user)
+
+                sut.filter(menu, false)
+
+                Assert.assertEquals(
+                    expectedLockVisibilities.lockFile,
+                    menu.findItem(R.id.action_lock_file).isVisible
+                )
+                Assert.assertEquals(
+                    expectedLockVisibilities.unlockFile,
+                    menu.findItem(R.id.action_unlock_file).isVisible
+                )
+                Assert.assertEquals(
+                    expectedLockVisibilities.lockedBy,
+                    menu.findItem(R.id.action_locked_by).isVisible
+                )
+                Assert.assertEquals(
+                    expectedLockVisibilities.lockedUntil,
+                    menu.findItem(R.id.action_locked_until).isVisible
+                )
+
+                // locked by and until should always be disabled, they're not real actions
+                Assert.assertFalse(menu.findItem(R.id.action_locked_by).isEnabled)
+                Assert.assertFalse(menu.findItem(R.id.action_locked_until).isEnabled)
+            }
+        }
+    }
+}