From f78a7fa630b7be39c0508e36faa912d1557c85df Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 11:22:25 +0100 Subject: [PATCH 01/10] Extract import database logic in ContentSettingsManager --- .../settings/ContentSettingsFragment.java | 52 ++--------- .../settings/ContentSettingsManager.kt | 92 ++++++++++++++++++- 2 files changed, 95 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index d7766f7b0..1d9b8e102 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -224,33 +224,24 @@ public class ContentSettingsFragment extends BasePreferenceFragment { private void importDatabase(final String filePath) { // check if file is supported - try (ZipFile zipFile = new ZipFile(filePath)) { - } catch (final IOException ioe) { + if (!manager.isValidZipFile(filePath)) { Toast.makeText(getContext(), R.string.no_valid_zip_file, Toast.LENGTH_SHORT) - .show(); + .show(); return; } try { - if (!databasesDir.exists() && !databasesDir.mkdir()) { + if (!manager.ensureDbDirectoryExists()) { throw new Exception("Could not create databases dir"); } - final boolean isDbFileExtracted = ZipHelper.extractFileFromZip(filePath, - newpipeDb.getPath(), "newpipe.db"); - - if (isDbFileExtracted) { - newpipeDbJournal.delete(); - newpipeDbWal.delete(); - newpipeDbShm.delete(); - } else { + if (!manager.extractDb(filePath)) { Toast.makeText(getContext(), R.string.could_not_import_all_files, Toast.LENGTH_LONG) - .show(); + .show(); } //If settings file exist, ask if it should be imported. - if (ZipHelper.extractFileFromZip(filePath, newpipeSettings.getPath(), - "newpipe.settings")) { + if (manager.containSettings(filePath)) { final AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); alert.setTitle(R.string.import_settings); @@ -261,7 +252,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment { }); alert.setPositiveButton(getString(R.string.finish), (dialog, which) -> { dialog.dismiss(); - loadSharedPreferences(newpipeSettings); + manager.loadSharedPreferences(PreferenceManager + .getDefaultSharedPreferences(requireContext())); // restart app to properly load db System.exit(0); }); @@ -275,34 +267,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { } } - private void loadSharedPreferences(final File src) { - try (ObjectInputStream input = new ObjectInputStream(new FileInputStream(src))) { - final SharedPreferences.Editor prefEdit = PreferenceManager - .getDefaultSharedPreferences(requireContext()).edit(); - prefEdit.clear(); - final Map entries = (Map) input.readObject(); - for (final Map.Entry entry : entries.entrySet()) { - final Object v = entry.getValue(); - final String key = entry.getKey(); - - if (v instanceof Boolean) { - prefEdit.putBoolean(key, (Boolean) v); - } else if (v instanceof Float) { - prefEdit.putFloat(key, (Float) v); - } else if (v instanceof Integer) { - prefEdit.putInt(key, (Integer) v); - } else if (v instanceof Long) { - prefEdit.putLong(key, (Long) v); - } else if (v instanceof String) { - prefEdit.putString(key, (String) v); - } - } - prefEdit.commit(); - } catch (final IOException | ClassNotFoundException e) { - e.printStackTrace(); - } - } - /*////////////////////////////////////////////////////////////////////////// // Error //////////////////////////////////////////////////////////////////////////*/ diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 2682ac5e0..2a2c4df20 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -1,23 +1,34 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences +import androidx.preference.PreferenceManager import org.schabi.newpipe.util.ZipHelper import java.io.BufferedOutputStream import java.io.File +import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException +import java.io.ObjectInputStream import java.io.ObjectOutputStream -import java.lang.Exception +import java.util.zip.ZipFile import java.util.zip.ZipOutputStream class ContentSettingsManager( - private val newpipeDb: File, - private val newpipeSettings: File + private val databasesDir: File, + private val newpipeDb: File, + private val newpipeDbJournal: File, + private var newpipeDbShm: File, + private val newpipeDbWal: File, + private val newpipeSettings: File, ) { constructor(homeDir: File) : this( - File(homeDir, "databases/newpipe.db"), - File(homeDir, "databases/newpipe.settings") + File(homeDir, "/databases"), + File(homeDir, "/databases/newpipe.db"), + File(homeDir, "/databases/newpipe.db-journal"), + File(homeDir, "/databases/newpipe.db-shm"), + File(homeDir, "/databases/newpipe.db-wal"), + File(homeDir, "/databases/newpipe.settings") ) /** @@ -42,4 +53,75 @@ class ContentSettingsManager( ZipHelper.addFileToZip(outZip, newpipeSettings.path, "newpipe.settings") } } + + fun isValidZipFile(filePath: String): Boolean { + try { + ZipFile(filePath).use { + return@isValidZipFile true + } + } catch (ioe: IOException) { + return false + } + } + + /** + * Tries to create database directory if it does not exist. + * + * @return Whether the directory exists afterwards. + */ + fun ensureDbDirectoryExists(): Boolean { + return !databasesDir.exists() && !databasesDir.mkdir() + } + + fun extractDb(filePath: String): Boolean { + val success = ZipHelper.extractFileFromZip(filePath, newpipeDb.path, "newpipe.db") + if (success) { + newpipeDbJournal.delete() + newpipeDbWal.delete() + newpipeDbShm.delete() + } + + return success + } + + fun containSettings(filePath: String): Boolean { + return ZipHelper + .extractFileFromZip(filePath, newpipeSettings.path, "newpipe.settings") + } + + fun loadSharedPreferences(preferences: SharedPreferences) { + try { + val preferenceEditor = preferences.edit() + + ObjectInputStream(FileInputStream(newpipeSettings)).use { input -> + preferenceEditor.clear() + val entries = input.readObject() as Map + for ((key, value) in entries) { + when (value) { + is Boolean -> { + preferenceEditor.putBoolean(key, value) + } + is Float -> { + preferenceEditor.putFloat(key, value) + } + is Int -> { + preferenceEditor.putInt(key, value) + } + is Long -> { + preferenceEditor.putLong(key, value) + } + is String -> { + preferenceEditor.putString(key, value) + } + } + } + preferenceEditor.commit() + } + } catch (e: IOException) { + e.printStackTrace() + } catch (e: ClassNotFoundException) { + e.printStackTrace() + } + } + } From cef791ba1baa639476ebc00a8060d5f4ac1c07a1 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 14:02:34 +0100 Subject: [PATCH 02/10] Introduce NewPipeFileLocator class It handles locating specific NewPipe files based on the home directory of the app. --- .../settings/ContentSettingsFragment.java | 2 +- .../settings/ContentSettingsManager.kt | 68 ++++++++----------- .../newpipe/settings/NewPipeFileLocator.kt | 22 ++++++ 3 files changed, 51 insertions(+), 41 deletions(-) create mode 100644 app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 1d9b8e102..f783df85e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -129,7 +129,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { newpipeSettings = new File(homeDir, "/databases/newpipe.settings"); newpipeSettings.delete(); - manager = new ContentSettingsManager(homeDir); + manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); addPreferencesFromResource(R.xml.content_settings); diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 2a2c4df20..5e92f59bf 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -1,10 +1,8 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences -import androidx.preference.PreferenceManager import org.schabi.newpipe.util.ZipHelper import java.io.BufferedOutputStream -import java.io.File import java.io.FileInputStream import java.io.FileOutputStream import java.io.IOException @@ -13,23 +11,7 @@ import java.io.ObjectOutputStream import java.util.zip.ZipFile import java.util.zip.ZipOutputStream -class ContentSettingsManager( - private val databasesDir: File, - private val newpipeDb: File, - private val newpipeDbJournal: File, - private var newpipeDbShm: File, - private val newpipeDbWal: File, - private val newpipeSettings: File, -) { - - constructor(homeDir: File) : this( - File(homeDir, "/databases"), - File(homeDir, "/databases/newpipe.db"), - File(homeDir, "/databases/newpipe.db-journal"), - File(homeDir, "/databases/newpipe.db-shm"), - File(homeDir, "/databases/newpipe.db-wal"), - File(homeDir, "/databases/newpipe.settings") - ) +class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { /** * Exports given [SharedPreferences] to the file in given outputPath. @@ -38,19 +20,19 @@ class ContentSettingsManager( @Throws(Exception::class) fun exportDatabase(preferences: SharedPreferences, outputPath: String) { ZipOutputStream(BufferedOutputStream(FileOutputStream(outputPath))) - .use { outZip -> - ZipHelper.addFileToZip(outZip, newpipeDb.path, "newpipe.db") + .use { outZip -> + ZipHelper.addFileToZip(outZip, fileLocator.dbDir.path, "newpipe.db") - try { - ObjectOutputStream(FileOutputStream(newpipeSettings)).use { output -> - output.writeObject(preferences.all) - output.flush() + try { + ObjectOutputStream(FileOutputStream(fileLocator.settings)).use { output -> + output.writeObject(preferences.all) + output.flush() + } + } catch (e: IOException) { + e.printStackTrace() } - } catch (e: IOException) { - e.printStackTrace() - } - ZipHelper.addFileToZip(outZip, newpipeSettings.path, "newpipe.settings") + ZipHelper.addFileToZip(outZip, fileLocator.settings.path, "newpipe.settings") } } @@ -70,30 +52,37 @@ class ContentSettingsManager( * @return Whether the directory exists afterwards. */ fun ensureDbDirectoryExists(): Boolean { - return !databasesDir.exists() && !databasesDir.mkdir() + return !fileLocator.dbDir.exists() && !fileLocator.dbDir.mkdir() } - fun extractDb(filePath: String): Boolean { - val success = ZipHelper.extractFileFromZip(filePath, newpipeDb.path, "newpipe.db") + + fun extractDb( + filePath: String, + ): Boolean { + val success = ZipHelper.extractFileFromZip(filePath, fileLocator.db.path, "newpipe.db") if (success) { - newpipeDbJournal.delete() - newpipeDbWal.delete() - newpipeDbShm.delete() + fileLocator.dbJournal.delete() + fileLocator.dbWal.delete() + fileLocator.dbShm.delete() } return success } - fun containSettings(filePath: String): Boolean { + fun containSettings( + filePath: String, + ): Boolean { return ZipHelper - .extractFileFromZip(filePath, newpipeSettings.path, "newpipe.settings") + .extractFileFromZip(filePath, fileLocator.settings.path, "newpipe.settings") } - fun loadSharedPreferences(preferences: SharedPreferences) { + fun loadSharedPreferences( + preferences: SharedPreferences, + ) { try { val preferenceEditor = preferences.edit() - ObjectInputStream(FileInputStream(newpipeSettings)).use { input -> + ObjectInputStream(FileInputStream(fileLocator.settings)).use { input -> preferenceEditor.clear() val entries = input.readObject() as Map for ((key, value) in entries) { @@ -123,5 +112,4 @@ class ContentSettingsManager( e.printStackTrace() } } - } diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt b/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt new file mode 100644 index 000000000..1fe2fffa0 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt @@ -0,0 +1,22 @@ +package org.schabi.newpipe.settings + +import java.io.File + +/** + * Locates specific files of NewPipe based on the home directory of the app. + */ +class NewPipeFileLocator(private val homeDir: File) { + + val dbDir by lazy { File(homeDir, "/databases") } + + val db by lazy { File(homeDir, "/databases/newpipe.db") } + + val dbJournal by lazy { File(homeDir, "/databases/newpipe.db-journal") } + + val dbShm by lazy { File(homeDir, "/databases/newpipe.db-shm") } + + val dbWal by lazy { File(homeDir, "/databases/newpipe.db-wal") } + + val settings by lazy { File(homeDir, "/databases/newpipe.settings") } + +} From ea91a62c89e70fc392c811af5dbcea34a9064035 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 14:10:10 +0100 Subject: [PATCH 03/10] Adjust ExportTest to new DI with FileLocator --- app/build.gradle | 4 +++- .../org/schabi/newpipe/settings/ContentSettingsManager.kt | 2 +- .../schabi/newpipe/settings/ContentSettingsManagerTest.kt | 8 +++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9fb9cf85f..b3c6f6bad 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,6 +102,7 @@ ext { groupieVersion = '2.8.1' markwonVersion = '4.6.0' googleAutoServiceVersion = '1.0-rc7' + mockitoVersion = '3.6.0' } configurations { @@ -235,7 +236,8 @@ dependencies { implementation "org.ocpsoft.prettytime:prettytime:4.0.6.Final" testImplementation 'junit:junit:4.13.1' - testImplementation 'org.mockito:mockito-core:3.6.0' + testImplementation "org.mockito:mockito-core:${mockitoVersion}" + testImplementation "org.mockito:mockito-inline:${mockitoVersion}" androidTestImplementation "androidx.test.ext:junit:1.1.2" androidTestImplementation "androidx.room:room-testing:${androidxRoomVersion}" diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 5e92f59bf..f278c6b24 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -21,7 +21,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { fun exportDatabase(preferences: SharedPreferences, outputPath: String) { ZipOutputStream(BufferedOutputStream(FileOutputStream(outputPath))) .use { outZip -> - ZipHelper.addFileToZip(outZip, fileLocator.dbDir.path, "newpipe.db") + ZipHelper.addFileToZip(outZip, fileLocator.db.path, "newpipe.db") try { ObjectOutputStream(FileOutputStream(fileLocator.settings)).use { output -> diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index 5ac132f7f..67895fc7c 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -1,6 +1,7 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences +import com.nononsenseapps.filepicker.NewFolderFragment import org.junit.Assert import org.junit.Assume import org.junit.Before @@ -24,6 +25,7 @@ class ContentSettingsManagerTest { class ExportTest { companion object { + private lateinit var fileLocator: NewPipeFileLocator private lateinit var newpipeDb: File private lateinit var newpipeSettings: File @@ -37,6 +39,10 @@ class ContentSettingsManagerTest { newpipeDb = File(dbPath!!) newpipeSettings = File(settingsPath!!) + + fileLocator = Mockito.mock(NewPipeFileLocator::class.java, Mockito.withSettings().stubOnly()) + `when`(fileLocator.db).thenReturn(newpipeDb) + `when`(fileLocator.settings).thenReturn(newpipeSettings) } } @@ -52,7 +58,7 @@ class ContentSettingsManagerTest { val expectedPreferences = mapOf("such pref" to "much wow") `when`(preferences.all).thenReturn(expectedPreferences) - val manager = ContentSettingsManager(newpipeDb, newpipeSettings) + val manager = ContentSettingsManager(fileLocator) val output = File.createTempFile("newpipe_", "") manager.exportDatabase(preferences, output.absolutePath) From 19cd3a17df4f3b17b72604c5887f3aea7ab3fbb2 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 14:14:48 +0100 Subject: [PATCH 04/10] Move isValidZipFile to ZipHelper --- .../newpipe/settings/ContentSettingsFragment.java | 2 +- .../schabi/newpipe/settings/ContentSettingsManager.kt | 10 ---------- .../main/java/org/schabi/newpipe/util/ZipHelper.java | 10 ++++++++++ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index f783df85e..2339de53a 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -224,7 +224,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { private void importDatabase(final String filePath) { // check if file is supported - if (!manager.isValidZipFile(filePath)) { + if (!ZipHelper.isValidZipFile(filePath)) { Toast.makeText(getContext(), R.string.no_valid_zip_file, Toast.LENGTH_SHORT) .show(); return; diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index f278c6b24..3ab3dc8f3 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -36,16 +36,6 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { } } - fun isValidZipFile(filePath: String): Boolean { - try { - ZipFile(filePath).use { - return@isValidZipFile true - } - } catch (ioe: IOException) { - return false - } - } - /** * Tries to create database directory if it does not exist. * diff --git a/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java b/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java index f9a950d2b..e2b766bb0 100644 --- a/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java +++ b/app/src/main/java/org/schabi/newpipe/util/ZipHelper.java @@ -4,7 +4,9 @@ import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.IOException; import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -99,4 +101,12 @@ public final class ZipHelper { return found; } } + + public static boolean isValidZipFile(final String filePath) { + try (ZipFile ignored = new ZipFile(filePath)) { + return true; + } catch (final IOException ioe) { + return false; + } + } } From f778c4892359ba5bcb3b411637a530713066267f Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 15:15:38 +0100 Subject: [PATCH 05/10] Add basic tests for settings import --- .../settings/ContentSettingsManagerTest.kt | 110 +++++++++++++++++- app/src/test/resources/settings/empty.zip | Bin 0 -> 22 bytes app/src/test/resources/settings/newpipe.zip | Bin 0 -> 8317 bytes 3 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 app/src/test/resources/settings/empty.zip create mode 100644 app/src/test/resources/settings/newpipe.zip diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index 67895fc7c..111fd7c09 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -1,8 +1,10 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences -import com.nononsenseapps.filepicker.NewFolderFragment import org.junit.Assert +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue import org.junit.Assume import org.junit.Before import org.junit.BeforeClass @@ -11,10 +13,16 @@ import org.junit.runner.RunWith import org.junit.runners.Suite import org.mockito.Mockito import org.mockito.Mockito.`when` +import org.mockito.Mockito.anyString +import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.atLeastOnce +import org.mockito.Mockito.verify +import org.mockito.Mockito.withSettings import org.mockito.junit.MockitoJUnitRunner import org.schabi.newpipe.settings.ContentSettingsManagerTest.ExportTest import java.io.File import java.io.ObjectInputStream +import java.nio.file.Files import java.util.zip.ZipFile @RunWith(Suite::class) @@ -40,7 +48,7 @@ class ContentSettingsManagerTest { newpipeDb = File(dbPath!!) newpipeSettings = File(settingsPath!!) - fileLocator = Mockito.mock(NewPipeFileLocator::class.java, Mockito.withSettings().stubOnly()) + fileLocator = Mockito.mock(NewPipeFileLocator::class.java, withSettings().stubOnly()) `when`(fileLocator.db).thenReturn(newpipeDb) `when`(fileLocator.settings).thenReturn(newpipeSettings) } @@ -50,7 +58,7 @@ class ContentSettingsManagerTest { @Before fun setupMocks() { - preferences = Mockito.mock(SharedPreferences::class.java, Mockito.withSettings().stubOnly()) + preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) } @Test @@ -79,4 +87,100 @@ class ContentSettingsManagerTest { } } } + + @RunWith(MockitoJUnitRunner::class) + class ImportTest { + companion object { + private lateinit var fileLocator: NewPipeFileLocator + private lateinit var zip: File + private lateinit var emptyZip: File + private lateinit var db: File + private lateinit var dbJournal: File + private lateinit var dbWal: File + private lateinit var dbShm: File + private lateinit var settings: File + + @JvmStatic + @BeforeClass + fun setupReadOnlyFiles() { + val zipPath = ImportTest::class.java.classLoader?.getResource("settings/newpipe.zip")?.file + val emptyZipPath = ImportTest::class.java.classLoader?.getResource("settings/empty.zip")?.file + Assume.assumeNotNull(zipPath) + Assume.assumeNotNull(emptyZipPath) + + zip = File(zipPath!!) + emptyZip = File(emptyZipPath!!) + } + } + + @Before + fun setupWriteFiles() { + db = File.createTempFile("newpipe_", "") + dbJournal = File.createTempFile("newpipe_", "") + dbWal = File.createTempFile("newpipe_", "") + dbShm = File.createTempFile("newpipe_", "") + settings = File.createTempFile("newpipe_", "") + + fileLocator = Mockito.mock(NewPipeFileLocator::class.java, withSettings().stubOnly()) + `when`(fileLocator.db).thenReturn(db) + `when`(fileLocator.dbJournal).thenReturn(dbJournal) + `when`(fileLocator.dbShm).thenReturn(dbShm) + `when`(fileLocator.dbWal).thenReturn(dbWal) + `when`(fileLocator.settings).thenReturn(settings) + } + + @Test + fun `The database must be extracted from the zip file`() { + val success = ContentSettingsManager(fileLocator).extractDb(zip.path) + + assertTrue(success) + assertFalse(dbJournal.exists()) + assertFalse(dbWal.exists()) + assertFalse(dbShm.exists()) + assertTrue("database file size is zero", Files.size(db.toPath()) > 0) + } + + @Test + fun `Extracting the database from an empty zip must not work`() { + val success = ContentSettingsManager(fileLocator).extractDb(emptyZip.path) + + assertFalse(success) + assertTrue(dbJournal.exists()) + assertTrue(dbWal.exists()) + assertTrue(dbShm.exists()) + assertEquals(0, Files.size(db.toPath())) + } + + @Test + fun `Contain setting must return true, if a settings file exists in the zip`() { + val contains = ContentSettingsManager(fileLocator).containSettings(zip.path) + + assertTrue(contains) + } + + @Test + fun `Contain setting must return false, if a no settings file exists in the zip`() { + val contains = ContentSettingsManager(fileLocator).containSettings(emptyZip.path) + + assertFalse(contains) + } + + @Test + fun `Preferences must be set from the settings file`() { + val preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) + val editor = Mockito.mock(SharedPreferences.Editor::class.java) + `when`(preferences.edit()).thenReturn(editor) + + + val manager = ContentSettingsManager(fileLocator) + manager.containSettings(zip.path) + manager.loadSharedPreferences(preferences) + + verify(editor, atLeastOnce()).putBoolean(anyString(), anyBoolean()) + } + + + } + + } diff --git a/app/src/test/resources/settings/empty.zip b/app/src/test/resources/settings/empty.zip new file mode 100644 index 0000000000000000000000000000000000000000..15cb0ecb3e219d1701294bfdf0fe3f5cb5d208e7 GIT binary patch literal 22 NcmWIWW@Tf*000g10H*)| literal 0 HcmV?d00001 diff --git a/app/src/test/resources/settings/newpipe.zip b/app/src/test/resources/settings/newpipe.zip new file mode 100644 index 0000000000000000000000000000000000000000..1ce8431feb3d4f2b14e770ac7f8a3b7efac07436 GIT binary patch literal 8317 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 literal 0 HcmV?d00001 From 8fceffd6fd0afd882ff8ae27a00b53c899b2b11b Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 15:16:22 +0100 Subject: [PATCH 06/10] Introduce NewPipeFileLocator class --- .../newpipe/settings/ContentSettingsManager.kt | 12 +++--------- .../newpipe/settings/ContentSettingsManagerTest.kt | 11 ++++++----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 3ab3dc8f3..0e779edbf 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -46,9 +46,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { } - fun extractDb( - filePath: String, - ): Boolean { + fun extractDb(filePath: String): Boolean { val success = ZipHelper.extractFileFromZip(filePath, fileLocator.db.path, "newpipe.db") if (success) { fileLocator.dbJournal.delete() @@ -59,16 +57,12 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { return success } - fun containSettings( - filePath: String, - ): Boolean { + fun containSettings(filePath: String): Boolean { return ZipHelper .extractFileFromZip(filePath, fileLocator.settings.path, "newpipe.settings") } - fun loadSharedPreferences( - preferences: SharedPreferences, - ) { + fun loadSharedPreferences(preferences: SharedPreferences) { try { val preferenceEditor = preferences.edit() diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index 111fd7c09..e139dad7b 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -19,14 +19,14 @@ import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.verify import org.mockito.Mockito.withSettings import org.mockito.junit.MockitoJUnitRunner -import org.schabi.newpipe.settings.ContentSettingsManagerTest.ExportTest +import org.schabi.newpipe.settings.ContentSettingsManagerTest.* import java.io.File import java.io.ObjectInputStream import java.nio.file.Files import java.util.zip.ZipFile @RunWith(Suite::class) -@Suite.SuiteClasses(ExportTest::class) +@Suite.SuiteClasses(ExportTest::class, ImportTest::class) class ContentSettingsManagerTest { @RunWith(MockitoJUnitRunner::class) @@ -73,23 +73,24 @@ class ContentSettingsManagerTest { val zipFile = ZipFile(output.absoluteFile) val entries = zipFile.entries().toList() - Assert.assertEquals(2, entries.size) + assertEquals(2, entries.size) zipFile.getInputStream(entries.first { it.name == "newpipe.db" }).use { actual -> newpipeDb.inputStream().use { expected -> - Assert.assertEquals(expected.reader().readText(), actual.reader().readText()) + assertEquals(expected.reader().readText(), actual.reader().readText()) } } zipFile.getInputStream(entries.first { it.name == "newpipe.settings" }).use { actual -> val actualPreferences = ObjectInputStream(actual).readObject() - Assert.assertEquals(expectedPreferences, actualPreferences) + assertEquals(expectedPreferences, actualPreferences) } } } @RunWith(MockitoJUnitRunner::class) class ImportTest { + companion object { private lateinit var fileLocator: NewPipeFileLocator private lateinit var zip: File From 122e80fae9afc2e5bc75aa3cd73af027391358d0 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:28:10 +0100 Subject: [PATCH 07/10] Remove subclasses from ContentSettingsManagerTest ExportTest provides no value. ImportTest creates temporary files even if not needed. --- .../settings/ContentSettingsFragment.java | 7 +- .../settings/ContentSettingsManager.kt | 2 +- .../settings/ContentSettingsManagerTest.kt | 251 ++++++++---------- .../test/resources/settings/newpipe.settings | Bin 0 -> 2445 bytes 4 files changed, 106 insertions(+), 154 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 2339de53a..18d49b507 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -32,14 +32,9 @@ import org.schabi.newpipe.util.FilePickerActivityHelper; import org.schabi.newpipe.util.ZipHelper; import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.ObjectInputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; -import java.util.Map; -import java.util.zip.ZipFile; import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage; @@ -241,7 +236,7 @@ public class ContentSettingsFragment extends BasePreferenceFragment { } //If settings file exist, ask if it should be imported. - if (manager.containSettings(filePath)) { + if (manager.extractSettings(filePath)) { final AlertDialog.Builder alert = new AlertDialog.Builder(getContext()); alert.setTitle(R.string.import_settings); diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 0e779edbf..bab29a30a 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -57,7 +57,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { return success } - fun containSettings(filePath: String): Boolean { + fun extractSettings(filePath: String): Boolean { return ZipHelper .extractFileFromZip(filePath, fileLocator.settings.path, "newpipe.settings") } diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index e139dad7b..875ef758a 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -1,187 +1,144 @@ package org.schabi.newpipe.settings import android.content.SharedPreferences -import org.junit.Assert import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue -import org.junit.Assume import org.junit.Before -import org.junit.BeforeClass import org.junit.Test import org.junit.runner.RunWith -import org.junit.runners.Suite import org.mockito.Mockito import org.mockito.Mockito.`when` import org.mockito.Mockito.anyString import org.mockito.Mockito.anyBoolean +import org.mockito.Mockito.anyInt import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.verify import org.mockito.Mockito.withSettings import org.mockito.junit.MockitoJUnitRunner -import org.schabi.newpipe.settings.ContentSettingsManagerTest.* import java.io.File import java.io.ObjectInputStream import java.nio.file.Files import java.util.zip.ZipFile -@RunWith(Suite::class) -@Suite.SuiteClasses(ExportTest::class, ImportTest::class) +@RunWith(MockitoJUnitRunner::class) class ContentSettingsManagerTest { - @RunWith(MockitoJUnitRunner::class) - class ExportTest { + companion object { + private val classloader = ContentSettingsManager::class.java.classLoader!! + } - companion object { - private lateinit var fileLocator: NewPipeFileLocator - private lateinit var newpipeDb: File - private lateinit var newpipeSettings: File + private lateinit var fileLocator: NewPipeFileLocator - @JvmStatic - @BeforeClass - fun setupFiles() { - val dbPath = ExportTest::class.java.classLoader?.getResource("settings/newpipe.db")?.file - val settingsPath = ExportTest::class.java.classLoader?.getResource("settings/newpipe.settings")?.path - Assume.assumeNotNull(dbPath) - Assume.assumeNotNull(settingsPath) + @Before + fun setupFileLocator() { + fileLocator = Mockito.mock(NewPipeFileLocator::class.java, withSettings().stubOnly()) + } - newpipeDb = File(dbPath!!) - newpipeSettings = File(settingsPath!!) + @Test + fun `The settings must be exported successfully in the correct format`() { + val db = File(classloader.getResource("settings/newpipe.db")!!.file) + val newpipeSettings = File.createTempFile("newpipe_", "") + `when`(fileLocator.db).thenReturn(db) + `when`(fileLocator.settings).thenReturn(newpipeSettings) - fileLocator = Mockito.mock(NewPipeFileLocator::class.java, withSettings().stubOnly()) - `when`(fileLocator.db).thenReturn(newpipeDb) - `when`(fileLocator.settings).thenReturn(newpipeSettings) + val expectedPreferences = mapOf("such pref" to "much wow") + val sharedPreferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) + `when`(sharedPreferences.all).thenReturn(expectedPreferences) + + val output = File.createTempFile("newpipe_", "") + ContentSettingsManager(fileLocator).exportDatabase(sharedPreferences, output.absolutePath) + + val zipFile = ZipFile(output) + val entries = zipFile.entries().toList() + assertEquals(2, entries.size) + + zipFile.getInputStream(entries.first { it.name == "newpipe.db" }).use { actual -> + db.inputStream().use { expected -> + assertEquals(expected.reader().readText(), actual.reader().readText()) } } - private lateinit var preferences: SharedPreferences - - @Before - fun setupMocks() { - preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) - } - - @Test - fun `The settings must be exported successfully in the correct format`() { - val expectedPreferences = mapOf("such pref" to "much wow") - `when`(preferences.all).thenReturn(expectedPreferences) - - val manager = ContentSettingsManager(fileLocator) - - val output = File.createTempFile("newpipe_", "") - manager.exportDatabase(preferences, output.absolutePath) - - val zipFile = ZipFile(output.absoluteFile) - val entries = zipFile.entries().toList() - assertEquals(2, entries.size) - - zipFile.getInputStream(entries.first { it.name == "newpipe.db" }).use { actual -> - newpipeDb.inputStream().use { expected -> - assertEquals(expected.reader().readText(), actual.reader().readText()) - } - } - - zipFile.getInputStream(entries.first { it.name == "newpipe.settings" }).use { actual -> - val actualPreferences = ObjectInputStream(actual).readObject() - assertEquals(expectedPreferences, actualPreferences) - } + zipFile.getInputStream(entries.first { it.name == "newpipe.settings" }).use { actual -> + val actualPreferences = ObjectInputStream(actual).readObject() + assertEquals(expectedPreferences, actualPreferences) } } - @RunWith(MockitoJUnitRunner::class) - class ImportTest { - - companion object { - private lateinit var fileLocator: NewPipeFileLocator - private lateinit var zip: File - private lateinit var emptyZip: File - private lateinit var db: File - private lateinit var dbJournal: File - private lateinit var dbWal: File - private lateinit var dbShm: File - private lateinit var settings: File - - @JvmStatic - @BeforeClass - fun setupReadOnlyFiles() { - val zipPath = ImportTest::class.java.classLoader?.getResource("settings/newpipe.zip")?.file - val emptyZipPath = ImportTest::class.java.classLoader?.getResource("settings/empty.zip")?.file - Assume.assumeNotNull(zipPath) - Assume.assumeNotNull(emptyZipPath) - - zip = File(zipPath!!) - emptyZip = File(emptyZipPath!!) - } - } - - @Before - fun setupWriteFiles() { - db = File.createTempFile("newpipe_", "") - dbJournal = File.createTempFile("newpipe_", "") - dbWal = File.createTempFile("newpipe_", "") - dbShm = File.createTempFile("newpipe_", "") - settings = File.createTempFile("newpipe_", "") - - fileLocator = Mockito.mock(NewPipeFileLocator::class.java, withSettings().stubOnly()) - `when`(fileLocator.db).thenReturn(db) - `when`(fileLocator.dbJournal).thenReturn(dbJournal) - `when`(fileLocator.dbShm).thenReturn(dbShm) - `when`(fileLocator.dbWal).thenReturn(dbWal) - `when`(fileLocator.settings).thenReturn(settings) - } - - @Test - fun `The database must be extracted from the zip file`() { - val success = ContentSettingsManager(fileLocator).extractDb(zip.path) - - assertTrue(success) - assertFalse(dbJournal.exists()) - assertFalse(dbWal.exists()) - assertFalse(dbShm.exists()) - assertTrue("database file size is zero", Files.size(db.toPath()) > 0) - } - - @Test - fun `Extracting the database from an empty zip must not work`() { - val success = ContentSettingsManager(fileLocator).extractDb(emptyZip.path) - - assertFalse(success) - assertTrue(dbJournal.exists()) - assertTrue(dbWal.exists()) - assertTrue(dbShm.exists()) - assertEquals(0, Files.size(db.toPath())) - } - - @Test - fun `Contain setting must return true, if a settings file exists in the zip`() { - val contains = ContentSettingsManager(fileLocator).containSettings(zip.path) - - assertTrue(contains) - } - - @Test - fun `Contain setting must return false, if a no settings file exists in the zip`() { - val contains = ContentSettingsManager(fileLocator).containSettings(emptyZip.path) - - assertFalse(contains) - } - - @Test - fun `Preferences must be set from the settings file`() { - val preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) - val editor = Mockito.mock(SharedPreferences.Editor::class.java) - `when`(preferences.edit()).thenReturn(editor) - - - val manager = ContentSettingsManager(fileLocator) - manager.containSettings(zip.path) - manager.loadSharedPreferences(preferences) - - verify(editor, atLeastOnce()).putBoolean(anyString(), anyBoolean()) - } + @Test + fun `The database must be extracted from the zip file`() { + val db = File.createTempFile("newpipe_", "") + val dbJournal = File.createTempFile("newpipe_", "") + val dbWal = File.createTempFile("newpipe_", "") + val dbShm = File.createTempFile("newpipe_", "") + `when`(fileLocator.db).thenReturn(db) + `when`(fileLocator.dbJournal).thenReturn(dbJournal) + `when`(fileLocator.dbShm).thenReturn(dbShm) + `when`(fileLocator.dbWal).thenReturn(dbWal) + val zip = File(classloader.getResource("settings/newpipe.zip")?.file!!) + val success = ContentSettingsManager(fileLocator).extractDb(zip.path) + assertTrue(success) + assertFalse(dbJournal.exists()) + assertFalse(dbWal.exists()) + assertFalse(dbShm.exists()) + assertTrue("database file size is zero", Files.size(db.toPath()) > 0) } + @Test + fun `Extracting the database from an empty zip must not work`() { + val db = File.createTempFile("newpipe_", "") + val dbJournal = File.createTempFile("newpipe_", "") + val dbWal = File.createTempFile("newpipe_", "") + val dbShm = File.createTempFile("newpipe_", "") + `when`(fileLocator.db).thenReturn(db) + val emptyZip = File(classloader.getResource("settings/empty.zip")?.file!!) + val success = ContentSettingsManager(fileLocator).extractDb(emptyZip.path) + + assertFalse(success) + assertTrue(dbJournal.exists()) + assertTrue(dbWal.exists()) + assertTrue(dbShm.exists()) + assertEquals(0, Files.size(db.toPath())) + } + + @Test + fun `Contains setting must return true if a settings file exists in the zip`() { + val settings = File.createTempFile("newpipe_", "") + `when`(fileLocator.settings).thenReturn(settings) + + val zip = File(classloader.getResource("settings/newpipe.zip")?.file!!) + val contains = ContentSettingsManager(fileLocator).extractSettings(zip.path) + + assertTrue(contains) + } + + @Test + fun `Contains setting must return false if a no settings file exists in the zip`() { + val settings = File.createTempFile("newpipe_", "") + `when`(fileLocator.settings).thenReturn(settings) + + val emptyZip = File(classloader.getResource("settings/empty.zip")?.file!!) + val contains = ContentSettingsManager(fileLocator).extractSettings(emptyZip.path) + + assertFalse(contains) + } + + @Test + fun `Preferences must be set from the settings file`() { + val settings = File(classloader.getResource("settings/newpipe.settings")!!.path) + `when`(fileLocator.settings).thenReturn(settings) + + val preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly()) + val editor = Mockito.mock(SharedPreferences.Editor::class.java) + `when`(preferences.edit()).thenReturn(editor) + + ContentSettingsManager(fileLocator).loadSharedPreferences(preferences) + + verify(editor, atLeastOnce()).putBoolean(anyString(), anyBoolean()) + verify(editor, atLeastOnce()).putString(anyString(), anyString()) + verify(editor, atLeastOnce()).putInt(anyString(), anyInt()) + } } diff --git a/app/src/test/resources/settings/newpipe.settings b/app/src/test/resources/settings/newpipe.settings index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..56e6c5d5dd53ba66b0144215b928f6137f67fc30 100644 GIT binary patch literal 2445 zcmaJ@zi%8x7#-VjLL8FV`Qea26rcba>tWC@AwsfT$@bXs8f9v`AFEZ+6$YOH59>lXiFZn>X*h?|t{^FSQuFTKUxM znYEg2zINM$?2f4xkNp1A&#Mo9T~PD4)KczDddnp2{FXY(nWvDsJRMi>zNh5#VDub* zAL4tR)oUR!Icat}?AFGUwuKqux74L$JFtmi>&mddYi`Qn+I8o0GUYEX`-i`M_wV2H zYVH%YxM%X3#?>6F3)rzPNV`&-I<-y@Tv7);G`0-8>T|WASe>bZ>_TJU)PZP6@6bdZ z9%l6-@Q$>=Kq2-vVM=x4N~V(AB`+la;Pq}zHOZra^+iNFU8ZtXU7UAfw;Se;JYs1z#%U6?Ueu%DpT+pJEuT!Of|jCT)*Nnk2iU7A*1hui^( zD=HDGC;QI&U<;BA$)Ec3`yc-K;;T*gV5{?iSIg0*(Jyyv5#Y;5-(EcS%^zRSD>bg* zKDgjyR2nW|y=PN$t-8x{N_n#u6JT3b`v}iIK30IkWq}DhEse*!hq^MHv3f&jeP_L0 zxK2f#gT!>bw|>X%SqkfSX>`w4w9e{^t8Q-p483ZdsB*vt+ynCUU$oh43)KX42h z!4@eLKP2YDYl(LuXn0`c{EqGrcCQ_eRY9_--rYPe-2qm}mnLthiEbp{GPG*)96gee zsdQQwl`V%;ws?k$m!pbO;ErW9c(hCS))im5}2_^Pw<68fK2z8dISMv0Drk&AjoMs#>b9it&?BwVX2r$E{;3Vfb9jr!2~|;gdEOfJ zRg-wLmebHAlWVyrlTL29au110>3z4cwz<}8C4S|ZE8h>UY!@zahID4Nlp3^hdvU(< zG$8MR!&QWtmk5#u=!(flW)dW#+6HDd+uY5B6oU7g`vA$VNV({1Y1^Z4NS7l(@kHy2 zpk0{7RK@(2>B#D6b6HdytS;sTafKF5b%USEgn|Y=0qEttZ%)w|ni~KpkK%laVjRSU^ zjkP0)wMJ5$@#E%1cYR0S!jG8J9etsl{&8xzDqo6d(dI)d@yix%W`<6)%&E>_ Date: Sat, 19 Dec 2020 16:35:30 +0100 Subject: [PATCH 08/10] Extract settings file deletion --- .../settings/ContentSettingsFragment.java | 17 +--------------- .../settings/ContentSettingsManager.kt | 5 ++++- .../settings/ContentSettingsManagerTest.kt | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java index 18d49b507..c0639131c 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java @@ -44,13 +44,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment { private ContentSettingsManager manager; - private File databasesDir; - private File newpipeDb; - private File newpipeDbJournal; - private File newpipeDbShm; - private File newpipeDbWal; - private File newpipeSettings; - private String thumbnailLoadToggleKey; private String youtubeRestrictedModeEnabledKey; @@ -115,16 +108,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment { @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { final File homeDir = ContextCompat.getDataDir(requireContext()); - databasesDir = new File(homeDir, "/databases"); - newpipeDb = new File(homeDir, "/databases/newpipe.db"); - newpipeDbJournal = new File(homeDir, "/databases/newpipe.db-journal"); - newpipeDbShm = new File(homeDir, "/databases/newpipe.db-shm"); - newpipeDbWal = new File(homeDir, "/databases/newpipe.db-wal"); - - newpipeSettings = new File(homeDir, "/databases/newpipe.settings"); - newpipeSettings.delete(); - manager = new ContentSettingsManager(new NewPipeFileLocator(homeDir)); + manager.deleteSettingsFile(); addPreferencesFromResource(R.xml.content_settings); diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index bab29a30a..d461ac61b 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -8,7 +8,6 @@ import java.io.FileOutputStream import java.io.IOException import java.io.ObjectInputStream import java.io.ObjectOutputStream -import java.util.zip.ZipFile import java.util.zip.ZipOutputStream class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { @@ -36,6 +35,10 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { } } + fun deleteSettingsFile() { + fileLocator.settings.delete() + } + /** * Tries to create database directory if it does not exist. * diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index 875ef758a..088b7e1d1 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -65,6 +65,26 @@ class ContentSettingsManagerTest { } } + @Test + fun `Settings file must be deleted`() { + val settings = File.createTempFile("newpipe_", "") + `when`(fileLocator.settings).thenReturn(settings) + + ContentSettingsManager(fileLocator).deleteSettingsFile() + + assertFalse(settings.exists()) + } + + @Test + fun `Deleting settings file must do nothing if none exist`() { + val settings = File("non_existent") + `when`(fileLocator.settings).thenReturn(settings) + + ContentSettingsManager(fileLocator).deleteSettingsFile() + + assertFalse(settings.exists()) + } + @Test fun `The database must be extracted from the zip file`() { val db = File.createTempFile("newpipe_", "") From fcfdcd1025a6fc005c11e82a0ace8a5fe3fba1a3 Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:53:11 +0100 Subject: [PATCH 09/10] Fix ensureDbDirectoryExists --- .../settings/ContentSettingsManager.kt | 3 +-- .../settings/ContentSettingsManagerTest.kt | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index d461ac61b..49d35d984 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -45,10 +45,9 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { * @return Whether the directory exists afterwards. */ fun ensureDbDirectoryExists(): Boolean { - return !fileLocator.dbDir.exists() && !fileLocator.dbDir.mkdir() + return fileLocator.dbDir.exists() || fileLocator.dbDir.mkdir() } - fun extractDb(filePath: String): Boolean { val success = ZipHelper.extractFileFromZip(filePath, fileLocator.db.path, "newpipe.db") if (success) { diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index 088b7e1d1..a21ad7cb1 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -4,6 +4,7 @@ import android.content.SharedPreferences import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue +import org.junit.Assume import org.junit.Before import org.junit.Test import org.junit.runner.RunWith @@ -85,6 +86,25 @@ class ContentSettingsManagerTest { assertFalse(settings.exists()) } + @Test + fun `Ensuring db directory existence must work`() { + val dir = Files.createTempDirectory("newpipe_").toFile() + Assume.assumeTrue(dir.delete()) + `when`(fileLocator.dbDir).thenReturn(dir) + + ContentSettingsManager(fileLocator).ensureDbDirectoryExists() + assertTrue(dir.exists()) + } + + @Test + fun `Ensuring db directory existence must work when the directory already exists`() { + val dir = Files.createTempDirectory("newpipe_").toFile() + `when`(fileLocator.dbDir).thenReturn(dir) + + ContentSettingsManager(fileLocator).ensureDbDirectoryExists() + assertTrue(dir.exists()) + } + @Test fun `The database must be extracted from the zip file`() { val db = File.createTempFile("newpipe_", "") From 716d79597050a24b315d5b384e744b4a3b47983b Mon Sep 17 00:00:00 2001 From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com> Date: Sat, 19 Dec 2020 16:54:42 +0100 Subject: [PATCH 10/10] cleanup --- .../settings/ContentSettingsManager.kt | 23 ++++++++++--------- .../newpipe/settings/NewPipeFileLocator.kt | 1 - .../settings/ContentSettingsManagerTest.kt | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt index 49d35d984..1730a230e 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt @@ -19,19 +19,19 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { @Throws(Exception::class) fun exportDatabase(preferences: SharedPreferences, outputPath: String) { ZipOutputStream(BufferedOutputStream(FileOutputStream(outputPath))) - .use { outZip -> - ZipHelper.addFileToZip(outZip, fileLocator.db.path, "newpipe.db") + .use { outZip -> + ZipHelper.addFileToZip(outZip, fileLocator.db.path, "newpipe.db") - try { - ObjectOutputStream(FileOutputStream(fileLocator.settings)).use { output -> - output.writeObject(preferences.all) - output.flush() - } - } catch (e: IOException) { - e.printStackTrace() + try { + ObjectOutputStream(FileOutputStream(fileLocator.settings)).use { output -> + output.writeObject(preferences.all) + output.flush() } + } catch (e: IOException) { + e.printStackTrace() + } - ZipHelper.addFileToZip(outZip, fileLocator.settings.path, "newpipe.settings") + ZipHelper.addFileToZip(outZip, fileLocator.settings.path, "newpipe.settings") } } @@ -61,7 +61,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { fun extractSettings(filePath: String): Boolean { return ZipHelper - .extractFileFromZip(filePath, fileLocator.settings.path, "newpipe.settings") + .extractFileFromZip(filePath, fileLocator.settings.path, "newpipe.settings") } fun loadSharedPreferences(preferences: SharedPreferences) { @@ -70,6 +70,7 @@ class ContentSettingsManager(private val fileLocator: NewPipeFileLocator) { ObjectInputStream(FileInputStream(fileLocator.settings)).use { input -> preferenceEditor.clear() + @Suppress("UNCHECKED_CAST") val entries = input.readObject() as Map for ((key, value) in entries) { when (value) { diff --git a/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt b/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt index 1fe2fffa0..c2f93d15f 100644 --- a/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt +++ b/app/src/main/java/org/schabi/newpipe/settings/NewPipeFileLocator.kt @@ -18,5 +18,4 @@ class NewPipeFileLocator(private val homeDir: File) { val dbWal by lazy { File(homeDir, "/databases/newpipe.db-wal") } val settings by lazy { File(homeDir, "/databases/newpipe.settings") } - } diff --git a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt index a21ad7cb1..3c59c29b3 100644 --- a/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt +++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt @@ -10,9 +10,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito import org.mockito.Mockito.`when` -import org.mockito.Mockito.anyString import org.mockito.Mockito.anyBoolean import org.mockito.Mockito.anyInt +import org.mockito.Mockito.anyString import org.mockito.Mockito.atLeastOnce import org.mockito.Mockito.verify import org.mockito.Mockito.withSettings