Extract export database logic into own class
- Separate it from the UI. - Add happy path unit test.
This commit is contained in:
parent
a54bc96eab
commit
f7f00293cc
6 changed files with 127 additions and 26 deletions
|
@ -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)) {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
app/src/test/resources/settings/newpipe.db
Normal file
1
app/src/test/resources/settings/newpipe.db
Normal file
|
@ -0,0 +1 @@
|
|||
such db much wow
|
0
app/src/test/resources/settings/newpipe.settings
Normal file
0
app/src/test/resources/settings/newpipe.settings
Normal file
|
@ -17,7 +17,7 @@
|
|||
|
||||
<suppress checks="EmptyBlock"
|
||||
files="ContentSettingsFragment.java"
|
||||
lines="244,245"/>
|
||||
lines="227,245"/>
|
||||
|
||||
<!-- org.schabi.newpipe.streams -->
|
||||
<suppress checks="LineLength"
|
||||
|
|
Loading…
Reference in a new issue