mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +00:00 
			
		
		
		
	Extract export database logic into own class
- Separate it from the UI. - Add happy path unit test.
This commit is contained in:
		| @@ -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" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 XiangRongLin
					XiangRongLin