Extract export database logic into own class

- Separate it from the UI.
- Add happy path unit test.
This commit is contained in:
XiangRongLin 2020-12-01 20:12:42 +01:00
parent a54bc96eab
commit f7f00293cc
6 changed files with 127 additions and 26 deletions

View File

@ -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)) {

View File

@ -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")
}
}
}

View File

@ -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)
}
}
}
}

View File

@ -0,0 +1 @@
such db much wow

View File

@ -17,7 +17,7 @@
<suppress checks="EmptyBlock"
files="ContentSettingsFragment.java"
lines="244,245"/>
lines="227,245"/>
<!-- org.schabi.newpipe.streams -->
<suppress checks="LineLength"