From f7f00293cc5a7b37c10c29bb80e483a8091bc766 Mon Sep 17 00:00:00 2001
From: XiangRongLin <41164160+XiangRongLin@users.noreply.github.com>
Date: Tue, 1 Dec 2020 20:12:42 +0100
Subject: [PATCH] Extract export database logic into own class
- Separate it from the UI.
- Add happy path unit test.
---
.../settings/ContentSettingsFragment.java | 33 +++------
.../settings/ContentSettingsManager.kt | 45 ++++++++++++
.../settings/ContentSettingsManagerTest.kt | 72 +++++++++++++++++++
app/src/test/resources/settings/newpipe.db | 1 +
.../test/resources/settings/newpipe.settings | 0
checkstyle-suppressions.xml | 2 +-
6 files changed, 127 insertions(+), 26 deletions(-)
create mode 100644 app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
create mode 100644 app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt
create mode 100644 app/src/test/resources/settings/newpipe.db
create mode 100644 app/src/test/resources/settings/newpipe.settings
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 b0425ebfa..6ef2f732e 100644
--- a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsFragment.java
@@ -30,19 +30,15 @@ import org.schabi.newpipe.report.UserAction;
import org.schabi.newpipe.util.FilePickerActivityHelper;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
import static org.schabi.newpipe.util.Localization.assureCorrectAppLanguage;
@@ -50,6 +46,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
private static final int REQUEST_IMPORT_PATH = 8945;
private static final int REQUEST_EXPORT_PATH = 30945;
+ private ContentSettingsManager manager;
+
private File databasesDir;
private File newpipeDb;
private File newpipeDbJournal;
@@ -131,6 +129,8 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
newpipeSettings = new File(homeDir + "/databases/newpipe.settings");
newpipeSettings.delete();
+ manager = new ContentSettingsManager(homeDir);
+
addPreferencesFromResource(R.xml.content_settings);
final Preference importDataPreference = findPreference(getString(R.string.import_data));
@@ -212,33 +212,16 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
//checkpoint before export
NewPipeDatabase.checkpoint();
- try (ZipOutputStream outZip = new ZipOutputStream(new BufferedOutputStream(
- new FileOutputStream(path)))) {
- ZipHelper.addFileToZip(outZip, newpipeDb.getPath(), "newpipe.db");
+ final SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(requireContext());
+ manager.exportDatabase(preferences, path);
- saveSharedPreferencesToFile(newpipeSettings);
- ZipHelper.addFileToZip(outZip, newpipeSettings.getPath(),
- "newpipe.settings");
- }
-
- Toast.makeText(getContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT)
- .show();
+ Toast.makeText(getContext(), R.string.export_complete_toast, Toast.LENGTH_SHORT).show();
} catch (final Exception e) {
onError(e);
}
}
- private void saveSharedPreferencesToFile(final File dst) {
- try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(dst))) {
- final SharedPreferences pref
- = PreferenceManager.getDefaultSharedPreferences(requireContext());
- output.writeObject(pref.getAll());
- output.flush();
- } catch (final IOException e) {
- e.printStackTrace();
- }
- }
-
private void importDatabase(final String filePath) {
// check if file is supported
try (ZipFile zipFile = new ZipFile(filePath)) {
diff --git a/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
new file mode 100644
index 000000000..b0ea89993
--- /dev/null
+++ b/app/src/main/java/org/schabi/newpipe/settings/ContentSettingsManager.kt
@@ -0,0 +1,45 @@
+package org.schabi.newpipe.settings
+
+import android.content.SharedPreferences
+import org.schabi.newpipe.util.ZipHelper
+import java.io.BufferedOutputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.ObjectOutputStream
+import java.lang.Exception
+import java.util.zip.ZipOutputStream
+
+class ContentSettingsManager(
+ private val newpipeDb: File,
+ private val newpipeSettings: File
+) {
+
+ constructor(homeDir: String) : this(
+ File("$homeDir/databases/newpipe.db"),
+ File("$homeDir/databases/newpipe.settings")
+ )
+
+ /**
+ * Exports given [SharedPreferences] to the file in given outputPath.
+ * It also creates the file.
+ */
+ @Throws(Exception::class)
+ fun exportDatabase(preferences: SharedPreferences, outputPath: String) {
+ ZipOutputStream(BufferedOutputStream(FileOutputStream(outputPath)))
+ .use { outZip ->
+ ZipHelper.addFileToZip(outZip, newpipeDb.path, "newpipe.db")
+
+ try {
+ ObjectOutputStream(FileOutputStream(newpipeSettings)).use { output ->
+ output.writeObject(preferences.all)
+ output.flush()
+ }
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+
+ ZipHelper.addFileToZip(outZip, newpipeSettings.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
new file mode 100644
index 000000000..9809fd5fc
--- /dev/null
+++ b/app/src/test/java/org/schabi/newpipe/settings/ContentSettingsManagerTest.kt
@@ -0,0 +1,72 @@
+package org.schabi.newpipe.settings
+
+import android.content.SharedPreferences
+import org.junit.Assert
+import org.junit.Assume
+import org.junit.Before
+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.junit.MockitoJUnitRunner
+import org.schabi.newpipe.settings.ContentSettingsManagerTest.ExportTest
+import java.io.File
+import java.io.ObjectInputStream
+import java.util.zip.ZipFile
+
+@RunWith(Suite::class)
+@Suite.SuiteClasses(ExportTest::class)
+class ContentSettingsManagerTest {
+
+ @RunWith(MockitoJUnitRunner::class)
+ class ExportTest {
+
+ private lateinit var preferences: SharedPreferences
+ private lateinit var newpipeDb: File
+ private lateinit var newpipeSettings: File
+
+ @Before
+ fun beforeClass() {
+
+ val dbPath = javaClass.classLoader?.getResource("settings/newpipe.db")?.file
+ val settingsPath = javaClass.classLoader?.getResource("settings/newpipe.settings")?.path
+ Assume.assumeNotNull(dbPath)
+ Assume.assumeNotNull(settingsPath)
+
+ newpipeDb = File(dbPath!!)
+ newpipeSettings = File(settingsPath!!)
+ }
+
+ @Before
+ fun before() {
+ preferences = Mockito.mock(SharedPreferences::class.java, Mockito.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(newpipeDb, newpipeSettings)
+
+ val output = File.createTempFile("newpipe_", "")
+ manager.exportDatabase(preferences, output.absolutePath)
+
+ val zipFile = ZipFile(output.absoluteFile)
+ val entries = zipFile.entries().toList()
+ Assert.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())
+ }
+ }
+
+ zipFile.getInputStream(entries.first { it.name == "newpipe.settings" }).use { actual ->
+ val actualPreferences = ObjectInputStream(actual).readObject()
+ Assert.assertEquals(expectedPreferences, actualPreferences)
+ }
+ }
+ }
+}
diff --git a/app/src/test/resources/settings/newpipe.db b/app/src/test/resources/settings/newpipe.db
new file mode 100644
index 000000000..cd3fc4717
--- /dev/null
+++ b/app/src/test/resources/settings/newpipe.db
@@ -0,0 +1 @@
+such db much wow
\ No newline at end of file
diff --git a/app/src/test/resources/settings/newpipe.settings b/app/src/test/resources/settings/newpipe.settings
new file mode 100644
index 000000000..e69de29bb
diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml
index add17d42d..0a5190b29 100644
--- a/checkstyle-suppressions.xml
+++ b/checkstyle-suppressions.xml
@@ -17,7 +17,7 @@
+ lines="227,245"/>