NewPipe/app/src/test/java/org/schabi/newpipe/settings/ImportExportManagerTest.kt

185 lines
7.4 KiB
Kotlin
Raw Normal View History

package org.schabi.newpipe.settings
import android.content.SharedPreferences
2024-03-27 11:31:16 +00:00
import com.grack.nanojson.JsonParser
2020-12-19 14:15:38 +00:00
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertThrows
2020-12-19 14:15:38 +00:00
import org.junit.Assert.assertTrue
2020-12-19 15:53:11 +00:00
import org.junit.Assume
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito
2020-12-19 14:15:38 +00:00
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.anyInt
2020-12-19 15:54:42 +00:00
import org.mockito.Mockito.anyString
2020-12-19 14:15:38 +00:00
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.verify
2021-12-05 02:22:29 +00:00
import org.mockito.Mockito.`when`
2020-12-19 14:15:38 +00:00
import org.mockito.Mockito.withSettings
import org.mockito.junit.MockitoJUnitRunner
2024-03-27 11:31:16 +00:00
import org.schabi.newpipe.settings.export.BackupFileLocator
import org.schabi.newpipe.settings.export.ImportExportManager
2021-01-14 21:04:40 +00:00
import org.schabi.newpipe.streams.io.StoredFileHelper
import us.shandian.giga.io.FileStream
import java.io.File
import java.io.ObjectInputStream
2020-12-19 14:15:38 +00:00
import java.nio.file.Files
import java.util.zip.ZipFile
@RunWith(MockitoJUnitRunner::class)
class ImportExportManagerTest {
companion object {
private val classloader = ImportExportManager::class.java.classLoader!!
}
2024-03-27 11:31:16 +00:00
private lateinit var fileLocator: BackupFileLocator
2021-01-14 21:04:40 +00:00
private lateinit var storedFileHelper: StoredFileHelper
@Before
fun setupFileLocator() {
2024-03-27 11:31:16 +00:00
fileLocator = Mockito.mock(BackupFileLocator::class.java, withSettings().stubOnly())
2021-01-14 21:04:40 +00:00
storedFileHelper = Mockito.mock(StoredFileHelper::class.java, withSettings().stubOnly())
}
@Test
fun `The settings must be exported successfully in the correct format`() {
val db = File(classloader.getResource("settings/newpipe.db")!!.file)
`when`(fileLocator.db).thenReturn(db)
val expectedPreferences = mapOf("such pref" to "much wow")
2021-01-14 21:04:40 +00:00
val sharedPreferences =
Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly())
`when`(sharedPreferences.all).thenReturn(expectedPreferences)
val output = File.createTempFile("newpipe_", "")
2021-01-14 21:04:40 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(output))
ImportExportManager(fileLocator).exportDatabase(sharedPreferences, storedFileHelper)
val zipFile = ZipFile(output)
val entries = zipFile.entries().toList()
2024-03-27 11:31:16 +00:00
assertEquals(3, entries.size)
2020-12-19 14:15:38 +00:00
zipFile.getInputStream(entries.first { it.name == "newpipe.db" }).use { actual ->
db.inputStream().use { expected ->
assertEquals(expected.reader().readText(), actual.reader().readText())
2020-12-19 14:15:38 +00:00
}
}
zipFile.getInputStream(entries.first { it.name == "newpipe.settings" }).use { actual ->
val actualPreferences = ObjectInputStream(actual).readObject()
assertEquals(expectedPreferences, actualPreferences)
2020-12-19 14:15:38 +00:00
}
2020-12-19 15:35:30 +00:00
2024-03-27 11:31:16 +00:00
zipFile.getInputStream(entries.first { it.name == "preferences.json" }).use { actual ->
val actualPreferences = JsonParser.`object`().from(actual)
assertEquals(expectedPreferences, actualPreferences)
}
2020-12-19 15:35:30 +00:00
}
2020-12-19 15:53:11 +00:00
@Test
fun `Ensuring db directory existence must work`() {
val dir = Files.createTempDirectory("newpipe_").toFile()
Assume.assumeTrue(dir.delete())
`when`(fileLocator.dbDir).thenReturn(dir)
ImportExportManager(fileLocator).ensureDbDirectoryExists()
2020-12-19 15:53:11 +00:00
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)
ImportExportManager(fileLocator).ensureDbDirectoryExists()
2020-12-19 15:53:11 +00:00
assertTrue(dir.exists())
}
@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/db_ser_json.zip")?.file!!)
2021-01-14 21:04:40 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(zip))
val success = ImportExportManager(fileLocator).extractDb(storedFileHelper)
assertTrue(success)
assertFalse(dbJournal.exists())
assertFalse(dbWal.exists())
assertFalse(dbShm.exists())
assertTrue("database file size is zero", Files.size(db.toPath()) > 0)
}
2020-12-19 14:15:38 +00:00
@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/nodb_noser_nojson.zip")?.file!!)
2021-01-14 21:04:40 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(emptyZip))
val success = ImportExportManager(fileLocator).extractDb(storedFileHelper)
assertFalse(success)
assertTrue(dbJournal.exists())
assertTrue(dbWal.exists())
assertTrue(dbShm.exists())
assertEquals(0, Files.size(db.toPath()))
}
2020-12-19 14:15:38 +00:00
@Test
fun `Contains setting must return true if a settings file exists in the zip`() {
val zip = File(classloader.getResource("settings/db_ser_json.zip")?.file!!)
2021-01-14 21:04:40 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(zip))
2024-03-27 11:31:16 +00:00
assertTrue(ImportExportManager(fileLocator).exportHasSerializedPrefs(storedFileHelper))
}
2020-12-19 14:15:38 +00:00
@Test
fun `Contains setting must return false if no settings file exists in the zip`() {
val emptyZip = File(classloader.getResource("settings/nodb_noser_nojson.zip")?.file!!)
2021-01-14 21:04:40 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(emptyZip))
2024-03-27 11:31:16 +00:00
assertFalse(ImportExportManager(fileLocator).exportHasSerializedPrefs(storedFileHelper))
}
2020-12-19 14:15:38 +00:00
@Test
fun `Preferences must be set from the settings file`() {
val zip = File(classloader.getResource("settings/db_ser_json.zip")?.file!!)
2024-03-27 11:31:16 +00:00
`when`(storedFileHelper.stream).thenReturn(FileStream(zip))
2020-12-19 14:15:38 +00:00
val preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly())
val editor = Mockito.mock(SharedPreferences.Editor::class.java)
`when`(preferences.edit()).thenReturn(editor)
2024-03-27 11:31:16 +00:00
`when`(editor.commit()).thenReturn(true)
2020-12-19 14:15:38 +00:00
2024-03-27 11:31:16 +00:00
ImportExportManager(fileLocator).loadSerializedPrefs(storedFileHelper, preferences)
2020-12-19 14:15:38 +00:00
verify(editor, atLeastOnce()).putBoolean(anyString(), anyBoolean())
verify(editor, atLeastOnce()).putString(anyString(), anyString())
verify(editor, atLeastOnce()).putInt(anyString(), anyInt())
2020-12-19 14:15:38 +00:00
}
@Test
fun `Importing preferences with a serialization injected class should fail`() {
val emptyZip = File(classloader.getResource("settings/db_vulnser_json.zip")?.file!!)
`when`(storedFileHelper.stream).thenReturn(FileStream(emptyZip))
val preferences = Mockito.mock(SharedPreferences::class.java, withSettings().stubOnly())
assertThrows(ClassNotFoundException::class.java) {
2024-03-27 11:31:16 +00:00
ImportExportManager(fileLocator).loadSerializedPrefs(storedFileHelper, preferences)
}
}
}