From b74284e1a357699e3ca39b652999f3de57eb43b5 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 19 Jul 2020 11:20:39 +0800 Subject: [PATCH 01/32] Adaptations to Robolectric 4.3 - Update gradle plugin to 3.6.4, the minimal version without updating to SDK 29. This is necessary for fixing some classloader issues with BouncyCastle when running tests - Update to Robolectric 4.3; also added AndroidX test packages as required - As first step to Robolectric adaptation, removed no longer valid `constants = BuildConfig.class` in tests --- app/build.gradle | 10 ++++++++-- .../compress/AbstractCompressedHelperTaskTest.java | 2 -- .../asynchronous/services/ExtractServiceTest.java | 2 -- .../amaze/filemanager/filesystem/OperationsTest.java | 2 -- .../amaze/filemanager/filesystem/RootHelperTest.java | 2 -- .../filesystem/cloud/CloudStreamSourceTest.java | 2 -- .../filesystem/compressed/B0rkenZipTest.java | 2 -- .../filesystem/compressed/CompressedHelperTest.java | 2 -- .../extractcontents/AbstractExtractorTest.java | 2 -- .../filesystem/files/FileListSorterTest.java | 2 -- .../filesystem/smbstreamer/StreamSourceTest.java | 2 -- .../filesystem/ssh/AbstractSftpServerTest.java | 2 -- .../filesystem/ssh/SshConnectionPoolTest.java | 2 -- .../filesystem/usb/SingletonUsbOtgTest.java | 2 -- .../amaze/filemanager/filesystem/usb/UsbOtgTest.java | 2 -- .../amaze/filemanager/test/ShadowCryptUtilTest.java | 2 -- .../filemanager/ui/activities/MainActivityTest.java | 2 -- .../ui/activities/TextEditorActivityTest.java | 2 -- .../java/com/amaze/filemanager/ui/icons/IconsTest.java | 2 -- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 21 files changed, 11 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 072f82aefa..88138400db 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -85,14 +85,14 @@ android { } ext { - robolectricVersion = '3.8' + robolectricVersion = '4.3' glideVersion = '4.11.0' sshjVersion = '0.26.0' jcifsVersion = '2.1.3' fabSpeedDialVersion = '3.1.1' roomVersion = '2.2.5' bouncyCastleVersion = '1.65' - awaitilityVersion = "3.1.6" + awaitilityVersion = "4.0.3" } dependencies { @@ -115,6 +115,12 @@ dependencies { testImplementation 'junit:junit:4.12'//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction + testImplementation 'androidx.test:core:1.2.0' + testImplementation 'androidx.test:runner:1.2.0' + testImplementation 'androidx.test:rules:1.2.0' + testImplementation 'androidx.test.ext:junit:1.1.1' +// testImplementation 'androidx.test.ext:truth:1.2.0' +// testImplementation 'com.google.truth:truth:0.42' testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index e292fdc8a1..7f3490dcd5 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -36,7 +36,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.CompressedObjectParcelable; import com.amaze.filemanager.asynchronous.asynctasks.AsyncTaskResult; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -45,7 +44,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 27, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index d2fae6f272..8d276a336d 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -42,7 +42,6 @@ import org.robolectric.shadows.ShadowEnvironment; import org.robolectric.shadows.ShadowToast; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -53,7 +52,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class ExtractServiceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 0e9c0dc33b..8a4000e65f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -33,7 +33,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; @@ -42,7 +41,6 @@ @RunWith(RobolectricTestRunner.class) @Config( maxSdk = 27, - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}) public class OperationsTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index 7a2f1a1725..714715e28b 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -38,7 +38,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.test.ShadowShellInteractive; import com.amaze.filemanager.ui.activities.MainActivity; @@ -49,7 +48,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, maxSdk = 27) public class RootHelperTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index c5a10ee96f..c1778e0e8f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -39,7 +39,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.os.Environment; @@ -47,7 +46,6 @@ /** Created by Rustam Khadipash on 31/3/2018. */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class CloudStreamSourceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index d0ffef1965..9054059334 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -36,7 +36,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.adapters.data.CompressedObjectParcelable; import com.amaze.filemanager.asynchronous.asynctasks.compress.ZipHelperTask; @@ -48,7 +47,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class B0rkenZipTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index 51f99a5bfe..f16ceb5222 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -33,7 +33,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.compressed.extractcontents.Extractor; import com.amaze.filemanager.filesystem.compressed.extractcontents.helpers.Bzip2Extractor; import com.amaze.filemanager.filesystem.compressed.extractcontents.helpers.GzipExtractor; @@ -58,7 +57,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class CompressedHelperTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index 6fe6f01a27..c14d8da229 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -43,7 +43,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.compressed.ArchivePasswordCache; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -52,7 +51,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 14, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index 8cf0efa219..2055d3e498 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -32,7 +32,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowDateFormat; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.LayoutElementParcelable; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; @@ -43,7 +42,6 @@ */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, maxSdk = 27) public class FileListSorterTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index ddbcfc71c2..873eeeec1e 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -37,7 +37,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.shadows.jcifs.smb.ShadowSmbFile; @@ -48,7 +47,6 @@ /** Created by Rustam Khadipash on 30/3/2018. */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, maxSdk = 27) public class StreamSourceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index 06a62d0a86..f1d24471bb 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -39,7 +39,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.ssh.test.TestKeyProvider; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -47,7 +46,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public abstract class AbstractSftpServerTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index 318010d4a1..1e2194a592 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -38,7 +38,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.database.UtilitiesDatabase; import com.amaze.filemanager.database.UtilsHandler; import com.amaze.filemanager.database.models.OperationData; @@ -54,7 +53,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, maxSdk = 27) public class SshConnectionPoolTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 1f2694a006..7d1d0ccbb5 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -31,7 +31,6 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.ui.activities.MainActivity; @@ -40,7 +39,6 @@ @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 9d7ae3d5ed..46be1ae2c8 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -33,7 +33,6 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.StorageDirectoryParcelable; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.ui.activities.MainActivity; @@ -44,7 +43,6 @@ @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index 9fcf0f6d32..a8e3e0e6aa 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -31,7 +31,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.database.UtilitiesDatabase; import com.amaze.filemanager.database.UtilsHandler; import com.amaze.filemanager.database.models.OperationData; @@ -41,7 +40,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, maxSdk = 27) public class ShadowCryptUtilTest { diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index f88a610ad4..5ebd236266 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -28,12 +28,10 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class MainActivityTest { diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 81fc202483..240e404b28 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -42,7 +42,6 @@ import org.robolectric.shadows.ShadowContentResolver; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.application.AppConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -56,7 +55,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 7738346a9b..0862363ebe 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -30,14 +30,12 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowMimeTypeMap; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.webkit.MimeTypeMap; @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class IconsTest { diff --git a/build.gradle b/build.gradle index 32441b83c7..72804fdd25 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.6.4' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0708d5ee2..b0225133bb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 24 12:34:34 ART 2019 +#Sun Jul 19 11:09:24 HKT 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip From 1b43654b58d387fc9d2fa98793bebdc61cc2fe53 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 25 Jul 2020 22:22:25 +0800 Subject: [PATCH 02/32] build.gradle cleanups, add support for test against API 28 - decoupled some library versions to variables - add support for tests against API 28. API 29 requires Java 9, so it's disabled (although stub had been added) - change test runner to AndroidJUnit4 per docs recommended - RuntimeEnvironment.application -> ApplicationProvider.getApplicationContext() (where applicable - GenericCopyUtilTest relies on Theories to run test, can still use old method) --- app/build.gradle | 50 +++++----- .../AbstractCompressedHelperTaskTest.java | 7 +- .../compress/EncryptedZipHelperTaskTest.java | 6 +- .../compress/TarGzHelperTaskTest.java | 6 +- .../compress/ZipHelperTaskTest.java | 6 +- .../services/ExtractServiceTest.java | 16 +-- .../filesystem/OperationsTest.java | 41 ++++---- .../filesystem/RootHelperTest.java | 7 +- .../cloud/CloudStreamSourceTest.java | 7 +- .../filesystem/compressed/B0rkenZipTest.java | 33 ++++--- .../compressed/CompressedHelperTest.java | 11 ++- .../AbstractExtractorTest.java | 13 +-- .../filesystem/files/FileListSorterTest.java | 97 ++++++++++--------- .../smbstreamer/StreamSourceTest.java | 7 +- .../ssh/AbstractSftpServerTest.java | 7 +- .../filesystem/ssh/ListFilesOnSshdTest.java | 7 +- .../filesystem/ssh/SshConnectionPoolTest.java | 12 +-- .../filesystem/usb/SingletonUsbOtgTest.java | 7 +- .../filesystem/usb/UsbOtgTest.java | 7 +- .../filemanager/test/ShadowCryptUtilTest.java | 19 ++-- .../ui/activities/MainActivityTest.java | 7 +- .../ui/activities/TextEditorActivityTest.java | 12 ++- .../amaze/filemanager/ui/icons/IconsTest.java | 7 +- build.gradle | 6 ++ gradle.properties | 2 +- 25 files changed, 216 insertions(+), 184 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 88138400db..6825324c9b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,12 +80,13 @@ android { testOptions { unitTests { includeAndroidResources = true + returnDefaultValues = true } } } ext { - robolectricVersion = '4.3' + robolectricVersion = '4.3.1' glideVersion = '4.11.0' sshjVersion = '0.26.0' jcifsVersion = '2.1.3' @@ -93,6 +94,11 @@ ext { roomVersion = '2.2.5' bouncyCastleVersion = '1.65' awaitilityVersion = "4.0.3" + androidXTestVersion = "1.2.0" + junitVersion = "4.13" + slf4jVersion = "1.7.25" + mockitoVersion = "3.4.4" + androidBillingVersion = "2.1.0" } dependencies { @@ -106,29 +112,28 @@ dependencies { implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.room:room-runtime:$roomVersion" + implementation "com.android.billingclient:billing:$androidBillingVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" - implementation 'com.android.billingclient:billing:2.1.0' annotationProcessor 'androidx.annotation:annotation:1.1.0' //For tests - androidTestImplementation 'junit:junit:4.12'//tests the app logic - testImplementation 'junit:junit:4.12'//tests the app logic + testImplementation "junit:junit:$junitVersion"//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction - testImplementation 'androidx.test:core:1.2.0' - testImplementation 'androidx.test:runner:1.2.0' - testImplementation 'androidx.test:rules:1.2.0' + testImplementation "androidx.test:core:$androidXTestVersion" + testImplementation "androidx.test:runner:$androidXTestVersion" + testImplementation "androidx.test:rules:$androidXTestVersion" testImplementation 'androidx.test.ext:junit:1.1.1' -// testImplementation 'androidx.test.ext:truth:1.2.0' -// testImplementation 'com.google.truth:truth:0.42' - + testImplementation "org.mockito:mockito-core:$mockitoVersion" testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" + testAnnotationProcessor "com.google.auto.service:auto-service:1.0-rc4" + androidTestImplementation "junit:junit:$junitVersion"//tests the app logic androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - debugImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test:rules:1.2.0' - androidTestImplementation 'androidx.annotation:annotation:1.1.0' + androidTestImplementation "androidx.test:core:$androidXTestVersion" + androidTestImplementation "androidx.test:runner:$androidXTestVersion" + androidTestImplementation "androidx.test:rules:$androidXTestVersion" androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'commons-net:commons-net:3.6' androidTestImplementation "org.awaitility:awaitility:$awaitilityVersion" @@ -149,28 +154,18 @@ dependencies { implementation 'com.afollestad.material-dialogs:core:0.9.6.0' implementation 'com.afollestad.material-dialogs:commons:0.9.6.0' - //FTP Server - /* - implementation 'org.apache.mina:mina-core:2.0.13' - implementation 'org.apache.ftpserver:ftpserver-core:1.0.6' - implementation 'org.apache.ftpserver:ftplet-api:1.0.6' - */ - // https://mvnrepository.com/artifact/org.apache.mina/mina-core - implementation group: 'org.apache.mina', name: 'mina-core', version: '2.0.16' // https://mvnrepository.com/artifact/org.slf4j/slf4j-api - implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25' + implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4jVersion // https://mvnrepository.com/artifact/org.slf4j/slf4j-simple - implementation group: 'org.slf4j', name: 'slf4j-android', version: '1.7.25' + implementation group: 'org.slf4j', name: 'slf4j-android', version: slf4jVersion // https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j - implementation group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.25' + implementation group: 'org.slf4j', name: 'jcl-over-slf4j', version: slf4jVersion - //implementation files('libs/ftplet-api-1.1.0-SNAPSHOT.jar') // https://mvnrepository.com/artifact/org.apache.ftpserver/ftplet-api implementation group: 'org.apache.ftpserver', name: 'ftplet-api', version: '1.1.0' - //implementation files('libs/ftpserver-core-1.1.0-SNAPSHOT.jar') // https://mvnrepository.com/artifact/org.apache.ftpserver/ftpserver-core implementation group: 'org.apache.ftpserver', name: 'ftpserver-core', version: '1.1.0' @@ -189,13 +184,12 @@ dependencies { //SFTP implementation "com.hierynomus:sshj:$sshjVersion" + //smb implementation "eu.agno3.jcifs:jcifs-ng:$jcifsVersion" implementation "org.bouncycastle:bcpkix-jdk15on:$bouncyCastleVersion" implementation "org.bouncycastle:bcprov-jdk15on:$bouncyCastleVersion" - implementation "eu.agno3.jcifs:jcifs-ng:$jcifsVersion" - //Glide: loads icons seemlessly implementation "com.github.bumptech.glide:glide:$glideVersion" implementation ("com.github.bumptech.glide:recyclerview-integration:$glideVersion") { diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index 7f3490dcd5..085cac4526 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -32,7 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; @@ -42,11 +41,13 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 27, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractCompressedHelperTaskTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java index d78bc07d2b..79efc9b532 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java @@ -22,15 +22,15 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class EncryptedZipHelperTaskTest extends AbstractCompressedHelperTaskTest { protected CompressedHelperTask createTask(String relativePath) { return new ZipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive-encrypted.zip") .getAbsolutePath(), relativePath, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java index 9004d6366c..f82673002a 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java @@ -22,16 +22,16 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class TarGzHelperTaskTest extends AbstractCompressedHelperTaskTest { @Override protected CompressedHelperTask createTask(String relativePath) { return new GzipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive.tar.gz") .getAbsolutePath(), relativePath, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java index b78c23fa74..0914d91266 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java @@ -22,15 +22,15 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class ZipHelperTaskTest extends AbstractCompressedHelperTaskTest { protected CompressedHelperTask createTask(String relativePath) { return new ZipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive.zip").getAbsolutePath(), relativePath, false, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index 8d276a336d..78a5af6868 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -36,8 +36,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; import org.robolectric.shadows.ShadowToast; @@ -49,11 +47,13 @@ import android.os.Environment; import androidx.annotation.NonNull; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class ExtractServiceTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); @@ -140,7 +140,8 @@ public void tearDown() throws Exception { public void testExtractZipSlip() { performTest(zipfile1); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -148,7 +149,8 @@ public void testExtractZipSlip() { public void testExtractZipSlipWin() { performTest(zipfile2); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -234,7 +236,7 @@ public void testExtractListPasswordProtected7Zip() { private void performTest(@NonNull File archiveFile) { Intent intent = - new Intent(RuntimeEnvironment.application, ExtractService.class) + new Intent(ApplicationProvider.getApplicationContext(), ExtractService.class) .putExtra(ExtractService.KEY_PATH_ZIP, archiveFile.getAbsolutePath()) .putExtra(ExtractService.KEY_ENTRIES_ZIP, new String[0]) .putExtra( diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 8a4000e65f..6c7a6b990a 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -29,8 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -38,9 +36,12 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( - maxSdk = 27, + maxSdk = 28, shadows = {ShadowMultiDex.class}) public class OperationsTest { @@ -67,7 +68,7 @@ public void testMkdir() throws InterruptedException { CountDownLatch waiter = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -87,7 +88,7 @@ public void testMkdirDuplicate() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -102,7 +103,7 @@ public void done(HybridFile hFile, boolean b) { AtomicBoolean assertFlag = new AtomicBoolean(false); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -123,7 +124,7 @@ public void testMkdirNewFolderSameNameAsCurrentFolder() throws InterruptedExcept CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -139,7 +140,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( newFolder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -154,7 +155,7 @@ public void done(HybridFile hFile, boolean b) { AtomicBoolean assertFlag = new AtomicBoolean(false); Operations.mkdir( newFolder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -177,7 +178,7 @@ public void testRename() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( oldFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -193,7 +194,7 @@ public void done(HybridFile hFile, boolean b) { oldFolderHF, newFolderHF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void done(HybridFile hFile, boolean b) { @@ -213,7 +214,7 @@ public void testRenameSameName() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -230,7 +231,7 @@ public void done(HybridFile hFile, boolean b) { folderHF, folderHF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void exists(HybridFile file) { @@ -251,7 +252,7 @@ public void testRenameSameName2() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -268,7 +269,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( folder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -285,7 +286,7 @@ public void done(HybridFile hFile, boolean b) { folderHF, folder2HF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void exists(HybridFile file) { @@ -306,7 +307,7 @@ public void testRenameSameName3() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -323,7 +324,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( folder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -343,7 +344,7 @@ public void done(HybridFile hFile, boolean b) { folder2HF, folder3HF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void done(HybridFile file, boolean b) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index 714715e28b..d27f4c0c5c 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -35,7 +35,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -44,12 +43,14 @@ import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import eu.chainfire.libsuperuser.Shell; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, - maxSdk = 27) + maxSdk = 28) public class RootHelperTest { private static final File sysroot = diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index c1778e0e8f..6764b6edb9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -36,18 +36,19 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + /** Created by Rustam Khadipash on 31/3/2018. */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class CloudStreamSourceTest { private CloudStreamSource cs; private String testFilePath; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index 9054059334..61db2c66dd 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -31,8 +31,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; @@ -45,10 +43,13 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class B0rkenZipTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); @@ -91,7 +92,7 @@ public void setUp() throws Exception { public void testExtractZipWithWrongPathUnix() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile1.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -104,7 +105,7 @@ public void testExtractZipWithWrongPathUnix() throws Exception { public void testExtractZipWithWrongPathWindows() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile2.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -117,7 +118,7 @@ public void testExtractZipWithWrongPathWindows() throws Exception { public void testExtractZipWithSlashPrefixEntry() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile3.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -130,12 +131,17 @@ public void testExtractZipWithSlashPrefixEntry() throws Exception { public void testZipHelperTaskShouldOmitInvalidEntries() throws Exception { ZipHelperTask task = new ZipHelperTask( - RuntimeEnvironment.application, zipfile1.getAbsolutePath(), null, false, (data) -> {}); + ApplicationProvider.getApplicationContext(), + zipfile1.getAbsolutePath(), + null, + false, + (data) -> {}); List result = task.execute().get().result; assertEquals(1, result.size()); assertEquals("good.txt", result.get(0).path); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -143,12 +149,17 @@ public void testZipHelperTaskShouldOmitInvalidEntries() throws Exception { public void testZipHelperTaskShouldOmitInvalidEntriesWithBackslash() throws Exception { ZipHelperTask task = new ZipHelperTask( - RuntimeEnvironment.application, zipfile2.getAbsolutePath(), null, false, (data) -> {}); + ApplicationProvider.getApplicationContext(), + zipfile2.getAbsolutePath(), + null, + false, + (data) -> {}); List result = task.execute().get().result; assertEquals(1, result.size()); assertEquals("good.txt", result.get(0).path); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } } diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index f16ceb5222..b327165fe8 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -29,8 +29,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.filesystem.compressed.extractcontents.Extractor; @@ -55,10 +53,13 @@ import android.content.Context; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class CompressedHelperTest { private Context context; @@ -66,7 +67,7 @@ public class CompressedHelperTest { @Before public void setUp() { - context = RuntimeEnvironment.application; + context = ApplicationProvider.getApplicationContext(); emptyUpdateListener = new Extractor.OnUpdate() { @Override diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index c14d8da229..83bd264f81 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -38,8 +38,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; @@ -49,11 +47,14 @@ import android.content.Context; import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 14, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractExtractorTest { protected abstract Class extractorClass(); @@ -83,7 +84,7 @@ public void testFixEntryName() throws Exception { extractorClass() .getConstructor(Context.class, String.class, String.class, Extractor.OnUpdate.class) .newInstance( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), getArchiveFile().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), null); @@ -117,7 +118,7 @@ protected void doTestExtractFiles() throws Exception { extractorClass() .getConstructor(Context.class, String.class, String.class, Extractor.OnUpdate.class) .newInstance( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), getArchiveFile().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), new Extractor.OnUpdate() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index 2055d3e498..acaa725abc 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -27,8 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowDateFormat; @@ -36,14 +34,17 @@ import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + /** * because of test based on mock-up, extension testing isn't tested so, assume all extension is * "*{slash}*" */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, - maxSdk = 27) + maxSdk = 28) public class FileListSorterTest { /** * Purpose: when dirsOnTop is 0, if file1 is directory && file2 is not directory, result is -1 @@ -55,7 +56,7 @@ public void testDir0File1DirAndFile2NoDir() { FileListSorter fileListSorter = new FileListSorter(0, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -69,7 +70,7 @@ public void testDir0File1DirAndFile2NoDir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -101,7 +102,7 @@ public void testDir0File1NoDirAndFile2Dir() { FileListSorter fileListSorter = new FileListSorter(0, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -115,7 +116,7 @@ public void testDir0File1NoDirAndFile2Dir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -141,7 +142,7 @@ public void testDir1File1DirAndFile2NoDir() { FileListSorter fileListSorter = new FileListSorter(1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -155,7 +156,7 @@ public void testDir1File1DirAndFile2NoDir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -181,7 +182,7 @@ public void testDir1File1NoDirAndFile2Dir() { FileListSorter fileListSorter = new FileListSorter(1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -195,7 +196,7 @@ public void testDir1File1NoDirAndFile2Dir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -223,7 +224,7 @@ public void testSort0File1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -237,7 +238,7 @@ public void testSort0File1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -263,7 +264,7 @@ public void testSort0File2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -277,7 +278,7 @@ public void testSort0File2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -303,7 +304,7 @@ public void testSort0TitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -317,7 +318,7 @@ public void testSort0TitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", @@ -343,7 +344,7 @@ public void testSort1File1DateLastest() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -357,7 +358,7 @@ public void testSort1File1DateLastest() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -383,7 +384,7 @@ public void testSort1File2DateLastest() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -397,7 +398,7 @@ public void testSort1File2DateLastest() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -423,7 +424,7 @@ public void testSort1FileDateSame() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -437,7 +438,7 @@ public void testSort1FileDateSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -463,7 +464,7 @@ public void testSort2NoDirAndFile1SizeBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -477,7 +478,7 @@ public void testSort2NoDirAndFile1SizeBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -503,7 +504,7 @@ public void testSort2NoDirAndFile2SizeBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -517,7 +518,7 @@ public void testSort2NoDirAndFile2SizeBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -543,7 +544,7 @@ public void testSort2NoDirAndFileSizeSame() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -557,7 +558,7 @@ public void testSort2NoDirAndFileSizeSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -584,7 +585,7 @@ public void testSort2File1DirAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -598,7 +599,7 @@ public void testSort2File1DirAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -625,7 +626,7 @@ public void testSort2File1DirAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -639,7 +640,7 @@ public void testSort2File1DirAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -666,7 +667,7 @@ public void testSort2File2DirAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -680,7 +681,7 @@ public void testSort2File2DirAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -707,7 +708,7 @@ public void testSort2File2DirAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -721,7 +722,7 @@ public void testSort2File2DirAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -747,7 +748,7 @@ public void testSort2File2DirAndFileTitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -761,7 +762,7 @@ public void testSort2File2DirAndFileTitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -789,7 +790,7 @@ public void testSort3FileExtensionSameAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -803,7 +804,7 @@ public void testSort3FileExtensionSameAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -831,7 +832,7 @@ public void testSort3FileExtensionSameAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -845,7 +846,7 @@ public void testSort3FileExtensionSameAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -872,7 +873,7 @@ public void testSort3FileExtensionSameAndFileTitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -886,7 +887,7 @@ public void testSort3FileExtensionSameAndFileTitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", @@ -911,7 +912,7 @@ public void testSortAnotherNumber() { FileListSorter fileListSorter = new FileListSorter(-1, 4, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -925,7 +926,7 @@ public void testSortAnotherNumber() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index 873eeeec1e..f1b51fa828 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -33,7 +33,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; @@ -42,13 +41,15 @@ import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import jcifs.smb.SmbFile; /** Created by Rustam Khadipash on 30/3/2018. */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, - maxSdk = 27) + maxSdk = 28) public class StreamSourceTest { private SmbFile file; private StreamSource ss; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index f1d24471bb..ca037ea83d 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -36,7 +36,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.filesystem.ssh.test.TestKeyProvider; @@ -44,10 +43,12 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractSftpServerTest { protected SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java index e8c71008fb..e348338224 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java @@ -35,13 +35,14 @@ import java.util.concurrent.CountDownLatch; import org.junit.Test; -import org.robolectric.RuntimeEnvironment; import com.amaze.filemanager.filesystem.HybridFile; import com.amaze.filemanager.utils.OpenMode; import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class ListFilesOnSshdTest extends AbstractSftpServerTest { @Test @@ -75,7 +76,7 @@ private void performVerify() throws InterruptedException { new HybridFile(OpenMode.SFTP, "ssh://testuser:testpassword@127.0.0.1:" + serverPort); CountDownLatch waiter = new CountDownLatch(7); file.forEachChildrenFile( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, (fileFound) -> { assertTrue(fileFound.getPath() + " not seen as directory", fileFound.isDirectory()); @@ -117,7 +118,7 @@ public void testListDirsAndFilesAndSymlinks() throws Exception { new HybridFile(OpenMode.SFTP, "ssh://testuser:testpassword@127.0.0.1:" + serverPort); CountDownLatch waiter = new CountDownLatch(15); file.forEachChildrenFile( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, (fileFound) -> { if (!fileFound.getName().endsWith(".txt")) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index 1e2194a592..ccff28ecaa 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -34,8 +34,6 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.database.UtilitiesDatabase; @@ -48,13 +46,15 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import net.schmizz.sshj.common.SecurityUtils; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 27) + maxSdk = 28) public class SshConnectionPoolTest { private SshServer server; @@ -303,8 +303,8 @@ private void saveSshConnectionSettings( @NonNull String validUsername, @Nullable String validPassword, @Nullable PrivateKey privateKey) { - utilitiesDatabase = UtilitiesDatabase.initialize(RuntimeEnvironment.application); - utilsHandler = new UtilsHandler(RuntimeEnvironment.application, utilitiesDatabase); + utilitiesDatabase = UtilitiesDatabase.initialize(ApplicationProvider.getApplicationContext()); + utilsHandler = new UtilsHandler(ApplicationProvider.getApplicationContext(), utilitiesDatabase); String privateKeyContents = null; if (privateKey != null) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 7d1d0ccbb5..6e322aae0b 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -36,12 +35,14 @@ import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; + @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) public class SingletonUsbOtgTest { @Test public void usbConnectionTest() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 46be1ae2c8..958c6c6f7e 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -40,12 +39,14 @@ import android.text.TextUtils; +import androidx.test.ext.junit.runners.AndroidJUnit4; + @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) public class UsbOtgTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index a8e3e0e6aa..9a6271a45e 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -27,8 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.database.UtilitiesDatabase; @@ -38,25 +36,30 @@ import com.amaze.filemanager.filesystem.ssh.SshClientUtils; import com.amaze.filemanager.shadows.ShadowMultiDex; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 27) + maxSdk = 28) public class ShadowCryptUtilTest { @Test public void testEncryptDecrypt() throws GeneralSecurityException, IOException { String text = "test"; - String encrypted = CryptUtil.encryptPassword(RuntimeEnvironment.application, text); - assertEquals(text, CryptUtil.decryptPassword(RuntimeEnvironment.application, encrypted)); + String encrypted = CryptUtil.encryptPassword(ApplicationProvider.getApplicationContext(), text); + assertEquals( + text, CryptUtil.decryptPassword(ApplicationProvider.getApplicationContext(), encrypted)); } @Test public void testWithUtilsHandler() { UtilitiesDatabase utilitiesDatabase = - UtilitiesDatabase.initialize(RuntimeEnvironment.application); - UtilsHandler utilsHandler = new UtilsHandler(RuntimeEnvironment.application, utilitiesDatabase); + UtilitiesDatabase.initialize(ApplicationProvider.getApplicationContext()); + UtilsHandler utilsHandler = + new UtilsHandler(ApplicationProvider.getApplicationContext(), utilitiesDatabase); String fingerprint = "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"; String url = "ssh://test:test@127.0.0.1:22"; diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 5ebd236266..83f4f7669b 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -24,16 +24,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class MainActivityTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 240e404b28..e4fbb8ca58 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -34,8 +34,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -53,11 +51,14 @@ import android.os.Environment; import android.widget.TextView; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) /* Restrict minSdk to 24 since it'd fail at SDK 21-23. This may only be fixed by upgrading to Robolectric 4. @@ -88,7 +89,8 @@ public void testOpenFileUri() throws IOException { public void testOpenContentUri() throws Exception { Uri uri = Uri.parse("content://foo.bar.test.streamprovider/temp/thisisatest.txt"); - ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver(); + ContentResolver contentResolver = + ApplicationProvider.getApplicationContext().getContentResolver(); ShadowContentResolver shadowContentResolver = Shadows.shadowOf(contentResolver); shadowContentResolver.registerInputStream( uri, new ByteArrayInputStream(fileContents.getBytes("UTF-8"))); diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 0862363ebe..6d9d57880b 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -25,7 +25,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowMimeTypeMap; @@ -34,10 +33,12 @@ import android.webkit.MimeTypeMap; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class IconsTest { @Before diff --git a/build.gradle b/build.gradle index 72804fdd25..84c7e82200 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,8 @@ configurations { robo25 robo26 robo27 + robo28 +// robo29 } dependencies { @@ -69,6 +71,8 @@ dependencies { robo25 "org.robolectric:android-all:7.1.0_r7-robolectric-r1" robo26 "org.robolectric:android-all:8.0.0_r4-robolectric-r1" robo27 "org.robolectric:android-all:8.1.0-robolectric-4611349" + robo28 "org.robolectric:android-all:9-robolectric-4913185-2" +// robo29 "org.robolectric:android-all:Q-robolectric-5415296" } def robolectricDependencies = "${rootProject.buildDir.path}/robolectric" @@ -85,6 +89,8 @@ task fetchRobolectricDependencies(type: Copy) { from configurations.robo25 from configurations.robo26 from configurations.robo27 + from configurations.robo28 +// from configurations.robo29 into robolectricDependencies } diff --git a/gradle.properties b/gradle.properties index 5cbbfbb834..678f09d103 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true android.useAndroidX=true -android.enableUnitTestBinaryResources=false + # Workaround for Android Gradle Plugin before 3.6.0. # See https://github.com/robolectric/robolectric/issues/5299#issuecomment-543125381 # and https://issuetracker.google.com/issues/142580430 From 75f496cb8864eb01a1c15d954860e670d120cca0 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Tue, 28 Jul 2020 17:45:37 +0800 Subject: [PATCH 03/32] Fixes for editing SMB connections - moved jcifs.Config.registerSmbURLHandler() from SmbConnectDialog to AppConfig.runInBackground() - encrypt paths in UtilsHandler.renameSMB() as it was stored encrypted in database Tested on Oneplus 2 running AOSPExtended (7.1.2) and LG Nexus 5x running AOSPExtended (9.0). --- .../com/amaze/filemanager/application/AppConfig.java | 5 ++--- .../com/amaze/filemanager/database/UtilsHandler.java | 9 +++++++++ .../amaze/filemanager/ui/dialogs/SmbConnectDialog.java | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java index da79e231e4..5d40ca5ade 100644 --- a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java +++ b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java @@ -87,12 +87,11 @@ public void onCreate() { utilsProvider = new UtilitiesProvider(this); utilsHandler = new UtilsHandler(this, utilitiesDatabase); - // FIXME: in unit tests when AppConfig is rapidly created/destroyed this call will cause - // IllegalThreadStateException. - // Until this gets fixed only one test case can be run in a time. - Raymond, 24/4/2018 backgroundHandlerThread.start(); backgroundHandler = new Handler(backgroundHandlerThread.getLooper()); + runInBackground(jcifs.Config::registerSmbURLHandler); + // disabling file exposure method check for api n+ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); diff --git a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java index b4785fd8db..3068ce3106 100644 --- a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java +++ b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java @@ -58,6 +58,8 @@ */ public class UtilsHandler { + private static final String TAG = UtilsHandler.class.getSimpleName(); + private final Context context; private final UtilitiesDatabase utilitiesDatabase; @@ -313,6 +315,13 @@ public void renameBookmark(String oldName, String oldPath, String newName, Strin } public void renameSMB(String oldName, String oldPath, String newName, String newPath) { + try { + oldPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), oldPath); + newPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), newPath); + } catch (GeneralSecurityException | IOException e) { + Log.e(TAG, "Error encrypting SMB path", e); + } + SmbEntry smbEntry = utilitiesDatabase.smbEntryDao().findByNameAndPath(oldName, oldPath); smbEntry.name = newName; smbEntry.path = newPath; diff --git a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java index 94196cb28c..1f2f45a8d3 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java +++ b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java @@ -207,7 +207,6 @@ public void afterTextChanged(Editable s) { String userp = "", passp = "", ipp = "", domainp = ""; conName.setText(name); try { - jcifs.Config.registerSmbURLHandler(); URL a = new URL(path); String userinfo = a.getUserInfo(); if (userinfo != null) { From 97db16f15d2511ceb3b4090eaccf0742baea63ec Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 1 Aug 2020 10:58:23 +0800 Subject: [PATCH 04/32] [WIP] test cases collection and fixes as work goes on - ColorUtils: Add back missing break statement to prevent unknown icons being colored to default color - NotificationConstants: Fix constant to use per reported by Android Studio - Return of MainActivity test - Remove deprecated API usage in TextEditorActivityTest - Add test cases for CloudSheetFragment, NotificationConstants, SmbUtil, TinyDB, along with some more little util classes --- .../filemanager/ui/colors/ColorUtils.java | 1 + .../notifications/NotificationConstants.java | 2 +- .../com/amaze/filemanager/utils/Utils.java | 7 +- .../com/amaze/filemanager/test/TestUtils.java | 71 ++++++++ .../ui/activities/MainActivityTest.java | 61 +++++-- .../ui/activities/TextEditorActivityTest.java | 20 +-- .../filemanager/ui/colors/ColorUtilsTest.java | 96 ++++++++++ .../ui/fragments/CloudSheetFragmentTest.java | 54 ++++++ .../NotificationConstantsTest.java | 167 ++++++++++++++++++ .../filemanager/utils/AnimUtilsTest.java | 72 ++++++++ .../amaze/filemanager/utils/OpenModeTest.java | 58 ++++++ .../amaze/filemanager/utils/SmbUtilTest.java | 74 ++++++++ .../amaze/filemanager/utils/TinyDBTest.java | 72 ++++++++ .../amaze/filemanager/utils/UtilsTest.java | 106 ++++++++++- 14 files changed, 825 insertions(+), 36 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java diff --git a/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java b/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java index a310b64654..2583c2d41e 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java +++ b/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java @@ -59,6 +59,7 @@ public static void colorizeIcons( break; case Icons.NOT_KNOWN: background.setColor(Utils.getColor(context, R.color.generic_item)); + break; default: background.setColor(defaultColor); break; diff --git a/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java b/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java index b723ddebb8..6a1581871f 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java +++ b/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java @@ -77,7 +77,7 @@ public static void setMetadata( case TYPE_FTP: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { notification.setCategory(Notification.CATEGORY_SERVICE); - notification.setVisibility(Notification.VISIBILITY_PUBLIC); + notification.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notification.setPriority(Notification.PRIORITY_MAX); diff --git a/app/src/main/java/com/amaze/filemanager/utils/Utils.java b/app/src/main/java/com/amaze/filemanager/utils/Utils.java index fb100dd187..f83a0df6b7 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/Utils.java +++ b/app/src/main/java/com/amaze/filemanager/utils/Utils.java @@ -52,6 +52,7 @@ import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; import androidx.core.graphics.drawable.DrawableCompat; @@ -221,12 +222,12 @@ private static String sanitizeInputOnce(String input) { } /** Returns uri associated to specific basefile */ - public static Uri getUriForBaseFile(Context context, HybridFileParcelable baseFile) { + public static Uri getUriForBaseFile( + @NonNull Context context, @NonNull HybridFileParcelable baseFile) { switch (baseFile.getMode()) { case FILE: case ROOT: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return FileProvider.getUriForFile( context, context.getPackageName(), new File(baseFile.getPath())); } else { @@ -340,7 +341,7 @@ public static Snackbar showThemedSnackbar( MainActivity mainActivity, CharSequence text, int length, - int actionTextId, + @StringRes int actionTextId, Runnable actionCallback) { Snackbar snackbar = Snackbar.make(mainActivity.findViewById(R.id.content_frame), text, length) diff --git a/app/src/test/java/com/amaze/filemanager/test/TestUtils.java b/app/src/test/java/com/amaze/filemanager/test/TestUtils.java index 1cf11ec007..2f011f86d1 100644 --- a/app/src/test/java/com/amaze/filemanager/test/TestUtils.java +++ b/app/src/test/java/com/amaze/filemanager/test/TestUtils.java @@ -20,15 +20,27 @@ package com.amaze.filemanager.test; +import static android.os.Build.VERSION_CODES.P; import static org.robolectric.Shadows.shadowOf; +import java.io.File; import java.lang.reflect.Field; +import org.robolectric.shadows.ShadowStorageManager; import org.robolectric.util.Scheduler; import com.amaze.filemanager.application.AppConfig; +import android.os.Build; +import android.os.Environment; import android.os.Handler; +import android.os.Parcel; +import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.StorageVolume; + +import androidx.annotation.NonNull; +import androidx.test.core.app.ApplicationProvider; public class TestUtils { @@ -63,4 +75,63 @@ public static void flushAppConfigHandlerThread() { throw new AssertionError("Unable to access backgroundHandler within AppConfig"); } } + + /** + * Populate "internal device storage" to StorageManager with directory as provided by Robolectric. + * + *

Tests need storage access must call this on test case setup for SDK >= N to work. + */ + public static void initializeInternalStorage() { + Parcel parcel = Parcel.obtain(); + File dir = Environment.getExternalStorageDirectory(); + parcel.writeString("FS-internal"); + if (Build.VERSION.SDK_INT < P) parcel.writeInt(0); + parcel.writeString(dir.getAbsolutePath()); + if (Build.VERSION.SDK_INT >= P) parcel.writeString(dir.getAbsolutePath()); + parcel.writeString("robolectric internal storage"); + parcel.writeInt(1); + parcel.writeInt(0); + parcel.writeInt(1); + if (Build.VERSION.SDK_INT < P) parcel.writeLong(1024 * 1024); + parcel.writeInt(0); + parcel.writeLong(1024 * 1024); + parcel.writeParcelable(UserHandle.getUserHandleForUid(0), 0); + parcel.writeString("1234-5678"); + parcel.writeString(Environment.MEDIA_MOUNTED); + addVolumeToStorageManager(parcel); + } + + /** + * Populate "external device storage" to StorageManager with directory as provided by Robolectric. + * + *

Tests need storage access must call this on test case setup for SDK >= N to work. + */ + public static void initializeExternalStorage() { + Parcel parcel = Parcel.obtain(); + File dir = Environment.getExternalStoragePublicDirectory("external"); + parcel.writeString("FS-external"); + if (Build.VERSION.SDK_INT < P) parcel.writeInt(0); + parcel.writeString(dir.getAbsolutePath()); + if (Build.VERSION.SDK_INT >= P) parcel.writeString(dir.getAbsolutePath()); + parcel.writeString("robolectric external storage"); + parcel.writeInt(0); + parcel.writeInt(1); + parcel.writeInt(0); + if (Build.VERSION.SDK_INT < P) parcel.writeLong(1024 * 1024); + parcel.writeInt(0); + parcel.writeLong(1024 * 1024); + parcel.writeParcelable(UserHandle.getUserHandleForUid(0), 0); + parcel.writeString("ABCD-EFGH"); + parcel.writeString(Environment.MEDIA_MOUNTED); + addVolumeToStorageManager(parcel); + } + + private static void addVolumeToStorageManager(@NonNull Parcel parcel) { + parcel.setDataPosition(0); + ShadowStorageManager storageManager = + shadowOf( + ApplicationProvider.getApplicationContext().getSystemService(StorageManager.class)); + StorageVolume volume = StorageVolume.CREATOR.createFromParcel(parcel); + storageManager.addStorageVolume(volume); + } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 83f4f7669b..da087f9bde 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -20,33 +20,66 @@ package com.amaze.filemanager.ui.activities; -import org.junit.Ignore; +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.P; +import static androidx.test.core.app.ActivityScenario.launch; +import static org.robolectric.Shadows.shadowOf; + +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; +import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; +import org.robolectric.shadows.ShadowStorageManager; import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.test.TestUtils; + +import android.os.Build; +import android.os.storage.StorageManager; +import androidx.lifecycle.Lifecycle; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) @Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) + shadows = {ShadowMultiDex.class, ShadowStorageManager.class}, + maxSdk = P) +/* + * Need to make LooperMode PAUSED and flush the main looper before activity can show up. + * @see {@link LooperMode.Mode.PAUSED} + * @see {@link StackOverflow discussion} + */ +@LooperMode(LooperMode.Mode.PAUSED) public class MainActivityTest { + @Before + public void setUp() { + if (Build.VERSION.SDK_INT >= N) TestUtils.initializeInternalStorage(); + } + + @After + public void tearDown() { + if (Build.VERSION.SDK_INT >= N) + shadowOf(ApplicationProvider.getApplicationContext().getSystemService(StorageManager.class)) + .resetStorageVolumeList(); + } + @Test - @Ignore public void testMainActivity() { - ActivityController controller = - Robolectric.buildActivity(MainActivity.class) - .create() - .start() - .resume() - .visible() - .pause() - .destroy(); + ActivityScenario scenario = launch(MainActivity.class); + + ShadowLooper.idleMainLooper(); + + scenario.moveToState(Lifecycle.State.STARTED); + + scenario.onActivity( + activity -> { + scenario.close(); + }); } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index e4fbb8ca58..8244ddbacc 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -20,10 +20,8 @@ package com.amaze.filemanager.ui.activities; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.File; @@ -45,7 +43,6 @@ import com.amaze.filemanager.shadows.ShadowMultiDex; import android.content.ContentResolver; -import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Environment; @@ -57,13 +54,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, maxSdk = 28) -/* - Restrict minSdk to 24 since it'd fail at SDK 21-23. - This may only be fixed by upgrading to Robolectric 4. - See https://github.com/robolectric/robolectric/issues/3947 -*/ public class TextEditorActivityTest { private final String fileContents = "fsdfsdfs"; @@ -82,7 +73,7 @@ public void testOpenFileUri() throws IOException { intent.setData(Uri.fromFile(file)); generateActivity(intent); - assertThat(text.getText().toString(), is(fileContents + "\n")); + assertEquals(fileContents + "\n", text.getText().toString()); } @Test @@ -120,7 +111,7 @@ private File simulateFile() throws IOException { file.createNewFile(); if (!file.canWrite()) file.setWritable(true); - assertThat(file.canWrite(), is(true)); + assertTrue(file.canWrite()); PrintWriter out = new PrintWriter(file); out.write(fileContents); @@ -129,9 +120,4 @@ private File simulateFile() throws IOException { return file; } - - private Uri getFileContentUri(Context context, File file) { - fail("Cannot create content URI"); - return null; - } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java new file mode 100644 index 0000000000..cb6a39383a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.colors; + +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.P; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.ui.icons.Icons; +import com.amaze.filemanager.utils.Utils; + +import android.content.res.ColorStateList; +import android.graphics.drawable.GradientDrawable; + +import androidx.annotation.ColorInt; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = N, maxSdk = P) +public class ColorUtilsTest { + + @Test + public void testSetColorizeIcons() { + doTest(R.color.video_item, Icons.VIDEO); + doTest(R.color.audio_item, Icons.AUDIO); + doTest(R.color.pdf_item, Icons.PDF); + doTest(R.color.code_item, Icons.CODE); + doTest(R.color.text_item, Icons.TEXT); + doTest(R.color.archive_item, Icons.COMPRESSED); + doTest(R.color.apk_item, Icons.APK); + doTest(R.color.generic_item, Icons.NOT_KNOWN); + assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + } + + @Test + public void testSetColorizeIconsGeneric() { + doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE); + doTestGeneric(R.color.primary_indigo, Icons.CONTACT); + doTestGeneric(R.color.primary_indigo, Icons.EVENTS); + doTestGeneric(R.color.primary_indigo, Icons.FONT); + doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION); + doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS); + doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); + doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); + doTestGeneric(R.color.primary_indigo, Icons.GIF); + assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + } + + private void doTest(@ColorInt int expected, int icon) { + GradientDrawable drawable = new GradientDrawable(); + ColorUtils.colorizeIcons( + ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); + doCompare( + ColorStateList.valueOf( + Utils.getColor(ApplicationProvider.getApplicationContext(), expected)), + drawable); + drawable = null; + } + + private void doTestGeneric(@ColorInt int expected, int icon) { + GradientDrawable drawable = new GradientDrawable(); + ColorUtils.colorizeIcons( + ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); + doCompare(ColorStateList.valueOf(expected), drawable); + drawable = null; + } + + private void doCompare(ColorStateList expected, GradientDrawable drawable) { + assertEquals(expected, drawable.getColor()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java new file mode 100644 index 0000000000..ebb6a72367 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.fragments; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.robolectric.Shadows.shadowOf; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.database.CloudContract; + +import android.content.pm.PackageInfo; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class CloudSheetFragmentTest { + + @Test + public void testIsCloudProviderAvailable() { + assertFalse( + CloudSheetFragment.isCloudProviderAvailable(ApplicationProvider.getApplicationContext())); + + PackageInfo pi = new PackageInfo(); + pi.packageName = CloudContract.APP_PACKAGE_NAME; + shadowOf(ApplicationProvider.getApplicationContext().getPackageManager()).installPackage(pi); + + assertTrue( + CloudSheetFragment.isCloudProviderAvailable(ApplicationProvider.getApplicationContext())); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java new file mode 100644 index 0000000000..7b7062c4ca --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.notifications; + +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_MIN; +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.O; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.CHANNEL_FTP_ID; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.CHANNEL_NORMAL_ID; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.TYPE_FTP; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.TYPE_NORMAL; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.robolectric.Shadows.shadowOf; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowNotificationManager; + +import com.amaze.filemanager.R; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; + +import androidx.core.app.NotificationCompat; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class NotificationConstantsTest { + + private Context context; + + private NotificationManager notificationManager; + + private ShadowNotificationManager shadowNotificationManager; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + shadowNotificationManager = shadowOf(notificationManager); + } + + @After + public void tearDown() { + notificationManager.cancelAll(); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetMetadataIllegalType() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID); + NotificationConstants.setMetadata(context, builder, -1); + NotificationConstants.setMetadata(context, builder, 2); + NotificationConstants.setMetadata(context, builder, Integer.MAX_VALUE); + builder = new NotificationCompat.Builder(context, CHANNEL_FTP_ID); + NotificationConstants.setMetadata(context, builder, -1); + NotificationConstants.setMetadata(context, builder, 2); + NotificationConstants.setMetadata(context, builder, Integer.MAX_VALUE); + } + + @Test + @Config(maxSdk = N) + public void testNormalNotification() { + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID) + .setContentTitle(context.getString(R.string.waiting_title)) + .setContentText(context.getString(R.string.waiting_content)) + .setAutoCancel(false) + .setSmallIcon(R.drawable.ic_all_inclusive_white_36dp) + .setProgress(0, 0, true); + + NotificationConstants.setMetadata(context, builder, TYPE_NORMAL); + Notification result = builder.build(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + assertEquals(Notification.CATEGORY_SERVICE, result.category); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + assertEquals(Notification.PRIORITY_MIN, result.priority); + } else { + assertEquals(Notification.PRIORITY_DEFAULT, result.priority); + } + } + + @Test + @Config(maxSdk = N) + public void testFtpNotification() { + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, CHANNEL_FTP_ID) + .setContentTitle("FTP server test") + .setContentText("FTP listening at 127.0.0.1:22") + .setSmallIcon(R.drawable.ic_ftp_light) + .setTicker(context.getString(R.string.ftp_notif_starting)) + .setOngoing(true) + .setOnlyAlertOnce(true); + NotificationConstants.setMetadata(context, builder, TYPE_FTP); + Notification result = builder.build(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + assertEquals(Notification.CATEGORY_SERVICE, result.category); + assertEquals(Notification.VISIBILITY_PUBLIC, result.visibility); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + assertEquals(Notification.PRIORITY_MAX, result.priority); + } else { + assertEquals(Notification.PRIORITY_DEFAULT, result.priority); + } + } + + @Test + @Config(minSdk = O) + public void testCreateNormalChannel() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID); + NotificationConstants.setMetadata(context, builder, TYPE_NORMAL); + List channels = shadowNotificationManager.getNotificationChannels(); + assertNotNull(channels); + assertEquals(1, channels.size()); + NotificationChannel channel = (NotificationChannel) channels.get(0); + assertEquals(IMPORTANCE_MIN, channel.getImportance()); + assertEquals(CHANNEL_NORMAL_ID, channel.getId()); + assertEquals(context.getString(R.string.channel_name_normal), channel.getName()); + assertEquals(context.getString(R.string.channel_description_normal), channel.getDescription()); + } + + @Test + @Config(minSdk = O) + public void testCreateFtpChannel() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_FTP_ID); + NotificationConstants.setMetadata(context, builder, TYPE_FTP); + List channels = shadowNotificationManager.getNotificationChannels(); + assertNotNull(channels); + assertEquals(1, channels.size()); + NotificationChannel channel = (NotificationChannel) channels.get(0); + assertEquals(IMPORTANCE_HIGH, channel.getImportance()); + assertEquals(CHANNEL_FTP_ID, channel.getId()); + assertEquals(context.getString(R.string.channel_name_ftp), channel.getName()); + assertEquals(context.getString(R.string.channel_description_ftp), channel.getDescription()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java new file mode 100644 index 0000000000..3cc2e3315a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mock; +import static org.robolectric.Shadows.shadowOf; + +import java.lang.reflect.Field; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.ui.views.ThemedTextView; + +import android.os.Looper; +import android.view.animation.Interpolator; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class AnimUtilsTest { + + @Test + public void testGetFastOutSlowInInterpolator() + throws NoSuchFieldException, IllegalAccessException { + Field f = AnimUtils.class.getDeclaredField("fastOutSlowIn"); + f.setAccessible(true); + assertNull(f.get(null)); + Interpolator result = + AnimUtils.getFastOutSlowInInterpolator(ApplicationProvider.getApplicationContext()); + assertNotNull(result); + assertNotNull(f.get(null)); + } + + @Test + public void testMarqueeAfterDelay() { + ThemedTextView mock = mock(ThemedTextView.class); + doCallRealMethod().when(mock).setSelected(anyBoolean()); + doCallRealMethod().when(mock).isSelected(); + mock.setSelected(false); + + AnimUtils.marqueeAfterDelay(150, mock); + shadowOf(Looper.myLooper()).getScheduler().advanceToLastPostedRunnable(); + assertTrue(mock.isSelected()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java b/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java new file mode 100644 index 0000000000..4f7a66db42 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static com.amaze.filemanager.utils.OpenMode.BOX; +import static com.amaze.filemanager.utils.OpenMode.CUSTOM; +import static com.amaze.filemanager.utils.OpenMode.DROPBOX; +import static com.amaze.filemanager.utils.OpenMode.FILE; +import static com.amaze.filemanager.utils.OpenMode.GDRIVE; +import static com.amaze.filemanager.utils.OpenMode.ONEDRIVE; +import static com.amaze.filemanager.utils.OpenMode.OTG; +import static com.amaze.filemanager.utils.OpenMode.ROOT; +import static com.amaze.filemanager.utils.OpenMode.SFTP; +import static com.amaze.filemanager.utils.OpenMode.SMB; +import static com.amaze.filemanager.utils.OpenMode.UNKNOWN; +import static java.lang.Integer.MAX_VALUE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; + +public class OpenModeTest { + + @Test + public void testGetOpenMode() { + assertEquals(UNKNOWN, OpenMode.getOpenMode(0)); + assertEquals(FILE, OpenMode.getOpenMode(1)); + assertEquals(SMB, OpenMode.getOpenMode(2)); + assertEquals(SFTP, OpenMode.getOpenMode(3)); + assertEquals(CUSTOM, OpenMode.getOpenMode(4)); + assertEquals(ROOT, OpenMode.getOpenMode(5)); + assertEquals(OTG, OpenMode.getOpenMode(6)); + assertEquals(GDRIVE, OpenMode.getOpenMode(7)); + assertEquals(DROPBOX, OpenMode.getOpenMode(8)); + assertEquals(BOX, OpenMode.getOpenMode(9)); + assertEquals(ONEDRIVE, OpenMode.getOpenMode(10)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> OpenMode.getOpenMode(-1)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> OpenMode.getOpenMode(MAX_VALUE)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java new file mode 100644 index 0000000000..b9645cb815 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.test.ShadowCryptUtil; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + minSdk = 19, + maxSdk = 28, + shadows = {ShadowCryptUtil.class}) +public class SmbUtilTest { + + @Test + public void testEncryptDecrypt() throws GeneralSecurityException, IOException { + String path = "smb://root:toor@127.0.0.1"; + String encrypted = + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path); + assertNotEquals(path, encrypted); + assertTrue(encrypted.startsWith("smb://root:")); + assertTrue(encrypted.endsWith("@127.0.0.1")); + String decrypted = + SmbUtil.getSmbDecryptedPath(ApplicationProvider.getApplicationContext(), encrypted); + assertEquals(path, decrypted); + } + + @Test + public void testEncryptWithoutCredentials() throws GeneralSecurityException, IOException { + String path = "smb://127.0.0.1"; + assertEquals( + path, SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path)); + } + + @Test + @Ignore("Good idea to fix me") + public void testEncryptWithoutPassword() throws GeneralSecurityException, IOException { + String path = "smb://toor@127.0.0.1"; + assertEquals( + path, SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java new file mode 100644 index 0000000000..ae4a996513 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class TinyDBTest { + + private SharedPreferences prefs; + + @Before + public void setUp() { + prefs = + PreferenceManager.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext()); + } + + @Test + public void testSaveLoadBooleanArray() { + Boolean[] value = new Boolean[] {true, false, true, false, true, true, false}; + TinyDB.putBooleanArray(prefs, "foobar", value); + Boolean[] result = + TinyDB.getBooleanArray( + prefs, "foobar", new Boolean[] {false, false, false, false, false, false, false}); + assertArrayEquals(value, result); + } + + @Test + public void testLoadBooleanArrayShouldReturnDefaultValue() { + Boolean[] expected = + TinyDB.getBooleanArray( + prefs, "foobaz", new Boolean[] {true, false, true, false, false, false}); + Boolean[] result = TinyDB.getBooleanArray(prefs, "foobaz", expected); + assertArrayEquals(expected, result); + } + + @Test + public void testLoadBooleanArrayShouldReturnDefaultValue2() { + assertNull(TinyDB.getBooleanArray(prefs, "foobam", null)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java index a9895512b7..eb21bf51e0 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java @@ -20,12 +20,40 @@ package com.amaze.filemanager.utils; +import static android.os.Build.VERSION_CODES.N; import static com.amaze.filemanager.utils.Utils.formatTimer; import static com.amaze.filemanager.utils.Utils.sanitizeInput; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowToast; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.filesystem.HybridFileParcelable; + +import android.net.Uri; +import android.os.Build; +import android.os.storage.StorageVolume; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) public class UtilsTest { @Test public void @@ -59,4 +87,80 @@ public void testFormatTimer() { assertEquals("02:45", formatTimer(165)); assertEquals("30:33", formatTimer(1833)); } + + @Test + public void testDifferenceStrings() { + assertNull(Utils.differenceStrings(null, null)); + assertEquals("abc", Utils.differenceStrings("abc", null)); + assertEquals("abc", Utils.differenceStrings(null, "abc")); + assertEquals("", Utils.differenceStrings("abc12345", "abc")); + assertEquals("", Utils.differenceStrings("pqrstuv345", "pqrstuv")); + assertEquals("12345", Utils.differenceStrings("abc", "abc12345")); + } + + @Test + public void testGetUriForBaseFile() { + HybridFileParcelable file = new HybridFileParcelable("/storage/emulated/0/test.txt"); + for (OpenMode m : new OpenMode[] {OpenMode.FILE, OpenMode.ROOT}) { + file.setMode(m); + Uri uri = Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file); + if (Build.VERSION.SDK_INT < N) { + assertEquals("file:///storage/emulated/0/test.txt", uri.toString()); + } else { + assertEquals( + "content://" + + ApplicationProvider.getApplicationContext().getPackageName() + + "/storage_root/storage/emulated/0/test.txt", + uri.toString()); + } + } + + for (OpenMode m : + new OpenMode[] { + OpenMode.DROPBOX, OpenMode.GDRIVE, OpenMode.ONEDRIVE, OpenMode.SMB, OpenMode.BOX + }) { + file = new HybridFileParcelable("/foo/bar/test.txt"); + file.setMode(m); + assertNull(Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file)); + assertEquals( + ApplicationProvider.getApplicationContext().getString(R.string.smb_launch_error), + ShadowToast.getTextOfLatestToast()); + } + + file.setMode(OpenMode.CUSTOM); + assertNull(Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file)); + } + + @Test + public void testIsNullOrEmptyCollection() { + assertTrue(Utils.isNullOrEmpty((Collection) null)); + assertTrue(Utils.isNullOrEmpty(Collections.EMPTY_SET)); + assertFalse(Utils.isNullOrEmpty(Collections.singletonList(null))); + assertFalse(Utils.isNullOrEmpty(Arrays.asList(new Object()))); + Collection l = new ArrayList(); + l.add(new Object()); + assertFalse(Utils.isNullOrEmpty(l)); + } + + @Test + public void testIsNullOrEmptyString() { + assertTrue(Utils.isNullOrEmpty((String) null)); + assertTrue(Utils.isNullOrEmpty("")); + assertFalse(Utils.isNullOrEmpty("null")); + assertFalse(Utils.isNullOrEmpty("empty")); + assertFalse(Utils.isNullOrEmpty("this is a string")); + } + + @Test + @Config(minSdk = N) + public void testGetVolumeDirectory() throws Exception { + StorageVolume mock = mock(StorageVolume.class); + Field f = StorageVolume.class.getDeclaredField("mPath"); + f.setAccessible(true); + f.set(mock, new File("/storage/emulated/0")); + + File result = Utils.getVolumeDirectory(mock); + assertNotNull(result); + assertEquals(new File("/storage/emulated/0"), result); + } } From d2809661de980c63196c11b4ccffb5676b50a3c7 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 2 Aug 2020 18:19:01 +0800 Subject: [PATCH 05/32] [WIP] test cases collection and fixes as work goes on - Added test cases for DbViewerTask, WriteFileAbstraction and EditableFileAbstraction - EditableFileAbstraction, schema changed from integer to enum constant --- app/build.gradle | 2 + .../asynchronous/asynctasks/DbViewerTask.java | 6 +- .../asynchronous/asynctasks/ReadFileTask.java | 4 +- .../asynctasks/WriteFileAbstraction.java | 4 +- .../filesystem/EditableFileAbstraction.java | 19 +- .../ui/activities/TextEditorActivity.java | 8 +- .../asynctasks/DbViewerTaskTest.java | 163 ++++++++++++ .../asynctasks/WriteFileAbstractionTest.java | 231 ++++++++++++++++++ .../EditableFileAbstractionTest.java | 97 ++++++++ .../filemanager/ui/colors/ColorUtilsTest.java | 4 +- app/src/test/resources/test.db | Bin 0 -> 36864 bytes 11 files changed, 519 insertions(+), 19 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java create mode 100644 app/src/test/resources/test.db diff --git a/app/build.gradle b/app/build.gradle index 6825324c9b..943c384bb6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -124,9 +124,11 @@ dependencies { testImplementation "androidx.test:runner:$androidXTestVersion" testImplementation "androidx.test:rules:$androidXTestVersion" testImplementation 'androidx.test.ext:junit:1.1.1' + //testImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' testImplementation "org.mockito:mockito-core:$mockitoVersion" testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" + testImplementation 'org.jsoup:jsoup:1.11.2' testAnnotationProcessor "com.google.auto.service:auto-service:1.0-rc4" androidTestImplementation "junit:junit:$junitVersion"//tests the app logic diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java index 943d125d5d..a4a3d79e6e 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java @@ -52,7 +52,7 @@ public DbViewerTask( this.dbViewerFragment = dbViewerFragment; stringBuilder = new StringBuilder(); - webView.getSettings().setDefaultTextEncodingName("utf-8"); + this.webView.getSettings().setDefaultTextEncodingName("utf-8"); } @Override @@ -62,10 +62,10 @@ protected void onPreExecute() { if (dbViewerFragment.databaseViewerActivity.getAppTheme().equals(AppTheme.DARK) || dbViewerFragment.databaseViewerActivity.getAppTheme().equals(AppTheme.BLACK)) { - htmlInit = "" + ""; + htmlInit = "
"; } else { - htmlInit = "" + "
"; + htmlInit = "
"; } stringBuilder.append(htmlInit); dbViewerFragment.loadingText.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java index 0e3967a46b..5831a82fc3 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java @@ -74,13 +74,13 @@ protected ReturnedValues doInBackground(Void... params) { InputStream inputStream = null; switch (fileAbstraction.scheme) { - case EditableFileAbstraction.SCHEME_CONTENT: + case CONTENT: if (fileAbstraction.uri == null) throw new NullPointerException("Something went really wrong!"); inputStream = contentResolver.openInputStream(fileAbstraction.uri); break; - case EditableFileAbstraction.SCHEME_FILE: + case FILE: final HybridFileParcelable hybridFileParcelable = fileAbstraction.hybridFileParcelable; if (hybridFileParcelable == null) throw new NullPointerException("Something went really wrong!"); diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java index ff72be125f..3470e6ffc1 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java @@ -79,7 +79,7 @@ protected Integer doInBackground(Void... voids) { OutputStream outputStream; switch (fileAbstraction.scheme) { - case EditableFileAbstraction.SCHEME_CONTENT: + case CONTENT: if (fileAbstraction.uri == null) throw new NullPointerException("Something went really wrong!"); @@ -90,7 +90,7 @@ protected Integer doInBackground(Void... voids) { } break; - case EditableFileAbstraction.SCHEME_FILE: + case FILE: final HybridFileParcelable hybridFileParcelable = fileAbstraction.hybridFileParcelable; if (hybridFileParcelable == null) throw new NullPointerException("Something went really wrong!"); diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java b/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java index f411ca033c..62c8ac9c12 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java @@ -20,6 +20,9 @@ package com.amaze.filemanager.filesystem; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.CONTENT; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; + import com.amaze.filemanager.utils.Utils; import android.content.Context; @@ -27,6 +30,8 @@ import android.net.Uri; import android.provider.OpenableColumns; +import androidx.annotation.NonNull; + /** * This is a special representation of a file that is to be used so that uris can be loaded as * editable files. @@ -35,19 +40,21 @@ */ public class EditableFileAbstraction { - public static final int SCHEME_CONTENT = 0; - public static final int SCHEME_FILE = 1; + public enum Scheme { + CONTENT, + FILE + } public final Uri uri; public final String name; - public final int scheme; + public final Scheme scheme; public final HybridFileParcelable hybridFileParcelable; - public EditableFileAbstraction(Context context, Uri uri) { + public EditableFileAbstraction(@NonNull Context context, @NonNull Uri uri) { switch (uri.getScheme()) { case "content": this.uri = uri; - this.scheme = SCHEME_CONTENT; + this.scheme = CONTENT; String tempName = null; Cursor c = @@ -79,7 +86,7 @@ public EditableFileAbstraction(Context context, Uri uri) { this.hybridFileParcelable = null; break; case "file": - this.scheme = SCHEME_FILE; + this.scheme = FILE; String path = uri.getPath(); if (path == null) diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java index e41f68f6c3..51f15ff510 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java @@ -20,6 +20,7 @@ package com.amaze.filemanager.ui.activities; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_TEXTEDITOR_NEWSTACK; @@ -322,7 +323,7 @@ private void load() { try { mInput.setText(data.fileContents); - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE + if (mFile.scheme.equals(FILE) && getExternalCacheDir() != null && mFile .hybridFileParcelable @@ -403,8 +404,7 @@ public boolean onOptionsItemSelected(MenuItem item) { saveFile(mInput.getText().toString()); break; case R.id.details: - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE - && mFile.hybridFileParcelable.getFile().exists()) { + if (mFile.scheme.equals(FILE) && mFile.hybridFileParcelable.getFile().exists()) { GeneralDialogCreation.showPropertiesDialogWithoutPermissions( mFile.hybridFileParcelable, this, getAppTheme()); } else { @@ -412,7 +412,7 @@ public boolean onOptionsItemSelected(MenuItem item) { } break; case R.id.openwith: - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE) { + if (mFile.scheme.equals(FILE)) { File currentFile = mFile.hybridFileParcelable.getFile(); if (currentFile.exists()) { boolean useNewStack = getBoolean(PREFERENCE_TEXTEDITOR_NEWSTACK); diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java new file mode 100644 index 0000000000..8d34294f3a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.asynchronous.asynctasks; + +import static android.view.View.VISIBLE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.ui.activities.DatabaseViewerActivity; +import com.amaze.filemanager.ui.fragments.DbViewerFragment; +import com.amaze.filemanager.ui.theme.AppTheme; + +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.view.View; +import android.webkit.WebView; +import android.widget.TextView; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class DbViewerTaskTest { + + private WebView webView; + + @Before + public void setUp() { + webView = new WebView(ApplicationProvider.getApplicationContext()); + } + + @After + public void tearDown() { + webView.destroy(); + } + + @Test + public void testOnPreExecute() { + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + mock.databaseViewerActivity = mock(DatabaseViewerActivity.class); + mock.loadingText.setVisibility(View.GONE); + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.DARK); + + DbViewerTask task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#ffffff")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.BLACK); + task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#ffffff")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.LIGHT); + task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#000000")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + } + + @Test + public void testExecute() { + SQLiteDatabase sqLiteDatabase = + SQLiteDatabase.openDatabase( + "src/test/resources/test.db", null, SQLiteDatabase.OPEN_READONLY); + assertNotNull(sqLiteDatabase); + + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + Cursor schemaCursor = sqLiteDatabase.rawQuery("PRAGMA table_info('users');", null); + Cursor contentCursor = sqLiteDatabase.rawQuery("SELECT * FROM users", null); + + DbViewerTask task = new DbViewerTask(schemaCursor, contentCursor, webView, mock); + task.doInBackground(); + + assertNotNull(task.schemaList); + assertNotNull(task.contentList); + + // 3 columns + assertEquals(3, task.schemaList.size()); + // 4 records + assertEquals(4, task.contentList.size()); + assertEquals("4 records loaded", loadingText.getText().toString()); + + sqLiteDatabase.close(); + } + + @Test + public void testCompleteTask() { + SQLiteDatabase sqLiteDatabase = + SQLiteDatabase.openDatabase( + "src/test/resources/test.db", null, SQLiteDatabase.OPEN_READONLY); + assertNotNull(sqLiteDatabase); + + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + mock.databaseViewerActivity = mock(DatabaseViewerActivity.class); + mock.loadingText.setVisibility(View.GONE); + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.DARK); + Cursor schemaCursor = sqLiteDatabase.rawQuery("PRAGMA table_info('users');", null); + Cursor contentCursor = sqLiteDatabase.rawQuery("SELECT * FROM users", null); + + DbViewerTask task = new DbViewerTask(schemaCursor, contentCursor, webView, mock); + task.onPreExecute(); + task.doInBackground(); + task.onPostExecute(null); + + assertNotNull(task.stringBuilder.toString()); + + Document html = Jsoup.parse(task.stringBuilder.toString()); + assertNotNull(html); + Elements elements = html.getElementsByTag("table"); + assertEquals(1, elements.size()); + elements = elements.get(0).getElementsByTag("tr"); + assertEquals(5, elements.size()); + Elements headerRow = elements.get(0).getElementsByTag("th"); + assertEquals(3, headerRow.size()); + + sqLiteDatabase.close(); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java new file mode 100644 index 0000000000..fc957ab881 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.asynchronous.asynctasks; + +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.EXCEPTION_SHELL_NOT_RUNNING; +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.EXCEPTION_STREAM_NOT_FOUND; +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.NORMAL; +import static org.junit.Assert.assertEquals; +import static org.robolectric.Shadows.shadowOf; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; + +import org.apache.ftpserver.util.IoUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import com.amaze.filemanager.exceptions.ShellNotRunningException; +import com.amaze.filemanager.filesystem.EditableFileAbstraction; +import com.amaze.filemanager.filesystem.FileUtil; +import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.utils.RootUtils; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.Uri; +import android.os.Environment; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class WriteFileAbstractionTest { + + private static final String contents = "This is modified data"; + + @Test + public void testWriteContentUri() { + Uri uri = Uri.parse("content://com.amaze.filemanager.test/foobar.txt"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + shadowOf(cr).registerOutputStream(uri, bout); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + assertEquals(contents, new String(bout.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testWriteFileNonRoot() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + public void testWriteFileOverwriting() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + IoUtils.copy(new StringReader("Dummy test content"), new FileWriter(file), 1024); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class, BypassMountPartitionRootUtils.class}) + public void testWriteFileRoot() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + File cacheFile = File.createTempFile("test.txt", "cache"); + cacheFile.deleteOnExit(); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class}) + public void testWriteFileRootNoCacheFile() { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_STREAM_NOT_FOUND, result); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class}) + public void testWriteFileRootCacheFileNotFound() { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + File cacheFile = new File(Environment.getExternalStorageDirectory(), "test.txt.cache"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_STREAM_NOT_FOUND, result); + } + + @Test + @Config(shadows = {ShellNotRunningRootUtils.class}) + public void testWriteFileRootShellNotRunning() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + File cacheFile = File.createTempFile("test.txt", "cache"); + cacheFile.deleteOnExit(); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_SHELL_NOT_RUNNING, result); + } + + @Test(expected = IllegalArgumentException.class) + public void testWriteBogeyUri() { + Uri uri = Uri.parse("ftp://bogey.ftp/test.txt"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + shadowOf(cr).registerOutputStream(uri, bout); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + + task.doInBackground(); + } + + @Implements(FileUtil.class) + static class BlockAllOutputStreamsFileUtil { + + @Implementation + public static OutputStream getOutputStream(final File target, Context context) + throws FileNotFoundException { + return null; + } + } + + @Implements(RootUtils.class) + static class BypassMountPartitionRootUtils { + + @Implementation + public static void cat(String sourcePath, String destinationPath) + throws ShellNotRunningException { + try { + IoUtils.copy(new FileInputStream(sourcePath), new FileOutputStream(destinationPath), 512); + } catch (IOException e) { + throw new ShellNotRunningException(); + } + } + } + + @Implements(RootUtils.class) + static class ShellNotRunningRootUtils { + @Implementation + public static void cat(String sourcePath, String destinationPath) + throws ShellNotRunningException { + throw new ShellNotRunningException(); + } + } +} diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java new file mode 100644 index 0000000000..2b44e41fad --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.filesystem; + +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.CONTENT; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.File; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.shadows.ShadowMultiDex; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.net.Uri; +import android.os.Environment; +import android.provider.OpenableColumns; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class EditableFileAbstractionTest { + + @Test(expected = IllegalArgumentException.class) + public void testBogeyUri() { + new EditableFileAbstraction( + ApplicationProvider.getApplicationContext(), Uri.parse("https://github.com/TeamAmaze")); + } + + @Test + public void testContentUri() { + Uri uri = Uri.parse("content://com.amaze.filemanager.test/foobar/foobar.txt"); + String displayName = "foobar.txt"; + ContentResolver cr = ApplicationProvider.getApplicationContext().getContentResolver(); + ContentValues content = new ContentValues(); + content.put(OpenableColumns.DISPLAY_NAME, displayName); + cr.insert(uri, content); + + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals(CONTENT, verify.scheme); + assertEquals(displayName, verify.name); + assertNull(verify.hybridFileParcelable); + assertEquals(uri, verify.uri); + } + + @Test + public void testNonExistentContentUri() { + Uri uri = Uri.parse("content://foo.bar.bogey.uri/test.txt"); + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals("test.txt", verify.name); + assertNull(verify.hybridFileParcelable); + assertEquals(CONTENT, verify.scheme); + assertEquals(uri, verify.uri); + } + + @Test + public void testFileUri() { + File file = new File(Environment.getExternalStorageDirectory(), "test.odt"); + Uri uri = Uri.fromFile(file); + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals("test.odt", verify.name); + assertNotNull(verify.hybridFileParcelable); + assertEquals(FILE, verify.scheme); + assertNull(verify.uri); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java index cb6a39383a..334a7e9599 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -54,7 +54,7 @@ public void testSetColorizeIcons() { doTest(R.color.archive_item, Icons.COMPRESSED); doTest(R.color.apk_item, Icons.APK); doTest(R.color.generic_item, Icons.NOT_KNOWN); - assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... } @Test @@ -68,7 +68,7 @@ public void testSetColorizeIconsGeneric() { doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); doTestGeneric(R.color.primary_indigo, Icons.GIF); - assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... } private void doTest(@ColorInt int expected, int icon) { diff --git a/app/src/test/resources/test.db b/app/src/test/resources/test.db new file mode 100644 index 0000000000000000000000000000000000000000..f86ffa33ed10fe833ec197d2eceb9ae9250411b1 GIT binary patch literal 36864 zcmeI*-)qxA0KoCPT-qkZ?gpcTB0?AlmWenOWDhc@1Q~W!X9w-;lpxsy5DTA#2dZ1+grNXO*Yng+vEQE`DmsQ zg^ihWwJ03lo;4mGDf;Q2rS|f;KU;4^7oz#FeyI`G7izVmCNn+Wp1H;9rk5)Om5SWF zomL<_b+*p$JZZKwJKbJq3NO#k&dtm(h8Ls7aAu)#X|`?-Fc;Mu;X-}(%0gtT(rK>7 z<9;K$W@53HX&T@RWx4vR-GMAbg{Ul8fP?k<))$k_re^7WbD_pqj z=7Wg|xtLz!;K;preIxE%k9Q?=J1%-x<`G-{qvn&<&4aQK1cAI?{?%@2t2jG8pS9Fq zn%U#-?`Bokn!Vngq-&br$`-3tl@HDY`$=Zso)hWDtvbIiI++$#<|pRapION)u6``^ zNBu%SH4y>=2q1s}0tg_000IagfB*sr{CffiTvwFK-6ZMvlcZZxt{AJdlGaq~_*Bvw zaa<7u&6W1`_|)mi^Cw58DSXI20oZ!VP&8NM>UTo_&|mZ?6Cogg00IagfB*srAbUkUv|e>EEd0tg_000IagfB*srAbheKmY**5I_I{1Q0*~f&X2=PWkUE*EMS=r|h2qIId$7 JW`~*o|0nwGFIfNp literal 0 HcmV?d00001 From eb9b94f6d774ca4a8be56571f598658bf1158af0 Mon Sep 17 00:00:00 2001 From: VishalNehra Date: Fri, 7 Aug 2020 13:00:28 +0530 Subject: [PATCH 06/32] 1946: Add translucent theme at amaze startup --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d1923c7c71..b1270ade0b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,7 +56,8 @@ android:label="@string/appbar_name" android:launchMode="singleInstance" android:name=".ui.activities.MainActivity" - android:theme="@style/appCompatLight"> + android:theme="@android:style/Theme.Translucent.NoTitleBar" + android:screenOrientation="sensor"> From 67da23ddd25f3cf1fa837d23b7c111d7c24fe04d Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 8 Aug 2020 10:17:16 +0800 Subject: [PATCH 07/32] [WIP] test cases collection --- .../filemanager/application/AppConfig.java | 12 +- .../filesystem/MediaStoreHack.java | 2 +- .../preference_fragments/PrefFrag.java | 2 +- .../ui/views/WarnableTextInputValidator.java | 46 +++--- .../application/AppConfigTest.java | 116 +++++++++++++++ .../filemanager/ssh/SshClientUtilTest.java | 38 +++++ .../activities/PreferencesActivityTest.java | 136 ++++++++++++++++++ .../views/WarnableTextInputValidatorTest.java | 88 ++++++++++++ 8 files changed, 405 insertions(+), 35 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java diff --git a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java index da79e231e4..2b69f7c719 100644 --- a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java +++ b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java @@ -179,11 +179,7 @@ public static void toast(Context context, @StringRes int message) { final Context c = context; final @StringRes int m = message; - ((AppConfig) context) - .runInApplicationThread( - () -> { - Toast.makeText(c, m, Toast.LENGTH_LONG).show(); - }); + getInstance().runInApplicationThread(() -> Toast.makeText(c, m, Toast.LENGTH_LONG).show()); } } @@ -207,11 +203,7 @@ public static void toast(Context context, String message) { final Context c = context; final String m = message; - ((AppConfig) context) - .runInApplicationThread( - () -> { - Toast.makeText(c, m, Toast.LENGTH_LONG).show(); - }); + getInstance().runInApplicationThread(() -> Toast.makeText(c, m, Toast.LENGTH_LONG).show()); } } diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java b/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java index b5c5e45e76..b613ebd93b 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java @@ -154,7 +154,7 @@ private static int getTemporaryAlbumId(final Context context) { try { temporaryTrack = installTemporaryTrack(context); } catch (final IOException ex) { - Log.w("MediaFile", "Error installing tempory track.", ex); + Log.w("MediaFile", "Error installing temporary track.", ex); return 0; } final Uri filesUri = MediaStore.Files.getContentUri("external"); diff --git a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java index 018c72c345..9c4db6e745 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java +++ b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java @@ -164,7 +164,7 @@ public void onCreate(Bundle savedInstanceState) { masterPasswordPreference.setEnabled(false); return true; }); - } catch (NoClassDefFoundError error) { + } catch (NoClassDefFoundError | ClassCastException error) { error.printStackTrace(); // fingerprint manager class not defined in the framework diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java b/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java index cb95407130..71125c98ad 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java @@ -34,11 +34,11 @@ public final class WarnableTextInputValidator extends SimpleTextWatcher implements View.OnFocusChangeListener, View.OnTouchListener { - private final Context mContext; - private final EditText mEditText; - private final View mButton; - private final WarnableTextInputLayout mTextInputLayout; - private final OnTextValidate mValidator; + private final Context context; + private final EditText editText; + private final View button; + private final WarnableTextInputLayout textInputLayout; + private final OnTextValidate validator; private @DrawableRes int warningDrawable, errorDrawable; public WarnableTextInputValidator( @@ -47,15 +47,15 @@ public WarnableTextInputValidator( WarnableTextInputLayout textInputLayout, View positiveButton, OnTextValidate validator) { - mContext = context; - mEditText = editText; - mEditText.setOnFocusChangeListener(this); - mEditText.addTextChangedListener(this); - mTextInputLayout = textInputLayout; - mButton = positiveButton; - mButton.setOnTouchListener(this); - mButton.setEnabled(false); - mValidator = validator; + this.context = context; + this.editText = editText; + this.editText.setOnFocusChangeListener(this); + this.editText.addTextChangedListener(this); + this.textInputLayout = textInputLayout; + button = positiveButton; + button.setOnTouchListener(this); + button.setEnabled(false); + this.validator = validator; warningDrawable = R.drawable.ic_warning_24dp; errorDrawable = R.drawable.ic_error_24dp; @@ -65,7 +65,7 @@ public WarnableTextInputValidator( public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { int state = doValidate(false); - mButton.setEnabled(state != ReturnState.STATE_ERROR); + button.setEnabled(state != ReturnState.STATE_ERROR); } } @@ -86,24 +86,24 @@ public void afterTextChanged(Editable s) { /** @return ReturnState.state */ private int doValidate(boolean onlySetWarning) { - ReturnState state = mValidator.isTextValid(mEditText.getText().toString()); + ReturnState state = validator.isTextValid(editText.getText().toString()); switch (state.state) { case ReturnState.STATE_NORMAL: - mTextInputLayout.removeError(); + textInputLayout.removeError(); setEditTextIcon(null); - mButton.setEnabled(true); + button.setEnabled(true); break; case ReturnState.STATE_ERROR: if (!onlySetWarning) { - mTextInputLayout.setError(mContext.getString(state.text)); + textInputLayout.setError(context.getString(state.text)); setEditTextIcon(errorDrawable); } - mButton.setEnabled(false); + button.setEnabled(false); break; case ReturnState.STATE_WARNING: - mTextInputLayout.setWarning(state.text); + textInputLayout.setWarning(state.text); setEditTextIcon(warningDrawable); - mButton.setEnabled(true); + button.setEnabled(true); break; } @@ -112,7 +112,7 @@ private int doValidate(boolean onlySetWarning) { private void setEditTextIcon(@DrawableRes Integer drawable) { @DrawableRes int drawableInt = drawable != null ? drawable : 0; - mEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawableInt, 0); + editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawableInt, 0); } public interface OnTextValidate { diff --git a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java new file mode 100644 index 0000000000..77e61cba5c --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.application; + +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Field; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowToast; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.ui.activities.MainActivity; +import com.bumptech.glide.Glide; +import com.bumptech.glide.MemoryCategory; + +import android.os.StrictMode; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = 28) +public class AppConfigTest { + + @After + public void tearDown() { + ShadowToast.reset(); + } + + @Test + public void testSetVmPolicyOnAppCreateHasNoFlags() throws Exception { + Field maskField = StrictMode.VmPolicy.class.getDeclaredField("mask"); + maskField.setAccessible(true); + assertEquals(0, maskField.get(StrictMode.getVmPolicy())); + } + + @Test + public void testToastWithNullContext() { + AppConfig.toast(null, R.string.ok); + assertNull(ShadowToast.getLatestToast()); + } + + @Test + public void testToastWithStringRes() { + AppConfig.toast(ApplicationProvider.getApplicationContext(), R.string.ok); + await().atMost(5, TimeUnit.SECONDS).until(() -> ShadowToast.getLatestToast() != null); + assertEquals( + ApplicationProvider.getApplicationContext().getString(R.string.ok), + ShadowToast.getTextOfLatestToast()); + } + + @Test + public void testToastWithString() { + AppConfig.toast(ApplicationProvider.getApplicationContext(), "Hello world"); + await().atMost(5, TimeUnit.SECONDS).until(() -> ShadowToast.getLatestToast() != null); + assertEquals("Hello world", ShadowToast.getTextOfLatestToast()); + } + + @Test + public void testGetImageLoader() throws Exception { + Field requestQueue = AppConfig.class.getDeclaredField("requestQueue"); + Field imageLoader = AppConfig.class.getDeclaredField("imageLoader"); + requestQueue.setAccessible(true); + imageLoader.setAccessible(true); + + assertNull(requestQueue.get(AppConfig.getInstance())); + assertNull(imageLoader.get(AppConfig.getInstance())); + + assertNotNull(AppConfig.getInstance().getImageLoader()); + } + + @Test + public void testGlideMemoryCategorySetToHigh() throws Exception { + Field memoryCategory = Glide.class.getDeclaredField("memoryCategory"); + memoryCategory.setAccessible(true); + assertEquals( + MemoryCategory.HIGH, + memoryCategory.get(Glide.get(ApplicationProvider.getApplicationContext()))); + } + + @Test + public void testGetScreenUtils() { + assertNull(AppConfig.getInstance().getScreenUtils()); + + MainActivity mock = mock(MainActivity.class); + AppConfig.getInstance().setMainActivityContext(mock); + assertNotNull(AppConfig.getInstance().getScreenUtils()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java b/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java new file mode 100644 index 0000000000..3c455db9a2 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ssh; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.amaze.filemanager.filesystem.ssh.SshClientUtils; + +public class SshClientUtilTest { + @Test + public void testExtractRemotePathFromUri() { + assertEquals( + "/home/user/foo/bar", + SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22/home/user/foo/bar")); + assertEquals("/", SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22/")); + assertEquals("/", SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22")); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java new file mode 100644 index 0000000000..e45a4a6d1f --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.activities; + +import static android.os.Build.VERSION_CODES.P; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_BOOKMARKS_ADDED; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_CHANGEPATHS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORIZE_ICONS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_NEED_TO_SET_HOME; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_ROOTMODE; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_DIVIDERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_FILE_SIZE; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_GOBACK_BUTTON; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_HEADERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_HIDDENFILES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_LAST_MODIFIED; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_PERMISSIONS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_SIDEBAR_FOLDERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_SIDEBAR_QUICKACCESSES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_THUMB; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_TEXTEDITOR_NEWSTACK; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_USE_CIRCULAR_IMAGES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_VIEW; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import androidx.lifecycle.Lifecycle; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = P) +public class PreferencesActivityTest { + + private static final String[] DEFAULT_FALSE_PREFS = + new String[] { + PREFERENCE_SHOW_PERMISSIONS, + PREFERENCE_SHOW_GOBACK_BUTTON, + PREFERENCE_SHOW_HIDDENFILES, + PREFERENCE_BOOKMARKS_ADDED, + PREFERENCE_ROOTMODE, + PREFERENCE_COLORED_NAVIGATION, + PREFERENCE_TEXTEDITOR_NEWSTACK, + PREFERENCE_CHANGEPATHS + }; + + private static final String[] DEFAULT_TRUE_PREFS = + new String[] { + PREFERENCE_SHOW_FILE_SIZE, + PREFERENCE_SHOW_DIVIDERS, + PREFERENCE_SHOW_HEADERS, + PREFERENCE_USE_CIRCULAR_IMAGES, + PREFERENCE_COLORIZE_ICONS, + PREFERENCE_SHOW_THUMB, + PREFERENCE_SHOW_SIDEBAR_QUICKACCESSES, + PREFERENCE_NEED_TO_SET_HOME, + PREFERENCE_SHOW_SIDEBAR_FOLDERS, + PREFERENCE_VIEW, + PREFERENCE_SHOW_LAST_MODIFIED + }; + + private ActivityScenario scenario; + + @Before + public void setUp() { + scenario = ActivityScenario.launch(PreferencesActivity.class); + scenario.moveToState(Lifecycle.State.STARTED); + } + + @After + public void tearDown() { + scenario.close(); + } + + @Test + public void testGetBooleanWithNoSavedValue() { + scenario.onActivity( + activity -> { + for (String pref : DEFAULT_FALSE_PREFS) { + assertFalse(activity.getBoolean(pref)); + } + for (String pref : DEFAULT_TRUE_PREFS) { + assertTrue(activity.getBoolean(pref)); + } + assertThrows(IllegalArgumentException.class, () -> activity.getBoolean("foobar")); + }); + } + + @Test + public void testGetBooleanWithSavedValue() { + SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext()); + scenario.onActivity( + activity -> { + for (String pref : DEFAULT_FALSE_PREFS) { + preferences.edit().putBoolean(pref, true).commit(); + assertTrue(activity.getBoolean(pref)); + } + for (String pref : DEFAULT_TRUE_PREFS) { + preferences.edit().putBoolean(pref, false).commit(); + assertFalse(activity.getBoolean(pref)); + } + assertThrows(IllegalArgumentException.class, () -> activity.getBoolean("foobar")); + }); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java new file mode 100644 index 0000000000..082457eb4b --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.views; + +import static android.os.Build.VERSION_CODES.P; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.R; + +import android.content.Context; +import android.widget.Button; +import android.widget.EditText; + +import androidx.appcompat.widget.AppCompatButton; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = P) +public class WarnableTextInputValidatorTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + context.setTheme(R.style.appCompatBlack); + } + + @Test + public void testValidate() { + EditText textfield = new AppCompatEditText(context); + WarnableTextInputLayout layout = + new WarnableTextInputLayout(context, Robolectric.buildAttributeSet().build()); + Button button = new AppCompatButton(context); + WarnableTextInputValidator.OnTextValidate validator = + text -> + ("Pass".equals(text)) + ? new WarnableTextInputValidator.ReturnState( + WarnableTextInputValidator.ReturnState.STATE_NORMAL, R.string.ok) + : new WarnableTextInputValidator.ReturnState( + WarnableTextInputValidator.ReturnState.STATE_ERROR, R.string.error); + + WarnableTextInputValidator target = + new WarnableTextInputValidator( + ApplicationProvider.getApplicationContext(), textfield, layout, button, validator); + textfield.setText(""); + target.performClick(); + assertFalse(button.isEnabled()); + assertEquals(context.getString(R.string.error), layout.getError()); + textfield.setText("pass"); + target.performClick(); + assertFalse(button.isEnabled()); + assertEquals(context.getString(R.string.error), layout.getError()); + textfield.setText("Pass"); + target.performClick(); + assertTrue(button.isEnabled()); + assertNull(layout.getError()); + } +} From 03b7d564fc17ee908d69231ba57ef7e8a0011b28 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 8 Aug 2020 16:29:57 +0800 Subject: [PATCH 08/32] Additional try/catch to handle broken symlinks With the current logic, if there is a broken symlink the block will exit at all, causing incomplete file listings. Adding a try/catch here can keep the loop to stay. --- .../filemanager/filesystem/HybridFile.java | 8 +++++-- .../filesystem/ssh/ListFilesOnSshdTest.java | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index 9f9ca90189..3c03cdfdf7 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -788,8 +788,12 @@ public Void execute(SFTPClient client) { client.ls(SshClientUtils.extractRemotePathFrom(path))) { boolean isDirectory = info.isDirectory(); if (info.getAttributes().getType().equals(FileMode.Type.SYMLINK)) { - FileAttributes symlinkAttrs = client.stat(info.getPath()); - isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); + try { + FileAttributes symlinkAttrs = client.stat(info.getPath()); + isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); + } catch (IOException ifSymlinkIsBroken) { + continue; + } } HybridFileParcelable f = new HybridFileParcelable(String.format("%s/%s", path, info.getName())); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java index e8c71008fb..2e11bde230 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java @@ -144,4 +144,26 @@ public void testListDirsAndFilesAndSymlinks() throws Exception { "symlink3.txt", "symlink4.txt")); } + + @Test + public void testListDirsAndBrokenSymlinks() throws Exception { + File sysroot = new File(Environment.getExternalStorageDirectory(), "sysroot"); + sysroot.mkdir(); + Files.createSymbolicLink( + Paths.get( + new File(Environment.getExternalStorageDirectory(), "b0rken.symlink") + .getAbsolutePath()), + Paths.get(new File("/tmp/notfound.file").getAbsolutePath())); + for (String s : new String[] {"srv", "var", "tmp"}) { + File subdir = new File(sysroot, s); + subdir.mkdir(); + Files.createSymbolicLink( + Paths.get(new File(Environment.getExternalStorageDirectory(), s).getAbsolutePath()), + Paths.get(subdir.getAbsolutePath())); + } + for (String s : new String[] {"bin", "lib", "usr"}) { + new File(Environment.getExternalStorageDirectory(), s).mkdir(); + } + performVerify(); + } } From a0f2183875ae7c8da96d78173db2793707d3f116 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Tue, 28 Jul 2020 17:45:37 +0800 Subject: [PATCH 09/32] Fixes for editing SMB connections - moved jcifs.Config.registerSmbURLHandler() from SmbConnectDialog to AppConfig.runInBackground() - encrypt paths in UtilsHandler.renameSMB() as it was stored encrypted in database Tested on Oneplus 2 running AOSPExtended (7.1.2) and LG Nexus 5x running AOSPExtended (9.0). --- .../com/amaze/filemanager/application/AppConfig.java | 5 ++--- .../com/amaze/filemanager/database/UtilsHandler.java | 9 +++++++++ .../amaze/filemanager/ui/dialogs/SmbConnectDialog.java | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java index 2b69f7c719..2ef2746d19 100644 --- a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java +++ b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java @@ -87,12 +87,11 @@ public void onCreate() { utilsProvider = new UtilitiesProvider(this); utilsHandler = new UtilsHandler(this, utilitiesDatabase); - // FIXME: in unit tests when AppConfig is rapidly created/destroyed this call will cause - // IllegalThreadStateException. - // Until this gets fixed only one test case can be run in a time. - Raymond, 24/4/2018 backgroundHandlerThread.start(); backgroundHandler = new Handler(backgroundHandlerThread.getLooper()); + runInBackground(jcifs.Config::registerSmbURLHandler); + // disabling file exposure method check for api n+ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); diff --git a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java index b4785fd8db..3068ce3106 100644 --- a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java +++ b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java @@ -58,6 +58,8 @@ */ public class UtilsHandler { + private static final String TAG = UtilsHandler.class.getSimpleName(); + private final Context context; private final UtilitiesDatabase utilitiesDatabase; @@ -313,6 +315,13 @@ public void renameBookmark(String oldName, String oldPath, String newName, Strin } public void renameSMB(String oldName, String oldPath, String newName, String newPath) { + try { + oldPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), oldPath); + newPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), newPath); + } catch (GeneralSecurityException | IOException e) { + Log.e(TAG, "Error encrypting SMB path", e); + } + SmbEntry smbEntry = utilitiesDatabase.smbEntryDao().findByNameAndPath(oldName, oldPath); smbEntry.name = newName; smbEntry.path = newPath; diff --git a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java index 94196cb28c..1f2f45a8d3 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java +++ b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java @@ -207,7 +207,6 @@ public void afterTextChanged(Editable s) { String userp = "", passp = "", ipp = "", domainp = ""; conName.setText(name); try { - jcifs.Config.registerSmbURLHandler(); URL a = new URL(path); String userinfo = a.getUserInfo(); if (userinfo != null) { From 0b6a61cfc02cc19f990baac80d18567a82ab9225 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 8 Aug 2020 22:42:28 +0800 Subject: [PATCH 10/32] MainActivityTest test addConnection() --- .../shadows/jcifs/smb/ShadowSmbFile.java | 5 ++ .../ui/activities/MainActivityTest.java | 66 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java b/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java index 2896864971..f13a2f5ac4 100644 --- a/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java +++ b/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java @@ -56,4 +56,9 @@ public InputStream getInputStream() throws IOException { public long length() throws SmbException { return file.length(); } + + @Implementation + public SmbFile[] listFiles() { + return new SmbFile[0]; + } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index da087f9bde..4b315dc8fb 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -23,8 +23,16 @@ import static android.os.Build.VERSION_CODES.N; import static android.os.Build.VERSION_CODES.P; import static androidx.test.core.app.ActivityScenario.launch; +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import static org.robolectric.Shadows.shadowOf; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.concurrent.TimeUnit; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -34,8 +42,12 @@ import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowStorageManager; +import com.amaze.filemanager.application.AppConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.shadows.jcifs.smb.ShadowSmbFile; +import com.amaze.filemanager.test.ShadowCryptUtil; import com.amaze.filemanager.test.TestUtils; +import com.amaze.filemanager.utils.SmbUtil; import android.os.Build; import android.os.storage.StorageManager; @@ -47,7 +59,12 @@ @RunWith(AndroidJUnit4.class) @Config( - shadows = {ShadowMultiDex.class, ShadowStorageManager.class}, + shadows = { + ShadowMultiDex.class, + ShadowStorageManager.class, + ShadowCryptUtil.class, + ShadowSmbFile.class + }, maxSdk = P) /* * Need to make LooperMode PAUSED and flush the main looper before activity can show up. @@ -70,7 +87,7 @@ public void tearDown() { } @Test - public void testMainActivity() { + public void testUpdateSmbExceptionShouldNotThrowNPE() { ActivityScenario scenario = launch(MainActivity.class); ShadowLooper.idleMainLooper(); @@ -79,7 +96,50 @@ public void testMainActivity() { scenario.onActivity( activity -> { - scenario.close(); + String path = "smb://root:toor@192.168.1.1"; + String oldName = "SMB connection"; + String newName = "root@192.168.1.1"; + try { + + activity.addConnection( + false, + oldName, + path, + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path), + null, + null); + activity.addConnection( + true, + newName, + path, + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path), + oldName, + path); + + ShadowLooper.idleMainLooper(); + + await() + .atMost(5, TimeUnit.SECONDS) + .until(() -> AppConfig.getInstance().getUtilsHandler().getSmbList().size() > 0); + await() + .atMost(5, TimeUnit.SECONDS) + .until( + () -> + AppConfig.getInstance() + .getUtilsHandler() + .getSmbList() + .get(0)[0] + .equals(newName)); + List verify = AppConfig.getInstance().getUtilsHandler().getSmbList(); + String[] entry = verify.get(0); + assertEquals(path, entry[1]); + + } catch (GeneralSecurityException | IOException e) { + fail(e.getMessage()); + } finally { + scenario.moveToState(Lifecycle.State.DESTROYED); + scenario.close(); + } }); } } From 1d93a30626710c63ca0e8ff4d87fca28dbe10cd7 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 9 Aug 2020 11:10:10 +0800 Subject: [PATCH 11/32] Changes per PR feedback - Log broken symbolic link - Refactor ListFilesOnSshdTest for better codacy compliance. Also changed performVerify() to use awaitility's await() to better match the situation that file listings should not be broken because of broken symlinks --- .../filemanager/filesystem/HybridFile.java | 4 ++ .../filesystem/ssh/ListFilesOnSshdTest.java | 46 ++++++------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index 3c03cdfdf7..850cb07b36 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -792,6 +792,10 @@ public Void execute(SFTPClient client) { FileAttributes symlinkAttrs = client.stat(info.getPath()); isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); } catch (IOException ifSymlinkIsBroken) { + Log.w( + TAG, + String.format( + "Symbolic link %s is broken, skipping", info.getPath())); continue; } } diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java index 2e11bde230..eaf9d396b4 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java @@ -20,6 +20,7 @@ package com.amaze.filemanager.filesystem.ssh; +import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.hasItems; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -28,6 +29,7 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -49,11 +51,16 @@ public void testNormalListDirs() throws InterruptedException { for (String s : new String[] {"sysroot", "srv", "var", "tmp", "bin", "lib", "usr"}) { new File(Environment.getExternalStorageDirectory(), s).mkdir(); } - performVerify(); + assertTrue(performVerify()); } @Test public void testListDirsAndSymlinks() throws Exception { + createNecessaryDirsForSymlinkRelatedTests(); + assertTrue(performVerify()); + } + + private void createNecessaryDirsForSymlinkRelatedTests() throws IOException { File sysroot = new File(Environment.getExternalStorageDirectory(), "sysroot"); sysroot.mkdir(); for (String s : new String[] {"srv", "var", "tmp"}) { @@ -66,41 +73,27 @@ public void testListDirsAndSymlinks() throws Exception { for (String s : new String[] {"bin", "lib", "usr"}) { new File(Environment.getExternalStorageDirectory(), s).mkdir(); } - performVerify(); } - private void performVerify() throws InterruptedException { + private boolean performVerify() { List result = new ArrayList<>(); HybridFile file = new HybridFile(OpenMode.SFTP, "ssh://testuser:testpassword@127.0.0.1:" + serverPort); - CountDownLatch waiter = new CountDownLatch(7); file.forEachChildrenFile( RuntimeEnvironment.application, false, (fileFound) -> { assertTrue(fileFound.getPath() + " not seen as directory", fileFound.isDirectory()); result.add(fileFound.getName()); - waiter.countDown(); }); - waiter.await(); - assertEquals(7, result.size()); + await().until(() -> result.size() == 7); assertThat(result, hasItems("sysroot", "srv", "var", "tmp", "bin", "lib", "usr")); + return true; } @Test public void testListDirsAndFilesAndSymlinks() throws Exception { - File sysroot = new File(Environment.getExternalStorageDirectory(), "sysroot"); - sysroot.mkdir(); - for (String s : new String[] {"srv", "var", "tmp"}) { - File subdir = new File(sysroot, s); - subdir.mkdir(); - Files.createSymbolicLink( - Paths.get(new File(Environment.getExternalStorageDirectory(), s).getAbsolutePath()), - Paths.get(subdir.getAbsolutePath())); - } - for (String s : new String[] {"bin", "lib", "usr"}) { - new File(Environment.getExternalStorageDirectory(), s).mkdir(); - } + createNecessaryDirsForSymlinkRelatedTests(); for (int i = 1; i <= 4; i++) { File f = new File(Environment.getExternalStorageDirectory(), i + ".txt"); FileOutputStream out = new FileOutputStream(f); @@ -147,23 +140,12 @@ public void testListDirsAndFilesAndSymlinks() throws Exception { @Test public void testListDirsAndBrokenSymlinks() throws Exception { - File sysroot = new File(Environment.getExternalStorageDirectory(), "sysroot"); - sysroot.mkdir(); + createNecessaryDirsForSymlinkRelatedTests(); Files.createSymbolicLink( Paths.get( new File(Environment.getExternalStorageDirectory(), "b0rken.symlink") .getAbsolutePath()), Paths.get(new File("/tmp/notfound.file").getAbsolutePath())); - for (String s : new String[] {"srv", "var", "tmp"}) { - File subdir = new File(sysroot, s); - subdir.mkdir(); - Files.createSymbolicLink( - Paths.get(new File(Environment.getExternalStorageDirectory(), s).getAbsolutePath()), - Paths.get(subdir.getAbsolutePath())); - } - for (String s : new String[] {"bin", "lib", "usr"}) { - new File(Environment.getExternalStorageDirectory(), s).mkdir(); - } - performVerify(); + assertTrue(performVerify()); } } From 8e94af5391d405fab1d047a544b5fb71df884628 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 9 Aug 2020 21:53:11 +0800 Subject: [PATCH 12/32] Adaptation for running the build on JDK 9 With Robolectric 4's support for SDK >= 29 in place, they require the tests must run on JDK 9 or above. Therefore some adaptations must be done to allow this. - add back APIs removed in JDK 9 which are required by Android builds - all Robolectric test cases will have their maxSdk @Config settings centralized in robolectric.properties Due to https://github.com/robolectric/robolectric/issues/5456 and developer adaptation to JDK > 8 is still not yet in place, running the test suite within Android Studio is still not possible out-of-the-box, this commit will not enable running with SDK 29 yet; but once everyone's ready it will be just a switch at robolectric.properties above Tested building from command line with JDK 11 (Latest LTS version) and Android Studio, both on Ubuntu Focal x86_64. Reference: https://medium.com/@jack_martynov/adopt-android-build-on-the-jdk11-macos-cc8f05995341 --- .../application/AppConfigTest.java | 2 - .../asynctasks/DbViewerTaskTest.java | 4 +- .../asynctasks/WriteFileAbstractionTest.java | 4 +- .../AbstractCompressedHelperTaskTest.java | 5 +- .../services/ExtractServiceTest.java | 4 +- .../EditableFileAbstractionTest.java | 4 +- .../filesystem/OperationsTest.java | 4 +- .../filesystem/RootHelperTest.java | 4 +- .../cloud/CloudStreamSourceTest.java | 4 +- .../filesystem/compressed/B0rkenZipTest.java | 4 +- .../compressed/CompressedHelperTest.java | 4 +- .../AbstractExtractorTest.java | 3 +- .../filesystem/files/FileListSorterTest.java | 4 +- .../smbstreamer/StreamSourceTest.java | 4 +- .../ssh/AbstractSftpServerTest.java | 4 +- .../filesystem/ssh/SshConnectionPoolTest.java | 4 +- .../filesystem/usb/SingletonUsbOtgTest.java | 3 +- .../filesystem/usb/UsbOtgTest.java | 3 +- .../filemanager/test/ShadowCryptUtilTest.java | 4 +- .../ui/activities/MainActivityTest.java | 5 +- .../activities/PreferencesActivityTest.java | 3 -- .../ui/activities/TextEditorActivityTest.java | 4 +- .../filemanager/ui/colors/ColorUtilsTest.java | 47 +++++++++---------- .../ui/fragments/CloudSheetFragmentTest.java | 2 +- .../amaze/filemanager/ui/icons/IconsTest.java | 4 +- .../NotificationConstantsTest.java | 2 +- .../views/WarnableTextInputValidatorTest.java | 3 -- .../filemanager/utils/AnimUtilsTest.java | 2 +- .../amaze/filemanager/utils/SmbUtilTest.java | 1 - .../amaze/filemanager/utils/TinyDBTest.java | 2 +- .../amaze/filemanager/utils/UtilsTest.java | 2 +- app/src/test/resources/robolectric.properties | 1 + build.gradle | 30 ++++++++++-- 33 files changed, 78 insertions(+), 102 deletions(-) create mode 100644 app/src/test/resources/robolectric.properties diff --git a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java index 77e61cba5c..183375750c 100644 --- a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java +++ b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java @@ -32,7 +32,6 @@ import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; import com.amaze.filemanager.R; @@ -46,7 +45,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = 28) public class AppConfigTest { @After diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java index 8d34294f3a..c9c042f968 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java @@ -51,9 +51,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class DbViewerTaskTest { private WebView webView; diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java index fc957ab881..c7093e9a64 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java @@ -59,9 +59,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class WriteFileAbstractionTest { private static final String contents = "This is modified data"; diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index 085cac4526..618d244e04 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -44,10 +44,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - minSdk = 27, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public abstract class AbstractCompressedHelperTaskTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index 78a5af6868..d608c463d0 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -51,9 +51,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class ExtractServiceTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java index 2b44e41fad..d216223244 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java @@ -44,9 +44,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class EditableFileAbstractionTest { @Test(expected = IllegalArgumentException.class) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 6c7a6b990a..871628a289 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -40,9 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class OperationsTest { private File storageRoot = Environment.getExternalStorageDirectory(); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index d27f4c0c5c..39e02c25fb 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -48,9 +48,7 @@ import eu.chainfire.libsuperuser.Shell; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}) public class RootHelperTest { private static final File sysroot = diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index 6764b6edb9..abe76c114f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -46,9 +46,7 @@ /** Created by Rustam Khadipash on 31/3/2018. */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class CloudStreamSourceTest { private CloudStreamSource cs; private String testFilePath; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index 61db2c66dd..53f874c3ec 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -47,9 +47,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class B0rkenZipTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index b327165fe8..134e433f17 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -57,9 +57,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class CompressedHelperTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index 83bd264f81..b51fd6eebd 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -53,8 +53,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 14, - maxSdk = 28) + minSdk = 14) public abstract class AbstractExtractorTest { protected abstract Class extractorClass(); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index acaa725abc..57490dcab9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -42,9 +42,7 @@ * "*{slash}*" */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowDateFormat.class}) public class FileListSorterTest { /** * Purpose: when dirsOnTop is 0, if file1 is directory && file2 is not directory, result is -1 diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index f1b51fa828..5ac87031a1 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -47,9 +47,7 @@ /** Created by Rustam Khadipash on 30/3/2018. */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowSmbFile.class}) public class StreamSourceTest { private SmbFile file; private StreamSource ss; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index ca037ea83d..5d08b196dc 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -46,9 +46,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public abstract class AbstractSftpServerTest { protected SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index ccff28ecaa..8db0cccff9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -52,9 +52,7 @@ import net.schmizz.sshj.common.SecurityUtils; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}) public class SshConnectionPoolTest { private SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 6e322aae0b..be4cd8390d 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -41,8 +41,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, - maxSdk = 28) + minSdk = 24) public class SingletonUsbOtgTest { @Test public void usbConnectionTest() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 958c6c6f7e..7cac7181a2 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -45,8 +45,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, - maxSdk = 28) + minSdk = 24) public class UsbOtgTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index 9a6271a45e..8761127eff 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -40,9 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}) public class ShadowCryptUtilTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 4b315dc8fb..1197dbe822 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -21,7 +21,6 @@ package com.amaze.filemanager.ui.activities; import static android.os.Build.VERSION_CODES.N; -import static android.os.Build.VERSION_CODES.P; import static androidx.test.core.app.ActivityScenario.launch; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; @@ -64,8 +63,7 @@ ShadowStorageManager.class, ShadowCryptUtil.class, ShadowSmbFile.class - }, - maxSdk = P) + }) /* * Need to make LooperMode PAUSED and flush the main looper before activity can show up. * @see {@link LooperMode.Mode.PAUSED} @@ -131,6 +129,7 @@ public void testUpdateSmbExceptionShouldNotThrowNPE() { .get(0)[0] .equals(newName)); List verify = AppConfig.getInstance().getUtilsHandler().getSmbList(); + assertEquals(1, verify.size()); String[] entry = verify.get(0); assertEquals(path, entry[1]); diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java index e45a4a6d1f..9c1f339cd0 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java @@ -20,7 +20,6 @@ package com.amaze.filemanager.ui.activities; -import static android.os.Build.VERSION_CODES.P; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_BOOKMARKS_ADDED; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_CHANGEPATHS; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; @@ -48,7 +47,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -59,7 +57,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = P) public class PreferencesActivityTest { private static final String[] DEFAULT_FALSE_PREFS = diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 8244ddbacc..fc1c1db5c6 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -52,9 +52,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class TextEditorActivityTest { private final String fileContents = "fsdfsdfs"; diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java index 334a7e9599..eef3000376 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -21,9 +21,8 @@ package com.amaze.filemanager.ui.colors; import static android.os.Build.VERSION_CODES.N; -import static android.os.Build.VERSION_CODES.P; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,37 +40,35 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = N, maxSdk = P) +@Config(minSdk = N) public class ColorUtilsTest { @Test public void testSetColorizeIcons() { - doTest(R.color.video_item, Icons.VIDEO); - doTest(R.color.audio_item, Icons.AUDIO); - doTest(R.color.pdf_item, Icons.PDF); - doTest(R.color.code_item, Icons.CODE); - doTest(R.color.text_item, Icons.TEXT); - doTest(R.color.archive_item, Icons.COMPRESSED); - doTest(R.color.apk_item, Icons.APK); - doTest(R.color.generic_item, Icons.NOT_KNOWN); - assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... + assertTrue(doTest(R.color.video_item, Icons.VIDEO)); + assertTrue(doTest(R.color.audio_item, Icons.AUDIO)); + assertTrue(doTest(R.color.pdf_item, Icons.PDF)); + assertTrue(doTest(R.color.code_item, Icons.CODE)); + assertTrue(doTest(R.color.text_item, Icons.TEXT)); + assertTrue(doTest(R.color.archive_item, Icons.COMPRESSED)); + assertTrue(doTest(R.color.apk_item, Icons.APK)); + assertTrue(doTest(R.color.generic_item, Icons.NOT_KNOWN)); } @Test public void testSetColorizeIconsGeneric() { - doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE); - doTestGeneric(R.color.primary_indigo, Icons.CONTACT); - doTestGeneric(R.color.primary_indigo, Icons.EVENTS); - doTestGeneric(R.color.primary_indigo, Icons.FONT); - doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION); - doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS); - doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); - doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); - doTestGeneric(R.color.primary_indigo, Icons.GIF); - assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.CONTACT)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.EVENTS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.FONT)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.GIF)); } - private void doTest(@ColorInt int expected, int icon) { + private boolean doTest(@ColorInt int expected, int icon) { GradientDrawable drawable = new GradientDrawable(); ColorUtils.colorizeIcons( ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); @@ -80,14 +77,16 @@ private void doTest(@ColorInt int expected, int icon) { Utils.getColor(ApplicationProvider.getApplicationContext(), expected)), drawable); drawable = null; + return true; } - private void doTestGeneric(@ColorInt int expected, int icon) { + private boolean doTestGeneric(@ColorInt int expected, int icon) { GradientDrawable drawable = new GradientDrawable(); ColorUtils.colorizeIcons( ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); doCompare(ColorStateList.valueOf(expected), drawable); drawable = null; + return true; } private void doCompare(ColorStateList expected, GradientDrawable drawable) { diff --git a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java index ebb6a72367..69e35f03d2 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java @@ -36,7 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class CloudSheetFragmentTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 6d9d57880b..835de52ccf 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -36,9 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class IconsTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java index 7b7062c4ca..cbe7c34707 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java @@ -54,7 +54,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class NotificationConstantsTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java index 082457eb4b..cbf609fafc 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java @@ -20,7 +20,6 @@ package com.amaze.filemanager.ui.views; -import static android.os.Build.VERSION_CODES.P; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -30,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.annotation.Config; import com.amaze.filemanager.R; @@ -44,7 +42,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = P) public class WarnableTextInputValidatorTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java index 3cc2e3315a..a5150b5406 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java @@ -43,7 +43,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class AnimUtilsTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java index b9645cb815..eb6bb15ded 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java @@ -40,7 +40,6 @@ @RunWith(AndroidJUnit4.class) @Config( minSdk = 19, - maxSdk = 28, shadows = {ShadowCryptUtil.class}) public class SmbUtilTest { diff --git a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java index ae4a996513..c297ad1a02 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java @@ -35,7 +35,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class TinyDBTest { private SharedPreferences prefs; diff --git a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java index eb21bf51e0..4a4947f4ab 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java @@ -53,7 +53,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class UtilsTest { @Test public void diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties new file mode 100644 index 0000000000..6a520f2ee7 --- /dev/null +++ b/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +maxSdk=28 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 84c7e82200..d386348feb 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ plugins { } allprojects { + repositories { google() jcenter() @@ -56,7 +57,7 @@ configurations { robo26 robo27 robo28 -// robo29 + robo29 } dependencies { @@ -72,7 +73,7 @@ dependencies { robo26 "org.robolectric:android-all:8.0.0_r4-robolectric-r1" robo27 "org.robolectric:android-all:8.1.0-robolectric-4611349" robo28 "org.robolectric:android-all:9-robolectric-4913185-2" -// robo29 "org.robolectric:android-all:Q-robolectric-5415296" + robo29 "org.robolectric:android-all:10-robolectric-5803371" } def robolectricDependencies = "${rootProject.buildDir.path}/robolectric" @@ -90,7 +91,7 @@ task fetchRobolectricDependencies(type: Copy) { from configurations.robo26 from configurations.robo27 from configurations.robo28 -// from configurations.robo29 + from configurations.robo29 into robolectricDependencies } @@ -108,5 +109,28 @@ subprojects { it.dependsOn fetchRobolectricDependencies } } + if (project.plugins.hasPlugin("jacoco-android")){ + android { + testOptions.unitTests.all { + jacoco { + excludes = ['jdk.internal.*'] + } + } + } + } + dependencies { + compileOnly 'com.github.pengrad:jdk9-deps:1.0' + + if (project.hasProperty('kapt')) { + kapt 'javax.xml.bind:jaxb-api:2.3.1' + kapt 'com.sun.xml.bind:jaxb-core:2.3.0.1' + kapt 'com.sun.xml.bind:jaxb-impl:2.3.2' + } + + annotationProcessor 'javax.xml.bind:jaxb-api:2.3.1' + annotationProcessor 'com.sun.xml.bind:jaxb-core:2.3.0.1' + annotationProcessor 'com.sun.xml.bind:jaxb-impl:2.3.2' + } } + } \ No newline at end of file From 9329fee947937e1283725f5521ee1a17aec9be3c Mon Sep 17 00:00:00 2001 From: TranceLove Date: Mon, 10 Aug 2020 14:09:45 +0800 Subject: [PATCH 13/32] Fix screen rotation problem after PR #1947 applied In #1947 there was a `android:screenOrientation="sensor"` declared in the manifest, causing UI to rotate as the device changes its orientation, which is quite annoying. Remove it. Tested on Fairphone 3 running LineageOS 16.0 (9.0), still no white screen at startup even when Amaze uses dark themes. --- app/src/main/AndroidManifest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b1270ade0b..d337a140fb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,8 +56,7 @@ android:label="@string/appbar_name" android:launchMode="singleInstance" android:name=".ui.activities.MainActivity" - android:theme="@android:style/Theme.Translucent.NoTitleBar" - android:screenOrientation="sensor"> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> From 232d4e2d620b9923787e2eab3675bfcb0e2f0b9f Mon Sep 17 00:00:00 2001 From: saunak Date: Mon, 17 Aug 2020 01:51:01 +0530 Subject: [PATCH 14/32] #1856. Fix for app crash when using save as option from browser. Added text file creation method within FileUtil and check for intent type = text, basis which a text file will be created on the path the user is currently present. --- .../filemanager/filesystem/FileUtil.java | 30 +++++++++++++ .../ui/activities/MainActivity.java | 43 ++++++++++++++----- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java index 7428f8eaa7..6f2e0a004f 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.OutputStreamWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; @@ -619,6 +620,35 @@ public static boolean mkfile(final File file, Context context) { return false; } + public static boolean mktextfile(String data, String path, String fileName) { + + File f = new File(path + "/" + fileName + ".txt"); + FileOutputStream out = null; + OutputStreamWriter outputWriter = null; + if (f.exists()) { + f.delete(); + } + try { + f.createNewFile(); + out = new FileOutputStream(f); + + outputWriter = new OutputStreamWriter(out); + outputWriter.write(data); + return true; + } catch (IOException io) { + Log.e(FileUtil.LOG, io.getMessage()); + return false; + } finally { + try { + outputWriter.close(); + out.flush(); + out.close(); + } catch (IOException e) { + Log.e(FileUtil.LOG, e.getMessage()); + } + } + } + /** * Delete a folder. * diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index 2359410cc4..b0cb0501c0 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -519,16 +519,20 @@ private void checkForExternalIntent(Intent intent) { zippath = Utils.sanitizeInput(uri.toString()); } - } else if (actionIntent.equals(Intent.ACTION_SEND) && type != null) { - // save a single file to filesystem - Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); - ArrayList uris = new ArrayList<>(); - uris.add(uri); - initFabToSave(uris); + } else if (actionIntent.equals(Intent.ACTION_SEND)) { + if (type.equals("text/plain")) { + initFabToSave(null); + } else { + // save a single file to filesystem + Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM); + ArrayList uris = new ArrayList<>(); + uris.add(uri); + initFabToSave(uris); + } + // disable screen rotation just for convenience purpose + // TODO: Support screen rotation when saving a file + Utils.disableScreenRotation(this); - // disable screen rotation just for convenience purpose - // TODO: Support screen rotation when saving a file - Utils.disableScreenRotation(this); } else if (actionIntent.equals(Intent.ACTION_SEND_MULTIPLE) && type != null) { // save multiple files to filesystem @@ -580,6 +584,23 @@ private void initFabToSave(final ArrayList uris) { .show(); finish(); } + } else { + Bundle extras = intent.getExtras(); + String data = + extras.getString(Intent.EXTRA_SUBJECT) + + "\nURL: " + + extras.getString(Intent.EXTRA_TEXT); + String fileName = Long.toString(System.currentTimeMillis()); + FileUtil.mktextfile(data, getCurrentMainFragment().getCurrentPath(), fileName); + + Toast.makeText( + MainActivity.this, + getResources().getString(R.string.saving) + + " to " + + getCurrentMainFragment().getCurrentPath(), + Toast.LENGTH_LONG) + .show(); + finish(); } }); // Ensure the FAB menu is visible @@ -2053,7 +2074,9 @@ public void onLoadFinished(Loader loader, final Cursor data) { } @Override - public void onLoaderReset(Loader loader) {} + public void onLoaderReset(Loader loader) { + // For passing code check + } private static final class FabActionListener implements SpeedDialView.OnActionSelectedListener { From e88d8329fb2d95c9fad22c4f45f400c4a5c132db Mon Sep 17 00:00:00 2001 From: saunak Date: Mon, 17 Aug 2020 01:55:20 +0530 Subject: [PATCH 15/32] #1856. Fix for app crash when using save as option from browser. Added text file creation method within FileUtil and check for intent type = text, basis which a text file will be created on the path the user is currently present. --- .../com/amaze/filemanager/ui/activities/MainActivity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index b0cb0501c0..3e2609b5bc 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -529,9 +529,9 @@ private void checkForExternalIntent(Intent intent) { uris.add(uri); initFabToSave(uris); } - // disable screen rotation just for convenience purpose - // TODO: Support screen rotation when saving a file - Utils.disableScreenRotation(this); + // disable screen rotation just for convenience purpose + // TODO: Support screen rotation when saving a file + Utils.disableScreenRotation(this); } else if (actionIntent.equals(Intent.ACTION_SEND_MULTIPLE) && type != null) { // save multiple files to filesystem From 7a6f2fae715d04e7cb89c37a39d5c1b58528c5bd Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 15 Aug 2020 00:19:06 +0800 Subject: [PATCH 16/32] Fix OTG not loading file lists on Android >= N + refactoring - Allow USB device detection on Android >= N - Add back missing dialog.show() in Drawer when asking user to open USB device root at Android DocumentsUI - Moved SSH isDirectory() symlink checks to SshClientUtil - combined MediaStore image/video query methods together + fix arguments --- app/build.gradle | 4 +- .../data/StorageDirectoryParcelable.java | 8 +- .../asynctasks/LoadFilesListTask.java | 54 ++---- .../asynctasks/PrepareCopyTask.java | 2 +- .../asynchronous/services/CopyService.java | 4 +- .../filemanager/database/UtilsHandler.java | 12 +- .../filemanager/filesystem/FileUtil.java | 2 +- .../filemanager/filesystem/HybridFile.java | 163 ++++-------------- .../filesystem/HybridFileParcelable.java | 33 +++- .../filemanager/filesystem/Operations.java | 10 +- .../filesystem/files/FileUtils.java | 4 +- .../filesystem/ssh/SshClientUtils.java | 16 ++ .../ui/activities/MainActivity.java | 5 +- .../filemanager/ui/views/drawer/Drawer.java | 6 +- .../filemanager/utils/MainActivityHelper.java | 10 +- .../com/amaze/filemanager/utils/OTGUtil.java | 2 + .../filesystem/ssh/SshClientUtilTest.java | 108 ++++++++++++ 17 files changed, 244 insertions(+), 199 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java diff --git a/app/build.gradle b/app/build.gradle index 072f82aefa..52f823e2a2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -80,6 +80,7 @@ android { testOptions { unitTests { includeAndroidResources = true + returnDefaultValues = true } } } @@ -93,6 +94,7 @@ ext { roomVersion = '2.2.5' bouncyCastleVersion = '1.65' awaitilityVersion = "3.1.6" + mockitoVersion = "3.4.4" } dependencies { @@ -115,7 +117,7 @@ dependencies { testImplementation 'junit:junit:4.12'//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction - + testImplementation "org.mockito:mockito-core:$mockitoVersion" testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" diff --git a/app/src/main/java/com/amaze/filemanager/adapters/data/StorageDirectoryParcelable.java b/app/src/main/java/com/amaze/filemanager/adapters/data/StorageDirectoryParcelable.java index 846ac22832..6cdd6e069b 100644 --- a/app/src/main/java/com/amaze/filemanager/adapters/data/StorageDirectoryParcelable.java +++ b/app/src/main/java/com/amaze/filemanager/adapters/data/StorageDirectoryParcelable.java @@ -28,17 +28,17 @@ /** Identifies a mounted volume */ public class StorageDirectoryParcelable implements Parcelable { - public final String path; - public final String name; + @NonNull public final String path; + @NonNull public final String name; public final @DrawableRes int iconRes; - public StorageDirectoryParcelable(String path, String name, int iconRes) { + public StorageDirectoryParcelable(@NonNull String path, @NonNull String name, int iconRes) { this.path = path; this.name = name; this.iconRes = iconRes; } - public StorageDirectoryParcelable(Parcel im) { + public StorageDirectoryParcelable(@NonNull Parcel im) { path = im.readString(); name = im.readString(); iconRes = im.readInt(); diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/LoadFilesListTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/LoadFilesListTask.java index 60193fbcfc..a4c9fd736c 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/LoadFilesListTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/LoadFilesListTask.java @@ -55,6 +55,8 @@ import android.provider.MediaStore; import android.text.format.Formatter; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.util.Pair; import jcifs.smb.SmbAuthException; @@ -299,72 +301,42 @@ private LayoutElementParcelable createListParcelables(HybridFileParcelable baseF } private ArrayList listImages() { - ArrayList images = new ArrayList<>(); final String[] projection = {MediaStore.Images.Media.DATA}; - final Cursor cursor = - context - .getContentResolver() - .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, null); - if (cursor == null) return images; - else if (cursor.getCount() > 0 && cursor.moveToFirst()) { - do { - String path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)); - HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles); - if (strings != null) { - LayoutElementParcelable parcelable = createListParcelables(strings); - if (parcelable != null) images.add(parcelable); - } - } while (cursor.moveToNext()); - } - cursor.close(); - return images; + return listMediaCommon(projection, null); } private ArrayList listVideos() { - ArrayList videos = new ArrayList<>(); - final String[] projection = {MediaStore.Images.Media.DATA}; - final Cursor cursor = - context - .getContentResolver() - .query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null, null); - if (cursor == null) return videos; - else if (cursor.getCount() > 0 && cursor.moveToFirst()) { - do { - String path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)); - HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles); - if (strings != null) { - LayoutElementParcelable parcelable = createListParcelables(strings); - if (parcelable != null) videos.add(parcelable); - } - } while (cursor.moveToNext()); - } - cursor.close(); - return videos; + final String[] projection = {MediaStore.Video.Media.DATA}; + return listMediaCommon(projection, null); } private ArrayList listaudio() { String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0"; String[] projection = {MediaStore.Audio.Media.DATA}; + return listMediaCommon(projection, selection); + } + private @NonNull ArrayList listMediaCommon( + @NonNull String[] projection, @Nullable String selection) { Cursor cursor = context .getContentResolver() .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection, null, null); - ArrayList songs = new ArrayList<>(); - if (cursor == null) return songs; + ArrayList retval = new ArrayList<>(); + if (cursor == null) return retval; else if (cursor.getCount() > 0 && cursor.moveToFirst()) { do { String path = cursor.getString(cursor.getColumnIndex(MediaStore.Files.FileColumns.DATA)); HybridFileParcelable strings = RootHelper.generateBaseFile(new File(path), showHiddenFiles); if (strings != null) { LayoutElementParcelable parcelable = createListParcelables(strings); - if (parcelable != null) songs.add(parcelable); + if (parcelable != null) retval.add(parcelable); } } while (cursor.moveToNext()); } cursor.close(); - return songs; + return retval; } private ArrayList listDocs() { diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/PrepareCopyTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/PrepareCopyTask.java index fbab9b63cf..dbcf4a94cd 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/PrepareCopyTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/PrepareCopyTask.java @@ -239,7 +239,7 @@ private void showDialog( final MaterialDialog dialog = dialogBuilder.build(); dialog.show(); - if (filesToCopy.get(0).getParent().equals(path)) { + if (filesToCopy.get(0).getParent(context).equals(path)) { View negative = dialog.getActionButton(DialogAction.NEGATIVE); negative.setEnabled(false); } diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/services/CopyService.java b/app/src/main/java/com/amaze/filemanager/asynchronous/services/CopyService.java index 0db9a59752..e71c626fa6 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/services/CopyService.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/services/CopyService.java @@ -535,7 +535,7 @@ boolean checkFiles(HybridFile hFile1, HybridFile hFile2) throws ShellNotRunningE return RootHelper.fileExists(hFile2.getPath()); } else { ArrayList baseFiles = - RootHelper.getFilesList(hFile1.getParent(), true, true, null); + RootHelper.getFilesList(hFile1.getParent(c), true, true, null); int i = -1; int index = -1; for (HybridFileParcelable b : baseFiles) { @@ -546,7 +546,7 @@ boolean checkFiles(HybridFile hFile1, HybridFile hFile2) throws ShellNotRunningE } } ArrayList baseFiles1 = - RootHelper.getFilesList(hFile1.getParent(), true, true, null); + RootHelper.getFilesList(hFile1.getParent(c), true, true, null); int i1 = -1; int index1 = -1; for (HybridFileParcelable b : baseFiles1) { diff --git a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java index b4785fd8db..7bb88cb075 100644 --- a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java +++ b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java @@ -155,15 +155,15 @@ public void removeFromDatabase(OperationData operationData) { } public void addCommonBookmarks() { - String sd = Environment.getExternalStorageDirectory() + "/"; + File sd = Environment.getExternalStorageDirectory(); String[] dirs = new String[] { - sd + Environment.DIRECTORY_DCIM, - sd + Environment.DIRECTORY_DOWNLOADS, - sd + Environment.DIRECTORY_MOVIES, - sd + Environment.DIRECTORY_MUSIC, - sd + Environment.DIRECTORY_PICTURES + new File(sd, Environment.DIRECTORY_DCIM).getAbsolutePath(), + new File(sd, Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), + new File(sd, Environment.DIRECTORY_MOVIES).getAbsolutePath(), + new File(sd, Environment.DIRECTORY_MUSIC).getAbsolutePath(), + new File(sd, Environment.DIRECTORY_PICTURES).getAbsolutePath() }; for (String dir : dirs) { diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java index 7428f8eaa7..777f4ea11b 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java @@ -1170,7 +1170,7 @@ private int getTemporaryAlbumId() { } private File installTemporaryTrack() throws IOException { - File externalFilesDir = getExternalFilesDir(context); + File externalFilesDir = context.getExternalFilesDir(null); if (externalFilesDir == null) { return null; } diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index 850cb07b36..af0ba9c6ed 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -57,19 +57,18 @@ import android.util.Log; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.documentfile.provider.DocumentFile; import jcifs.smb.SmbException; import jcifs.smb.SmbFile; import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.common.Buffer; -import net.schmizz.sshj.sftp.FileAttributes; import net.schmizz.sshj.sftp.FileMode; import net.schmizz.sshj.sftp.RemoteFile; import net.schmizz.sshj.sftp.RemoteResourceInfo; import net.schmizz.sshj.sftp.SFTPClient; import net.schmizz.sshj.sftp.SFTPException; -import net.schmizz.sshj.xfer.FilePermission; /** Created by Arpit on 07-07-2015. */ // Hybrid file for handeling all types of files @@ -194,6 +193,7 @@ public boolean isGoogleDriveFile() { return mode == OpenMode.GDRIVE; } + @Nullable public File getFile() { return new File(path); } @@ -210,21 +210,19 @@ HybridFileParcelable generateBaseFileFromParent() { public long lastModified() throws SmbException { switch (mode) { case SFTP: - SshClientUtils.execute( + return SshClientUtils.execute( new SFtpClientTemplate(path) { @Override - public Long execute(SFTPClient client) throws IOException { + public Long execute(@NonNull SFTPClient client) throws IOException { return client.mtime(SshClientUtils.extractRemotePathFrom(path)); } }); - break; case SMB: SmbFile smbFile = getSmbFile(); if (smbFile != null) return smbFile.lastModified(); break; case FILE: - new File(path).lastModified(); - break; + return getFile().lastModified(); case ROOT: HybridFileParcelable baseFile = generateBaseFileFromParent(); if (baseFile != null) return baseFile.getDate(); @@ -232,40 +230,8 @@ public Long execute(SFTPClient client) throws IOException { return new File("/").lastModified(); } - /** @deprecated use {@link #length(Context)} to handle content resolvers */ - public long length() { - long s = 0L; - switch (mode) { - case SFTP: - return SshClientUtils.execute( - new SFtpClientTemplate(path) { - @Override - public Long execute(SFTPClient client) throws IOException { - return client.size(SshClientUtils.extractRemotePathFrom(path)); - } - }); - case SMB: - SmbFile smbFile = getSmbFile(); - if (smbFile != null) - try { - s = smbFile.length(); - } catch (SmbException e) { - } - return s; - case FILE: - s = new File(path).length(); - return s; - case ROOT: - HybridFileParcelable baseFile = generateBaseFileFromParent(); - if (baseFile != null) return baseFile.getSize(); - break; - } - return s; - } - /** Helper method to find length */ public long length(Context context) { - long s = 0l; switch (mode) { case SFTP: @@ -279,7 +245,7 @@ public long length(Context context) { } return s; case FILE: - s = new File(path).length(); + s = getFile().length(); return s; case ROOT: HybridFileParcelable baseFile = generateBaseFileFromParent(); @@ -335,9 +301,9 @@ public String getName() { if (smbFile != null) return smbFile.getName(); break; case FILE: - return new File(path).getName(); + return getFile().getName(); case ROOT: - return new File(path).getName(); + return getFile().getName(); default: StringBuilder builder = new StringBuilder(path); name = builder.substring(builder.lastIndexOf("/") + 1, builder.length()); @@ -353,14 +319,12 @@ public String getName(Context context) { if (smbFile != null) return smbFile.getName(); break; case FILE: - return new File(path).getName(); case ROOT: - return new File(path).getName(); + return getFile().getName(); case OTG: return OTGUtil.getDocumentFile(path, context, false).getName(); default: - StringBuilder builder = new StringBuilder(path); - name = builder.substring(builder.lastIndexOf("/") + 1, builder.length()); + name = path.substring(path.lastIndexOf('/')); } return name; } @@ -393,33 +357,6 @@ public boolean isCustomPath() { || path.equals("6"); } - /** - * Returns a path to parent for various {@link #mode} - * - * @deprecated use {@link #getParent(Context)} to handle content resolvers - */ - public String getParent() { - String parentPath = ""; - switch (mode) { - case SMB: - try { - parentPath = new SmbFile(path).getParent(); - } catch (MalformedURLException e) { - parentPath = ""; - e.printStackTrace(); - } - break; - case FILE: - case ROOT: - parentPath = new File(path).getParent(); - break; - default: - StringBuilder builder = new StringBuilder(path); - return builder.substring(0, builder.length() - (getName().length() + 1)); - } - return parentPath; - } - /** Helper method to get parent path */ public String getParent(Context context) { @@ -435,7 +372,7 @@ public String getParent(Context context) { break; case FILE: case ROOT: - parentPath = new File(path).getParent(); + parentPath = getFile().getParent(); break; case OTG: default: @@ -478,7 +415,7 @@ public boolean isDirectory() { } break; case FILE: - isDirectory = new File(path).isDirectory(); + isDirectory = getFile().isDirectory(); break; case ROOT: try { @@ -494,7 +431,7 @@ public boolean isDirectory() { isDirectory = false; break; default: - isDirectory = new File(path).isDirectory(); + isDirectory = getFile().isDirectory(); break; } return isDirectory; @@ -531,7 +468,7 @@ public Boolean execute(SFTPClient client) throws IOException { } break; case FILE: - isDirectory = new File(path).isDirectory(); + isDirectory = getFile().isDirectory(); break; case ROOT: try { @@ -573,7 +510,7 @@ public Boolean execute(SFTPClient client) throws IOException { .getFolder(); break; default: - isDirectory = new File(path).isDirectory(); + isDirectory = getFile().isDirectory(); break; } return isDirectory; @@ -595,7 +532,7 @@ public long folderSize() { } break; case FILE: - size = FileUtils.folderSize(new File(path), null); + size = FileUtils.folderSize(getFile(), null); break; case ROOT: HybridFileParcelable baseFile = generateBaseFileFromParent(); @@ -630,7 +567,7 @@ public Long execute(SFTPClient client) throws IOException { } break; case FILE: - size = FileUtils.folderSize(new File(path), null); + size = FileUtils.folderSize(getFile(), null); break; case ROOT: HybridFileParcelable baseFile = generateBaseFileFromParent(); @@ -670,7 +607,7 @@ public long getUsableSpace() { break; case FILE: case ROOT: - size = new File(path).getUsableSpace(); + size = getFile().getUsableSpace(); break; case DROPBOX: case BOX: @@ -729,7 +666,7 @@ public long getTotal(Context context) { break; case FILE: case ROOT: - size = new File(path).getTotalSpace(); + size = getFile().getTotalSpace(); break; case DROPBOX: case BOX: @@ -786,29 +723,8 @@ public Void execute(SFTPClient client) { try { for (RemoteResourceInfo info : client.ls(SshClientUtils.extractRemotePathFrom(path))) { - boolean isDirectory = info.isDirectory(); - if (info.getAttributes().getType().equals(FileMode.Type.SYMLINK)) { - try { - FileAttributes symlinkAttrs = client.stat(info.getPath()); - isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); - } catch (IOException ifSymlinkIsBroken) { - Log.w( - TAG, - String.format( - "Symbolic link %s is broken, skipping", info.getPath())); - continue; - } - } - HybridFileParcelable f = - new HybridFileParcelable(String.format("%s/%s", path, info.getName())); - f.setName(info.getName()); - f.setMode(OpenMode.SFTP); - f.setDirectory(isDirectory); - f.setDate(info.getAttributes().getMtime() * 1000); - f.setSize(isDirectory ? 0 : info.getAttributes().getSize()); - f.setPermission( - Integer.toString( - FilePermission.toMask(info.getAttributes().getPermissions()), 8)); + boolean isDirectory = SshClientUtils.isDirectory(client, info); + HybridFileParcelable f = new HybridFileParcelable(path, isDirectory, info); onFileFound.onFileFound(f); } } catch (IOException e) { @@ -825,12 +741,7 @@ public Void execute(SFTPClient client) { try { SmbFile smbFile = new SmbFile(path); for (SmbFile smbFile1 : smbFile.listFiles()) { - HybridFileParcelable baseFile = new HybridFileParcelable(smbFile1.getPath()); - baseFile.setName(smbFile1.getName()); - baseFile.setMode(OpenMode.SMB); - baseFile.setDirectory(smbFile1.isDirectory()); - baseFile.setDate(smbFile1.lastModified()); - baseFile.setSize(baseFile.isDirectory() ? 0 : smbFile1.length()); + HybridFileParcelable baseFile = new HybridFileParcelable(smbFile1); onFileFound.onFileFound(baseFile); } } catch (MalformedURLException | SmbException e) { @@ -875,17 +786,9 @@ public ArrayList execute(SFTPClient client) { try { for (RemoteResourceInfo info : client.ls(SshClientUtils.extractRemotePathFrom(path))) { + boolean isDirectory = SshClientUtils.isDirectory(client, info); HybridFileParcelable f = - new HybridFileParcelable( - String.format("%s/%s", path, info.getName())); - f.setName(info.getName()); - f.setMode(OpenMode.SFTP); - f.setDirectory(info.isDirectory()); - f.setDate(info.getAttributes().getMtime() * 1000); - f.setSize(f.isDirectory() ? 0 : info.getAttributes().getSize()); - f.setPermission( - Integer.toString( - FilePermission.toMask(info.getAttributes().getPermissions()), 8)); + new HybridFileParcelable(path, isDirectory, info); retval.add(f); } } catch (IOException e) { @@ -912,10 +815,10 @@ public ArrayList execute(SFTPClient client) { arrayList.add(baseFile); } } catch (MalformedURLException e) { - if (arrayList != null) arrayList.clear(); + arrayList.clear(); e.printStackTrace(); } catch (SmbException e) { - if (arrayList != null) arrayList.clear(); + arrayList.clear(); e.printStackTrace(); } break; @@ -1119,7 +1022,7 @@ public void close() throws IOException { break; default: try { - outputStream = FileUtil.getOutputStream(new File(path), context); + outputStream = FileUtil.getOutputStream(getFile(), context); } catch (Exception e) { outputStream = null; e.printStackTrace(); @@ -1163,7 +1066,7 @@ public Boolean execute(SFTPClient client) throws IOException { CloudStorage cloudStorageOneDrive = dataUtils.getAccount(OpenMode.ONEDRIVE); exists = cloudStorageOneDrive.exists(CloudUtil.stripPath(OpenMode.ONEDRIVE, path)); } else if (isLocal()) { - exists = new File(path).exists(); + exists = getFile().exists(); } else if (isRoot()) { return RootHelper.fileExists(path); } @@ -1189,7 +1092,7 @@ public boolean isSimpleFile() { && !isOtgFile() && !isCustomPath() && !android.util.Patterns.EMAIL_ADDRESS.matcher(path).matches() - && !new File(path).isDirectory() + && (getFile() != null && !getFile().isDirectory()) && !isOneDriveFile() && !isGoogleDriveFile() && !isDropBoxFile() @@ -1208,7 +1111,7 @@ public boolean setLastModified(final long date) { return false; } } - File f = new File(path); + File f = getFile(); return f.setLastModified(date); } @@ -1267,7 +1170,7 @@ public Void execute(SFTPClient client) { } catch (Exception e) { e.printStackTrace(); } - } else FileUtil.mkdir(new File(path), context); + } else FileUtil.mkdir(getFile(), context); } public boolean delete(Context context, boolean rootmode) throws ShellNotRunningException { @@ -1294,7 +1197,7 @@ public Void execute(SFTPClient client) throws IOException { setMode(OpenMode.ROOT); RootUtils.delete(getPath()); } else { - FileUtil.deleteFile(new File(path), context); + FileUtil.deleteFile(getFile(), context); } } return !exists(); @@ -1320,7 +1223,7 @@ public LayoutElementParcelable generateLayoutElement(@NonNull Context c, boolean switch (mode) { case FILE: case ROOT: - File file = new File(path); + File file = getFile(); LayoutElementParcelable layoutElement; if (isDirectory()) { diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java index f6d2fe1f40..71f6711ce2 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java @@ -21,10 +21,17 @@ package com.amaze.filemanager.filesystem; import com.amaze.filemanager.utils.OpenMode; +import com.amaze.filemanager.utils.Utils; +import android.content.Context; import android.os.Parcel; import android.os.Parcelable; +import jcifs.smb.SmbException; +import jcifs.smb.SmbFile; +import net.schmizz.sshj.sftp.RemoteResourceInfo; +import net.schmizz.sshj.xfer.FilePermission; + /** Created by arpitkh996 on 11-01-2016. */ public class HybridFileParcelable extends HybridFile implements Parcelable { @@ -49,12 +56,36 @@ public HybridFileParcelable( this.permission = permission; } + public HybridFileParcelable(SmbFile smbFile) throws SmbException { + super(OpenMode.SMB, smbFile.getPath()); + setName(smbFile.getName()); + setDirectory(smbFile.isDirectory()); + setDate(smbFile.lastModified()); + setSize(smbFile.isDirectory() ? 0 : smbFile.length()); + } + + public HybridFileParcelable(String path, boolean isDirectory, RemoteResourceInfo sshFile) { + super(OpenMode.SFTP, String.format("%s/%s", path, sshFile.getName())); + setName(sshFile.getName()); + setDirectory(isDirectory); + setDate(sshFile.getAttributes().getMtime() * 1000); + setSize(isDirectory ? 0 : sshFile.getAttributes().getSize()); + setPermission( + Integer.toString(FilePermission.toMask(sshFile.getAttributes().getPermissions()), 8)); + } + @Override public String getName() { - if (name != null && name.length() > 0) return name; + if (!Utils.isNullOrEmpty(name)) return name; else return super.getName(); } + @Override + public String getName(Context context) { + if (!Utils.isNullOrEmpty(name)) return name; + else return super.getName(context); + } + public void setName(String name) { this.name = name; } diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java index 225b754b9b..647280795c 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/Operations.java @@ -133,7 +133,8 @@ protected Void doInBackground(Void... params) { DocumentFile directoryToCreate = OTGUtil.getDocumentFile(file.getPath(), context, false); if (directoryToCreate != null) errorCallBack.exists(file); - DocumentFile parentDirectory = OTGUtil.getDocumentFile(file.getParent(), context, false); + DocumentFile parentDirectory = + OTGUtil.getDocumentFile(file.getParent(context), context, false); if (parentDirectory.isDirectory()) { parentDirectory.createDirectory(file.getName(context)); errorCallBack.done(file, true); @@ -178,7 +179,7 @@ protected Void doInBackground(Void... params) { } } else { if (file.isLocal() || file.isRoot()) { - int mode = checkFolder(new File(file.getParent()), context); + int mode = checkFolder(new File(file.getParent(context)), context); if (mode == 2) { errorCallBack.launchSAF(file); return null; @@ -317,7 +318,8 @@ protected Void doInBackground(Void... params) { DocumentFile fileToCreate = OTGUtil.getDocumentFile(file.getPath(), context, false); if (fileToCreate != null) errorCallBack.exists(file); - DocumentFile parentDirectory = OTGUtil.getDocumentFile(file.getParent(), context, false); + DocumentFile parentDirectory = + OTGUtil.getDocumentFile(file.getParent(context), context, false); if (parentDirectory.isDirectory()) { parentDirectory.createFile( file.getName(context).substring(file.getName(context).lastIndexOf(".")), @@ -327,7 +329,7 @@ protected Void doInBackground(Void... params) { return null; } else { if (file.isLocal() || file.isRoot()) { - int mode = checkFolder(new File(file.getParent()), context); + int mode = checkFolder(new File(file.getParent(context)), context); if (mode == 2) { errorCallBack.launchSAF(file); return null; diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/files/FileUtils.java b/app/src/main/java/com/amaze/filemanager/filesystem/files/FileUtils.java index cd13cf4954..1c340e724b 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/files/FileUtils.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/files/FileUtils.java @@ -800,7 +800,9 @@ public static boolean isPathAccessible(String dir, SharedPreferences pref) { public static boolean isRoot( String dir) { // TODO: 5/5/2017 hardcoding root might lead to problems down the line - return !dir.contains(OTGUtil.PREFIX_OTG) && !dir.startsWith("/storage"); + return !dir.contains(OTGUtil.PREFIX_OTG) + && !dir.startsWith(OTGUtil.PREFIX_MEDIA_REMOVABLE) + && !dir.startsWith("/storage"); } /** Converts ArrayList of HybridFileParcelable to ArrayList of File */ diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java index 55291b4898..0bff12a5f0 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java @@ -49,6 +49,9 @@ import net.schmizz.sshj.SSHClient; import net.schmizz.sshj.connection.channel.direct.Session; +import net.schmizz.sshj.sftp.FileAttributes; +import net.schmizz.sshj.sftp.FileMode; +import net.schmizz.sshj.sftp.RemoteResourceInfo; import net.schmizz.sshj.sftp.SFTPClient; public abstract class SshClientUtils { @@ -283,4 +286,17 @@ public static String deriveSftpPathFrom( ? String.format("ssh://%s@%s:%d", username, hostname, port) : String.format("ssh://%s:%s@%s:%d", username, password, hostname, port); } + + public static boolean isDirectory(@NonNull SFTPClient client, @NonNull RemoteResourceInfo info) { + boolean isDirectory = info.isDirectory(); + if (info.getAttributes().getType().equals(FileMode.Type.SYMLINK)) { + try { + FileAttributes symlinkAttrs = client.stat(info.getPath()); + isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); + } catch (IOException ifSymlinkIsBroken) { + Log.w(TAG, String.format("Symbolic link %s is broken, skipping", info.getPath())); + } + } + return isDirectory; + } } diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index 2359410cc4..3db351582f 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -1213,7 +1213,7 @@ public void onResume() { registerReceiver(mainActivityHelper.mNotificationReceiver, newFilter); registerReceiver(receiver2, new IntentFilter(TAG_INTENT_FILTER_GENERAL)); - if (SDK_INT >= Build.VERSION_CODES.KITKAT && SDK_INT < Build.VERSION_CODES.N) { + if (SDK_INT >= Build.VERSION_CODES.KITKAT) { updateUsbInformation(); } } @@ -1484,10 +1484,9 @@ protected void onActivityResult(int requestCode, int responseCode, Intent intent } else if (requestCode == REQUEST_CODE_SAF) { if (responseCode == Activity.RESULT_OK && intent.getData() != null) { // otg access - Uri usbOtgRoot = Uri.parse(intent.getData().toString()); + Uri usbOtgRoot = intent.getData(); SingletonUsbOtg.getInstance().setUsbOtgRoot(usbOtgRoot); getCurrentMainFragment().loadlist(OTGUtil.PREFIX_OTG, false, OpenMode.OTG); - drawer.closeIfNotLocked(); if (drawer.isLocked()) drawer.onDrawerClosed(); } else { diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/Drawer.java b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/Drawer.java index e7dc335abf..33ae923492 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/drawer/Drawer.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/drawer/Drawer.java @@ -263,7 +263,7 @@ public void refreshDrawer() { storageDirectoryPaths.add(file); - if (file.contains(OTGUtil.PREFIX_OTG)) { + if (file.contains(OTGUtil.PREFIX_OTG) || file.startsWith(OTGUtil.PREFIX_MEDIA_REMOVABLE)) { addNewItem( menu, STORAGES_GROUP, @@ -694,7 +694,8 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP - && meta.path.contains(OTGUtil.PREFIX_OTG) + && (meta.path.contains(OTGUtil.PREFIX_OTG) + || meta.path.startsWith(OTGUtil.PREFIX_MEDIA_REMOVABLE)) && SingletonUsbOtg.getInstance().getUsbOtgRoot() == null) { MaterialDialog dialog = GeneralDialogCreation.showOtgSafExplanationDialog(mainActivity); dialog @@ -705,6 +706,7 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { mainActivity.startActivityForResult(safIntent, MainActivity.REQUEST_CODE_SAF); dialog.dismiss(); }); + dialog.show(); } else { pendingPath = meta.path; closeIfNotLocked(); diff --git a/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java b/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java index 072deae523..6e385b98a1 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java +++ b/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java @@ -453,7 +453,10 @@ public void exists(final HybridFile file) { .show(); if (ma != null && ma.getActivity() != null) { // retry with dialog prompted again - mkfile(file.getMode(), file.getParent(), ma); + mkfile( + file.getMode(), + file.getParent(mainActivity.getApplicationContext()), + ma); } }); } @@ -531,7 +534,10 @@ public void exists(final HybridFile file) { .show(); if (ma != null && ma.getActivity() != null) { // retry with dialog prompted again - mkdir(file.getMode(), file.getParent(), ma); + mkdir( + file.getMode(), + file.getParent(mainActivity.getApplicationContext()), + ma); } }); } diff --git a/app/src/main/java/com/amaze/filemanager/utils/OTGUtil.java b/app/src/main/java/com/amaze/filemanager/utils/OTGUtil.java index e3b7ae00bb..3f54730421 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/OTGUtil.java +++ b/app/src/main/java/com/amaze/filemanager/utils/OTGUtil.java @@ -51,6 +51,8 @@ public class OTGUtil { public static final String PREFIX_OTG = "otg:/"; + public static final String PREFIX_MEDIA_REMOVABLE = "/mnt/media_rw"; + /** * Returns an array of list of files at a specific path in OTG * diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java new file mode 100644 index 0000000000..c715dae943 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.filesystem.ssh; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; + +import org.junit.Test; + +import net.schmizz.sshj.sftp.FileAttributes; +import net.schmizz.sshj.sftp.FileMode; +import net.schmizz.sshj.sftp.RemoteResourceInfo; +import net.schmizz.sshj.sftp.SFTPClient; + +public class SshClientUtilTest { + + @Test + public void testIsDirectoryNormal() { + RemoteResourceInfo mock = mock(RemoteResourceInfo.class); + when(mock.isDirectory()).thenReturn(true); + FileAttributes mockAttributes = + new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); + when(mock.getAttributes()).thenReturn(mockAttributes); + SFTPClient mockClient = mock(SFTPClient.class); + assertTrue(SshClientUtils.isDirectory(mockClient, mock)); + } + + @Test + public void testIsDirectoryWithFile() { + RemoteResourceInfo mock = mock(RemoteResourceInfo.class); + when(mock.isDirectory()).thenReturn(false); + FileAttributes mockAttributes = + new FileAttributes.Builder().withType(FileMode.Type.REGULAR).build(); + when(mock.getAttributes()).thenReturn(mockAttributes); + SFTPClient mockClient = mock(SFTPClient.class); + assertFalse(SshClientUtils.isDirectory(mockClient, mock)); + } + + @Test + public void testIsDirectorySymlinkNormal() throws IOException { + RemoteResourceInfo mock = mock(RemoteResourceInfo.class); + when(mock.getPath()).thenReturn("/sysroot/etc"); + when(mock.isDirectory()).thenReturn(true); + FileAttributes mockAttributes = + new FileAttributes.Builder().withType(FileMode.Type.SYMLINK).build(); + when(mock.getAttributes()).thenReturn(mockAttributes); + + SFTPClient mockClient = mock(SFTPClient.class); + mockAttributes = new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); + when(mockClient.stat("/sysroot/etc")).thenReturn(mockAttributes); + + assertTrue(SshClientUtils.isDirectory(mockClient, mock)); + } + + @Test + public void testIsDirectorySymlinkBrokenDirectory() throws IOException { + RemoteResourceInfo mock = mock(RemoteResourceInfo.class); + when(mock.getPath()).thenReturn("/sysroot/etc"); + when(mock.isDirectory()).thenReturn(true); + FileAttributes mockAttributes = + new FileAttributes.Builder().withType(FileMode.Type.SYMLINK).build(); + when(mock.getAttributes()).thenReturn(mockAttributes); + + SFTPClient mockClient = mock(SFTPClient.class); + mockAttributes = new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); + when(mockClient.stat("/sysroot/etc")).thenThrow(new IOException()); + + assertTrue(SshClientUtils.isDirectory(mockClient, mock)); + } + + @Test + public void testIsDirectorySymlinkBrokenFile() throws IOException { + RemoteResourceInfo mock = mock(RemoteResourceInfo.class); + when(mock.getPath()).thenReturn("/sysroot/etc"); + when(mock.isDirectory()).thenReturn(false); + FileAttributes mockAttributes = + new FileAttributes.Builder().withType(FileMode.Type.SYMLINK).build(); + when(mock.getAttributes()).thenReturn(mockAttributes); + + SFTPClient mockClient = mock(SFTPClient.class); + mockAttributes = new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); + when(mockClient.stat("/sysroot/etc")).thenThrow(new IOException()); + + assertFalse(SshClientUtils.isDirectory(mockClient, mock)); + } +} From c6c77dab0815928258db929491dc80de9264df63 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Mon, 17 Aug 2020 16:25:07 +0800 Subject: [PATCH 17/32] Fix unit test regression routine using SshClientUtils.isDirectory() needs IOException --- app/build.gradle | 4 ++-- .../amaze/filemanager/filesystem/HybridFile.java | 16 ++++++++++++++-- .../filesystem/ssh/SshClientUtils.java | 4 +++- .../filesystem/ssh/SshClientUtilTest.java | 9 +++++---- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 52f823e2a2..104c3f7820 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -113,8 +113,8 @@ dependencies { annotationProcessor 'androidx.annotation:annotation:1.1.0' //For tests - androidTestImplementation 'junit:junit:4.12'//tests the app logic - testImplementation 'junit:junit:4.12'//tests the app logic + androidTestImplementation 'junit:junit:4.13'//tests the app logic + testImplementation 'junit:junit:4.13'//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction testImplementation "org.mockito:mockito-core:$mockitoVersion" diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index af0ba9c6ed..7d9657ffa5 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -723,7 +723,13 @@ public Void execute(SFTPClient client) { try { for (RemoteResourceInfo info : client.ls(SshClientUtils.extractRemotePathFrom(path))) { - boolean isDirectory = SshClientUtils.isDirectory(client, info); + boolean isDirectory = false; + try { + isDirectory = SshClientUtils.isDirectory(client, info); + } catch (IOException ifBrokenSymlink) { + Log.w(TAG, "IOException checking isDirectory(): " + info.getPath()); + continue; + } HybridFileParcelable f = new HybridFileParcelable(path, isDirectory, info); onFileFound.onFileFound(f); } @@ -786,7 +792,13 @@ public ArrayList execute(SFTPClient client) { try { for (RemoteResourceInfo info : client.ls(SshClientUtils.extractRemotePathFrom(path))) { - boolean isDirectory = SshClientUtils.isDirectory(client, info); + boolean isDirectory = false; + try { + isDirectory = SshClientUtils.isDirectory(client, info); + } catch (IOException ifBrokenSymlink) { + Log.w(TAG, "IOException checking isDirectory(): " + info.getPath()); + continue; + } HybridFileParcelable f = new HybridFileParcelable(path, isDirectory, info); retval.add(f); diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java index 0bff12a5f0..b8f3d8c470 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/SshClientUtils.java @@ -287,7 +287,8 @@ public static String deriveSftpPathFrom( : String.format("ssh://%s:%s@%s:%d", username, password, hostname, port); } - public static boolean isDirectory(@NonNull SFTPClient client, @NonNull RemoteResourceInfo info) { + public static boolean isDirectory(@NonNull SFTPClient client, @NonNull RemoteResourceInfo info) + throws IOException { boolean isDirectory = info.isDirectory(); if (info.getAttributes().getType().equals(FileMode.Type.SYMLINK)) { try { @@ -295,6 +296,7 @@ public static boolean isDirectory(@NonNull SFTPClient client, @NonNull RemoteRes isDirectory = symlinkAttrs.getType().equals(FileMode.Type.DIRECTORY); } catch (IOException ifSymlinkIsBroken) { Log.w(TAG, String.format("Symbolic link %s is broken, skipping", info.getPath())); + throw ifSymlinkIsBroken; } } return isDirectory; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java index c715dae943..162d2f80a1 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshClientUtilTest.java @@ -21,6 +21,7 @@ package com.amaze.filemanager.filesystem.ssh; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -37,7 +38,7 @@ public class SshClientUtilTest { @Test - public void testIsDirectoryNormal() { + public void testIsDirectoryNormal() throws IOException { RemoteResourceInfo mock = mock(RemoteResourceInfo.class); when(mock.isDirectory()).thenReturn(true); FileAttributes mockAttributes = @@ -48,7 +49,7 @@ public void testIsDirectoryNormal() { } @Test - public void testIsDirectoryWithFile() { + public void testIsDirectoryWithFile() throws IOException { RemoteResourceInfo mock = mock(RemoteResourceInfo.class); when(mock.isDirectory()).thenReturn(false); FileAttributes mockAttributes = @@ -87,7 +88,7 @@ public void testIsDirectorySymlinkBrokenDirectory() throws IOException { mockAttributes = new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); when(mockClient.stat("/sysroot/etc")).thenThrow(new IOException()); - assertTrue(SshClientUtils.isDirectory(mockClient, mock)); + assertThrows(IOException.class, () -> SshClientUtils.isDirectory(mockClient, mock)); } @Test @@ -103,6 +104,6 @@ public void testIsDirectorySymlinkBrokenFile() throws IOException { mockAttributes = new FileAttributes.Builder().withType(FileMode.Type.DIRECTORY).build(); when(mockClient.stat("/sysroot/etc")).thenThrow(new IOException()); - assertFalse(SshClientUtils.isDirectory(mockClient, mock)); + assertThrows(IOException.class, () -> SshClientUtils.isDirectory(mockClient, mock)); } } From 14691f23484b2b238302d91de1e91b24f5c90345 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Tue, 18 Aug 2020 23:01:36 +0800 Subject: [PATCH 18/32] Lifting tweaks in CustomSshJConfig to enable advanced crypto features Addresses #1961. Previously due to preventing conflict with stock BouncyCastle on Android devices some tweaks were added to CustomSshJConfig. But with full adaptation of BouncyCastle over the stock one it should be safe to remove the tweaks and use stock features as much as possible. Tested on Fairphone 3 running LineageOS 16.0 (9.0), using ED25519 private key to authenticate against OpenSSH server 8.2p1 on Ubuntu 20.04. --- .../filesystem/ssh/CustomSshJConfig.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java index 86e95412c6..2b7297bbce 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java @@ -23,10 +23,6 @@ import java.security.Security; import net.schmizz.sshj.DefaultConfig; -import net.schmizz.sshj.signature.SignatureDSA; -import net.schmizz.sshj.signature.SignatureRSA; -import net.schmizz.sshj.transport.random.JCERandom; -import net.schmizz.sshj.transport.random.SingletonRandomFactory; /** * sshj {@link net.schmizz.sshj.Config} for our own use. @@ -44,14 +40,4 @@ public static void init() { Security.removeProvider("BC"); Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 0); } - - // don't add ECDSA - protected void initSignatureFactories() { - setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory()); - } - - @Override - protected void initRandomFactory(boolean ignored) { - setRandomFactory(new SingletonRandomFactory(new JCERandom.Factory())); - } } From a5473ebafcc843eaf93d621ee19eb8aea4fff8d8 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Wed, 19 Aug 2020 09:29:47 +0800 Subject: [PATCH 19/32] Changes per PR feedback - use HybridFileParcelable(SmbFile) for jcifs SmbFile in HybridFile.listFiles() and HybridFile.forEachChildrenFile() - use HybridFileParcelable(RemoteResourceInfo) for sshj RemoteResourceInfo in HybridFile.listFiles() and HybridFile.forEachChildrenFile() - Add javadoc for the 2 new HybridFileParcelable constructors - remove duplicated parseSmbPath() and parseSftpPath() from MainActivityHelper --- .../com/amaze/filemanager/filesystem/FileUtil.java | 3 +-- .../amaze/filemanager/filesystem/HybridFile.java | 11 +++-------- .../filesystem/HybridFileParcelable.java | 13 +++++++++++++ .../filemanager/ui/views/appbar/BottomBar.java | 5 +++-- .../amaze/filemanager/utils/MainActivityHelper.java | 12 +----------- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java index 777f4ea11b..b55e5edc25 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java @@ -278,8 +278,7 @@ public List doInBackground() { } else { OutputStream outputStream = targetSmbFile.getOutputStream(); bufferedOutputStream = new BufferedOutputStream(outputStream); - retval.add( - mainActivity.mainActivityHelper.parseSmbPath(targetSmbFile.getPath())); + retval.add(HybridFile.parseSmbPath(targetSmbFile.getPath())); } break; case SFTP: diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java index 7d9657ffa5..556c2b212a 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java @@ -818,12 +818,7 @@ public ArrayList execute(SFTPClient client) { try { SmbFile smbFile = new SmbFile(path); for (SmbFile smbFile1 : smbFile.listFiles()) { - HybridFileParcelable baseFile = new HybridFileParcelable(smbFile1.getPath()); - baseFile.setName(smbFile1.getName()); - baseFile.setMode(OpenMode.SMB); - baseFile.setDirectory(smbFile1.isDirectory()); - baseFile.setDate(smbFile1.lastModified()); - baseFile.setSize(baseFile.isDirectory() ? 0 : smbFile1.length()); + HybridFileParcelable baseFile = new HybridFileParcelable(smbFile1); arrayList.add(baseFile); } } catch (MalformedURLException e) { @@ -861,12 +856,12 @@ public String getReadablePath(String path) { return path; } - String parseSftpPath(String a) { + public static String parseSftpPath(String a) { if (a.contains("@")) return "ssh://" + a.substring(a.indexOf("@") + 1, a.length()); else return a; } - String parseSmbPath(String a) { + public static String parseSmbPath(String a) { if (a.contains("@")) return "smb://" + a.substring(a.indexOf("@") + 1, a.length()); else return a; } diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java index 71f6711ce2..0c0f337627 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/HybridFileParcelable.java @@ -56,6 +56,12 @@ public HybridFileParcelable( this.permission = permission; } + /** + * Constructor for jcifs {@link SmbFile}. + * + * @param smbFile + * @throws SmbException + */ public HybridFileParcelable(SmbFile smbFile) throws SmbException { super(OpenMode.SMB, smbFile.getPath()); setName(smbFile.getName()); @@ -64,6 +70,13 @@ public HybridFileParcelable(SmbFile smbFile) throws SmbException { setSize(smbFile.isDirectory() ? 0 : smbFile.length()); } + /** + * Constructor for sshj {@link RemoteResourceInfo}. + * + * @param path + * @param isDirectory + * @param sshFile + */ public HybridFileParcelable(String path, boolean isDirectory, RemoteResourceInfo sshFile) { super(OpenMode.SFTP, String.format("%s/%s", path, sshFile.getName())); setName(sshFile.getName()); diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/appbar/BottomBar.java b/app/src/main/java/com/amaze/filemanager/ui/views/appbar/BottomBar.java index ecde625110..8808cb81d0 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/appbar/BottomBar.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/appbar/BottomBar.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import com.amaze.filemanager.R; +import com.amaze.filemanager.filesystem.HybridFile; import com.amaze.filemanager.filesystem.files.FileUtils; import com.amaze.filemanager.ui.activities.MainActivity; import com.amaze.filemanager.ui.dialogs.GeneralDialogCreation; @@ -341,10 +342,10 @@ public void updatePath( switch (openmode) { case SFTP: - newPath = mainActivityHelper.parseSftpPath(news); + newPath = HybridFile.parseSftpPath(news); break; case SMB: - newPath = mainActivityHelper.parseSmbPath(news); + newPath = HybridFile.parseSmbPath(news); break; case OTG: newPath = mainActivityHelper.parseOTGPath(news); diff --git a/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java b/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java index 6e385b98a1..c3cc6e70ee 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java +++ b/app/src/main/java/com/amaze/filemanager/utils/MainActivityHelper.java @@ -617,20 +617,10 @@ public void extractFile(File file) { } else Toast.makeText(mainActivity, R.string.not_allowed, Toast.LENGTH_SHORT).show(); } - public String parseSftpPath(String a) { - if (a.contains("@")) return "ssh://" + a.substring(a.lastIndexOf("@") + 1, a.length()); - else return a; - } - - public String parseSmbPath(String a) { - if (a.contains("@")) return "smb://" + a.substring(a.indexOf("@") + 1, a.length()); - else return a; - } - /** Retrieve a path with {@link OTGUtil#PREFIX_OTG} as prefix */ public String parseOTGPath(String path) { if (path.contains(OTGUtil.PREFIX_OTG)) return path; - else return OTGUtil.PREFIX_OTG + path.substring(path.indexOf(":") + 1, path.length()); + else return OTGUtil.PREFIX_OTG + path.substring(path.indexOf(":") + 1); } public String parseCloudPath(OpenMode serviceType, String path) { From 58bd39d32856ff29d0e374003004dc50a3f91137 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Mon, 10 Aug 2020 14:09:45 +0800 Subject: [PATCH 20/32] Fix screen rotation problem after PR #1947 applied In #1947 there was a `android:screenOrientation="sensor"` declared in the manifest, causing UI to rotate as the device changes its orientation, which is quite annoying. Remove it. Tested on Fairphone 3 running LineageOS 16.0 (9.0), still no white screen at startup even when Amaze uses dark themes. --- app/src/main/AndroidManifest.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b1270ade0b..d337a140fb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,8 +56,7 @@ android:label="@string/appbar_name" android:launchMode="singleInstance" android:name=".ui.activities.MainActivity" - android:theme="@android:style/Theme.Translucent.NoTitleBar" - android:screenOrientation="sensor"> + android:theme="@android:style/Theme.Translucent.NoTitleBar"> From d791bb4ac0353d1504bbf561f4afe84f8037334e Mon Sep 17 00:00:00 2001 From: TranceLove Date: Tue, 28 Jul 2020 17:45:37 +0800 Subject: [PATCH 21/32] Fixes for editing SMB connections - moved jcifs.Config.registerSmbURLHandler() from SmbConnectDialog to AppConfig.runInBackground() - encrypt paths in UtilsHandler.renameSMB() as it was stored encrypted in database Tested on Oneplus 2 running AOSPExtended (7.1.2) and LG Nexus 5x running AOSPExtended (9.0). --- .../com/amaze/filemanager/application/AppConfig.java | 5 ++--- .../com/amaze/filemanager/database/UtilsHandler.java | 9 +++++++++ .../amaze/filemanager/ui/dialogs/SmbConnectDialog.java | 1 - 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java index da79e231e4..5d40ca5ade 100644 --- a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java +++ b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java @@ -87,12 +87,11 @@ public void onCreate() { utilsProvider = new UtilitiesProvider(this); utilsHandler = new UtilsHandler(this, utilitiesDatabase); - // FIXME: in unit tests when AppConfig is rapidly created/destroyed this call will cause - // IllegalThreadStateException. - // Until this gets fixed only one test case can be run in a time. - Raymond, 24/4/2018 backgroundHandlerThread.start(); backgroundHandler = new Handler(backgroundHandlerThread.getLooper()); + runInBackground(jcifs.Config::registerSmbURLHandler); + // disabling file exposure method check for api n+ StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); diff --git a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java index b4785fd8db..3068ce3106 100644 --- a/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java +++ b/app/src/main/java/com/amaze/filemanager/database/UtilsHandler.java @@ -58,6 +58,8 @@ */ public class UtilsHandler { + private static final String TAG = UtilsHandler.class.getSimpleName(); + private final Context context; private final UtilitiesDatabase utilitiesDatabase; @@ -313,6 +315,13 @@ public void renameBookmark(String oldName, String oldPath, String newName, Strin } public void renameSMB(String oldName, String oldPath, String newName, String newPath) { + try { + oldPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), oldPath); + newPath = SmbUtil.getSmbEncryptedPath(AppConfig.getInstance(), newPath); + } catch (GeneralSecurityException | IOException e) { + Log.e(TAG, "Error encrypting SMB path", e); + } + SmbEntry smbEntry = utilitiesDatabase.smbEntryDao().findByNameAndPath(oldName, oldPath); smbEntry.name = newName; smbEntry.path = newPath; diff --git a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java index 94196cb28c..1f2f45a8d3 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java +++ b/app/src/main/java/com/amaze/filemanager/ui/dialogs/SmbConnectDialog.java @@ -207,7 +207,6 @@ public void afterTextChanged(Editable s) { String userp = "", passp = "", ipp = "", domainp = ""; conName.setText(name); try { - jcifs.Config.registerSmbURLHandler(); URL a = new URL(path); String userinfo = a.getUserInfo(); if (userinfo != null) { From 8fa65d1c4778b9a4e93a07e1e6f087b1aed19dd5 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Tue, 18 Aug 2020 23:01:36 +0800 Subject: [PATCH 22/32] Lifting tweaks in CustomSshJConfig to enable advanced crypto features Addresses #1961. Previously due to preventing conflict with stock BouncyCastle on Android devices some tweaks were added to CustomSshJConfig. But with full adaptation of BouncyCastle over the stock one it should be safe to remove the tweaks and use stock features as much as possible. Tested on Fairphone 3 running LineageOS 16.0 (9.0), using ED25519 private key to authenticate against OpenSSH server 8.2p1 on Ubuntu 20.04. --- .../filesystem/ssh/CustomSshJConfig.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java index 86e95412c6..2b7297bbce 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/ssh/CustomSshJConfig.java @@ -23,10 +23,6 @@ import java.security.Security; import net.schmizz.sshj.DefaultConfig; -import net.schmizz.sshj.signature.SignatureDSA; -import net.schmizz.sshj.signature.SignatureRSA; -import net.schmizz.sshj.transport.random.JCERandom; -import net.schmizz.sshj.transport.random.SingletonRandomFactory; /** * sshj {@link net.schmizz.sshj.Config} for our own use. @@ -44,14 +40,4 @@ public static void init() { Security.removeProvider("BC"); Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(), 0); } - - // don't add ECDSA - protected void initSignatureFactories() { - setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory()); - } - - @Override - protected void initRandomFactory(boolean ignored) { - setRandomFactory(new SingletonRandomFactory(new JCERandom.Factory())); - } } From 4cfdc0434f1364d1ddc1e96be25ae5215b77a4be Mon Sep 17 00:00:00 2001 From: saunak Date: Wed, 19 Aug 2020 21:46:27 +0530 Subject: [PATCH 23/32] #1856. Fix for app crash when using save as option from browser. Added text file creation method within FileUtil and check for intent type = text, basis which a text file will be created on the path the user is currently present. --- .../main/java/com/amaze/filemanager/filesystem/FileUtil.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java index 6f2e0a004f..e0c541c06d 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java @@ -625,12 +625,9 @@ public static boolean mktextfile(String data, String path, String fileName) { File f = new File(path + "/" + fileName + ".txt"); FileOutputStream out = null; OutputStreamWriter outputWriter = null; - if (f.exists()) { - f.delete(); - } try { f.createNewFile(); - out = new FileOutputStream(f); + out = new FileOutputStream(f, false); outputWriter = new OutputStreamWriter(out); outputWriter.write(data); From 5192653d3bcfde496854d3cdeaaa7da3b01b5aa1 Mon Sep 17 00:00:00 2001 From: saunak Date: Wed, 19 Aug 2020 21:50:04 +0530 Subject: [PATCH 24/32] #1856. Fix for app crash when using save as option from browser. Added text file creation method within FileUtil and check for intent type = text, basis which a text file will be created on the path the user is currently present. --- .../java/com/amaze/filemanager/ui/activities/MainActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index 3e2609b5bc..b28a58bf02 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -591,7 +591,7 @@ private void initFabToSave(final ArrayList uris) { + "\nURL: " + extras.getString(Intent.EXTRA_TEXT); String fileName = Long.toString(System.currentTimeMillis()); - FileUtil.mktextfile(data, getCurrentMainFragment().getCurrentPath(), fileName); + AppConfig.runInBackground(() -> FileUtil.mktextfile(data, getCurrentMainFragment().getCurrentPath(), fileName)); Toast.makeText( MainActivity.this, From b5a401c7ead79c61c09d569c399864bea35fdc0d Mon Sep 17 00:00:00 2001 From: saunak Date: Wed, 19 Aug 2020 22:59:45 +0530 Subject: [PATCH 25/32] #1856. Fix for app crash when using save as option from browser. Added text file creation method within FileUtil and check for intent type = text, basis which a text file will be created on the path the user is currently present. --- .../main/java/com/amaze/filemanager/filesystem/FileUtil.java | 1 - .../com/amaze/filemanager/ui/activities/MainActivity.java | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java index e0c541c06d..e70d42bfed 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/FileUtil.java @@ -628,7 +628,6 @@ public static boolean mktextfile(String data, String path, String fileName) { try { f.createNewFile(); out = new FileOutputStream(f, false); - outputWriter = new OutputStreamWriter(out); outputWriter.write(data); return true; diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java index b28a58bf02..b8b65b2952 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/MainActivity.java @@ -591,7 +591,10 @@ private void initFabToSave(final ArrayList uris) { + "\nURL: " + extras.getString(Intent.EXTRA_TEXT); String fileName = Long.toString(System.currentTimeMillis()); - AppConfig.runInBackground(() -> FileUtil.mktextfile(data, getCurrentMainFragment().getCurrentPath(), fileName)); + AppConfig.runInBackground( + () -> + FileUtil.mktextfile( + data, getCurrentMainFragment().getCurrentPath(), fileName)); Toast.makeText( MainActivity.this, From f7d3f2a072c85a8d6ea3e18952c2eb9489151a54 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 19 Jul 2020 11:20:39 +0800 Subject: [PATCH 26/32] Adaptations to Robolectric 4.3 - Update gradle plugin to 3.6.4, the minimal version without updating to SDK 29. This is necessary for fixing some classloader issues with BouncyCastle when running tests - Update to Robolectric 4.3; also added AndroidX test packages as required - As first step to Robolectric adaptation, removed no longer valid `constants = BuildConfig.class` in tests --- app/build.gradle | 11 +++++++++-- .../compress/AbstractCompressedHelperTaskTest.java | 2 -- .../asynchronous/services/ExtractServiceTest.java | 2 -- .../amaze/filemanager/filesystem/OperationsTest.java | 2 -- .../amaze/filemanager/filesystem/RootHelperTest.java | 2 -- .../filesystem/cloud/CloudStreamSourceTest.java | 2 -- .../filesystem/compressed/B0rkenZipTest.java | 2 -- .../filesystem/compressed/CompressedHelperTest.java | 2 -- .../extractcontents/AbstractExtractorTest.java | 2 -- .../filesystem/files/FileListSorterTest.java | 2 -- .../filesystem/smbstreamer/StreamSourceTest.java | 2 -- .../filesystem/ssh/AbstractSftpServerTest.java | 2 -- .../filesystem/ssh/SshConnectionPoolTest.java | 2 -- .../filesystem/usb/SingletonUsbOtgTest.java | 2 -- .../amaze/filemanager/filesystem/usb/UsbOtgTest.java | 2 -- .../amaze/filemanager/test/ShadowCryptUtilTest.java | 2 -- .../filemanager/ui/activities/MainActivityTest.java | 2 -- .../ui/activities/TextEditorActivityTest.java | 2 -- .../com/amaze/filemanager/ui/icons/IconsTest.java | 2 -- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 21 files changed, 12 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 104c3f7820..26e36eae6d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -113,11 +113,18 @@ dependencies { annotationProcessor 'androidx.annotation:annotation:1.1.0' //For tests - androidTestImplementation 'junit:junit:4.13'//tests the app logic - testImplementation 'junit:junit:4.13'//tests the app logic + androidTestImplementation 'junit:junit:4.12'//tests the app logic + testImplementation 'junit:junit:4.12'//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction + testImplementation 'androidx.test:core:1.2.0' + testImplementation 'androidx.test:runner:1.2.0' + testImplementation 'androidx.test:rules:1.2.0' + testImplementation 'androidx.test.ext:junit:1.1.1' testImplementation "org.mockito:mockito-core:$mockitoVersion" +// testImplementation 'androidx.test.ext:truth:1.2.0' +// testImplementation 'com.google.truth:truth:0.42' + testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index e292fdc8a1..7f3490dcd5 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -36,7 +36,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.CompressedObjectParcelable; import com.amaze.filemanager.asynchronous.asynctasks.AsyncTaskResult; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -45,7 +44,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 27, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index d2fae6f272..8d276a336d 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -42,7 +42,6 @@ import org.robolectric.shadows.ShadowEnvironment; import org.robolectric.shadows.ShadowToast; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -53,7 +52,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class ExtractServiceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 0e9c0dc33b..8a4000e65f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -33,7 +33,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; @@ -42,7 +41,6 @@ @RunWith(RobolectricTestRunner.class) @Config( maxSdk = 27, - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}) public class OperationsTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index 7a2f1a1725..714715e28b 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -38,7 +38,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.test.ShadowShellInteractive; import com.amaze.filemanager.ui.activities.MainActivity; @@ -49,7 +48,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, maxSdk = 27) public class RootHelperTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index c5a10ee96f..c1778e0e8f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -39,7 +39,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.os.Environment; @@ -47,7 +46,6 @@ /** Created by Rustam Khadipash on 31/3/2018. */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class CloudStreamSourceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index d0ffef1965..9054059334 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -36,7 +36,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.adapters.data.CompressedObjectParcelable; import com.amaze.filemanager.asynchronous.asynctasks.compress.ZipHelperTask; @@ -48,7 +47,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class B0rkenZipTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index 51f99a5bfe..f16ceb5222 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -33,7 +33,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.compressed.extractcontents.Extractor; import com.amaze.filemanager.filesystem.compressed.extractcontents.helpers.Bzip2Extractor; import com.amaze.filemanager.filesystem.compressed.extractcontents.helpers.GzipExtractor; @@ -58,7 +57,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class CompressedHelperTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index 6fe6f01a27..c14d8da229 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -43,7 +43,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.compressed.ArchivePasswordCache; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -52,7 +51,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 14, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index 8cf0efa219..2055d3e498 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -32,7 +32,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowDateFormat; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.LayoutElementParcelable; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; @@ -43,7 +42,6 @@ */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, maxSdk = 27) public class FileListSorterTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index ddbcfc71c2..873eeeec1e 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -37,7 +37,6 @@ import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.shadows.jcifs.smb.ShadowSmbFile; @@ -48,7 +47,6 @@ /** Created by Rustam Khadipash on 30/3/2018. */ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, maxSdk = 27) public class StreamSourceTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index 06a62d0a86..f1d24471bb 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -39,7 +39,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.filesystem.ssh.test.TestKeyProvider; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -47,7 +46,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public abstract class AbstractSftpServerTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index 318010d4a1..1e2194a592 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -38,7 +38,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.database.UtilitiesDatabase; import com.amaze.filemanager.database.UtilsHandler; import com.amaze.filemanager.database.models.OperationData; @@ -54,7 +53,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, maxSdk = 27) public class SshConnectionPoolTest { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 1f2694a006..7d1d0ccbb5 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -31,7 +31,6 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.ui.activities.MainActivity; @@ -40,7 +39,6 @@ @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 9d7ae3d5ed..46be1ae2c8 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -33,7 +33,6 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.adapters.data.StorageDirectoryParcelable; import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.ui.activities.MainActivity; @@ -44,7 +43,6 @@ @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index 9fcf0f6d32..a8e3e0e6aa 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -31,7 +31,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.database.UtilitiesDatabase; import com.amaze.filemanager.database.UtilsHandler; import com.amaze.filemanager.database.models.OperationData; @@ -41,7 +40,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, maxSdk = 27) public class ShadowCryptUtilTest { diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index f88a610ad4..5ebd236266 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -28,12 +28,10 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class MainActivityTest { diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 81fc202483..240e404b28 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -42,7 +42,6 @@ import org.robolectric.shadows.ShadowContentResolver; import org.robolectric.shadows.ShadowEnvironment; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.R; import com.amaze.filemanager.application.AppConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -56,7 +55,6 @@ @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, minSdk = 24, maxSdk = 27) diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 7738346a9b..0862363ebe 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -30,14 +30,12 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowMimeTypeMap; -import com.amaze.filemanager.BuildConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.webkit.MimeTypeMap; @RunWith(RobolectricTestRunner.class) @Config( - constants = BuildConfig.class, shadows = {ShadowMultiDex.class}, maxSdk = 27) public class IconsTest { diff --git a/build.gradle b/build.gradle index 32441b83c7..72804fdd25 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:3.6.4' classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4' // NOTE: Do not place your application dependencies here; they belong diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0708d5ee2..b0225133bb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Sep 24 12:34:34 ART 2019 +#Sun Jul 19 11:09:24 HKT 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip From 9aa4318498a3defb77bba4ba96718c2764a1412a Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 25 Jul 2020 22:22:25 +0800 Subject: [PATCH 27/32] build.gradle cleanups, add support for test against API 28 - decoupled some library versions to variables - add support for tests against API 28. API 29 requires Java 9, so it's disabled (although stub had been added) - change test runner to AndroidJUnit4 per docs recommended - RuntimeEnvironment.application -> ApplicationProvider.getApplicationContext() (where applicable - GenericCopyUtilTest relies on Theories to run test, can still use old method) --- app/build.gradle | 28 +++--- .../AbstractCompressedHelperTaskTest.java | 7 +- .../compress/EncryptedZipHelperTaskTest.java | 6 +- .../compress/TarGzHelperTaskTest.java | 6 +- .../compress/ZipHelperTaskTest.java | 6 +- .../services/ExtractServiceTest.java | 16 +-- .../filesystem/OperationsTest.java | 41 ++++---- .../filesystem/RootHelperTest.java | 7 +- .../cloud/CloudStreamSourceTest.java | 7 +- .../filesystem/compressed/B0rkenZipTest.java | 33 ++++--- .../compressed/CompressedHelperTest.java | 11 ++- .../AbstractExtractorTest.java | 13 +-- .../filesystem/files/FileListSorterTest.java | 97 ++++++++++--------- .../smbstreamer/StreamSourceTest.java | 7 +- .../ssh/AbstractSftpServerTest.java | 7 +- .../filesystem/ssh/ListFilesOnSshdTest.java | 7 +- .../filesystem/ssh/SshConnectionPoolTest.java | 12 +-- .../filesystem/usb/SingletonUsbOtgTest.java | 7 +- .../filesystem/usb/UsbOtgTest.java | 7 +- .../filemanager/test/ShadowCryptUtilTest.java | 19 ++-- .../ui/activities/MainActivityTest.java | 7 +- .../ui/activities/TextEditorActivityTest.java | 12 ++- .../amaze/filemanager/ui/icons/IconsTest.java | 7 +- build.gradle | 6 ++ gradle.properties | 2 +- 25 files changed, 209 insertions(+), 169 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 26e36eae6d..6891649c14 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,7 +86,7 @@ android { } ext { - robolectricVersion = '3.8' + robolectricVersion = '4.3.1' glideVersion = '4.11.0' sshjVersion = '0.26.0' jcifsVersion = '2.1.3' @@ -94,7 +94,11 @@ ext { roomVersion = '2.2.5' bouncyCastleVersion = '1.65' awaitilityVersion = "3.1.6" + androidXTestVersion = "1.2.0" + junitVersion = "4.13" + slf4jVersion = "1.7.25" mockitoVersion = "3.4.4" + androidBillingVersion = "2.1.0" } dependencies { @@ -108,30 +112,28 @@ dependencies { implementation 'androidx.palette:palette:1.0.0' implementation 'androidx.cardview:cardview:1.0.0' implementation "androidx.room:room-runtime:$roomVersion" + implementation "com.android.billingclient:billing:$androidBillingVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" - implementation 'com.android.billingclient:billing:2.1.0' annotationProcessor 'androidx.annotation:annotation:1.1.0' //For tests - androidTestImplementation 'junit:junit:4.12'//tests the app logic - testImplementation 'junit:junit:4.12'//tests the app logic + testImplementation "junit:junit:$junitVersion"//tests the app logic testImplementation "org.robolectric:robolectric:$robolectricVersion"//tests android interaction testImplementation "org.robolectric:shadows-httpclient:$robolectricVersion"//tests android interaction - testImplementation 'androidx.test:core:1.2.0' - testImplementation 'androidx.test:runner:1.2.0' - testImplementation 'androidx.test:rules:1.2.0' + testImplementation "androidx.test:core:$androidXTestVersion" + testImplementation "androidx.test:runner:$androidXTestVersion" + testImplementation "androidx.test:rules:$androidXTestVersion" testImplementation 'androidx.test.ext:junit:1.1.1' testImplementation "org.mockito:mockito-core:$mockitoVersion" -// testImplementation 'androidx.test.ext:truth:1.2.0' -// testImplementation 'com.google.truth:truth:0.42' - testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" + testAnnotationProcessor "com.google.auto.service:auto-service:1.0-rc4" + androidTestImplementation "junit:junit:$junitVersion"//tests the app logic androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - debugImplementation 'androidx.test:runner:1.2.0' - androidTestImplementation 'androidx.test:rules:1.2.0' - androidTestImplementation 'androidx.annotation:annotation:1.1.0' + androidTestImplementation "androidx.test:core:$androidXTestVersion" + androidTestImplementation "androidx.test:runner:$androidXTestVersion" + androidTestImplementation "androidx.test:rules:$androidXTestVersion" androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'commons-net:commons-net:3.6' androidTestImplementation "org.awaitility:awaitility:$awaitilityVersion" diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index 7f3490dcd5..085cac4526 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -32,7 +32,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; @@ -42,11 +41,13 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 27, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractCompressedHelperTaskTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java index d78bc07d2b..79efc9b532 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/EncryptedZipHelperTaskTest.java @@ -22,15 +22,15 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class EncryptedZipHelperTaskTest extends AbstractCompressedHelperTaskTest { protected CompressedHelperTask createTask(String relativePath) { return new ZipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive-encrypted.zip") .getAbsolutePath(), relativePath, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java index 9004d6366c..f82673002a 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/TarGzHelperTaskTest.java @@ -22,16 +22,16 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class TarGzHelperTaskTest extends AbstractCompressedHelperTaskTest { @Override protected CompressedHelperTask createTask(String relativePath) { return new GzipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive.tar.gz") .getAbsolutePath(), relativePath, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java index b78c23fa74..0914d91266 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/ZipHelperTaskTest.java @@ -22,15 +22,15 @@ import java.io.File; -import org.robolectric.RuntimeEnvironment; - import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class ZipHelperTaskTest extends AbstractCompressedHelperTaskTest { protected CompressedHelperTask createTask(String relativePath) { return new ZipHelperTask( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new File(Environment.getExternalStorageDirectory(), "test-archive.zip").getAbsolutePath(), relativePath, false, diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index 8d276a336d..78a5af6868 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -36,8 +36,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; import org.robolectric.shadows.ShadowToast; @@ -49,11 +47,13 @@ import android.os.Environment; import androidx.annotation.NonNull; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class ExtractServiceTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); @@ -140,7 +140,8 @@ public void tearDown() throws Exception { public void testExtractZipSlip() { performTest(zipfile1); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -148,7 +149,8 @@ public void testExtractZipSlip() { public void testExtractZipSlipWin() { performTest(zipfile2); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -234,7 +236,7 @@ public void testExtractListPasswordProtected7Zip() { private void performTest(@NonNull File archiveFile) { Intent intent = - new Intent(RuntimeEnvironment.application, ExtractService.class) + new Intent(ApplicationProvider.getApplicationContext(), ExtractService.class) .putExtra(ExtractService.KEY_PATH_ZIP, archiveFile.getAbsolutePath()) .putExtra(ExtractService.KEY_ENTRIES_ZIP, new String[0]) .putExtra( diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 8a4000e65f..6c7a6b990a 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -29,8 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -38,9 +36,12 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( - maxSdk = 27, + maxSdk = 28, shadows = {ShadowMultiDex.class}) public class OperationsTest { @@ -67,7 +68,7 @@ public void testMkdir() throws InterruptedException { CountDownLatch waiter = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -87,7 +88,7 @@ public void testMkdirDuplicate() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -102,7 +103,7 @@ public void done(HybridFile hFile, boolean b) { AtomicBoolean assertFlag = new AtomicBoolean(false); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -123,7 +124,7 @@ public void testMkdirNewFolderSameNameAsCurrentFolder() throws InterruptedExcept CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( newFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -139,7 +140,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( newFolder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -154,7 +155,7 @@ public void done(HybridFile hFile, boolean b) { AtomicBoolean assertFlag = new AtomicBoolean(false); Operations.mkdir( newFolder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -177,7 +178,7 @@ public void testRename() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( oldFolderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -193,7 +194,7 @@ public void done(HybridFile hFile, boolean b) { oldFolderHF, newFolderHF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void done(HybridFile hFile, boolean b) { @@ -213,7 +214,7 @@ public void testRenameSameName() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -230,7 +231,7 @@ public void done(HybridFile hFile, boolean b) { folderHF, folderHF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void exists(HybridFile file) { @@ -251,7 +252,7 @@ public void testRenameSameName2() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -268,7 +269,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( folder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -285,7 +286,7 @@ public void done(HybridFile hFile, boolean b) { folderHF, folder2HF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void exists(HybridFile file) { @@ -306,7 +307,7 @@ public void testRenameSameName3() throws InterruptedException { CountDownLatch waiter1 = new CountDownLatch(1); Operations.mkdir( folderHF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -323,7 +324,7 @@ public void done(HybridFile hFile, boolean b) { CountDownLatch waiter2 = new CountDownLatch(1); Operations.mkdir( folder2HF, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, new AbstractErrorCallback() { @Override @@ -343,7 +344,7 @@ public void done(HybridFile hFile, boolean b) { folder2HF, folder3HF, false, - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), new AbstractErrorCallback() { @Override public void done(HybridFile file, boolean b) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index 714715e28b..d27f4c0c5c 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -35,7 +35,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; @@ -44,12 +43,14 @@ import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import eu.chainfire.libsuperuser.Shell; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, - maxSdk = 27) + maxSdk = 28) public class RootHelperTest { private static final File sysroot = diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index c1778e0e8f..6764b6edb9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -36,18 +36,19 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + /** Created by Rustam Khadipash on 31/3/2018. */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class CloudStreamSourceTest { private CloudStreamSource cs; private String testFilePath; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index 9054059334..61db2c66dd 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -31,8 +31,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; @@ -45,10 +43,13 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class B0rkenZipTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); @@ -91,7 +92,7 @@ public void setUp() throws Exception { public void testExtractZipWithWrongPathUnix() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile1.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -104,7 +105,7 @@ public void testExtractZipWithWrongPathUnix() throws Exception { public void testExtractZipWithWrongPathWindows() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile2.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -117,7 +118,7 @@ public void testExtractZipWithWrongPathWindows() throws Exception { public void testExtractZipWithSlashPrefixEntry() throws Exception { Extractor extractor = new ZipExtractor( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), zipfile3.getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), emptyListener); @@ -130,12 +131,17 @@ public void testExtractZipWithSlashPrefixEntry() throws Exception { public void testZipHelperTaskShouldOmitInvalidEntries() throws Exception { ZipHelperTask task = new ZipHelperTask( - RuntimeEnvironment.application, zipfile1.getAbsolutePath(), null, false, (data) -> {}); + ApplicationProvider.getApplicationContext(), + zipfile1.getAbsolutePath(), + null, + false, + (data) -> {}); List result = task.execute().get().result; assertEquals(1, result.size()); assertEquals("good.txt", result.get(0).path); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } @@ -143,12 +149,17 @@ public void testZipHelperTaskShouldOmitInvalidEntries() throws Exception { public void testZipHelperTaskShouldOmitInvalidEntriesWithBackslash() throws Exception { ZipHelperTask task = new ZipHelperTask( - RuntimeEnvironment.application, zipfile2.getAbsolutePath(), null, false, (data) -> {}); + ApplicationProvider.getApplicationContext(), + zipfile2.getAbsolutePath(), + null, + false, + (data) -> {}); List result = task.execute().get().result; assertEquals(1, result.size()); assertEquals("good.txt", result.get(0).path); assertEquals( - RuntimeEnvironment.application.getString(R.string.multiple_invalid_archive_entries), + ApplicationProvider.getApplicationContext() + .getString(R.string.multiple_invalid_archive_entries), ShadowToast.getTextOfLatestToast()); } } diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index f16ceb5222..b327165fe8 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -29,8 +29,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.filesystem.compressed.extractcontents.Extractor; @@ -55,10 +53,13 @@ import android.content.Context; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class CompressedHelperTest { private Context context; @@ -66,7 +67,7 @@ public class CompressedHelperTest { @Before public void setUp() { - context = RuntimeEnvironment.application; + context = ApplicationProvider.getApplicationContext(); emptyUpdateListener = new Extractor.OnUpdate() { @Override diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index c14d8da229..83bd264f81 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -38,8 +38,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowEnvironment; @@ -49,11 +47,14 @@ import android.content.Context; import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 14, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractExtractorTest { protected abstract Class extractorClass(); @@ -83,7 +84,7 @@ public void testFixEntryName() throws Exception { extractorClass() .getConstructor(Context.class, String.class, String.class, Extractor.OnUpdate.class) .newInstance( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), getArchiveFile().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), null); @@ -117,7 +118,7 @@ protected void doTestExtractFiles() throws Exception { extractorClass() .getConstructor(Context.class, String.class, String.class, Extractor.OnUpdate.class) .newInstance( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), getArchiveFile().getAbsolutePath(), Environment.getExternalStorageDirectory().getAbsolutePath(), new Extractor.OnUpdate() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index 2055d3e498..acaa725abc 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -27,8 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowDateFormat; @@ -36,14 +34,17 @@ import com.amaze.filemanager.shadows.ShadowMultiDex; import com.amaze.filemanager.utils.OpenMode; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + /** * because of test based on mock-up, extension testing isn't tested so, assume all extension is * "*{slash}*" */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, - maxSdk = 27) + maxSdk = 28) public class FileListSorterTest { /** * Purpose: when dirsOnTop is 0, if file1 is directory && file2 is not directory, result is -1 @@ -55,7 +56,7 @@ public void testDir0File1DirAndFile2NoDir() { FileListSorter fileListSorter = new FileListSorter(0, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -69,7 +70,7 @@ public void testDir0File1DirAndFile2NoDir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -101,7 +102,7 @@ public void testDir0File1NoDirAndFile2Dir() { FileListSorter fileListSorter = new FileListSorter(0, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -115,7 +116,7 @@ public void testDir0File1NoDirAndFile2Dir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -141,7 +142,7 @@ public void testDir1File1DirAndFile2NoDir() { FileListSorter fileListSorter = new FileListSorter(1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -155,7 +156,7 @@ public void testDir1File1DirAndFile2NoDir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -181,7 +182,7 @@ public void testDir1File1NoDirAndFile2Dir() { FileListSorter fileListSorter = new FileListSorter(1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -195,7 +196,7 @@ public void testDir1File1NoDirAndFile2Dir() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -223,7 +224,7 @@ public void testSort0File1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -237,7 +238,7 @@ public void testSort0File1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -263,7 +264,7 @@ public void testSort0File2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -277,7 +278,7 @@ public void testSort0File2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -303,7 +304,7 @@ public void testSort0TitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 0, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -317,7 +318,7 @@ public void testSort0TitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", @@ -343,7 +344,7 @@ public void testSort1File1DateLastest() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -357,7 +358,7 @@ public void testSort1File1DateLastest() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -383,7 +384,7 @@ public void testSort1File2DateLastest() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -397,7 +398,7 @@ public void testSort1File2DateLastest() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -423,7 +424,7 @@ public void testSort1FileDateSame() { FileListSorter fileListSorter = new FileListSorter(-1, 1, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -437,7 +438,7 @@ public void testSort1FileDateSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -463,7 +464,7 @@ public void testSort2NoDirAndFile1SizeBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -477,7 +478,7 @@ public void testSort2NoDirAndFile1SizeBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -503,7 +504,7 @@ public void testSort2NoDirAndFile2SizeBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -517,7 +518,7 @@ public void testSort2NoDirAndFile2SizeBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -543,7 +544,7 @@ public void testSort2NoDirAndFileSizeSame() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -557,7 +558,7 @@ public void testSort2NoDirAndFileSizeSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -584,7 +585,7 @@ public void testSort2File1DirAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1", "C:\\AmazeFileManager\\abc1", "user", @@ -598,7 +599,7 @@ public void testSort2File1DirAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -625,7 +626,7 @@ public void testSort2File1DirAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -639,7 +640,7 @@ public void testSort2File1DirAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -666,7 +667,7 @@ public void testSort2File2DirAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -680,7 +681,7 @@ public void testSort2File2DirAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -707,7 +708,7 @@ public void testSort2File2DirAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -721,7 +722,7 @@ public void testSort2File2DirAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2", "C:\\AmazeFileManager\\abc2", "user", @@ -747,7 +748,7 @@ public void testSort2File2DirAndFileTitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 2, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -761,7 +762,7 @@ public void testSort2File2DirAndFileTitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc", "C:\\AmazeFileManager\\abc", "user", @@ -789,7 +790,7 @@ public void testSort3FileExtensionSameAndFile1TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc1.txt", "C:\\AmazeFileManager\\abc1", "user", @@ -803,7 +804,7 @@ public void testSort3FileExtensionSameAndFile1TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -831,7 +832,7 @@ public void testSort3FileExtensionSameAndFile2TitleBigger() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -845,7 +846,7 @@ public void testSort3FileExtensionSameAndFile2TitleBigger() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc2.txt", "C:\\AmazeFileManager\\abc2", "user", @@ -872,7 +873,7 @@ public void testSort3FileExtensionSameAndFileTitleSame() { FileListSorter fileListSorter = new FileListSorter(-1, 3, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -886,7 +887,7 @@ public void testSort3FileExtensionSameAndFileTitleSame() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", @@ -911,7 +912,7 @@ public void testSortAnotherNumber() { FileListSorter fileListSorter = new FileListSorter(-1, 4, 1); LayoutElementParcelable file1 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "abc.txt", "C:\\AmazeFileManager\\abc", "user", @@ -925,7 +926,7 @@ public void testSortAnotherNumber() { OpenMode.UNKNOWN); LayoutElementParcelable file2 = new LayoutElementParcelable( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), "ABC.txt", "C:\\AmazeFileManager\\ABC", "user", diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index 873eeeec1e..f1b51fa828 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -33,7 +33,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; @@ -42,13 +41,15 @@ import android.os.Environment; +import androidx.test.ext.junit.runners.AndroidJUnit4; + import jcifs.smb.SmbFile; /** Created by Rustam Khadipash on 30/3/2018. */ -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, - maxSdk = 27) + maxSdk = 28) public class StreamSourceTest { private SmbFile file; private StreamSource ss; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index f1d24471bb..ca037ea83d 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -36,7 +36,6 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import com.amaze.filemanager.filesystem.ssh.test.TestKeyProvider; @@ -44,10 +43,12 @@ import android.os.Environment; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public abstract class AbstractSftpServerTest { protected SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java index eaf9d396b4..c7fd6b02ba 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/ListFilesOnSshdTest.java @@ -37,13 +37,14 @@ import java.util.concurrent.CountDownLatch; import org.junit.Test; -import org.robolectric.RuntimeEnvironment; import com.amaze.filemanager.filesystem.HybridFile; import com.amaze.filemanager.utils.OpenMode; import android.os.Environment; +import androidx.test.core.app.ApplicationProvider; + public class ListFilesOnSshdTest extends AbstractSftpServerTest { @Test @@ -80,7 +81,7 @@ private boolean performVerify() { HybridFile file = new HybridFile(OpenMode.SFTP, "ssh://testuser:testpassword@127.0.0.1:" + serverPort); file.forEachChildrenFile( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, (fileFound) -> { assertTrue(fileFound.getPath() + " not seen as directory", fileFound.isDirectory()); @@ -110,7 +111,7 @@ public void testListDirsAndFilesAndSymlinks() throws Exception { new HybridFile(OpenMode.SFTP, "ssh://testuser:testpassword@127.0.0.1:" + serverPort); CountDownLatch waiter = new CountDownLatch(15); file.forEachChildrenFile( - RuntimeEnvironment.application, + ApplicationProvider.getApplicationContext(), false, (fileFound) -> { if (!fileFound.getName().endsWith(".txt")) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index 1e2194a592..ccff28ecaa 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -34,8 +34,6 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.database.UtilitiesDatabase; @@ -48,13 +46,15 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; import net.schmizz.sshj.common.SecurityUtils; -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 27) + maxSdk = 28) public class SshConnectionPoolTest { private SshServer server; @@ -303,8 +303,8 @@ private void saveSshConnectionSettings( @NonNull String validUsername, @Nullable String validPassword, @Nullable PrivateKey privateKey) { - utilitiesDatabase = UtilitiesDatabase.initialize(RuntimeEnvironment.application); - utilsHandler = new UtilsHandler(RuntimeEnvironment.application, utilitiesDatabase); + utilitiesDatabase = UtilitiesDatabase.initialize(ApplicationProvider.getApplicationContext()); + utilsHandler = new UtilsHandler(ApplicationProvider.getApplicationContext(), utilitiesDatabase); String privateKeyContents = null; if (privateKey != null) { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 7d1d0ccbb5..6e322aae0b 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -36,12 +35,14 @@ import android.net.Uri; +import androidx.test.ext.junit.runners.AndroidJUnit4; + @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) public class SingletonUsbOtgTest { @Test public void usbConnectionTest() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 46be1ae2c8..958c6c6f7e 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -29,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -40,12 +39,14 @@ import android.text.TextUtils; +import androidx.test.ext.junit.runners.AndroidJUnit4; + @Ignore("Test skipped due to Robolectric unable to inflate SpeedDialView") -@RunWith(RobolectricTestRunner.class) +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) public class UsbOtgTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index a8e3e0e6aa..9a6271a45e 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -27,8 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import com.amaze.filemanager.database.UtilitiesDatabase; @@ -38,25 +36,30 @@ import com.amaze.filemanager.filesystem.ssh.SshClientUtils; import com.amaze.filemanager.shadows.ShadowMultiDex; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 27) + maxSdk = 28) public class ShadowCryptUtilTest { @Test public void testEncryptDecrypt() throws GeneralSecurityException, IOException { String text = "test"; - String encrypted = CryptUtil.encryptPassword(RuntimeEnvironment.application, text); - assertEquals(text, CryptUtil.decryptPassword(RuntimeEnvironment.application, encrypted)); + String encrypted = CryptUtil.encryptPassword(ApplicationProvider.getApplicationContext(), text); + assertEquals( + text, CryptUtil.decryptPassword(ApplicationProvider.getApplicationContext(), encrypted)); } @Test public void testWithUtilsHandler() { UtilitiesDatabase utilitiesDatabase = - UtilitiesDatabase.initialize(RuntimeEnvironment.application); - UtilsHandler utilsHandler = new UtilsHandler(RuntimeEnvironment.application, utilitiesDatabase); + UtilitiesDatabase.initialize(ApplicationProvider.getApplicationContext()); + UtilsHandler utilsHandler = + new UtilsHandler(ApplicationProvider.getApplicationContext(), utilitiesDatabase); String fingerprint = "00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"; String url = "ssh://test:test@127.0.0.1:22"; diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 5ebd236266..83f4f7669b 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -24,16 +24,17 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import com.amaze.filemanager.shadows.ShadowMultiDex; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class MainActivityTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 240e404b28..e4fbb8ca58 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -34,8 +34,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; import org.robolectric.Shadows; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; @@ -53,11 +51,14 @@ import android.os.Environment; import android.widget.TextView; -@RunWith(RobolectricTestRunner.class) +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, minSdk = 24, - maxSdk = 27) + maxSdk = 28) /* Restrict minSdk to 24 since it'd fail at SDK 21-23. This may only be fixed by upgrading to Robolectric 4. @@ -88,7 +89,8 @@ public void testOpenFileUri() throws IOException { public void testOpenContentUri() throws Exception { Uri uri = Uri.parse("content://foo.bar.test.streamprovider/temp/thisisatest.txt"); - ContentResolver contentResolver = RuntimeEnvironment.application.getContentResolver(); + ContentResolver contentResolver = + ApplicationProvider.getApplicationContext().getContentResolver(); ShadowContentResolver shadowContentResolver = Shadows.shadowOf(contentResolver); shadowContentResolver.registerInputStream( uri, new ByteArrayInputStream(fileContents.getBytes("UTF-8"))); diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 0862363ebe..6d9d57880b 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -25,7 +25,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; import org.robolectric.Shadows; import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowMimeTypeMap; @@ -34,10 +33,12 @@ import android.webkit.MimeTypeMap; -@RunWith(RobolectricTestRunner.class) +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - maxSdk = 27) + maxSdk = 28) public class IconsTest { @Before diff --git a/build.gradle b/build.gradle index 72804fdd25..84c7e82200 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,8 @@ configurations { robo25 robo26 robo27 + robo28 +// robo29 } dependencies { @@ -69,6 +71,8 @@ dependencies { robo25 "org.robolectric:android-all:7.1.0_r7-robolectric-r1" robo26 "org.robolectric:android-all:8.0.0_r4-robolectric-r1" robo27 "org.robolectric:android-all:8.1.0-robolectric-4611349" + robo28 "org.robolectric:android-all:9-robolectric-4913185-2" +// robo29 "org.robolectric:android-all:Q-robolectric-5415296" } def robolectricDependencies = "${rootProject.buildDir.path}/robolectric" @@ -85,6 +89,8 @@ task fetchRobolectricDependencies(type: Copy) { from configurations.robo25 from configurations.robo26 from configurations.robo27 + from configurations.robo28 +// from configurations.robo29 into robolectricDependencies } diff --git a/gradle.properties b/gradle.properties index 5cbbfbb834..678f09d103 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ # The setting is particularly useful for tweaking memory settings. android.enableJetifier=true android.useAndroidX=true -android.enableUnitTestBinaryResources=false + # Workaround for Android Gradle Plugin before 3.6.0. # See https://github.com/robolectric/robolectric/issues/5299#issuecomment-543125381 # and https://issuetracker.google.com/issues/142580430 From a1c5bf15c33a5e06a7c581c6574a261a2761a193 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 1 Aug 2020 10:58:23 +0800 Subject: [PATCH 28/32] [WIP] test cases collection and fixes as work goes on - ColorUtils: Add back missing break statement to prevent unknown icons being colored to default color - NotificationConstants: Fix constant to use per reported by Android Studio - Return of MainActivity test - Remove deprecated API usage in TextEditorActivityTest - Add test cases for CloudSheetFragment, NotificationConstants, SmbUtil, TinyDB, along with some more little util classes --- .../filemanager/ui/colors/ColorUtils.java | 1 + .../notifications/NotificationConstants.java | 2 +- .../com/amaze/filemanager/utils/Utils.java | 7 +- .../com/amaze/filemanager/test/TestUtils.java | 71 ++++++++ .../ui/activities/MainActivityTest.java | 61 +++++-- .../ui/activities/TextEditorActivityTest.java | 20 +-- .../filemanager/ui/colors/ColorUtilsTest.java | 96 ++++++++++ .../ui/fragments/CloudSheetFragmentTest.java | 54 ++++++ .../NotificationConstantsTest.java | 167 ++++++++++++++++++ .../filemanager/utils/AnimUtilsTest.java | 72 ++++++++ .../amaze/filemanager/utils/OpenModeTest.java | 58 ++++++ .../amaze/filemanager/utils/SmbUtilTest.java | 74 ++++++++ .../amaze/filemanager/utils/TinyDBTest.java | 72 ++++++++ .../amaze/filemanager/utils/UtilsTest.java | 106 ++++++++++- 14 files changed, 825 insertions(+), 36 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java diff --git a/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java b/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java index a310b64654..2583c2d41e 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java +++ b/app/src/main/java/com/amaze/filemanager/ui/colors/ColorUtils.java @@ -59,6 +59,7 @@ public static void colorizeIcons( break; case Icons.NOT_KNOWN: background.setColor(Utils.getColor(context, R.color.generic_item)); + break; default: background.setColor(defaultColor); break; diff --git a/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java b/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java index b723ddebb8..6a1581871f 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java +++ b/app/src/main/java/com/amaze/filemanager/ui/notifications/NotificationConstants.java @@ -77,7 +77,7 @@ public static void setMetadata( case TYPE_FTP: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { notification.setCategory(Notification.CATEGORY_SERVICE); - notification.setVisibility(Notification.VISIBILITY_PUBLIC); + notification.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { notification.setPriority(Notification.PRIORITY_MAX); diff --git a/app/src/main/java/com/amaze/filemanager/utils/Utils.java b/app/src/main/java/com/amaze/filemanager/utils/Utils.java index fb100dd187..f83a0df6b7 100644 --- a/app/src/main/java/com/amaze/filemanager/utils/Utils.java +++ b/app/src/main/java/com/amaze/filemanager/utils/Utils.java @@ -52,6 +52,7 @@ import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.StringRes; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; import androidx.core.graphics.drawable.DrawableCompat; @@ -221,12 +222,12 @@ private static String sanitizeInputOnce(String input) { } /** Returns uri associated to specific basefile */ - public static Uri getUriForBaseFile(Context context, HybridFileParcelable baseFile) { + public static Uri getUriForBaseFile( + @NonNull Context context, @NonNull HybridFileParcelable baseFile) { switch (baseFile.getMode()) { case FILE: case ROOT: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return FileProvider.getUriForFile( context, context.getPackageName(), new File(baseFile.getPath())); } else { @@ -340,7 +341,7 @@ public static Snackbar showThemedSnackbar( MainActivity mainActivity, CharSequence text, int length, - int actionTextId, + @StringRes int actionTextId, Runnable actionCallback) { Snackbar snackbar = Snackbar.make(mainActivity.findViewById(R.id.content_frame), text, length) diff --git a/app/src/test/java/com/amaze/filemanager/test/TestUtils.java b/app/src/test/java/com/amaze/filemanager/test/TestUtils.java index 1cf11ec007..2f011f86d1 100644 --- a/app/src/test/java/com/amaze/filemanager/test/TestUtils.java +++ b/app/src/test/java/com/amaze/filemanager/test/TestUtils.java @@ -20,15 +20,27 @@ package com.amaze.filemanager.test; +import static android.os.Build.VERSION_CODES.P; import static org.robolectric.Shadows.shadowOf; +import java.io.File; import java.lang.reflect.Field; +import org.robolectric.shadows.ShadowStorageManager; import org.robolectric.util.Scheduler; import com.amaze.filemanager.application.AppConfig; +import android.os.Build; +import android.os.Environment; import android.os.Handler; +import android.os.Parcel; +import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.StorageVolume; + +import androidx.annotation.NonNull; +import androidx.test.core.app.ApplicationProvider; public class TestUtils { @@ -63,4 +75,63 @@ public static void flushAppConfigHandlerThread() { throw new AssertionError("Unable to access backgroundHandler within AppConfig"); } } + + /** + * Populate "internal device storage" to StorageManager with directory as provided by Robolectric. + * + *

Tests need storage access must call this on test case setup for SDK >= N to work. + */ + public static void initializeInternalStorage() { + Parcel parcel = Parcel.obtain(); + File dir = Environment.getExternalStorageDirectory(); + parcel.writeString("FS-internal"); + if (Build.VERSION.SDK_INT < P) parcel.writeInt(0); + parcel.writeString(dir.getAbsolutePath()); + if (Build.VERSION.SDK_INT >= P) parcel.writeString(dir.getAbsolutePath()); + parcel.writeString("robolectric internal storage"); + parcel.writeInt(1); + parcel.writeInt(0); + parcel.writeInt(1); + if (Build.VERSION.SDK_INT < P) parcel.writeLong(1024 * 1024); + parcel.writeInt(0); + parcel.writeLong(1024 * 1024); + parcel.writeParcelable(UserHandle.getUserHandleForUid(0), 0); + parcel.writeString("1234-5678"); + parcel.writeString(Environment.MEDIA_MOUNTED); + addVolumeToStorageManager(parcel); + } + + /** + * Populate "external device storage" to StorageManager with directory as provided by Robolectric. + * + *

Tests need storage access must call this on test case setup for SDK >= N to work. + */ + public static void initializeExternalStorage() { + Parcel parcel = Parcel.obtain(); + File dir = Environment.getExternalStoragePublicDirectory("external"); + parcel.writeString("FS-external"); + if (Build.VERSION.SDK_INT < P) parcel.writeInt(0); + parcel.writeString(dir.getAbsolutePath()); + if (Build.VERSION.SDK_INT >= P) parcel.writeString(dir.getAbsolutePath()); + parcel.writeString("robolectric external storage"); + parcel.writeInt(0); + parcel.writeInt(1); + parcel.writeInt(0); + if (Build.VERSION.SDK_INT < P) parcel.writeLong(1024 * 1024); + parcel.writeInt(0); + parcel.writeLong(1024 * 1024); + parcel.writeParcelable(UserHandle.getUserHandleForUid(0), 0); + parcel.writeString("ABCD-EFGH"); + parcel.writeString(Environment.MEDIA_MOUNTED); + addVolumeToStorageManager(parcel); + } + + private static void addVolumeToStorageManager(@NonNull Parcel parcel) { + parcel.setDataPosition(0); + ShadowStorageManager storageManager = + shadowOf( + ApplicationProvider.getApplicationContext().getSystemService(StorageManager.class)); + StorageVolume volume = StorageVolume.CREATOR.createFromParcel(parcel); + storageManager.addStorageVolume(volume); + } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 83f4f7669b..da087f9bde 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -20,33 +20,66 @@ package com.amaze.filemanager.ui.activities; -import org.junit.Ignore; +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.P; +import static androidx.test.core.app.ActivityScenario.launch; +import static org.robolectric.Shadows.shadowOf; + +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.Robolectric; -import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; +import org.robolectric.annotation.LooperMode; +import org.robolectric.shadows.ShadowLooper; +import org.robolectric.shadows.ShadowStorageManager; import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.test.TestUtils; + +import android.os.Build; +import android.os.storage.StorageManager; +import androidx.lifecycle.Lifecycle; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) @Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) + shadows = {ShadowMultiDex.class, ShadowStorageManager.class}, + maxSdk = P) +/* + * Need to make LooperMode PAUSED and flush the main looper before activity can show up. + * @see {@link LooperMode.Mode.PAUSED} + * @see {@link StackOverflow discussion} + */ +@LooperMode(LooperMode.Mode.PAUSED) public class MainActivityTest { + @Before + public void setUp() { + if (Build.VERSION.SDK_INT >= N) TestUtils.initializeInternalStorage(); + } + + @After + public void tearDown() { + if (Build.VERSION.SDK_INT >= N) + shadowOf(ApplicationProvider.getApplicationContext().getSystemService(StorageManager.class)) + .resetStorageVolumeList(); + } + @Test - @Ignore public void testMainActivity() { - ActivityController controller = - Robolectric.buildActivity(MainActivity.class) - .create() - .start() - .resume() - .visible() - .pause() - .destroy(); + ActivityScenario scenario = launch(MainActivity.class); + + ShadowLooper.idleMainLooper(); + + scenario.moveToState(Lifecycle.State.STARTED); + + scenario.onActivity( + activity -> { + scenario.close(); + }); } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index e4fbb8ca58..8244ddbacc 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -20,10 +20,8 @@ package com.amaze.filemanager.ui.activities; -import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.File; @@ -45,7 +43,6 @@ import com.amaze.filemanager.shadows.ShadowMultiDex; import android.content.ContentResolver; -import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Environment; @@ -57,13 +54,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, maxSdk = 28) -/* - Restrict minSdk to 24 since it'd fail at SDK 21-23. - This may only be fixed by upgrading to Robolectric 4. - See https://github.com/robolectric/robolectric/issues/3947 -*/ public class TextEditorActivityTest { private final String fileContents = "fsdfsdfs"; @@ -82,7 +73,7 @@ public void testOpenFileUri() throws IOException { intent.setData(Uri.fromFile(file)); generateActivity(intent); - assertThat(text.getText().toString(), is(fileContents + "\n")); + assertEquals(fileContents + "\n", text.getText().toString()); } @Test @@ -120,7 +111,7 @@ private File simulateFile() throws IOException { file.createNewFile(); if (!file.canWrite()) file.setWritable(true); - assertThat(file.canWrite(), is(true)); + assertTrue(file.canWrite()); PrintWriter out = new PrintWriter(file); out.write(fileContents); @@ -129,9 +120,4 @@ private File simulateFile() throws IOException { return file; } - - private Uri getFileContentUri(Context context, File file) { - fail("Cannot create content URI"); - return null; - } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java new file mode 100644 index 0000000000..cb6a39383a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.colors; + +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.P; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.ui.icons.Icons; +import com.amaze.filemanager.utils.Utils; + +import android.content.res.ColorStateList; +import android.graphics.drawable.GradientDrawable; + +import androidx.annotation.ColorInt; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = N, maxSdk = P) +public class ColorUtilsTest { + + @Test + public void testSetColorizeIcons() { + doTest(R.color.video_item, Icons.VIDEO); + doTest(R.color.audio_item, Icons.AUDIO); + doTest(R.color.pdf_item, Icons.PDF); + doTest(R.color.code_item, Icons.CODE); + doTest(R.color.text_item, Icons.TEXT); + doTest(R.color.archive_item, Icons.COMPRESSED); + doTest(R.color.apk_item, Icons.APK); + doTest(R.color.generic_item, Icons.NOT_KNOWN); + assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + } + + @Test + public void testSetColorizeIconsGeneric() { + doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE); + doTestGeneric(R.color.primary_indigo, Icons.CONTACT); + doTestGeneric(R.color.primary_indigo, Icons.EVENTS); + doTestGeneric(R.color.primary_indigo, Icons.FONT); + doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION); + doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS); + doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); + doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); + doTestGeneric(R.color.primary_indigo, Icons.GIF); + assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + } + + private void doTest(@ColorInt int expected, int icon) { + GradientDrawable drawable = new GradientDrawable(); + ColorUtils.colorizeIcons( + ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); + doCompare( + ColorStateList.valueOf( + Utils.getColor(ApplicationProvider.getApplicationContext(), expected)), + drawable); + drawable = null; + } + + private void doTestGeneric(@ColorInt int expected, int icon) { + GradientDrawable drawable = new GradientDrawable(); + ColorUtils.colorizeIcons( + ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); + doCompare(ColorStateList.valueOf(expected), drawable); + drawable = null; + } + + private void doCompare(ColorStateList expected, GradientDrawable drawable) { + assertEquals(expected, drawable.getColor()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java new file mode 100644 index 0000000000..ebb6a72367 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.fragments; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.robolectric.Shadows.shadowOf; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.database.CloudContract; + +import android.content.pm.PackageInfo; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class CloudSheetFragmentTest { + + @Test + public void testIsCloudProviderAvailable() { + assertFalse( + CloudSheetFragment.isCloudProviderAvailable(ApplicationProvider.getApplicationContext())); + + PackageInfo pi = new PackageInfo(); + pi.packageName = CloudContract.APP_PACKAGE_NAME; + shadowOf(ApplicationProvider.getApplicationContext().getPackageManager()).installPackage(pi); + + assertTrue( + CloudSheetFragment.isCloudProviderAvailable(ApplicationProvider.getApplicationContext())); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java new file mode 100644 index 0000000000..7b7062c4ca --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.notifications; + +import static android.app.NotificationManager.IMPORTANCE_HIGH; +import static android.app.NotificationManager.IMPORTANCE_MIN; +import static android.os.Build.VERSION_CODES.N; +import static android.os.Build.VERSION_CODES.O; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.CHANNEL_FTP_ID; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.CHANNEL_NORMAL_ID; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.TYPE_FTP; +import static com.amaze.filemanager.ui.notifications.NotificationConstants.TYPE_NORMAL; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.robolectric.Shadows.shadowOf; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowNotificationManager; + +import com.amaze.filemanager.R; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; +import android.os.Build; + +import androidx.core.app.NotificationCompat; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class NotificationConstantsTest { + + private Context context; + + private NotificationManager notificationManager; + + private ShadowNotificationManager shadowNotificationManager; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + notificationManager = + (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + shadowNotificationManager = shadowOf(notificationManager); + } + + @After + public void tearDown() { + notificationManager.cancelAll(); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetMetadataIllegalType() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID); + NotificationConstants.setMetadata(context, builder, -1); + NotificationConstants.setMetadata(context, builder, 2); + NotificationConstants.setMetadata(context, builder, Integer.MAX_VALUE); + builder = new NotificationCompat.Builder(context, CHANNEL_FTP_ID); + NotificationConstants.setMetadata(context, builder, -1); + NotificationConstants.setMetadata(context, builder, 2); + NotificationConstants.setMetadata(context, builder, Integer.MAX_VALUE); + } + + @Test + @Config(maxSdk = N) + public void testNormalNotification() { + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID) + .setContentTitle(context.getString(R.string.waiting_title)) + .setContentText(context.getString(R.string.waiting_content)) + .setAutoCancel(false) + .setSmallIcon(R.drawable.ic_all_inclusive_white_36dp) + .setProgress(0, 0, true); + + NotificationConstants.setMetadata(context, builder, TYPE_NORMAL); + Notification result = builder.build(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + assertEquals(Notification.CATEGORY_SERVICE, result.category); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + assertEquals(Notification.PRIORITY_MIN, result.priority); + } else { + assertEquals(Notification.PRIORITY_DEFAULT, result.priority); + } + } + + @Test + @Config(maxSdk = N) + public void testFtpNotification() { + NotificationCompat.Builder builder = + new NotificationCompat.Builder(context, CHANNEL_FTP_ID) + .setContentTitle("FTP server test") + .setContentText("FTP listening at 127.0.0.1:22") + .setSmallIcon(R.drawable.ic_ftp_light) + .setTicker(context.getString(R.string.ftp_notif_starting)) + .setOngoing(true) + .setOnlyAlertOnce(true); + NotificationConstants.setMetadata(context, builder, TYPE_FTP); + Notification result = builder.build(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + assertEquals(Notification.CATEGORY_SERVICE, result.category); + assertEquals(Notification.VISIBILITY_PUBLIC, result.visibility); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + assertEquals(Notification.PRIORITY_MAX, result.priority); + } else { + assertEquals(Notification.PRIORITY_DEFAULT, result.priority); + } + } + + @Test + @Config(minSdk = O) + public void testCreateNormalChannel() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_NORMAL_ID); + NotificationConstants.setMetadata(context, builder, TYPE_NORMAL); + List channels = shadowNotificationManager.getNotificationChannels(); + assertNotNull(channels); + assertEquals(1, channels.size()); + NotificationChannel channel = (NotificationChannel) channels.get(0); + assertEquals(IMPORTANCE_MIN, channel.getImportance()); + assertEquals(CHANNEL_NORMAL_ID, channel.getId()); + assertEquals(context.getString(R.string.channel_name_normal), channel.getName()); + assertEquals(context.getString(R.string.channel_description_normal), channel.getDescription()); + } + + @Test + @Config(minSdk = O) + public void testCreateFtpChannel() { + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_FTP_ID); + NotificationConstants.setMetadata(context, builder, TYPE_FTP); + List channels = shadowNotificationManager.getNotificationChannels(); + assertNotNull(channels); + assertEquals(1, channels.size()); + NotificationChannel channel = (NotificationChannel) channels.get(0); + assertEquals(IMPORTANCE_HIGH, channel.getImportance()); + assertEquals(CHANNEL_FTP_ID, channel.getId()); + assertEquals(context.getString(R.string.channel_name_ftp), channel.getName()); + assertEquals(context.getString(R.string.channel_description_ftp), channel.getDescription()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java new file mode 100644 index 0000000000..3cc2e3315a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mock; +import static org.robolectric.Shadows.shadowOf; + +import java.lang.reflect.Field; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.ui.views.ThemedTextView; + +import android.os.Looper; +import android.view.animation.Interpolator; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class AnimUtilsTest { + + @Test + public void testGetFastOutSlowInInterpolator() + throws NoSuchFieldException, IllegalAccessException { + Field f = AnimUtils.class.getDeclaredField("fastOutSlowIn"); + f.setAccessible(true); + assertNull(f.get(null)); + Interpolator result = + AnimUtils.getFastOutSlowInInterpolator(ApplicationProvider.getApplicationContext()); + assertNotNull(result); + assertNotNull(f.get(null)); + } + + @Test + public void testMarqueeAfterDelay() { + ThemedTextView mock = mock(ThemedTextView.class); + doCallRealMethod().when(mock).setSelected(anyBoolean()); + doCallRealMethod().when(mock).isSelected(); + mock.setSelected(false); + + AnimUtils.marqueeAfterDelay(150, mock); + shadowOf(Looper.myLooper()).getScheduler().advanceToLastPostedRunnable(); + assertTrue(mock.isSelected()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java b/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java new file mode 100644 index 0000000000..4f7a66db42 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/OpenModeTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static com.amaze.filemanager.utils.OpenMode.BOX; +import static com.amaze.filemanager.utils.OpenMode.CUSTOM; +import static com.amaze.filemanager.utils.OpenMode.DROPBOX; +import static com.amaze.filemanager.utils.OpenMode.FILE; +import static com.amaze.filemanager.utils.OpenMode.GDRIVE; +import static com.amaze.filemanager.utils.OpenMode.ONEDRIVE; +import static com.amaze.filemanager.utils.OpenMode.OTG; +import static com.amaze.filemanager.utils.OpenMode.ROOT; +import static com.amaze.filemanager.utils.OpenMode.SFTP; +import static com.amaze.filemanager.utils.OpenMode.SMB; +import static com.amaze.filemanager.utils.OpenMode.UNKNOWN; +import static java.lang.Integer.MAX_VALUE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import org.junit.Test; + +public class OpenModeTest { + + @Test + public void testGetOpenMode() { + assertEquals(UNKNOWN, OpenMode.getOpenMode(0)); + assertEquals(FILE, OpenMode.getOpenMode(1)); + assertEquals(SMB, OpenMode.getOpenMode(2)); + assertEquals(SFTP, OpenMode.getOpenMode(3)); + assertEquals(CUSTOM, OpenMode.getOpenMode(4)); + assertEquals(ROOT, OpenMode.getOpenMode(5)); + assertEquals(OTG, OpenMode.getOpenMode(6)); + assertEquals(GDRIVE, OpenMode.getOpenMode(7)); + assertEquals(DROPBOX, OpenMode.getOpenMode(8)); + assertEquals(BOX, OpenMode.getOpenMode(9)); + assertEquals(ONEDRIVE, OpenMode.getOpenMode(10)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> OpenMode.getOpenMode(-1)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> OpenMode.getOpenMode(MAX_VALUE)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java new file mode 100644 index 0000000000..b9645cb815 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.test.ShadowCryptUtil; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + minSdk = 19, + maxSdk = 28, + shadows = {ShadowCryptUtil.class}) +public class SmbUtilTest { + + @Test + public void testEncryptDecrypt() throws GeneralSecurityException, IOException { + String path = "smb://root:toor@127.0.0.1"; + String encrypted = + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path); + assertNotEquals(path, encrypted); + assertTrue(encrypted.startsWith("smb://root:")); + assertTrue(encrypted.endsWith("@127.0.0.1")); + String decrypted = + SmbUtil.getSmbDecryptedPath(ApplicationProvider.getApplicationContext(), encrypted); + assertEquals(path, decrypted); + } + + @Test + public void testEncryptWithoutCredentials() throws GeneralSecurityException, IOException { + String path = "smb://127.0.0.1"; + assertEquals( + path, SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path)); + } + + @Test + @Ignore("Good idea to fix me") + public void testEncryptWithoutPassword() throws GeneralSecurityException, IOException { + String path = "smb://toor@127.0.0.1"; + assertEquals( + path, SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java new file mode 100644 index 0000000000..ae4a996513 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.utils; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) +public class TinyDBTest { + + private SharedPreferences prefs; + + @Before + public void setUp() { + prefs = + PreferenceManager.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext()); + } + + @Test + public void testSaveLoadBooleanArray() { + Boolean[] value = new Boolean[] {true, false, true, false, true, true, false}; + TinyDB.putBooleanArray(prefs, "foobar", value); + Boolean[] result = + TinyDB.getBooleanArray( + prefs, "foobar", new Boolean[] {false, false, false, false, false, false, false}); + assertArrayEquals(value, result); + } + + @Test + public void testLoadBooleanArrayShouldReturnDefaultValue() { + Boolean[] expected = + TinyDB.getBooleanArray( + prefs, "foobaz", new Boolean[] {true, false, true, false, false, false}); + Boolean[] result = TinyDB.getBooleanArray(prefs, "foobaz", expected); + assertArrayEquals(expected, result); + } + + @Test + public void testLoadBooleanArrayShouldReturnDefaultValue2() { + assertNull(TinyDB.getBooleanArray(prefs, "foobam", null)); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java index a9895512b7..eb21bf51e0 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java @@ -20,12 +20,40 @@ package com.amaze.filemanager.utils; +import static android.os.Build.VERSION_CODES.N; import static com.amaze.filemanager.utils.Utils.formatTimer; import static com.amaze.filemanager.utils.Utils.sanitizeInput; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import java.io.File; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowToast; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.filesystem.HybridFileParcelable; + +import android.net.Uri; +import android.os.Build; +import android.os.storage.StorageVolume; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(minSdk = 19, maxSdk = 28) public class UtilsTest { @Test public void @@ -59,4 +87,80 @@ public void testFormatTimer() { assertEquals("02:45", formatTimer(165)); assertEquals("30:33", formatTimer(1833)); } + + @Test + public void testDifferenceStrings() { + assertNull(Utils.differenceStrings(null, null)); + assertEquals("abc", Utils.differenceStrings("abc", null)); + assertEquals("abc", Utils.differenceStrings(null, "abc")); + assertEquals("", Utils.differenceStrings("abc12345", "abc")); + assertEquals("", Utils.differenceStrings("pqrstuv345", "pqrstuv")); + assertEquals("12345", Utils.differenceStrings("abc", "abc12345")); + } + + @Test + public void testGetUriForBaseFile() { + HybridFileParcelable file = new HybridFileParcelable("/storage/emulated/0/test.txt"); + for (OpenMode m : new OpenMode[] {OpenMode.FILE, OpenMode.ROOT}) { + file.setMode(m); + Uri uri = Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file); + if (Build.VERSION.SDK_INT < N) { + assertEquals("file:///storage/emulated/0/test.txt", uri.toString()); + } else { + assertEquals( + "content://" + + ApplicationProvider.getApplicationContext().getPackageName() + + "/storage_root/storage/emulated/0/test.txt", + uri.toString()); + } + } + + for (OpenMode m : + new OpenMode[] { + OpenMode.DROPBOX, OpenMode.GDRIVE, OpenMode.ONEDRIVE, OpenMode.SMB, OpenMode.BOX + }) { + file = new HybridFileParcelable("/foo/bar/test.txt"); + file.setMode(m); + assertNull(Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file)); + assertEquals( + ApplicationProvider.getApplicationContext().getString(R.string.smb_launch_error), + ShadowToast.getTextOfLatestToast()); + } + + file.setMode(OpenMode.CUSTOM); + assertNull(Utils.getUriForBaseFile(ApplicationProvider.getApplicationContext(), file)); + } + + @Test + public void testIsNullOrEmptyCollection() { + assertTrue(Utils.isNullOrEmpty((Collection) null)); + assertTrue(Utils.isNullOrEmpty(Collections.EMPTY_SET)); + assertFalse(Utils.isNullOrEmpty(Collections.singletonList(null))); + assertFalse(Utils.isNullOrEmpty(Arrays.asList(new Object()))); + Collection l = new ArrayList(); + l.add(new Object()); + assertFalse(Utils.isNullOrEmpty(l)); + } + + @Test + public void testIsNullOrEmptyString() { + assertTrue(Utils.isNullOrEmpty((String) null)); + assertTrue(Utils.isNullOrEmpty("")); + assertFalse(Utils.isNullOrEmpty("null")); + assertFalse(Utils.isNullOrEmpty("empty")); + assertFalse(Utils.isNullOrEmpty("this is a string")); + } + + @Test + @Config(minSdk = N) + public void testGetVolumeDirectory() throws Exception { + StorageVolume mock = mock(StorageVolume.class); + Field f = StorageVolume.class.getDeclaredField("mPath"); + f.setAccessible(true); + f.set(mock, new File("/storage/emulated/0")); + + File result = Utils.getVolumeDirectory(mock); + assertNotNull(result); + assertEquals(new File("/storage/emulated/0"), result); + } } From d90cb838d26c34fe72cbd793bbbf3db63f36a09e Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 2 Aug 2020 18:19:01 +0800 Subject: [PATCH 29/32] [WIP] test cases collection and fixes as work goes on - Added test cases for DbViewerTask, WriteFileAbstraction and EditableFileAbstraction - EditableFileAbstraction, schema changed from integer to enum constant --- app/build.gradle | 2 + .../asynchronous/asynctasks/DbViewerTask.java | 6 +- .../asynchronous/asynctasks/ReadFileTask.java | 4 +- .../asynctasks/WriteFileAbstraction.java | 4 +- .../filesystem/EditableFileAbstraction.java | 19 +- .../ui/activities/TextEditorActivity.java | 8 +- .../asynctasks/DbViewerTaskTest.java | 163 ++++++++++++ .../asynctasks/WriteFileAbstractionTest.java | 231 ++++++++++++++++++ .../EditableFileAbstractionTest.java | 97 ++++++++ .../filemanager/ui/colors/ColorUtilsTest.java | 4 +- app/src/test/resources/test.db | Bin 0 -> 36864 bytes 11 files changed, 519 insertions(+), 19 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java create mode 100644 app/src/test/resources/test.db diff --git a/app/build.gradle b/app/build.gradle index 6891649c14..8c3823436c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -124,9 +124,11 @@ dependencies { testImplementation "androidx.test:runner:$androidXTestVersion" testImplementation "androidx.test:rules:$androidXTestVersion" testImplementation 'androidx.test.ext:junit:1.1.1' + //testImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' testImplementation "org.mockito:mockito-core:$mockitoVersion" testImplementation "org.apache.sshd:sshd-core:1.7.0" testImplementation "org.awaitility:awaitility:$awaitilityVersion" + testImplementation 'org.jsoup:jsoup:1.11.2' testAnnotationProcessor "com.google.auto.service:auto-service:1.0-rc4" androidTestImplementation "junit:junit:$junitVersion"//tests the app logic diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java index 943d125d5d..a4a3d79e6e 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTask.java @@ -52,7 +52,7 @@ public DbViewerTask( this.dbViewerFragment = dbViewerFragment; stringBuilder = new StringBuilder(); - webView.getSettings().setDefaultTextEncodingName("utf-8"); + this.webView.getSettings().setDefaultTextEncodingName("utf-8"); } @Override @@ -62,10 +62,10 @@ protected void onPreExecute() { if (dbViewerFragment.databaseViewerActivity.getAppTheme().equals(AppTheme.DARK) || dbViewerFragment.databaseViewerActivity.getAppTheme().equals(AppTheme.BLACK)) { - htmlInit = "" + "

"; + htmlInit = "
"; } else { - htmlInit = "" + "
"; + htmlInit = "
"; } stringBuilder.append(htmlInit); dbViewerFragment.loadingText.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java index 0e3967a46b..5831a82fc3 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/ReadFileTask.java @@ -74,13 +74,13 @@ protected ReturnedValues doInBackground(Void... params) { InputStream inputStream = null; switch (fileAbstraction.scheme) { - case EditableFileAbstraction.SCHEME_CONTENT: + case CONTENT: if (fileAbstraction.uri == null) throw new NullPointerException("Something went really wrong!"); inputStream = contentResolver.openInputStream(fileAbstraction.uri); break; - case EditableFileAbstraction.SCHEME_FILE: + case FILE: final HybridFileParcelable hybridFileParcelable = fileAbstraction.hybridFileParcelable; if (hybridFileParcelable == null) throw new NullPointerException("Something went really wrong!"); diff --git a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java index ff72be125f..3470e6ffc1 100644 --- a/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java +++ b/app/src/main/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstraction.java @@ -79,7 +79,7 @@ protected Integer doInBackground(Void... voids) { OutputStream outputStream; switch (fileAbstraction.scheme) { - case EditableFileAbstraction.SCHEME_CONTENT: + case CONTENT: if (fileAbstraction.uri == null) throw new NullPointerException("Something went really wrong!"); @@ -90,7 +90,7 @@ protected Integer doInBackground(Void... voids) { } break; - case EditableFileAbstraction.SCHEME_FILE: + case FILE: final HybridFileParcelable hybridFileParcelable = fileAbstraction.hybridFileParcelable; if (hybridFileParcelable == null) throw new NullPointerException("Something went really wrong!"); diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java b/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java index f411ca033c..62c8ac9c12 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/EditableFileAbstraction.java @@ -20,6 +20,9 @@ package com.amaze.filemanager.filesystem; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.CONTENT; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; + import com.amaze.filemanager.utils.Utils; import android.content.Context; @@ -27,6 +30,8 @@ import android.net.Uri; import android.provider.OpenableColumns; +import androidx.annotation.NonNull; + /** * This is a special representation of a file that is to be used so that uris can be loaded as * editable files. @@ -35,19 +40,21 @@ */ public class EditableFileAbstraction { - public static final int SCHEME_CONTENT = 0; - public static final int SCHEME_FILE = 1; + public enum Scheme { + CONTENT, + FILE + } public final Uri uri; public final String name; - public final int scheme; + public final Scheme scheme; public final HybridFileParcelable hybridFileParcelable; - public EditableFileAbstraction(Context context, Uri uri) { + public EditableFileAbstraction(@NonNull Context context, @NonNull Uri uri) { switch (uri.getScheme()) { case "content": this.uri = uri; - this.scheme = SCHEME_CONTENT; + this.scheme = CONTENT; String tempName = null; Cursor c = @@ -79,7 +86,7 @@ public EditableFileAbstraction(Context context, Uri uri) { this.hybridFileParcelable = null; break; case "file": - this.scheme = SCHEME_FILE; + this.scheme = FILE; String path = uri.getPath(); if (path == null) diff --git a/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java b/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java index e41f68f6c3..51f15ff510 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java +++ b/app/src/main/java/com/amaze/filemanager/ui/activities/TextEditorActivity.java @@ -20,6 +20,7 @@ package com.amaze.filemanager.ui.activities; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_TEXTEDITOR_NEWSTACK; @@ -322,7 +323,7 @@ private void load() { try { mInput.setText(data.fileContents); - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE + if (mFile.scheme.equals(FILE) && getExternalCacheDir() != null && mFile .hybridFileParcelable @@ -403,8 +404,7 @@ public boolean onOptionsItemSelected(MenuItem item) { saveFile(mInput.getText().toString()); break; case R.id.details: - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE - && mFile.hybridFileParcelable.getFile().exists()) { + if (mFile.scheme.equals(FILE) && mFile.hybridFileParcelable.getFile().exists()) { GeneralDialogCreation.showPropertiesDialogWithoutPermissions( mFile.hybridFileParcelable, this, getAppTheme()); } else { @@ -412,7 +412,7 @@ public boolean onOptionsItemSelected(MenuItem item) { } break; case R.id.openwith: - if (mFile.scheme == EditableFileAbstraction.SCHEME_FILE) { + if (mFile.scheme.equals(FILE)) { File currentFile = mFile.hybridFileParcelable.getFile(); if (currentFile.exists()) { boolean useNewStack = getBoolean(PREFERENCE_TEXTEDITOR_NEWSTACK); diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java new file mode 100644 index 0000000000..8d34294f3a --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.asynchronous.asynctasks; + +import static android.view.View.VISIBLE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.select.Elements; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.ui.activities.DatabaseViewerActivity; +import com.amaze.filemanager.ui.fragments.DbViewerFragment; +import com.amaze.filemanager.ui.theme.AppTheme; + +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.view.View; +import android.webkit.WebView; +import android.widget.TextView; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class DbViewerTaskTest { + + private WebView webView; + + @Before + public void setUp() { + webView = new WebView(ApplicationProvider.getApplicationContext()); + } + + @After + public void tearDown() { + webView.destroy(); + } + + @Test + public void testOnPreExecute() { + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + mock.databaseViewerActivity = mock(DatabaseViewerActivity.class); + mock.loadingText.setVisibility(View.GONE); + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.DARK); + + DbViewerTask task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#ffffff")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.BLACK); + task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#ffffff")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.LIGHT); + task = new DbViewerTask(null, null, webView, mock); + task.onPreExecute(); + assertEquals(VISIBLE, mock.loadingText.getVisibility()); + assertTrue(task.htmlInit.contains("color:#000000")); + assertEquals("utf-8", webView.getSettings().getDefaultTextEncodingName()); + } + + @Test + public void testExecute() { + SQLiteDatabase sqLiteDatabase = + SQLiteDatabase.openDatabase( + "src/test/resources/test.db", null, SQLiteDatabase.OPEN_READONLY); + assertNotNull(sqLiteDatabase); + + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + Cursor schemaCursor = sqLiteDatabase.rawQuery("PRAGMA table_info('users');", null); + Cursor contentCursor = sqLiteDatabase.rawQuery("SELECT * FROM users", null); + + DbViewerTask task = new DbViewerTask(schemaCursor, contentCursor, webView, mock); + task.doInBackground(); + + assertNotNull(task.schemaList); + assertNotNull(task.contentList); + + // 3 columns + assertEquals(3, task.schemaList.size()); + // 4 records + assertEquals(4, task.contentList.size()); + assertEquals("4 records loaded", loadingText.getText().toString()); + + sqLiteDatabase.close(); + } + + @Test + public void testCompleteTask() { + SQLiteDatabase sqLiteDatabase = + SQLiteDatabase.openDatabase( + "src/test/resources/test.db", null, SQLiteDatabase.OPEN_READONLY); + assertNotNull(sqLiteDatabase); + + DbViewerFragment mock = mock(DbViewerFragment.class); + TextView loadingText = new TextView(ApplicationProvider.getApplicationContext()); + mock.loadingText = loadingText; + mock.databaseViewerActivity = mock(DatabaseViewerActivity.class); + mock.loadingText.setVisibility(View.GONE); + when(mock.databaseViewerActivity.getAppTheme()).thenReturn(AppTheme.DARK); + Cursor schemaCursor = sqLiteDatabase.rawQuery("PRAGMA table_info('users');", null); + Cursor contentCursor = sqLiteDatabase.rawQuery("SELECT * FROM users", null); + + DbViewerTask task = new DbViewerTask(schemaCursor, contentCursor, webView, mock); + task.onPreExecute(); + task.doInBackground(); + task.onPostExecute(null); + + assertNotNull(task.stringBuilder.toString()); + + Document html = Jsoup.parse(task.stringBuilder.toString()); + assertNotNull(html); + Elements elements = html.getElementsByTag("table"); + assertEquals(1, elements.size()); + elements = elements.get(0).getElementsByTag("tr"); + assertEquals(5, elements.size()); + Elements headerRow = elements.get(0).getElementsByTag("th"); + assertEquals(3, headerRow.size()); + + sqLiteDatabase.close(); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java new file mode 100644 index 0000000000..fc957ab881 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.asynchronous.asynctasks; + +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.EXCEPTION_SHELL_NOT_RUNNING; +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.EXCEPTION_STREAM_NOT_FOUND; +import static com.amaze.filemanager.asynchronous.asynctasks.WriteFileAbstraction.NORMAL; +import static org.junit.Assert.assertEquals; +import static org.robolectric.Shadows.shadowOf; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; + +import org.apache.ftpserver.util.IoUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +import com.amaze.filemanager.exceptions.ShellNotRunningException; +import com.amaze.filemanager.filesystem.EditableFileAbstraction; +import com.amaze.filemanager.filesystem.FileUtil; +import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.utils.RootUtils; + +import android.content.ContentResolver; +import android.content.Context; +import android.net.Uri; +import android.os.Environment; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class WriteFileAbstractionTest { + + private static final String contents = "This is modified data"; + + @Test + public void testWriteContentUri() { + Uri uri = Uri.parse("content://com.amaze.filemanager.test/foobar.txt"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + shadowOf(cr).registerOutputStream(uri, bout); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + assertEquals(contents, new String(bout.toByteArray(), StandardCharsets.UTF_8)); + } + + @Test + public void testWriteFileNonRoot() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + public void testWriteFileOverwriting() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + IoUtils.copy(new StringReader("Dummy test content"), new FileWriter(file), 1024); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class, BypassMountPartitionRootUtils.class}) + public void testWriteFileRoot() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + File cacheFile = File.createTempFile("test.txt", "cache"); + cacheFile.deleteOnExit(); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(NORMAL, result); + + String verify = IoUtils.readFully(new FileInputStream(file)); + assertEquals(contents, verify); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class}) + public void testWriteFileRootNoCacheFile() { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_STREAM_NOT_FOUND, result); + } + + @Test + @Config(shadows = {BlockAllOutputStreamsFileUtil.class}) + public void testWriteFileRootCacheFileNotFound() { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + File cacheFile = new File(Environment.getExternalStorageDirectory(), "test.txt.cache"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_STREAM_NOT_FOUND, result); + } + + @Test + @Config(shadows = {ShellNotRunningRootUtils.class}) + public void testWriteFileRootShellNotRunning() throws IOException { + File file = new File(Environment.getExternalStorageDirectory(), "test.txt"); + Uri uri = Uri.fromFile(file); + File cacheFile = File.createTempFile("test.txt", "cache"); + cacheFile.deleteOnExit(); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, cacheFile, true, null); + int result = task.doInBackground(); + assertEquals(EXCEPTION_SHELL_NOT_RUNNING, result); + } + + @Test(expected = IllegalArgumentException.class) + public void testWriteBogeyUri() { + Uri uri = Uri.parse("ftp://bogey.ftp/test.txt"); + Context ctx = ApplicationProvider.getApplicationContext(); + ContentResolver cr = ctx.getContentResolver(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + shadowOf(cr).registerOutputStream(uri, bout); + + WriteFileAbstraction task = + new WriteFileAbstraction( + ctx, cr, new EditableFileAbstraction(ctx, uri), contents, null, false, null); + + task.doInBackground(); + } + + @Implements(FileUtil.class) + static class BlockAllOutputStreamsFileUtil { + + @Implementation + public static OutputStream getOutputStream(final File target, Context context) + throws FileNotFoundException { + return null; + } + } + + @Implements(RootUtils.class) + static class BypassMountPartitionRootUtils { + + @Implementation + public static void cat(String sourcePath, String destinationPath) + throws ShellNotRunningException { + try { + IoUtils.copy(new FileInputStream(sourcePath), new FileOutputStream(destinationPath), 512); + } catch (IOException e) { + throw new ShellNotRunningException(); + } + } + } + + @Implements(RootUtils.class) + static class ShellNotRunningRootUtils { + @Implementation + public static void cat(String sourcePath, String destinationPath) + throws ShellNotRunningException { + throw new ShellNotRunningException(); + } + } +} diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java new file mode 100644 index 0000000000..2b44e41fad --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.filesystem; + +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.CONTENT; +import static com.amaze.filemanager.filesystem.EditableFileAbstraction.Scheme.FILE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.io.File; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.shadows.ShadowMultiDex; + +import android.content.ContentResolver; +import android.content.ContentValues; +import android.net.Uri; +import android.os.Environment; +import android.provider.OpenableColumns; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config( + maxSdk = 28, + shadows = {ShadowMultiDex.class}) +public class EditableFileAbstractionTest { + + @Test(expected = IllegalArgumentException.class) + public void testBogeyUri() { + new EditableFileAbstraction( + ApplicationProvider.getApplicationContext(), Uri.parse("https://github.com/TeamAmaze")); + } + + @Test + public void testContentUri() { + Uri uri = Uri.parse("content://com.amaze.filemanager.test/foobar/foobar.txt"); + String displayName = "foobar.txt"; + ContentResolver cr = ApplicationProvider.getApplicationContext().getContentResolver(); + ContentValues content = new ContentValues(); + content.put(OpenableColumns.DISPLAY_NAME, displayName); + cr.insert(uri, content); + + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals(CONTENT, verify.scheme); + assertEquals(displayName, verify.name); + assertNull(verify.hybridFileParcelable); + assertEquals(uri, verify.uri); + } + + @Test + public void testNonExistentContentUri() { + Uri uri = Uri.parse("content://foo.bar.bogey.uri/test.txt"); + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals("test.txt", verify.name); + assertNull(verify.hybridFileParcelable); + assertEquals(CONTENT, verify.scheme); + assertEquals(uri, verify.uri); + } + + @Test + public void testFileUri() { + File file = new File(Environment.getExternalStorageDirectory(), "test.odt"); + Uri uri = Uri.fromFile(file); + EditableFileAbstraction verify = + new EditableFileAbstraction(ApplicationProvider.getApplicationContext(), uri); + assertEquals("test.odt", verify.name); + assertNotNull(verify.hybridFileParcelable); + assertEquals(FILE, verify.scheme); + assertNull(verify.uri); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java index cb6a39383a..334a7e9599 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -54,7 +54,7 @@ public void testSetColorizeIcons() { doTest(R.color.archive_item, Icons.COMPRESSED); doTest(R.color.apk_item, Icons.APK); doTest(R.color.generic_item, Icons.NOT_KNOWN); - assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... } @Test @@ -68,7 +68,7 @@ public void testSetColorizeIconsGeneric() { doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); doTestGeneric(R.color.primary_indigo, Icons.GIF); - assertNotNull(ApplicationProvider.getApplicationContext()); //idiotic codacy compliance... + assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... } private void doTest(@ColorInt int expected, int icon) { diff --git a/app/src/test/resources/test.db b/app/src/test/resources/test.db new file mode 100644 index 0000000000000000000000000000000000000000..f86ffa33ed10fe833ec197d2eceb9ae9250411b1 GIT binary patch literal 36864 zcmeI*-)qxA0KoCPT-qkZ?gpcTB0?AlmWenOWDhc@1Q~W!X9w-;lpxsy5DTA#2dZ1+grNXO*Yng+vEQE`DmsQ zg^ihWwJ03lo;4mGDf;Q2rS|f;KU;4^7oz#FeyI`G7izVmCNn+Wp1H;9rk5)Om5SWF zomL<_b+*p$JZZKwJKbJq3NO#k&dtm(h8Ls7aAu)#X|`?-Fc;Mu;X-}(%0gtT(rK>7 z<9;K$W@53HX&T@RWx4vR-GMAbg{Ul8fP?k<))$k_re^7WbD_pqj z=7Wg|xtLz!;K;preIxE%k9Q?=J1%-x<`G-{qvn&<&4aQK1cAI?{?%@2t2jG8pS9Fq zn%U#-?`Bokn!Vngq-&br$`-3tl@HDY`$=Zso)hWDtvbIiI++$#<|pRapION)u6``^ zNBu%SH4y>=2q1s}0tg_000IagfB*sr{CffiTvwFK-6ZMvlcZZxt{AJdlGaq~_*Bvw zaa<7u&6W1`_|)mi^Cw58DSXI20oZ!VP&8NM>UTo_&|mZ?6Cogg00IagfB*srAbUkUv|e>EEd0tg_000IagfB*srAbheKmY**5I_I{1Q0*~f&X2=PWkUE*EMS=r|h2qIId$7 JW`~*o|0nwGFIfNp literal 0 HcmV?d00001 From 3d1bb3e0b7a51fe19388e87754976e2232e00ad2 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 8 Aug 2020 10:17:16 +0800 Subject: [PATCH 30/32] [WIP] test cases collection --- .../filemanager/application/AppConfig.java | 12 +- .../filesystem/MediaStoreHack.java | 2 +- .../preference_fragments/PrefFrag.java | 2 +- .../ui/views/WarnableTextInputValidator.java | 46 +++--- .../application/AppConfigTest.java | 116 +++++++++++++++ .../filemanager/ssh/SshClientUtilTest.java | 38 +++++ .../activities/PreferencesActivityTest.java | 136 ++++++++++++++++++ .../views/WarnableTextInputValidatorTest.java | 88 ++++++++++++ 8 files changed, 405 insertions(+), 35 deletions(-) create mode 100644 app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java create mode 100644 app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java diff --git a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java index 5d40ca5ade..2ef2746d19 100644 --- a/app/src/main/java/com/amaze/filemanager/application/AppConfig.java +++ b/app/src/main/java/com/amaze/filemanager/application/AppConfig.java @@ -178,11 +178,7 @@ public static void toast(Context context, @StringRes int message) { final Context c = context; final @StringRes int m = message; - ((AppConfig) context) - .runInApplicationThread( - () -> { - Toast.makeText(c, m, Toast.LENGTH_LONG).show(); - }); + getInstance().runInApplicationThread(() -> Toast.makeText(c, m, Toast.LENGTH_LONG).show()); } } @@ -206,11 +202,7 @@ public static void toast(Context context, String message) { final Context c = context; final String m = message; - ((AppConfig) context) - .runInApplicationThread( - () -> { - Toast.makeText(c, m, Toast.LENGTH_LONG).show(); - }); + getInstance().runInApplicationThread(() -> Toast.makeText(c, m, Toast.LENGTH_LONG).show()); } } diff --git a/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java b/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java index b5c5e45e76..b613ebd93b 100644 --- a/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java +++ b/app/src/main/java/com/amaze/filemanager/filesystem/MediaStoreHack.java @@ -154,7 +154,7 @@ private static int getTemporaryAlbumId(final Context context) { try { temporaryTrack = installTemporaryTrack(context); } catch (final IOException ex) { - Log.w("MediaFile", "Error installing tempory track.", ex); + Log.w("MediaFile", "Error installing temporary track.", ex); return 0; } final Uri filesUri = MediaStore.Files.getContentUri("external"); diff --git a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java index 018c72c345..9c4db6e745 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java +++ b/app/src/main/java/com/amaze/filemanager/ui/fragments/preference_fragments/PrefFrag.java @@ -164,7 +164,7 @@ public void onCreate(Bundle savedInstanceState) { masterPasswordPreference.setEnabled(false); return true; }); - } catch (NoClassDefFoundError error) { + } catch (NoClassDefFoundError | ClassCastException error) { error.printStackTrace(); // fingerprint manager class not defined in the framework diff --git a/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java b/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java index cb95407130..71125c98ad 100644 --- a/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java +++ b/app/src/main/java/com/amaze/filemanager/ui/views/WarnableTextInputValidator.java @@ -34,11 +34,11 @@ public final class WarnableTextInputValidator extends SimpleTextWatcher implements View.OnFocusChangeListener, View.OnTouchListener { - private final Context mContext; - private final EditText mEditText; - private final View mButton; - private final WarnableTextInputLayout mTextInputLayout; - private final OnTextValidate mValidator; + private final Context context; + private final EditText editText; + private final View button; + private final WarnableTextInputLayout textInputLayout; + private final OnTextValidate validator; private @DrawableRes int warningDrawable, errorDrawable; public WarnableTextInputValidator( @@ -47,15 +47,15 @@ public WarnableTextInputValidator( WarnableTextInputLayout textInputLayout, View positiveButton, OnTextValidate validator) { - mContext = context; - mEditText = editText; - mEditText.setOnFocusChangeListener(this); - mEditText.addTextChangedListener(this); - mTextInputLayout = textInputLayout; - mButton = positiveButton; - mButton.setOnTouchListener(this); - mButton.setEnabled(false); - mValidator = validator; + this.context = context; + this.editText = editText; + this.editText.setOnFocusChangeListener(this); + this.editText.addTextChangedListener(this); + this.textInputLayout = textInputLayout; + button = positiveButton; + button.setOnTouchListener(this); + button.setEnabled(false); + this.validator = validator; warningDrawable = R.drawable.ic_warning_24dp; errorDrawable = R.drawable.ic_error_24dp; @@ -65,7 +65,7 @@ public WarnableTextInputValidator( public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { int state = doValidate(false); - mButton.setEnabled(state != ReturnState.STATE_ERROR); + button.setEnabled(state != ReturnState.STATE_ERROR); } } @@ -86,24 +86,24 @@ public void afterTextChanged(Editable s) { /** @return ReturnState.state */ private int doValidate(boolean onlySetWarning) { - ReturnState state = mValidator.isTextValid(mEditText.getText().toString()); + ReturnState state = validator.isTextValid(editText.getText().toString()); switch (state.state) { case ReturnState.STATE_NORMAL: - mTextInputLayout.removeError(); + textInputLayout.removeError(); setEditTextIcon(null); - mButton.setEnabled(true); + button.setEnabled(true); break; case ReturnState.STATE_ERROR: if (!onlySetWarning) { - mTextInputLayout.setError(mContext.getString(state.text)); + textInputLayout.setError(context.getString(state.text)); setEditTextIcon(errorDrawable); } - mButton.setEnabled(false); + button.setEnabled(false); break; case ReturnState.STATE_WARNING: - mTextInputLayout.setWarning(state.text); + textInputLayout.setWarning(state.text); setEditTextIcon(warningDrawable); - mButton.setEnabled(true); + button.setEnabled(true); break; } @@ -112,7 +112,7 @@ private int doValidate(boolean onlySetWarning) { private void setEditTextIcon(@DrawableRes Integer drawable) { @DrawableRes int drawableInt = drawable != null ? drawable : 0; - mEditText.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawableInt, 0); + editText.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawableInt, 0); } public interface OnTextValidate { diff --git a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java new file mode 100644 index 0000000000..77e61cba5c --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.application; + +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; + +import java.lang.reflect.Field; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowToast; + +import com.amaze.filemanager.R; +import com.amaze.filemanager.ui.activities.MainActivity; +import com.bumptech.glide.Glide; +import com.bumptech.glide.MemoryCategory; + +import android.os.StrictMode; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = 28) +public class AppConfigTest { + + @After + public void tearDown() { + ShadowToast.reset(); + } + + @Test + public void testSetVmPolicyOnAppCreateHasNoFlags() throws Exception { + Field maskField = StrictMode.VmPolicy.class.getDeclaredField("mask"); + maskField.setAccessible(true); + assertEquals(0, maskField.get(StrictMode.getVmPolicy())); + } + + @Test + public void testToastWithNullContext() { + AppConfig.toast(null, R.string.ok); + assertNull(ShadowToast.getLatestToast()); + } + + @Test + public void testToastWithStringRes() { + AppConfig.toast(ApplicationProvider.getApplicationContext(), R.string.ok); + await().atMost(5, TimeUnit.SECONDS).until(() -> ShadowToast.getLatestToast() != null); + assertEquals( + ApplicationProvider.getApplicationContext().getString(R.string.ok), + ShadowToast.getTextOfLatestToast()); + } + + @Test + public void testToastWithString() { + AppConfig.toast(ApplicationProvider.getApplicationContext(), "Hello world"); + await().atMost(5, TimeUnit.SECONDS).until(() -> ShadowToast.getLatestToast() != null); + assertEquals("Hello world", ShadowToast.getTextOfLatestToast()); + } + + @Test + public void testGetImageLoader() throws Exception { + Field requestQueue = AppConfig.class.getDeclaredField("requestQueue"); + Field imageLoader = AppConfig.class.getDeclaredField("imageLoader"); + requestQueue.setAccessible(true); + imageLoader.setAccessible(true); + + assertNull(requestQueue.get(AppConfig.getInstance())); + assertNull(imageLoader.get(AppConfig.getInstance())); + + assertNotNull(AppConfig.getInstance().getImageLoader()); + } + + @Test + public void testGlideMemoryCategorySetToHigh() throws Exception { + Field memoryCategory = Glide.class.getDeclaredField("memoryCategory"); + memoryCategory.setAccessible(true); + assertEquals( + MemoryCategory.HIGH, + memoryCategory.get(Glide.get(ApplicationProvider.getApplicationContext()))); + } + + @Test + public void testGetScreenUtils() { + assertNull(AppConfig.getInstance().getScreenUtils()); + + MainActivity mock = mock(MainActivity.class); + AppConfig.getInstance().setMainActivityContext(mock); + assertNotNull(AppConfig.getInstance().getScreenUtils()); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java b/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java new file mode 100644 index 0000000000..3c455db9a2 --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ssh/SshClientUtilTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ssh; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.amaze.filemanager.filesystem.ssh.SshClientUtils; + +public class SshClientUtilTest { + @Test + public void testExtractRemotePathFromUri() { + assertEquals( + "/home/user/foo/bar", + SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22/home/user/foo/bar")); + assertEquals("/", SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22/")); + assertEquals("/", SshClientUtils.extractRemotePathFrom("ssh://user:password@127.0.0.1:22")); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java new file mode 100644 index 0000000000..e45a4a6d1f --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.activities; + +import static android.os.Build.VERSION_CODES.P; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_BOOKMARKS_ADDED; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_CHANGEPATHS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORIZE_ICONS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_NEED_TO_SET_HOME; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_ROOTMODE; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_DIVIDERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_FILE_SIZE; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_GOBACK_BUTTON; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_HEADERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_HIDDENFILES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_LAST_MODIFIED; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_PERMISSIONS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_SIDEBAR_FOLDERS; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_SIDEBAR_QUICKACCESSES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_SHOW_THUMB; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_TEXTEDITOR_NEWSTACK; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_USE_CIRCULAR_IMAGES; +import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_VIEW; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import androidx.lifecycle.Lifecycle; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = P) +public class PreferencesActivityTest { + + private static final String[] DEFAULT_FALSE_PREFS = + new String[] { + PREFERENCE_SHOW_PERMISSIONS, + PREFERENCE_SHOW_GOBACK_BUTTON, + PREFERENCE_SHOW_HIDDENFILES, + PREFERENCE_BOOKMARKS_ADDED, + PREFERENCE_ROOTMODE, + PREFERENCE_COLORED_NAVIGATION, + PREFERENCE_TEXTEDITOR_NEWSTACK, + PREFERENCE_CHANGEPATHS + }; + + private static final String[] DEFAULT_TRUE_PREFS = + new String[] { + PREFERENCE_SHOW_FILE_SIZE, + PREFERENCE_SHOW_DIVIDERS, + PREFERENCE_SHOW_HEADERS, + PREFERENCE_USE_CIRCULAR_IMAGES, + PREFERENCE_COLORIZE_ICONS, + PREFERENCE_SHOW_THUMB, + PREFERENCE_SHOW_SIDEBAR_QUICKACCESSES, + PREFERENCE_NEED_TO_SET_HOME, + PREFERENCE_SHOW_SIDEBAR_FOLDERS, + PREFERENCE_VIEW, + PREFERENCE_SHOW_LAST_MODIFIED + }; + + private ActivityScenario scenario; + + @Before + public void setUp() { + scenario = ActivityScenario.launch(PreferencesActivity.class); + scenario.moveToState(Lifecycle.State.STARTED); + } + + @After + public void tearDown() { + scenario.close(); + } + + @Test + public void testGetBooleanWithNoSavedValue() { + scenario.onActivity( + activity -> { + for (String pref : DEFAULT_FALSE_PREFS) { + assertFalse(activity.getBoolean(pref)); + } + for (String pref : DEFAULT_TRUE_PREFS) { + assertTrue(activity.getBoolean(pref)); + } + assertThrows(IllegalArgumentException.class, () -> activity.getBoolean("foobar")); + }); + } + + @Test + public void testGetBooleanWithSavedValue() { + SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext()); + scenario.onActivity( + activity -> { + for (String pref : DEFAULT_FALSE_PREFS) { + preferences.edit().putBoolean(pref, true).commit(); + assertTrue(activity.getBoolean(pref)); + } + for (String pref : DEFAULT_TRUE_PREFS) { + preferences.edit().putBoolean(pref, false).commit(); + assertFalse(activity.getBoolean(pref)); + } + assertThrows(IllegalArgumentException.class, () -> activity.getBoolean("foobar")); + }); + } +} diff --git a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java new file mode 100644 index 0000000000..082457eb4b --- /dev/null +++ b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014-2020 Arpit Khurana , Vishal Nehra , + * Emmanuel Messulam, Raymond Lai and Contributors. + * + * This file is part of Amaze File Manager. + * + * Amaze File Manager 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 . + */ + +package com.amaze.filemanager.ui.views; + +import static android.os.Build.VERSION_CODES.P; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; + +import com.amaze.filemanager.R; + +import android.content.Context; +import android.widget.Button; +import android.widget.EditText; + +import androidx.appcompat.widget.AppCompatButton; +import androidx.appcompat.widget.AppCompatEditText; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +@RunWith(AndroidJUnit4.class) +@Config(maxSdk = P) +public class WarnableTextInputValidatorTest { + + private Context context; + + @Before + public void setUp() { + context = ApplicationProvider.getApplicationContext(); + context.setTheme(R.style.appCompatBlack); + } + + @Test + public void testValidate() { + EditText textfield = new AppCompatEditText(context); + WarnableTextInputLayout layout = + new WarnableTextInputLayout(context, Robolectric.buildAttributeSet().build()); + Button button = new AppCompatButton(context); + WarnableTextInputValidator.OnTextValidate validator = + text -> + ("Pass".equals(text)) + ? new WarnableTextInputValidator.ReturnState( + WarnableTextInputValidator.ReturnState.STATE_NORMAL, R.string.ok) + : new WarnableTextInputValidator.ReturnState( + WarnableTextInputValidator.ReturnState.STATE_ERROR, R.string.error); + + WarnableTextInputValidator target = + new WarnableTextInputValidator( + ApplicationProvider.getApplicationContext(), textfield, layout, button, validator); + textfield.setText(""); + target.performClick(); + assertFalse(button.isEnabled()); + assertEquals(context.getString(R.string.error), layout.getError()); + textfield.setText("pass"); + target.performClick(); + assertFalse(button.isEnabled()); + assertEquals(context.getString(R.string.error), layout.getError()); + textfield.setText("Pass"); + target.performClick(); + assertTrue(button.isEnabled()); + assertNull(layout.getError()); + } +} From f57c2751815d9fd8a20d878b3829409cc42cc688 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sat, 8 Aug 2020 22:42:28 +0800 Subject: [PATCH 31/32] MainActivityTest test addConnection() --- .../shadows/jcifs/smb/ShadowSmbFile.java | 5 ++ .../ui/activities/MainActivityTest.java | 66 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java b/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java index 2896864971..f13a2f5ac4 100644 --- a/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java +++ b/app/src/test/java/com/amaze/filemanager/shadows/jcifs/smb/ShadowSmbFile.java @@ -56,4 +56,9 @@ public InputStream getInputStream() throws IOException { public long length() throws SmbException { return file.length(); } + + @Implementation + public SmbFile[] listFiles() { + return new SmbFile[0]; + } } diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index da087f9bde..4b315dc8fb 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -23,8 +23,16 @@ import static android.os.Build.VERSION_CODES.N; import static android.os.Build.VERSION_CODES.P; import static androidx.test.core.app.ActivityScenario.launch; +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import static org.robolectric.Shadows.shadowOf; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.concurrent.TimeUnit; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -34,8 +42,12 @@ import org.robolectric.shadows.ShadowLooper; import org.robolectric.shadows.ShadowStorageManager; +import com.amaze.filemanager.application.AppConfig; import com.amaze.filemanager.shadows.ShadowMultiDex; +import com.amaze.filemanager.shadows.jcifs.smb.ShadowSmbFile; +import com.amaze.filemanager.test.ShadowCryptUtil; import com.amaze.filemanager.test.TestUtils; +import com.amaze.filemanager.utils.SmbUtil; import android.os.Build; import android.os.storage.StorageManager; @@ -47,7 +59,12 @@ @RunWith(AndroidJUnit4.class) @Config( - shadows = {ShadowMultiDex.class, ShadowStorageManager.class}, + shadows = { + ShadowMultiDex.class, + ShadowStorageManager.class, + ShadowCryptUtil.class, + ShadowSmbFile.class + }, maxSdk = P) /* * Need to make LooperMode PAUSED and flush the main looper before activity can show up. @@ -70,7 +87,7 @@ public void tearDown() { } @Test - public void testMainActivity() { + public void testUpdateSmbExceptionShouldNotThrowNPE() { ActivityScenario scenario = launch(MainActivity.class); ShadowLooper.idleMainLooper(); @@ -79,7 +96,50 @@ public void testMainActivity() { scenario.onActivity( activity -> { - scenario.close(); + String path = "smb://root:toor@192.168.1.1"; + String oldName = "SMB connection"; + String newName = "root@192.168.1.1"; + try { + + activity.addConnection( + false, + oldName, + path, + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path), + null, + null); + activity.addConnection( + true, + newName, + path, + SmbUtil.getSmbEncryptedPath(ApplicationProvider.getApplicationContext(), path), + oldName, + path); + + ShadowLooper.idleMainLooper(); + + await() + .atMost(5, TimeUnit.SECONDS) + .until(() -> AppConfig.getInstance().getUtilsHandler().getSmbList().size() > 0); + await() + .atMost(5, TimeUnit.SECONDS) + .until( + () -> + AppConfig.getInstance() + .getUtilsHandler() + .getSmbList() + .get(0)[0] + .equals(newName)); + List verify = AppConfig.getInstance().getUtilsHandler().getSmbList(); + String[] entry = verify.get(0); + assertEquals(path, entry[1]); + + } catch (GeneralSecurityException | IOException e) { + fail(e.getMessage()); + } finally { + scenario.moveToState(Lifecycle.State.DESTROYED); + scenario.close(); + } }); } } From eeba28a97c3f34f9de9e2523e9c391fa7d043cb5 Mon Sep 17 00:00:00 2001 From: TranceLove Date: Sun, 9 Aug 2020 21:53:11 +0800 Subject: [PATCH 32/32] Adaptation for running the build on JDK 9 With Robolectric 4's support for SDK >= 29 in place, they require the tests must run on JDK 9 or above. Therefore some adaptations must be done to allow this. - add back APIs removed in JDK 9 which are required by Android builds - all Robolectric test cases will have their maxSdk @Config settings centralized in robolectric.properties Due to https://github.com/robolectric/robolectric/issues/5456 and developer adaptation to JDK > 8 is still not yet in place, running the test suite within Android Studio is still not possible out-of-the-box, this commit will not enable running with SDK 29 yet; but once everyone's ready it will be just a switch at robolectric.properties above Tested building from command line with JDK 11 (Latest LTS version) and Android Studio, both on Ubuntu Focal x86_64. Reference: https://medium.com/@jack_martynov/adopt-android-build-on-the-jdk11-macos-cc8f05995341 --- .../application/AppConfigTest.java | 2 - .../asynctasks/DbViewerTaskTest.java | 4 +- .../asynctasks/WriteFileAbstractionTest.java | 4 +- .../AbstractCompressedHelperTaskTest.java | 5 +- .../services/ExtractServiceTest.java | 4 +- .../EditableFileAbstractionTest.java | 4 +- .../filesystem/OperationsTest.java | 4 +- .../filesystem/RootHelperTest.java | 4 +- .../cloud/CloudStreamSourceTest.java | 4 +- .../filesystem/compressed/B0rkenZipTest.java | 4 +- .../compressed/CompressedHelperTest.java | 4 +- .../AbstractExtractorTest.java | 3 +- .../filesystem/files/FileListSorterTest.java | 4 +- .../smbstreamer/StreamSourceTest.java | 4 +- .../ssh/AbstractSftpServerTest.java | 4 +- .../filesystem/ssh/SshConnectionPoolTest.java | 4 +- .../filesystem/usb/SingletonUsbOtgTest.java | 3 +- .../filesystem/usb/UsbOtgTest.java | 3 +- .../filemanager/test/ShadowCryptUtilTest.java | 4 +- .../ui/activities/MainActivityTest.java | 5 +- .../activities/PreferencesActivityTest.java | 3 -- .../ui/activities/TextEditorActivityTest.java | 4 +- .../filemanager/ui/colors/ColorUtilsTest.java | 47 +++++++++---------- .../ui/fragments/CloudSheetFragmentTest.java | 2 +- .../amaze/filemanager/ui/icons/IconsTest.java | 4 +- .../NotificationConstantsTest.java | 2 +- .../views/WarnableTextInputValidatorTest.java | 3 -- .../filemanager/utils/AnimUtilsTest.java | 2 +- .../amaze/filemanager/utils/SmbUtilTest.java | 1 - .../amaze/filemanager/utils/TinyDBTest.java | 2 +- .../amaze/filemanager/utils/UtilsTest.java | 2 +- app/src/test/resources/robolectric.properties | 1 + build.gradle | 30 ++++++++++-- 33 files changed, 78 insertions(+), 102 deletions(-) create mode 100644 app/src/test/resources/robolectric.properties diff --git a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java index 77e61cba5c..183375750c 100644 --- a/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java +++ b/app/src/test/java/com/amaze/filemanager/application/AppConfigTest.java @@ -32,7 +32,6 @@ import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowToast; import com.amaze.filemanager.R; @@ -46,7 +45,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = 28) public class AppConfigTest { @After diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java index 8d34294f3a..c9c042f968 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/DbViewerTaskTest.java @@ -51,9 +51,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class DbViewerTaskTest { private WebView webView; diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java index fc957ab881..c7093e9a64 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/WriteFileAbstractionTest.java @@ -59,9 +59,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class WriteFileAbstractionTest { private static final String contents = "This is modified data"; diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java index 085cac4526..618d244e04 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/asynctasks/compress/AbstractCompressedHelperTaskTest.java @@ -44,10 +44,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - minSdk = 27, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public abstract class AbstractCompressedHelperTaskTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java index 78a5af6868..d608c463d0 100644 --- a/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java +++ b/app/src/test/java/com/amaze/filemanager/asynchronous/services/ExtractServiceTest.java @@ -51,9 +51,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class ExtractServiceTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java index 2b44e41fad..d216223244 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/EditableFileAbstractionTest.java @@ -44,9 +44,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class EditableFileAbstractionTest { @Test(expected = IllegalArgumentException.class) diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java index 6c7a6b990a..871628a289 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/OperationsTest.java @@ -40,9 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - maxSdk = 28, - shadows = {ShadowMultiDex.class}) +@Config(shadows = {ShadowMultiDex.class}) public class OperationsTest { private File storageRoot = Environment.getExternalStorageDirectory(); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java index d27f4c0c5c..39e02c25fb 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/RootHelperTest.java @@ -48,9 +48,7 @@ import eu.chainfire.libsuperuser.Shell; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowShellInteractive.class}) public class RootHelperTest { private static final File sysroot = diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java index 6764b6edb9..abe76c114f 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/cloud/CloudStreamSourceTest.java @@ -46,9 +46,7 @@ /** Created by Rustam Khadipash on 31/3/2018. */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class CloudStreamSourceTest { private CloudStreamSource cs; private String testFilePath; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java index 61db2c66dd..53f874c3ec 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/B0rkenZipTest.java @@ -47,9 +47,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class B0rkenZipTest { private File zipfile1 = new File(Environment.getExternalStorageDirectory(), "zip-slip.zip"); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java index b327165fe8..134e433f17 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/CompressedHelperTest.java @@ -57,9 +57,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class CompressedHelperTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java index 83bd264f81..b51fd6eebd 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/compressed/extractcontents/AbstractExtractorTest.java @@ -53,8 +53,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 14, - maxSdk = 28) + minSdk = 14) public abstract class AbstractExtractorTest { protected abstract Class extractorClass(); diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java index acaa725abc..57490dcab9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/files/FileListSorterTest.java @@ -42,9 +42,7 @@ * "*{slash}*" */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowDateFormat.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowDateFormat.class}) public class FileListSorterTest { /** * Purpose: when dirsOnTop is 0, if file1 is directory && file2 is not directory, result is -1 diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java index f1b51fa828..5ac87031a1 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/smbstreamer/StreamSourceTest.java @@ -47,9 +47,7 @@ /** Created by Rustam Khadipash on 30/3/2018. */ @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowSmbFile.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowSmbFile.class}) public class StreamSourceTest { private SmbFile file; private StreamSource ss; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java index ca037ea83d..5d08b196dc 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/AbstractSftpServerTest.java @@ -46,9 +46,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public abstract class AbstractSftpServerTest { protected SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java index ccff28ecaa..8db0cccff9 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/ssh/SshConnectionPoolTest.java @@ -52,9 +52,7 @@ import net.schmizz.sshj.common.SecurityUtils; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}) public class SshConnectionPoolTest { private SshServer server; diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java index 6e322aae0b..be4cd8390d 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/SingletonUsbOtgTest.java @@ -41,8 +41,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, - maxSdk = 28) + minSdk = 24) public class SingletonUsbOtgTest { @Test public void usbConnectionTest() { diff --git a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java index 958c6c6f7e..7cac7181a2 100644 --- a/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java +++ b/app/src/test/java/com/amaze/filemanager/filesystem/usb/UsbOtgTest.java @@ -45,8 +45,7 @@ @RunWith(AndroidJUnit4.class) @Config( shadows = {ShadowMultiDex.class}, - minSdk = 24, - maxSdk = 28) + minSdk = 24) public class UsbOtgTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java index 9a6271a45e..8761127eff 100644 --- a/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/test/ShadowCryptUtilTest.java @@ -40,9 +40,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class, ShadowCryptUtil.class}) public class ShadowCryptUtilTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java index 4b315dc8fb..1197dbe822 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/MainActivityTest.java @@ -21,7 +21,6 @@ package com.amaze.filemanager.ui.activities; import static android.os.Build.VERSION_CODES.N; -import static android.os.Build.VERSION_CODES.P; import static androidx.test.core.app.ActivityScenario.launch; import static org.awaitility.Awaitility.await; import static org.junit.Assert.assertEquals; @@ -64,8 +63,7 @@ ShadowStorageManager.class, ShadowCryptUtil.class, ShadowSmbFile.class - }, - maxSdk = P) + }) /* * Need to make LooperMode PAUSED and flush the main looper before activity can show up. * @see {@link LooperMode.Mode.PAUSED} @@ -131,6 +129,7 @@ public void testUpdateSmbExceptionShouldNotThrowNPE() { .get(0)[0] .equals(newName)); List verify = AppConfig.getInstance().getUtilsHandler().getSmbList(); + assertEquals(1, verify.size()); String[] entry = verify.get(0); assertEquals(path, entry[1]); diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java index e45a4a6d1f..9c1f339cd0 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/PreferencesActivityTest.java @@ -20,7 +20,6 @@ package com.amaze.filemanager.ui.activities; -import static android.os.Build.VERSION_CODES.P; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_BOOKMARKS_ADDED; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_CHANGEPATHS; import static com.amaze.filemanager.ui.fragments.preference_fragments.PreferencesConstants.PREFERENCE_COLORED_NAVIGATION; @@ -48,7 +47,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.Config; import android.content.SharedPreferences; import android.preference.PreferenceManager; @@ -59,7 +57,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = P) public class PreferencesActivityTest { private static final String[] DEFAULT_FALSE_PREFS = diff --git a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java index 8244ddbacc..fc1c1db5c6 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/activities/TextEditorActivityTest.java @@ -52,9 +52,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class TextEditorActivityTest { private final String fileContents = "fsdfsdfs"; diff --git a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java index 334a7e9599..eef3000376 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/colors/ColorUtilsTest.java @@ -21,9 +21,8 @@ package com.amaze.filemanager.ui.colors; import static android.os.Build.VERSION_CODES.N; -import static android.os.Build.VERSION_CODES.P; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.junit.runner.RunWith; @@ -41,37 +40,35 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = N, maxSdk = P) +@Config(minSdk = N) public class ColorUtilsTest { @Test public void testSetColorizeIcons() { - doTest(R.color.video_item, Icons.VIDEO); - doTest(R.color.audio_item, Icons.AUDIO); - doTest(R.color.pdf_item, Icons.PDF); - doTest(R.color.code_item, Icons.CODE); - doTest(R.color.text_item, Icons.TEXT); - doTest(R.color.archive_item, Icons.COMPRESSED); - doTest(R.color.apk_item, Icons.APK); - doTest(R.color.generic_item, Icons.NOT_KNOWN); - assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... + assertTrue(doTest(R.color.video_item, Icons.VIDEO)); + assertTrue(doTest(R.color.audio_item, Icons.AUDIO)); + assertTrue(doTest(R.color.pdf_item, Icons.PDF)); + assertTrue(doTest(R.color.code_item, Icons.CODE)); + assertTrue(doTest(R.color.text_item, Icons.TEXT)); + assertTrue(doTest(R.color.archive_item, Icons.COMPRESSED)); + assertTrue(doTest(R.color.apk_item, Icons.APK)); + assertTrue(doTest(R.color.generic_item, Icons.NOT_KNOWN)); } @Test public void testSetColorizeIconsGeneric() { - doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE); - doTestGeneric(R.color.primary_indigo, Icons.CONTACT); - doTestGeneric(R.color.primary_indigo, Icons.EVENTS); - doTestGeneric(R.color.primary_indigo, Icons.FONT); - doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION); - doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS); - doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS); - doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED); - doTestGeneric(R.color.primary_indigo, Icons.GIF); - assertNotNull(ApplicationProvider.getApplicationContext()); // idiotic codacy compliance... + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.CERTIFICATE)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.CONTACT)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.EVENTS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.FONT)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.PRESENTATION)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.SPREADSHEETS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.DOCUMENTS)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.ENCRYPTED)); + assertTrue(doTestGeneric(R.color.primary_indigo, Icons.GIF)); } - private void doTest(@ColorInt int expected, int icon) { + private boolean doTest(@ColorInt int expected, int icon) { GradientDrawable drawable = new GradientDrawable(); ColorUtils.colorizeIcons( ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); @@ -80,14 +77,16 @@ private void doTest(@ColorInt int expected, int icon) { Utils.getColor(ApplicationProvider.getApplicationContext(), expected)), drawable); drawable = null; + return true; } - private void doTestGeneric(@ColorInt int expected, int icon) { + private boolean doTestGeneric(@ColorInt int expected, int icon) { GradientDrawable drawable = new GradientDrawable(); ColorUtils.colorizeIcons( ApplicationProvider.getApplicationContext(), icon, drawable, R.color.primary_indigo); doCompare(ColorStateList.valueOf(expected), drawable); drawable = null; + return true; } private void doCompare(ColorStateList expected, GradientDrawable drawable) { diff --git a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java index ebb6a72367..69e35f03d2 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/fragments/CloudSheetFragmentTest.java @@ -36,7 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class CloudSheetFragmentTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java index 6d9d57880b..835de52ccf 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/icons/IconsTest.java @@ -36,9 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config( - shadows = {ShadowMultiDex.class}, - maxSdk = 28) +@Config(shadows = {ShadowMultiDex.class}) public class IconsTest { @Before diff --git a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java index 7b7062c4ca..cbe7c34707 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/notifications/NotificationConstantsTest.java @@ -54,7 +54,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class NotificationConstantsTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java index 082457eb4b..cbf609fafc 100644 --- a/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java +++ b/app/src/test/java/com/amaze/filemanager/ui/views/WarnableTextInputValidatorTest.java @@ -20,7 +20,6 @@ package com.amaze.filemanager.ui.views; -import static android.os.Build.VERSION_CODES.P; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -30,7 +29,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; -import org.robolectric.annotation.Config; import com.amaze.filemanager.R; @@ -44,7 +42,6 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(maxSdk = P) public class WarnableTextInputValidatorTest { private Context context; diff --git a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java index 3cc2e3315a..a5150b5406 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/AnimUtilsTest.java @@ -43,7 +43,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class AnimUtilsTest { @Test diff --git a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java index b9645cb815..eb6bb15ded 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/SmbUtilTest.java @@ -40,7 +40,6 @@ @RunWith(AndroidJUnit4.class) @Config( minSdk = 19, - maxSdk = 28, shadows = {ShadowCryptUtil.class}) public class SmbUtilTest { diff --git a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java index ae4a996513..c297ad1a02 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/TinyDBTest.java @@ -35,7 +35,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class TinyDBTest { private SharedPreferences prefs; diff --git a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java index eb21bf51e0..4a4947f4ab 100644 --- a/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java +++ b/app/src/test/java/com/amaze/filemanager/utils/UtilsTest.java @@ -53,7 +53,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; @RunWith(AndroidJUnit4.class) -@Config(minSdk = 19, maxSdk = 28) +@Config(minSdk = 19) public class UtilsTest { @Test public void diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties new file mode 100644 index 0000000000..6a520f2ee7 --- /dev/null +++ b/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +maxSdk=28 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 84c7e82200..d386348feb 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ plugins { } allprojects { + repositories { google() jcenter() @@ -56,7 +57,7 @@ configurations { robo26 robo27 robo28 -// robo29 + robo29 } dependencies { @@ -72,7 +73,7 @@ dependencies { robo26 "org.robolectric:android-all:8.0.0_r4-robolectric-r1" robo27 "org.robolectric:android-all:8.1.0-robolectric-4611349" robo28 "org.robolectric:android-all:9-robolectric-4913185-2" -// robo29 "org.robolectric:android-all:Q-robolectric-5415296" + robo29 "org.robolectric:android-all:10-robolectric-5803371" } def robolectricDependencies = "${rootProject.buildDir.path}/robolectric" @@ -90,7 +91,7 @@ task fetchRobolectricDependencies(type: Copy) { from configurations.robo26 from configurations.robo27 from configurations.robo28 -// from configurations.robo29 + from configurations.robo29 into robolectricDependencies } @@ -108,5 +109,28 @@ subprojects { it.dependsOn fetchRobolectricDependencies } } + if (project.plugins.hasPlugin("jacoco-android")){ + android { + testOptions.unitTests.all { + jacoco { + excludes = ['jdk.internal.*'] + } + } + } + } + dependencies { + compileOnly 'com.github.pengrad:jdk9-deps:1.0' + + if (project.hasProperty('kapt')) { + kapt 'javax.xml.bind:jaxb-api:2.3.1' + kapt 'com.sun.xml.bind:jaxb-core:2.3.0.1' + kapt 'com.sun.xml.bind:jaxb-impl:2.3.2' + } + + annotationProcessor 'javax.xml.bind:jaxb-api:2.3.1' + annotationProcessor 'com.sun.xml.bind:jaxb-core:2.3.0.1' + annotationProcessor 'com.sun.xml.bind:jaxb-impl:2.3.2' + } } + } \ No newline at end of file