diff --git a/app/build.gradle b/app/build.gradle index daa6a7d41..9e40045c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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' diff --git a/app/src/main/java/org/koitharu/kotatsu/bookmarks/data/BookmarkEntity.kt b/app/src/main/java/org/koitharu/kotatsu/bookmarks/data/BookmarkEntity.kt index 1f348899b..f4bbba185 100644 --- a/app/src/main/java/org/koitharu/kotatsu/bookmarks/data/BookmarkEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/bookmarks/data/BookmarkEntity.kt @@ -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, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt index 7212b8569..27dd10255 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonDeserializer.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonDeserializer.kt new file mode 100644 index 000000000..96463e4a5 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonDeserializer.kt @@ -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), + ) +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonSerializer.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonSerializer.kt new file mode 100644 index 000000000..b6a035e87 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/JsonSerializer.kt @@ -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 +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt deleted file mode 100644 index 4e20b955f..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt +++ /dev/null @@ -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") - ) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt index c425f0e68..bfe64375f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaEntity.kt @@ -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, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt index fe813a02b..8c5e927c4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TagEntity.kt @@ -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, diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt index 5fe02f019..5cc62dbae 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt @@ -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, diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt index d79660a12..95ae66e87 100644 --- a/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt @@ -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 diff --git a/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt index 181499fa4..4842a36a7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt @@ -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, diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt index 230ab0d32..a4fff5d93 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt @@ -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()) } diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/AppBackupAgent.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/AppBackupAgent.kt index baa2a5217..52eb86cf0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/AppBackupAgent.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/AppBackupAgent.kt @@ -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() diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt index 79f2fc7c4..f63522140 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt @@ -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) diff --git a/app/src/test/java/org/koitharu/kotatsu/core/backup/JsonSerializerTest.kt b/app/src/test/java/org/koitharu/kotatsu/core/backup/JsonSerializerTest.kt new file mode 100644 index 000000000..45fda17ec --- /dev/null +++ b/app/src/test/java/org/koitharu/kotatsu/core/backup/JsonSerializerTest.kt @@ -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) + } +} \ No newline at end of file