Unit tests for json (de)serialization
This commit is contained in:
@@ -123,6 +123,7 @@ dependencies {
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.json:json:20220320'
|
||||
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
|
||||
|
||||
androidTestImplementation 'androidx.test:runner:1.4.0'
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
),
|
||||
]
|
||||
)
|
||||
class BookmarkEntity(
|
||||
data class BookmarkEntity(
|
||||
@ColumnInfo(name = "manga_id", index = true) val mangaId: Long,
|
||||
@ColumnInfo(name = "page_id", index = true) val pageId: Long,
|
||||
@ColumnInfo(name = "chapter_id") val chapterId: Long,
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package org.koitharu.kotatsu.core.backup
|
||||
|
||||
import androidx.room.withTransaction
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
|
||||
import org.koitharu.kotatsu.history.data.HistoryEntity
|
||||
import org.koitharu.kotatsu.parsers.util.json.JSONIterator
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
||||
|
||||
private const val PAGE_SIZE = 10
|
||||
|
||||
@@ -24,11 +22,11 @@ class BackupRepository(private val db: MangaDatabase) {
|
||||
}
|
||||
offset += history.size
|
||||
for (item in history) {
|
||||
val manga = item.manga.toJson()
|
||||
val manga = JsonSerializer(item.manga).toJson()
|
||||
val tags = JSONArray()
|
||||
item.tags.forEach { tags.put(it.toJson()) }
|
||||
item.tags.forEach { tags.put(JsonSerializer(it).toJson()) }
|
||||
manga.put("tags", tags)
|
||||
val json = item.history.toJson()
|
||||
val json = JsonSerializer(item.history).toJson()
|
||||
json.put("manga", manga)
|
||||
entry.data.put(json)
|
||||
}
|
||||
@@ -40,7 +38,7 @@ class BackupRepository(private val db: MangaDatabase) {
|
||||
val entry = BackupEntry(BackupEntry.CATEGORIES, JSONArray())
|
||||
val categories = db.favouriteCategoriesDao.findAll()
|
||||
for (item in categories) {
|
||||
entry.data.put(item.toJson())
|
||||
entry.data.put(JsonSerializer(item).toJson())
|
||||
}
|
||||
return entry
|
||||
}
|
||||
@@ -55,11 +53,11 @@ class BackupRepository(private val db: MangaDatabase) {
|
||||
}
|
||||
offset += favourites.size
|
||||
for (item in favourites) {
|
||||
val manga = item.manga.toJson()
|
||||
val manga = JsonSerializer(item.manga).toJson()
|
||||
val tags = JSONArray()
|
||||
item.tags.forEach { tags.put(it.toJson()) }
|
||||
item.tags.forEach { tags.put(JsonSerializer(it).toJson()) }
|
||||
manga.put("tags", tags)
|
||||
val json = item.favourite.toJson()
|
||||
val json = JsonSerializer(item.favourite).toJson()
|
||||
json.put("manga", manga)
|
||||
entry.data.put(json)
|
||||
}
|
||||
@@ -77,60 +75,54 @@ class BackupRepository(private val db: MangaDatabase) {
|
||||
return entry
|
||||
}
|
||||
|
||||
private fun MangaEntity.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
jo.put("id", id)
|
||||
jo.put("title", title)
|
||||
jo.put("alt_title", altTitle)
|
||||
jo.put("url", url)
|
||||
jo.put("public_url", publicUrl)
|
||||
jo.put("rating", rating)
|
||||
jo.put("nsfw", isNsfw)
|
||||
jo.put("cover_url", coverUrl)
|
||||
jo.put("large_cover_url", largeCoverUrl)
|
||||
jo.put("state", state)
|
||||
jo.put("author", author)
|
||||
jo.put("source", source)
|
||||
return jo
|
||||
suspend fun restoreHistory(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val mangaJson = item.getJSONObject("manga")
|
||||
val manga = JsonDeserializer(mangaJson).toMangaEntity()
|
||||
val tags = mangaJson.getJSONArray("tags").mapJSON {
|
||||
JsonDeserializer(it).toTagEntity()
|
||||
}
|
||||
val history = JsonDeserializer(item).toHistoryEntity()
|
||||
result += runCatching {
|
||||
db.withTransaction {
|
||||
db.tagsDao.upsert(tags)
|
||||
db.mangaDao.upsert(manga, tags)
|
||||
db.historyDao.upsert(history)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun TagEntity.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
jo.put("id", id)
|
||||
jo.put("title", title)
|
||||
jo.put("key", key)
|
||||
jo.put("source", source)
|
||||
return jo
|
||||
suspend fun restoreCategories(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val category = JsonDeserializer(item).toFavouriteCategoryEntity()
|
||||
result += runCatching {
|
||||
db.favouriteCategoriesDao.upsert(category)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun HistoryEntity.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
jo.put("manga_id", mangaId)
|
||||
jo.put("created_at", createdAt)
|
||||
jo.put("updated_at", updatedAt)
|
||||
jo.put("chapter_id", chapterId)
|
||||
jo.put("page", page)
|
||||
jo.put("scroll", scroll)
|
||||
jo.put("percent", percent)
|
||||
return jo
|
||||
}
|
||||
|
||||
private fun FavouriteCategoryEntity.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
jo.put("category_id", categoryId)
|
||||
jo.put("created_at", createdAt)
|
||||
jo.put("sort_key", sortKey)
|
||||
jo.put("title", title)
|
||||
jo.put("order", order)
|
||||
jo.put("track", track)
|
||||
return jo
|
||||
}
|
||||
|
||||
private fun FavouriteEntity.toJson(): JSONObject {
|
||||
val jo = JSONObject()
|
||||
jo.put("manga_id", mangaId)
|
||||
jo.put("category_id", categoryId)
|
||||
jo.put("created_at", createdAt)
|
||||
return jo
|
||||
suspend fun restoreFavourites(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val mangaJson = item.getJSONObject("manga")
|
||||
val manga = JsonDeserializer(mangaJson).toMangaEntity()
|
||||
val tags = mangaJson.getJSONArray("tags").mapJSON {
|
||||
JsonDeserializer(it).toTagEntity()
|
||||
}
|
||||
val favourite = JsonDeserializer(item).toFavouriteEntity()
|
||||
result += runCatching {
|
||||
db.withTransaction {
|
||||
db.tagsDao.upsert(tags)
|
||||
db.mangaDao.upsert(manga, tags)
|
||||
db.favouritesDao.upsert(favourite)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.koitharu.kotatsu.core.backup
|
||||
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
|
||||
import org.koitharu.kotatsu.history.data.HistoryEntity
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.json.getBooleanOrDefault
|
||||
import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
|
||||
class JsonDeserializer(private val json: JSONObject) {
|
||||
|
||||
fun toFavouriteEntity() = FavouriteEntity(
|
||||
mangaId = json.getLong("manga_id"),
|
||||
categoryId = json.getLong("category_id"),
|
||||
createdAt = json.getLong("created_at"),
|
||||
)
|
||||
|
||||
fun toMangaEntity() = MangaEntity(
|
||||
id = json.getLong("id"),
|
||||
title = json.getString("title"),
|
||||
altTitle = json.getStringOrNull("alt_title"),
|
||||
url = json.getString("url"),
|
||||
publicUrl = json.getStringOrNull("public_url").orEmpty(),
|
||||
rating = json.getDouble("rating").toFloat(),
|
||||
isNsfw = json.getBooleanOrDefault("nsfw", false),
|
||||
coverUrl = json.getString("cover_url"),
|
||||
largeCoverUrl = json.getStringOrNull("large_cover_url"),
|
||||
state = json.getStringOrNull("state"),
|
||||
author = json.getStringOrNull("author"),
|
||||
source = json.getString("source")
|
||||
)
|
||||
|
||||
fun toTagEntity() = TagEntity(
|
||||
id = json.getLong("id"),
|
||||
title = json.getString("title"),
|
||||
key = json.getString("key"),
|
||||
source = json.getString("source")
|
||||
)
|
||||
|
||||
fun toHistoryEntity() = HistoryEntity(
|
||||
mangaId = json.getLong("manga_id"),
|
||||
createdAt = json.getLong("created_at"),
|
||||
updatedAt = json.getLong("updated_at"),
|
||||
chapterId = json.getLong("chapter_id"),
|
||||
page = json.getInt("page"),
|
||||
scroll = json.getDouble("scroll").toFloat(),
|
||||
percent = json.getFloatOrDefault("percent", -1f),
|
||||
)
|
||||
|
||||
fun toFavouriteCategoryEntity() = FavouriteCategoryEntity(
|
||||
categoryId = json.getInt("category_id"),
|
||||
createdAt = json.getLong("created_at"),
|
||||
sortKey = json.getInt("sort_key"),
|
||||
title = json.getString("title"),
|
||||
order = json.getStringOrNull("order") ?: SortOrder.NEWEST.name,
|
||||
track = json.getBooleanOrDefault("track", true),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package org.koitharu.kotatsu.core.backup
|
||||
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
|
||||
import org.koitharu.kotatsu.history.data.HistoryEntity
|
||||
|
||||
class JsonSerializer private constructor(private val json: JSONObject) {
|
||||
|
||||
constructor(e: FavouriteEntity) : this(
|
||||
JSONObject().apply {
|
||||
put("manga_id", e.mangaId)
|
||||
put("category_id", e.categoryId)
|
||||
put("created_at", e.createdAt)
|
||||
}
|
||||
)
|
||||
|
||||
constructor(e: FavouriteCategoryEntity) : this(
|
||||
JSONObject().apply {
|
||||
put("category_id", e.categoryId)
|
||||
put("created_at", e.createdAt)
|
||||
put("sort_key", e.sortKey)
|
||||
put("title", e.title)
|
||||
put("order", e.order)
|
||||
put("track", e.track)
|
||||
}
|
||||
)
|
||||
|
||||
constructor(e: HistoryEntity) : this(
|
||||
JSONObject().apply {
|
||||
put("manga_id", e.mangaId)
|
||||
put("created_at", e.createdAt)
|
||||
put("updated_at", e.updatedAt)
|
||||
put("chapter_id", e.chapterId)
|
||||
put("page", e.page)
|
||||
put("scroll", e.scroll)
|
||||
put("percent", e.percent)
|
||||
}
|
||||
)
|
||||
|
||||
constructor(e: TagEntity) : this(
|
||||
JSONObject().apply {
|
||||
put("id", e.id)
|
||||
put("title", e.title)
|
||||
put("key", e.key)
|
||||
put("source", e.source)
|
||||
}
|
||||
)
|
||||
|
||||
constructor(e: MangaEntity) : this(
|
||||
JSONObject().apply {
|
||||
put("id", e.id)
|
||||
put("title", e.title)
|
||||
put("alt_title", e.altTitle)
|
||||
put("url", e.url)
|
||||
put("public_url", e.publicUrl)
|
||||
put("rating", e.rating)
|
||||
put("nsfw", e.isNsfw)
|
||||
put("cover_url", e.coverUrl)
|
||||
put("large_cover_url", e.largeCoverUrl)
|
||||
put("state", e.state)
|
||||
put("author", e.author)
|
||||
put("source", e.source)
|
||||
}
|
||||
)
|
||||
|
||||
fun toJson(): JSONObject = json
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.koitharu.kotatsu.core.backup
|
||||
|
||||
import androidx.room.withTransaction
|
||||
import org.json.JSONObject
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
|
||||
import org.koitharu.kotatsu.history.data.HistoryEntity
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.json.*
|
||||
|
||||
class RestoreRepository(private val db: MangaDatabase) {
|
||||
|
||||
suspend fun upsertHistory(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val mangaJson = item.getJSONObject("manga")
|
||||
val manga = parseManga(mangaJson)
|
||||
val tags = mangaJson.getJSONArray("tags").mapJSON {
|
||||
parseTag(it)
|
||||
}
|
||||
val history = parseHistory(item)
|
||||
result += runCatching {
|
||||
db.withTransaction {
|
||||
db.tagsDao.upsert(tags)
|
||||
db.mangaDao.upsert(manga, tags)
|
||||
db.historyDao.upsert(history)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
suspend fun upsertCategories(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val category = parseCategory(item)
|
||||
result += runCatching {
|
||||
db.favouriteCategoriesDao.upsert(category)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
suspend fun upsertFavourites(entry: BackupEntry): CompositeResult {
|
||||
val result = CompositeResult()
|
||||
for (item in entry.data.JSONIterator()) {
|
||||
val mangaJson = item.getJSONObject("manga")
|
||||
val manga = parseManga(mangaJson)
|
||||
val tags = mangaJson.getJSONArray("tags").mapJSON {
|
||||
parseTag(it)
|
||||
}
|
||||
val favourite = parseFavourite(item)
|
||||
result += runCatching {
|
||||
db.withTransaction {
|
||||
db.tagsDao.upsert(tags)
|
||||
db.mangaDao.upsert(manga, tags)
|
||||
db.favouritesDao.upsert(favourite)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun parseManga(json: JSONObject) = MangaEntity(
|
||||
id = json.getLong("id"),
|
||||
title = json.getString("title"),
|
||||
altTitle = json.getStringOrNull("alt_title"),
|
||||
url = json.getString("url"),
|
||||
publicUrl = json.getStringOrNull("public_url").orEmpty(),
|
||||
rating = json.getDouble("rating").toFloat(),
|
||||
isNsfw = json.getBooleanOrDefault("nsfw", false),
|
||||
coverUrl = json.getString("cover_url"),
|
||||
largeCoverUrl = json.getStringOrNull("large_cover_url"),
|
||||
state = json.getStringOrNull("state"),
|
||||
author = json.getStringOrNull("author"),
|
||||
source = json.getString("source")
|
||||
)
|
||||
|
||||
private fun parseTag(json: JSONObject) = TagEntity(
|
||||
id = json.getLong("id"),
|
||||
title = json.getString("title"),
|
||||
key = json.getString("key"),
|
||||
source = json.getString("source")
|
||||
)
|
||||
|
||||
private fun parseHistory(json: JSONObject) = HistoryEntity(
|
||||
mangaId = json.getLong("manga_id"),
|
||||
createdAt = json.getLong("created_at"),
|
||||
updatedAt = json.getLong("updated_at"),
|
||||
chapterId = json.getLong("chapter_id"),
|
||||
page = json.getInt("page"),
|
||||
scroll = json.getDouble("scroll").toFloat(),
|
||||
percent = json.getFloatOrDefault("percent", -1f),
|
||||
)
|
||||
|
||||
private fun parseCategory(json: JSONObject) = FavouriteCategoryEntity(
|
||||
categoryId = json.getInt("category_id"),
|
||||
createdAt = json.getLong("created_at"),
|
||||
sortKey = json.getInt("sort_key"),
|
||||
title = json.getString("title"),
|
||||
order = json.getStringOrNull("order") ?: SortOrder.NEWEST.name,
|
||||
track = json.getBooleanOrDefault("track", true),
|
||||
)
|
||||
|
||||
private fun parseFavourite(json: JSONObject) = FavouriteEntity(
|
||||
mangaId = json.getLong("manga_id"),
|
||||
categoryId = json.getLong("category_id"),
|
||||
createdAt = json.getLong("created_at")
|
||||
)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "manga")
|
||||
class MangaEntity(
|
||||
data class MangaEntity(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
@ColumnInfo(name = "manga_id") val id: Long,
|
||||
@ColumnInfo(name = "title") val title: String,
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "tags")
|
||||
class TagEntity(
|
||||
data class TagEntity(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
@ColumnInfo(name = "tag_id") val id: Long,
|
||||
@ColumnInfo(name = "title") val title: String,
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "favourite_categories")
|
||||
class FavouriteCategoryEntity(
|
||||
data class FavouriteCategoryEntity(
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = "category_id") val categoryId: Int,
|
||||
@ColumnInfo(name = "created_at") val createdAt: Long,
|
||||
|
||||
@@ -21,7 +21,7 @@ import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
)
|
||||
]
|
||||
)
|
||||
class FavouriteEntity(
|
||||
data class FavouriteEntity(
|
||||
@ColumnInfo(name = "manga_id", index = true) val mangaId: Long,
|
||||
@ColumnInfo(name = "category_id", index = true) val categoryId: Long,
|
||||
@ColumnInfo(name = "created_at") val createdAt: Long
|
||||
|
||||
@@ -17,7 +17,7 @@ import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
)
|
||||
]
|
||||
)
|
||||
class HistoryEntity(
|
||||
data class HistoryEntity(
|
||||
@PrimaryKey(autoGenerate = false)
|
||||
@ColumnInfo(name = "manga_id") val mangaId: Long,
|
||||
@ColumnInfo(name = "created_at") val createdAt: Long,
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
import org.koitharu.kotatsu.core.backup.BackupRepository
|
||||
import org.koitharu.kotatsu.core.backup.RestoreRepository
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.settings.backup.BackupViewModel
|
||||
import org.koitharu.kotatsu.settings.backup.RestoreViewModel
|
||||
@@ -18,7 +17,6 @@ val settingsModule
|
||||
get() = module {
|
||||
|
||||
factory { BackupRepository(get()) }
|
||||
factory { RestoreRepository(get()) }
|
||||
single(createdAtStart = true) { AppSettings(androidContext()) }
|
||||
|
||||
viewModel { BackupViewModel(get(), androidContext()) }
|
||||
|
||||
@@ -6,7 +6,10 @@ import android.app.backup.BackupDataOutput
|
||||
import android.app.backup.FullBackupDataOutput
|
||||
import android.os.ParcelFileDescriptor
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.koitharu.kotatsu.core.backup.*
|
||||
import org.koitharu.kotatsu.core.backup.BackupEntry
|
||||
import org.koitharu.kotatsu.core.backup.BackupRepository
|
||||
import org.koitharu.kotatsu.core.backup.BackupZipInput
|
||||
import org.koitharu.kotatsu.core.backup.BackupZipOutput
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import java.io.*
|
||||
|
||||
@@ -63,7 +66,7 @@ class AppBackupAgent : BackupAgent() {
|
||||
}
|
||||
|
||||
private fun restoreBackupFile(fd: FileDescriptor, size: Long) {
|
||||
val repository = RestoreRepository(MangaDatabase(applicationContext))
|
||||
val repository = BackupRepository(MangaDatabase(applicationContext))
|
||||
val tempFile = File.createTempFile("backup_", ".tmp")
|
||||
FileInputStream(fd).use { input ->
|
||||
tempFile.outputStream().use { output ->
|
||||
@@ -73,9 +76,9 @@ class AppBackupAgent : BackupAgent() {
|
||||
val backup = BackupZipInput(tempFile)
|
||||
try {
|
||||
runBlocking {
|
||||
repository.upsertHistory(backup.getEntry(BackupEntry.HISTORY))
|
||||
repository.upsertCategories(backup.getEntry(BackupEntry.CATEGORIES))
|
||||
repository.upsertFavourites(backup.getEntry(BackupEntry.FAVOURITES))
|
||||
repository.restoreHistory(backup.getEntry(BackupEntry.HISTORY))
|
||||
repository.restoreCategories(backup.getEntry(BackupEntry.CATEGORIES))
|
||||
repository.restoreFavourites(backup.getEntry(BackupEntry.FAVOURITES))
|
||||
}
|
||||
} finally {
|
||||
backup.close()
|
||||
|
||||
@@ -7,9 +7,9 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runInterruptible
|
||||
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.backup.BackupEntry
|
||||
import org.koitharu.kotatsu.core.backup.BackupRepository
|
||||
import org.koitharu.kotatsu.core.backup.BackupZipInput
|
||||
import org.koitharu.kotatsu.core.backup.CompositeResult
|
||||
import org.koitharu.kotatsu.core.backup.RestoreRepository
|
||||
import org.koitharu.kotatsu.utils.SingleLiveEvent
|
||||
import org.koitharu.kotatsu.utils.progress.Progress
|
||||
import java.io.File
|
||||
@@ -17,7 +17,7 @@ import java.io.FileNotFoundException
|
||||
|
||||
class RestoreViewModel(
|
||||
uri: Uri?,
|
||||
private val repository: RestoreRepository,
|
||||
private val repository: BackupRepository,
|
||||
context: Context
|
||||
) : BaseViewModel() {
|
||||
|
||||
@@ -44,13 +44,13 @@ class RestoreViewModel(
|
||||
val result = CompositeResult()
|
||||
|
||||
progress.value = Progress(0, 3)
|
||||
result += repository.upsertHistory(backup.getEntry(BackupEntry.HISTORY))
|
||||
result += repository.restoreHistory(backup.getEntry(BackupEntry.HISTORY))
|
||||
|
||||
progress.value = Progress(1, 3)
|
||||
result += repository.upsertCategories(backup.getEntry(BackupEntry.CATEGORIES))
|
||||
result += repository.restoreCategories(backup.getEntry(BackupEntry.CATEGORIES))
|
||||
|
||||
progress.value = Progress(2, 3)
|
||||
result += repository.upsertFavourites(backup.getEntry(BackupEntry.FAVOURITES))
|
||||
result += repository.restoreFavourites(backup.getEntry(BackupEntry.FAVOURITES))
|
||||
|
||||
progress.value = Progress(3, 3)
|
||||
onRestoreDone.call(result)
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
package org.koitharu.kotatsu.core.backup
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.koitharu.kotatsu.core.db.entity.MangaEntity
|
||||
import org.koitharu.kotatsu.core.db.entity.TagEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
|
||||
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
|
||||
import org.koitharu.kotatsu.history.data.HistoryEntity
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class JsonSerializerTest {
|
||||
|
||||
@Test
|
||||
fun toFavouriteEntity() {
|
||||
val entity = FavouriteEntity(
|
||||
mangaId = 40,
|
||||
categoryId = 20,
|
||||
createdAt = System.currentTimeMillis(),
|
||||
)
|
||||
val json = JsonSerializer(entity).toJson()
|
||||
val result = JsonDeserializer(json).toFavouriteEntity()
|
||||
assertEquals(entity, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toMangaEntity() {
|
||||
val entity = MangaEntity(
|
||||
id = 231,
|
||||
title = "Lorem Ipsum",
|
||||
altTitle = "Lorem Ispum 2",
|
||||
url = "erw",
|
||||
publicUrl = "hthth",
|
||||
rating = 0.78f,
|
||||
isNsfw = true,
|
||||
coverUrl = "5345",
|
||||
largeCoverUrl = null,
|
||||
state = MangaState.FINISHED.name,
|
||||
author = "RERE",
|
||||
source = MangaSource.DUMMY.name,
|
||||
)
|
||||
val json = JsonSerializer(entity).toJson()
|
||||
val result = JsonDeserializer(json).toMangaEntity()
|
||||
assertEquals(entity, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toTagEntity() {
|
||||
val entity = TagEntity(
|
||||
id = 934023534,
|
||||
title = "Adventure",
|
||||
key = "adventure",
|
||||
source = MangaSource.DUMMY.name,
|
||||
)
|
||||
val json = JsonSerializer(entity).toJson()
|
||||
val result = JsonDeserializer(json).toTagEntity()
|
||||
assertEquals(entity, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toHistoryEntity() {
|
||||
val entity = HistoryEntity(
|
||||
mangaId = 304135341,
|
||||
createdAt = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(6),
|
||||
updatedAt = System.currentTimeMillis(),
|
||||
chapterId = 29014843034,
|
||||
page = 35,
|
||||
scroll = 24.0f,
|
||||
percent = 0.6f,
|
||||
)
|
||||
val json = JsonSerializer(entity).toJson()
|
||||
val result = JsonDeserializer(json).toHistoryEntity()
|
||||
assertEquals(entity, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun toFavouriteCategoryEntity() {
|
||||
val entity = FavouriteCategoryEntity(
|
||||
categoryId = 142,
|
||||
createdAt = System.currentTimeMillis(),
|
||||
sortKey = 14,
|
||||
title = "Read later",
|
||||
order = SortOrder.RATING.name,
|
||||
track = false,
|
||||
)
|
||||
val json = JsonSerializer(entity).toJson()
|
||||
val result = JsonDeserializer(json).toFavouriteCategoryEntity()
|
||||
assertEquals(entity, result)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user