|
@@ -1,568 +1,412 @@
|
|
|
package eu.kanade.tachiyomi.data.backup
|
|
|
|
|
|
+import android.app.Application
|
|
|
+import android.content.Context
|
|
|
import android.os.Build
|
|
|
-import com.google.gson.Gson
|
|
|
-import com.google.gson.JsonElement
|
|
|
+import com.github.salomonbrys.kotson.fromJson
|
|
|
+import com.google.gson.JsonArray
|
|
|
import com.google.gson.JsonObject
|
|
|
import eu.kanade.tachiyomi.BuildConfig
|
|
|
import eu.kanade.tachiyomi.CustomRobolectricGradleTestRunner
|
|
|
+import eu.kanade.tachiyomi.data.backup.models.Backup
|
|
|
+import eu.kanade.tachiyomi.data.backup.models.DHistory
|
|
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
|
|
import eu.kanade.tachiyomi.data.database.models.*
|
|
|
+import eu.kanade.tachiyomi.source.SourceManager
|
|
|
+import eu.kanade.tachiyomi.source.online.HttpSource
|
|
|
import org.assertj.core.api.Assertions.assertThat
|
|
|
import org.junit.Before
|
|
|
import org.junit.Test
|
|
|
import org.junit.runner.RunWith
|
|
|
+import org.mockito.Mockito
|
|
|
+import org.mockito.Mockito.*
|
|
|
import org.robolectric.RuntimeEnvironment
|
|
|
import org.robolectric.annotation.Config
|
|
|
-import uy.kohesive.injekt.injectLazy
|
|
|
-import java.util.*
|
|
|
-
|
|
|
+import rx.Observable
|
|
|
+import rx.observers.TestSubscriber
|
|
|
+import uy.kohesive.injekt.Injekt
|
|
|
+import uy.kohesive.injekt.api.InjektModule
|
|
|
+import uy.kohesive.injekt.api.InjektRegistrar
|
|
|
+import uy.kohesive.injekt.api.addSingleton
|
|
|
+
|
|
|
+/**
|
|
|
+ * Test class for the [BackupManager].
|
|
|
+ * Note that this does not include the backup create/restore services.
|
|
|
+ */
|
|
|
@Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP))
|
|
|
@RunWith(CustomRobolectricGradleTestRunner::class)
|
|
|
class BackupTest {
|
|
|
+ // Create root object
|
|
|
+ var root = JsonObject()
|
|
|
|
|
|
- val gson: Gson by injectLazy()
|
|
|
+ // Create information object
|
|
|
+ var information = JsonObject()
|
|
|
|
|
|
- lateinit var db: DatabaseHelper
|
|
|
+ // Create manga array
|
|
|
+ var mangaEntries = JsonArray()
|
|
|
+
|
|
|
+ // Create category array
|
|
|
+ var categoryEntries = JsonArray()
|
|
|
+
|
|
|
+ lateinit var app: Application
|
|
|
+ lateinit var context: Context
|
|
|
+ lateinit var source: HttpSource
|
|
|
|
|
|
lateinit var backupManager: BackupManager
|
|
|
|
|
|
- lateinit var root: JsonObject
|
|
|
+ lateinit var db: DatabaseHelper
|
|
|
|
|
|
@Before
|
|
|
fun setup() {
|
|
|
- val app = RuntimeEnvironment.application
|
|
|
- db = DatabaseHelper(app)
|
|
|
- backupManager = BackupManager(db)
|
|
|
- root = JsonObject()
|
|
|
- }
|
|
|
+ app = RuntimeEnvironment.application
|
|
|
+ context = app.applicationContext
|
|
|
+ backupManager = BackupManager(context)
|
|
|
+ db = backupManager.databaseHelper
|
|
|
+
|
|
|
+ // Mock the source manager
|
|
|
+ val module = object : InjektModule {
|
|
|
+ override fun InjektRegistrar.registerInjectables() {
|
|
|
+ addSingleton(Mockito.mock(SourceManager::class.java, RETURNS_DEEP_STUBS))
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Injekt.importModule(module)
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreCategory() {
|
|
|
- val catName = "cat"
|
|
|
- root = createRootJson(null, toJson(createCategories(catName)))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ source = mock(HttpSource::class.java)
|
|
|
+ `when`(backupManager.sourceManager.get(anyLong())).thenReturn(source)
|
|
|
|
|
|
- val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).hasSize(1)
|
|
|
- assertThat(dbCats[0].name).isEqualTo(catName)
|
|
|
+ root.add(Backup.MANGAS, mangaEntries)
|
|
|
+ root.add(Backup.CATEGORIES, categoryEntries)
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test that checks if no crashes when no categories in library.
|
|
|
+ */
|
|
|
@Test
|
|
|
fun testRestoreEmptyCategory() {
|
|
|
- root = createRootJson(null, toJson(ArrayList<Any>()))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
- val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).isEmpty()
|
|
|
- }
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreExistingCategory() {
|
|
|
- val catName = "cat"
|
|
|
- db.insertCategory(createCategory(catName)).executeAsBlocking()
|
|
|
+ // Create backup of empty database
|
|
|
+ backupManager.backupCategories(categoryEntries)
|
|
|
|
|
|
- root = createRootJson(null, toJson(createCategories(catName)))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ // Restore Json
|
|
|
+ backupManager.restoreCategories(categoryEntries)
|
|
|
|
|
|
+ // Check if empty
|
|
|
val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).hasSize(1)
|
|
|
- assertThat(dbCats[0].name).isEqualTo(catName)
|
|
|
+ assertThat(dbCats).isEmpty()
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test to check if single category gets restored
|
|
|
+ */
|
|
|
@Test
|
|
|
- fun testRestoreCategories() {
|
|
|
- root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ fun testRestoreSingleCategory() {
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
|
|
|
- val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).hasSize(3)
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreExistingCategories() {
|
|
|
- db.insertCategories(createCategories("cat", "cat2")).executeAsBlocking()
|
|
|
+ // Create category and add to json
|
|
|
+ val category = addSingleCategory("category")
|
|
|
|
|
|
- root = createRootJson(null, toJson(createCategories("cat", "cat2", "cat3")))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ // Restore Json
|
|
|
+ backupManager.restoreCategories(categoryEntries)
|
|
|
|
|
|
- val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).hasSize(3)
|
|
|
+ // Check if successful
|
|
|
+ val dbCats = backupManager.databaseHelper.getCategories().executeAsBlocking()
|
|
|
+ assertThat(dbCats).hasSize(1)
|
|
|
+ assertThat(dbCats[0].name).isEqualTo(category.name)
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test to check if multiple categories get restored.
|
|
|
+ */
|
|
|
@Test
|
|
|
- fun testRestoreExistingCategoriesAlt() {
|
|
|
- db.insertCategories(createCategories("cat", "cat2", "cat3")).executeAsBlocking()
|
|
|
-
|
|
|
- root = createRootJson(null, toJson(createCategories("cat", "cat2")))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbCats = db.getCategories().executeAsBlocking()
|
|
|
- assertThat(dbCats).hasSize(3)
|
|
|
+ fun testRestoreMultipleCategories() {
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
+
|
|
|
+ // Create category and add to json
|
|
|
+ val category = addSingleCategory("category")
|
|
|
+ val category2 = addSingleCategory("category2")
|
|
|
+ val category3 = addSingleCategory("category3")
|
|
|
+ val category4 = addSingleCategory("category4")
|
|
|
+ val category5 = addSingleCategory("category5")
|
|
|
+
|
|
|
+ // Insert category to test if no duplicates on restore.
|
|
|
+ db.insertCategory(category).executeAsBlocking()
|
|
|
+
|
|
|
+ // Restore Json
|
|
|
+ backupManager.restoreCategories(categoryEntries)
|
|
|
+
|
|
|
+ // Check if successful
|
|
|
+ val dbCats = backupManager.databaseHelper.getCategories().executeAsBlocking()
|
|
|
+ assertThat(dbCats).hasSize(5)
|
|
|
+ assertThat(dbCats[0].name).isEqualTo(category.name)
|
|
|
+ assertThat(dbCats[1].name).isEqualTo(category2.name)
|
|
|
+ assertThat(dbCats[2].name).isEqualTo(category3.name)
|
|
|
+ assertThat(dbCats[3].name).isEqualTo(category4.name)
|
|
|
+ assertThat(dbCats[4].name).isEqualTo(category5.name)
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test if restore of manga is successful
|
|
|
+ */
|
|
|
@Test
|
|
|
fun testRestoreManga() {
|
|
|
- val mangaName = "title"
|
|
|
- val mangas = createMangas(mangaName)
|
|
|
- val elements = ArrayList<JsonElement>()
|
|
|
- for (manga in mangas) {
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- elements.add(entry)
|
|
|
- }
|
|
|
- root = createRootJson(toJson(elements), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbMangas = db.getMangas().executeAsBlocking()
|
|
|
- assertThat(dbMangas).hasSize(1)
|
|
|
- assertThat(dbMangas[0].title).isEqualTo(mangaName)
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreExistingManga() {
|
|
|
- val mangaName = "title"
|
|
|
- val manga = createManga(mangaName)
|
|
|
-
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
-
|
|
|
- val elements = ArrayList<JsonElement>()
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- elements.add(entry)
|
|
|
-
|
|
|
- root = createRootJson(toJson(elements), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbMangas = db.getMangas().executeAsBlocking()
|
|
|
- assertThat(dbMangas).hasSize(1)
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreExistingMangaWithUpdatedFields() {
|
|
|
- // Store a manga in db
|
|
|
- val mangaName = "title"
|
|
|
- val updatedThumbnailUrl = "updated thumbnail url"
|
|
|
- var manga = createManga(mangaName)
|
|
|
- manga.chapter_flags = 1024
|
|
|
- manga.thumbnail_url = updatedThumbnailUrl
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
-
|
|
|
- // Add an entry for a new manga with different attributes
|
|
|
- manga = createManga(mangaName)
|
|
|
- manga.chapter_flags = 512
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val elements = ArrayList<JsonElement>()
|
|
|
- elements.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(elements), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbMangas = db.getMangas().executeAsBlocking()
|
|
|
- assertThat(dbMangas).hasSize(1)
|
|
|
- assertThat(dbMangas[0].thumbnail_url).isEqualTo(updatedThumbnailUrl)
|
|
|
- assertThat(dbMangas[0].chapter_flags).isEqualTo(512)
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreChaptersForManga() {
|
|
|
- // Create a manga and 3 chapters
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = 1L
|
|
|
- val chapters = createChapters(manga, "1", "2", "3")
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("chapters", toJson(chapters))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbChapters).hasSize(3)
|
|
|
- }
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreChaptersForExistingManga() {
|
|
|
- val mangaId: Long = 3
|
|
|
- // Create a manga and 3 chapters
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = mangaId
|
|
|
- val chapters = createChapters(manga, "1", "2", "3")
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("chapters", toJson(chapters))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(mangaId).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbChapters).hasSize(3)
|
|
|
- }
|
|
|
+ // Add manga to database
|
|
|
+ val manga = getSingleManga("One Piece")
|
|
|
+ manga.viewer = 3
|
|
|
+ manga.id = db.insertManga(manga).executeAsBlocking().insertedId()
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreExistingChaptersForExistingManga() {
|
|
|
- val mangaId: Long = 5
|
|
|
- // Store a manga and 3 chapters
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = mangaId
|
|
|
- var chapters = createChapters(manga, "1", "2", "3")
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
- db.insertChapters(chapters).executeAsBlocking()
|
|
|
-
|
|
|
- // The backup contains a existing chapter and a new one, so it should have 4 chapters
|
|
|
- chapters = createChapters(manga, "3", "4")
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("chapters", toJson(chapters))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(mangaId).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val dbChapters = db.getChapters(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbChapters).hasSize(4)
|
|
|
- }
|
|
|
+ var favoriteManga = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking()
|
|
|
+ assertThat(favoriteManga).hasSize(1)
|
|
|
+ assertThat(favoriteManga[0].viewer).isEqualTo(3)
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreCategoriesForManga() {
|
|
|
- // Create a manga
|
|
|
- val manga = createManga("title")
|
|
|
+ // Update json with all options enabled
|
|
|
+ mangaEntries.add(backupManager.backupMangaObject(manga,1))
|
|
|
|
|
|
- // Create categories
|
|
|
- val categories = createCategories("cat1", "cat2", "cat3")
|
|
|
+ // Change manga in database to default values
|
|
|
+ val dbManga = getSingleManga("One Piece")
|
|
|
+ dbManga.id = manga.id
|
|
|
+ db.insertManga(dbManga).executeAsBlocking()
|
|
|
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("categories", toJson(createStringCategories("cat1")))
|
|
|
+ favoriteManga = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking()
|
|
|
+ assertThat(favoriteManga).hasSize(1)
|
|
|
+ assertThat(favoriteManga[0].viewer).isEqualTo(0)
|
|
|
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
+ // Restore local manga
|
|
|
+ backupManager.restoreMangaNoFetch(manga,dbManga)
|
|
|
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), toJson(categories))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ // Test if restore successful
|
|
|
+ favoriteManga = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking()
|
|
|
+ assertThat(favoriteManga).hasSize(1)
|
|
|
+ assertThat(favoriteManga[0].viewer).isEqualTo(3)
|
|
|
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
|
|
|
-
|
|
|
- assertThat(result).hasSize(1)
|
|
|
- assertThat(result).contains(Category.create("cat1"))
|
|
|
- assertThat(result).doesNotContain(Category.create("cat2"))
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreCategoriesForExistingManga() {
|
|
|
- // Store a manga
|
|
|
- val manga = createManga("title")
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
-
|
|
|
- // Create categories
|
|
|
- val categories = createCategories("cat1", "cat2", "cat3")
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("categories", toJson(createStringCategories("cat1")))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), toJson(categories))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
|
|
|
-
|
|
|
- assertThat(result).hasSize(1)
|
|
|
- assertThat(result).contains(Category.create("cat1"))
|
|
|
- assertThat(result).doesNotContain(Category.create("cat2"))
|
|
|
- }
|
|
|
-
|
|
|
- @Test
|
|
|
- fun testRestoreMultipleCategoriesForManga() {
|
|
|
- // Create a manga
|
|
|
- val manga = createManga("title")
|
|
|
+ // Clear database to test manga fetch
|
|
|
+ clearDatabase()
|
|
|
|
|
|
- // Create categories
|
|
|
- val categories = createCategories("cat1", "cat2", "cat3")
|
|
|
+ // Test if successful
|
|
|
+ favoriteManga = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking()
|
|
|
+ assertThat(favoriteManga).hasSize(0)
|
|
|
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("categories", toJson(createStringCategories("cat1", "cat3")))
|
|
|
+ // Restore Json
|
|
|
+ // Create JSON from manga to test parser
|
|
|
+ val json = backupManager.parser.toJsonTree(manga)
|
|
|
+ // Restore JSON from manga to test parser
|
|
|
+ val jsonManga = backupManager.parser.fromJson<MangaImpl>(json)
|
|
|
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
+ // Restore manga with fetch observable
|
|
|
+ val networkManga = getSingleManga("One Piece")
|
|
|
+ networkManga.description = "This is a description"
|
|
|
+ `when`(source.fetchMangaDetails(jsonManga)).thenReturn(Observable.just(networkManga))
|
|
|
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), toJson(categories))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ val obs = backupManager.restoreMangaFetchObservable(source, jsonManga)
|
|
|
+ val testSubscriber = TestSubscriber<Manga>()
|
|
|
+ obs.subscribe(testSubscriber)
|
|
|
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
+ testSubscriber.assertNoErrors()
|
|
|
|
|
|
- val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
|
|
|
-
|
|
|
- assertThat(result).hasSize(2)
|
|
|
- assertThat(result).contains(Category.create("cat1"), Category.create("cat3"))
|
|
|
- assertThat(result).doesNotContain(Category.create("cat2"))
|
|
|
+ // Check if restore successful
|
|
|
+ val dbCats = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking()
|
|
|
+ assertThat(dbCats).hasSize(1)
|
|
|
+ assertThat(dbCats[0].viewer).isEqualTo(3)
|
|
|
+ assertThat(dbCats[0].description).isEqualTo("This is a description")
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test if chapter restore is successful
|
|
|
+ */
|
|
|
@Test
|
|
|
- fun testRestoreMultipleCategoriesForExistingMangaAndCategory() {
|
|
|
- // Store a manga and a category
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = 1L
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
+ fun testRestoreChapters() {
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
|
|
|
- val cat = createCategory("cat1")
|
|
|
- cat.id = 1
|
|
|
- db.insertCategory(cat).executeAsBlocking()
|
|
|
- db.insertMangaCategory(MangaCategory.create(manga, cat)).executeAsBlocking()
|
|
|
+ // Insert manga
|
|
|
+ val manga = getSingleManga("One Piece")
|
|
|
+ manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
|
|
|
|
|
- // Create categories
|
|
|
- val categories = createCategories("cat1", "cat2", "cat3")
|
|
|
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("categories", toJson(createStringCategories("cat1", "cat2")))
|
|
|
+ // Create restore list
|
|
|
+ val chapters = ArrayList<Chapter>()
|
|
|
+ for (i in 1..8){
|
|
|
+ val chapter = getSingleChapter("Chapter $i")
|
|
|
+ chapter.read = true
|
|
|
+ chapters.add(chapter)
|
|
|
+ }
|
|
|
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
+ // Check parser
|
|
|
+ val chaptersJson = backupManager.parser.toJsonTree(chapters)
|
|
|
+ val restoredChapters = backupManager.parser.fromJson<List<ChapterImpl>>(chaptersJson)
|
|
|
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), toJson(categories))
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ // Fetch chapters from upstream
|
|
|
+ // Create list
|
|
|
+ val chaptersRemote = ArrayList<Chapter>()
|
|
|
+ (1..10).mapTo(chaptersRemote) { getSingleChapter("Chapter $it") }
|
|
|
+ `when`(source.fetchChapterList(manga)).thenReturn(Observable.just(chaptersRemote))
|
|
|
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
+ // Call restoreChapterFetchObservable
|
|
|
+ val obs = backupManager.restoreChapterFetchObservable(source, manga, restoredChapters)
|
|
|
+ val testSubscriber = TestSubscriber<Pair<List<Chapter>, List<Chapter>>>()
|
|
|
+ obs.subscribe(testSubscriber)
|
|
|
|
|
|
- val result = db.getCategoriesForManga(dbManga!!).executeAsBlocking()
|
|
|
+ testSubscriber.assertNoErrors()
|
|
|
|
|
|
- assertThat(result).hasSize(2)
|
|
|
- assertThat(result).contains(Category.create("cat1"), Category.create("cat2"))
|
|
|
- assertThat(result).doesNotContain(Category.create("cat3"))
|
|
|
+ val dbCats = backupManager.databaseHelper.getChapters(manga).executeAsBlocking()
|
|
|
+ assertThat(dbCats).hasSize(10)
|
|
|
+ assertThat(dbCats[0].read).isEqualTo(true)
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test to check if history restore works
|
|
|
+ */
|
|
|
@Test
|
|
|
- fun testRestoreSyncForManga() {
|
|
|
- // Create a manga and track
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = 1L
|
|
|
+ fun restoreHistoryForManga(){
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
|
|
|
- val track = createTrack(manga, 1, 2, 3)
|
|
|
+ val manga = getSingleManga("One Piece")
|
|
|
+ manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
|
|
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("sync", toJson(track))
|
|
|
+ // Create chapter
|
|
|
+ val chapter = getSingleChapter("Chapter 1")
|
|
|
+ chapter.manga_id = manga.id
|
|
|
+ chapter.read = true
|
|
|
+ chapter.id = backupManager.databaseHelper.insertChapter(chapter).executeAsBlocking().insertedId()
|
|
|
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
+ val historyJson = getSingleHistory(chapter)
|
|
|
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
+ val historyList = ArrayList<DHistory>()
|
|
|
+ historyList.add(historyJson)
|
|
|
|
|
|
- val dbManga = db.getManga(1).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
+ // Check parser
|
|
|
+ val historyListJson = backupManager.parser.toJsonTree(historyList)
|
|
|
+ val history = backupManager.parser.fromJson<List<DHistory>>(historyListJson)
|
|
|
|
|
|
- val dbSync = db.getTracks(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbSync).hasSize(3)
|
|
|
- }
|
|
|
+ // Restore categories
|
|
|
+ backupManager.restoreHistoryForManga(history)
|
|
|
|
|
|
- @Test
|
|
|
- fun testRestoreSyncForExistingManga() {
|
|
|
- val mangaId: Long = 3
|
|
|
- // Create a manga and 3 sync
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = mangaId
|
|
|
- val track = createTrack(manga, 1, 2, 3)
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("sync", toJson(track))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(mangaId).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val dbSync = db.getTracks(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbSync).hasSize(3)
|
|
|
+ val historyDB = backupManager.databaseHelper.getHistoryByMangaId(manga.id!!).executeAsBlocking()
|
|
|
+ assertThat(historyDB).hasSize(1)
|
|
|
+ assertThat(historyDB[0].last_read).isEqualTo(1000)
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Test to check if tracking restore works
|
|
|
+ */
|
|
|
@Test
|
|
|
- fun testRestoreExistingSyncForExistingManga() {
|
|
|
- val mangaId: Long = 5
|
|
|
- // Store a manga and 3 sync
|
|
|
- val manga = createManga("title")
|
|
|
- manga.id = mangaId
|
|
|
- var track = createTrack(manga, 1, 2, 3)
|
|
|
- db.insertManga(manga).executeAsBlocking()
|
|
|
- db.insertTracks(track).executeAsBlocking()
|
|
|
-
|
|
|
- // The backup contains a existing sync and a new one, so it should have 4 sync
|
|
|
- track = createTrack(manga, 3, 4)
|
|
|
-
|
|
|
- // Add an entry for the manga
|
|
|
- val entry = JsonObject()
|
|
|
- entry.add("manga", toJson(manga))
|
|
|
- entry.add("sync", toJson(track))
|
|
|
-
|
|
|
- // Append the entry to the backup list
|
|
|
- val mangas = ArrayList<JsonElement>()
|
|
|
- mangas.add(entry)
|
|
|
-
|
|
|
- // Restore from json
|
|
|
- root = createRootJson(toJson(mangas), null)
|
|
|
- backupManager.restoreFromJson(root)
|
|
|
-
|
|
|
- val dbManga = db.getManga(mangaId).executeAsBlocking()
|
|
|
- assertThat(dbManga).isNotNull()
|
|
|
-
|
|
|
- val dbSync = db.getTracks(dbManga!!).executeAsBlocking()
|
|
|
- assertThat(dbSync).hasSize(4)
|
|
|
- }
|
|
|
-
|
|
|
- private fun createRootJson(mangas: JsonElement?, categories: JsonElement?): JsonObject {
|
|
|
- val root = JsonObject()
|
|
|
- if (mangas != null)
|
|
|
- root.add("mangas", mangas)
|
|
|
- if (categories != null)
|
|
|
- root.add("categories", categories)
|
|
|
- return root
|
|
|
- }
|
|
|
-
|
|
|
- private fun createCategory(name: String): Category {
|
|
|
- val c = CategoryImpl()
|
|
|
- c.name = name
|
|
|
- return c
|
|
|
+ fun restoreTrackForManga() {
|
|
|
+ // Initialize json with version 2
|
|
|
+ initializeJsonTest(2)
|
|
|
+
|
|
|
+ // Create mangas
|
|
|
+ val manga = getSingleManga("One Piece")
|
|
|
+ val manga2 = getSingleManga("Bleach")
|
|
|
+ manga.id = backupManager.databaseHelper.insertManga(manga).executeAsBlocking().insertedId()
|
|
|
+ manga2.id = backupManager.databaseHelper.insertManga(manga2).executeAsBlocking().insertedId()
|
|
|
+
|
|
|
+ // Create track and add it to database
|
|
|
+ // This tests duplicate errors.
|
|
|
+ val track = getSingleTrack(manga)
|
|
|
+ track.last_chapter_read = 5
|
|
|
+ backupManager.databaseHelper.insertTrack(track).executeAsBlocking()
|
|
|
+ var trackDB = backupManager.databaseHelper.getTracks(manga).executeAsBlocking()
|
|
|
+ assertThat(trackDB).hasSize(1)
|
|
|
+ assertThat(trackDB[0].last_chapter_read).isEqualTo(5)
|
|
|
+ track.last_chapter_read = 7
|
|
|
+
|
|
|
+ // Create track for different manga to test track not in database
|
|
|
+ val track2 = getSingleTrack(manga2)
|
|
|
+ track2.last_chapter_read = 10
|
|
|
+
|
|
|
+ // Check parser and restore already in database
|
|
|
+ var trackList = listOf(track)
|
|
|
+ //Check parser
|
|
|
+ var trackListJson = backupManager.parser.toJsonTree(trackList)
|
|
|
+ var trackListRestore = backupManager.parser.fromJson<List<TrackImpl>>(trackListJson)
|
|
|
+ backupManager.restoreTrackForManga(manga, trackListRestore)
|
|
|
+
|
|
|
+ // Assert if restore works.
|
|
|
+ trackDB = backupManager.databaseHelper.getTracks(manga).executeAsBlocking()
|
|
|
+ assertThat(trackDB).hasSize(1)
|
|
|
+ assertThat(trackDB[0].last_chapter_read).isEqualTo(7)
|
|
|
+
|
|
|
+ // Check parser and restore already in database with lower chapter_read
|
|
|
+ track.last_chapter_read = 5
|
|
|
+ trackList = listOf(track)
|
|
|
+ backupManager.restoreTrackForManga(manga, trackList)
|
|
|
+
|
|
|
+ // Assert if restore works.
|
|
|
+ trackDB = backupManager.databaseHelper.getTracks(manga).executeAsBlocking()
|
|
|
+ assertThat(trackDB).hasSize(1)
|
|
|
+ assertThat(trackDB[0].last_chapter_read).isEqualTo(7)
|
|
|
+
|
|
|
+ // Check parser and restore, track not in database
|
|
|
+ trackList = listOf(track2)
|
|
|
+
|
|
|
+ //Check parser
|
|
|
+ trackListJson = backupManager.parser.toJsonTree(trackList)
|
|
|
+ trackListRestore = backupManager.parser.fromJson<List<TrackImpl>>(trackListJson)
|
|
|
+ backupManager.restoreTrackForManga(manga2, trackListRestore)
|
|
|
+
|
|
|
+ // Assert if restore works.
|
|
|
+ trackDB = backupManager.databaseHelper.getTracks(manga2).executeAsBlocking()
|
|
|
+ assertThat(trackDB).hasSize(1)
|
|
|
+ assertThat(trackDB[0].last_chapter_read).isEqualTo(10)
|
|
|
}
|
|
|
|
|
|
- private fun createCategories(vararg names: String): List<Category> {
|
|
|
- val cats = ArrayList<Category>()
|
|
|
- for (name in names) {
|
|
|
- cats.add(createCategory(name))
|
|
|
- }
|
|
|
- return cats
|
|
|
- }
|
|
|
-
|
|
|
- private fun createStringCategories(vararg names: String): List<String> {
|
|
|
- val cats = ArrayList<String>()
|
|
|
- for (name in names) {
|
|
|
- cats.add(name)
|
|
|
- }
|
|
|
- return cats
|
|
|
+ fun clearJson() {
|
|
|
+ root = JsonObject()
|
|
|
+ information = JsonObject()
|
|
|
+ mangaEntries = JsonArray()
|
|
|
+ categoryEntries = JsonArray()
|
|
|
}
|
|
|
|
|
|
- private fun createManga(title: String): Manga {
|
|
|
- val m = Manga.create(1)
|
|
|
- m.title = title
|
|
|
- m.author = ""
|
|
|
- m.artist = ""
|
|
|
- m.thumbnail_url = ""
|
|
|
- m.genre = "a list of genres"
|
|
|
- m.description = "long description"
|
|
|
- m.url = "url to manga"
|
|
|
- m.favorite = true
|
|
|
- return m
|
|
|
+ fun initializeJsonTest(version: Int) {
|
|
|
+ clearJson()
|
|
|
+ backupManager.setVersion(version)
|
|
|
}
|
|
|
|
|
|
- private fun createMangas(vararg titles: String): List<Manga> {
|
|
|
- val mangas = ArrayList<Manga>()
|
|
|
- for (title in titles) {
|
|
|
- mangas.add(createManga(title))
|
|
|
- }
|
|
|
- return mangas
|
|
|
+ fun addSingleCategory(name: String): Category {
|
|
|
+ val category = Category.create(name)
|
|
|
+ val catJson = backupManager.parser.toJsonTree(category)
|
|
|
+ categoryEntries.add(catJson)
|
|
|
+ return category
|
|
|
}
|
|
|
|
|
|
- private fun createChapter(manga: Manga, url: String): Chapter {
|
|
|
- val c = Chapter.create()
|
|
|
- c.url = url
|
|
|
- c.name = url
|
|
|
- c.manga_id = manga.id
|
|
|
- return c
|
|
|
+ fun clearDatabase(){
|
|
|
+ db.deleteMangas().executeAsBlocking()
|
|
|
+ db.deleteHistory().executeAsBlocking()
|
|
|
}
|
|
|
|
|
|
- private fun createChapters(manga: Manga, vararg urls: String): List<Chapter> {
|
|
|
- val chapters = ArrayList<Chapter>()
|
|
|
- for (url in urls) {
|
|
|
- chapters.add(createChapter(manga, url))
|
|
|
- }
|
|
|
- return chapters
|
|
|
+ fun getSingleHistory(chapter: Chapter): DHistory {
|
|
|
+ return DHistory(chapter.url, 1000)
|
|
|
}
|
|
|
|
|
|
- private fun createTrack(manga: Manga, syncId: Int): Track {
|
|
|
- val m = Track.create(syncId)
|
|
|
- m.manga_id = manga.id!!
|
|
|
- m.title = "title"
|
|
|
- return m
|
|
|
+ private fun getSingleTrack(manga: Manga): TrackImpl {
|
|
|
+ val track = TrackImpl()
|
|
|
+ track.title = manga.title
|
|
|
+ track.manga_id = manga.id!!
|
|
|
+ track.remote_id = 1
|
|
|
+ track.sync_id = 1
|
|
|
+ return track
|
|
|
}
|
|
|
|
|
|
- private fun createTrack(manga: Manga, vararg syncIds: Int): List<Track> {
|
|
|
- val ms = ArrayList<Track>()
|
|
|
- for (title in syncIds) {
|
|
|
- ms.add(createTrack(manga, title))
|
|
|
- }
|
|
|
- return ms
|
|
|
+ private fun getSingleManga(title: String): MangaImpl {
|
|
|
+ val manga = MangaImpl()
|
|
|
+ manga.source = 1
|
|
|
+ manga.title = title
|
|
|
+ manga.url = "/manga/$title"
|
|
|
+ manga.favorite = true
|
|
|
+ return manga
|
|
|
}
|
|
|
|
|
|
- private fun toJson(element: Any): JsonElement {
|
|
|
- return gson.toJsonTree(element)
|
|
|
+ private fun getSingleChapter(name: String): ChapterImpl {
|
|
|
+ val chapter = ChapterImpl()
|
|
|
+ chapter.name = name
|
|
|
+ chapter.url = "/read-online/$name-page-1.html"
|
|
|
+ return chapter
|
|
|
}
|
|
|
-
|
|
|
}
|