From 28b7a2d756aa582b1603a89d674e41097b82b25e Mon Sep 17 00:00:00 2001 From: Sean Mac Gillicuddy Date: Fri, 19 Jul 2019 09:44:21 +0100 Subject: [PATCH] #1295 Make FileSearch recursive --- .../kiwixmobile/utils/files/FileSearch.kt | 20 +++++++++------ .../kiwixmobile/utils/files/FileSearchTest.kt | 25 +++++++++++++------ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileSearch.kt b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileSearch.kt index 3d5d11a0e..9c47b6ab1 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileSearch.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/utils/files/FileSearch.kt @@ -75,13 +75,19 @@ class FileSearch @Inject constructor(private val context: Context) { *StorageDeviceUtils.getStorageDevices(context, false).map { it.name }.toTypedArray() ) - private fun scanDirectory(directory: String) = filesMatchingExtensions(directory) ?: emptyList() - - private fun filesMatchingExtensions(directory: String) = File(directory) - .listFiles { _, name -> name.endsWithAny(*zimFileExtensions) } - ?.toList() + private fun scanDirectory(directory: String): List = File(directory).listFiles() + ?.fold( + mutableListOf(), { acc, file -> + acc.apply { + if (file.isDirectory) { + addAll(scanDirectory(file.path)) + } else if (file.extension.isAny(*zimFileExtensions)) { + add(file) + } + } + }) ?: emptyList() } -internal fun String.endsWithAny(vararg suffixes: String) = - suffixes.fold(false, { acc, s -> acc or endsWith(s) }) +internal fun String.isAny(vararg suffixes: String) = + suffixes.firstOrNull { endsWith(it) } != null diff --git a/app/src/test/java/org/kiwix/kiwixmobile/utils/files/FileSearchTest.kt b/app/src/test/java/org/kiwix/kiwixmobile/utils/files/FileSearchTest.kt index 3fd2f32ea..8be6924e1 100644 --- a/app/src/test/java/org/kiwix/kiwixmobile/utils/files/FileSearchTest.kt +++ b/app/src/test/java/org/kiwix/kiwixmobile/utils/files/FileSearchTest.kt @@ -48,7 +48,6 @@ class FileSearchTest { private val contentResolver: ContentResolver = mockk() private val storageDevice: StorageDevice = mockk() - private val unitTestTempDirectoryPath = "unittest${File.separator}" init { setScheduler(Schedulers.trampoline()) @@ -89,15 +88,27 @@ class FileSearchTest { @Test fun `scan of directory that has files returns files`() { - val zimFile = File.createTempFile("${unitTestTempDirectoryPath}fileToFind", ".zim") - val zimaaFile = File.createTempFile("${unitTestTempDirectoryPath}fileToFind2", ".zimaa") - File.createTempFile("${unitTestTempDirectoryPath}willNotFind", ".txt") + val zimFile = File.createTempFile("fileToFind", ".zim") + val zimaaFile = File.createTempFile("fileToFind2", ".zimaa") + File.createTempFile("willNotFind", ".txt") every { contentResolver.query(any(), any(), any(), any(), any()) } returns null val fileList = fileSearch.scan(zimFile.parent) .test() .values()[0] assertThat(fileList).containsExactlyInAnyOrder(zimFile, zimaaFile) } + + @Test + fun `scan of directory recursively traverses filesystem`() { + val tempRoot = File.createTempFile("tofindroot", "extension") + .parentFile.absolutePath + val zimFile = File.createTempFile("fileToFind", ".zim", File("${tempRoot}${File.separator}dir").apply { mkdirs() }) + every { contentResolver.query(any(), any(), any(), any(), any()) } returns null + val fileList = fileSearch.scan(zimFile.parentFile.parent) + .test() + .values()[0] + assertThat(fileList).containsExactlyInAnyOrder(zimFile) + } } @Nested @@ -105,7 +116,7 @@ class FileSearchTest { @Test fun `scan media store, if files are readable they are returned`() { - val fileToFind = File.createTempFile("${unitTestTempDirectoryPath}fileToFind", ".zim") + val fileToFind = File.createTempFile("fileToFind", ".zim") expectFromMediaStore(fileToFind) fileSearch.scan("") .test() @@ -114,7 +125,7 @@ class FileSearchTest { @Test fun `scan media store, if files are not readable they are not returned`() { - val unreadableFile = File.createTempFile("${unitTestTempDirectoryPath}fileToFind", ".zim") + val unreadableFile = File.createTempFile("fileToFind", ".zim") expectFromMediaStore(unreadableFile) unreadableFile.delete() fileSearch.scan("") @@ -141,7 +152,7 @@ class FileSearchTest { } private fun deleteTempDirectory() { - File.createTempFile("${unitTestTempDirectoryPath}temp", ".txt") + File.createTempFile("temp", ".txt") .parentFile.deleteRecursively() } }