Unit tests for json (de)serialization

pull/203/head
Koitharu 4 years ago
parent 2d4c1b751e
commit 9eb5e699e1
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -123,6 +123,7 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1' debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
testImplementation 'org.json:json:20220320'
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4'
androidTestImplementation 'androidx.test:runner:1.4.0' 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 = "manga_id", index = true) val mangaId: Long,
@ColumnInfo(name = "page_id", index = true) val pageId: Long, @ColumnInfo(name = "page_id", index = true) val pageId: Long,
@ColumnInfo(name = "chapter_id") val chapterId: Long, @ColumnInfo(name = "chapter_id") val chapterId: Long,

@ -1,14 +1,12 @@
package org.koitharu.kotatsu.core.backup package org.koitharu.kotatsu.core.backup
import androidx.room.withTransaction
import org.json.JSONArray import org.json.JSONArray
import org.json.JSONObject import org.json.JSONObject
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.parsers.util.json.JSONIterator
import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.parsers.util.json.mapJSON
import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity
import org.koitharu.kotatsu.favourites.data.FavouriteEntity
import org.koitharu.kotatsu.history.data.HistoryEntity
private const val PAGE_SIZE = 10 private const val PAGE_SIZE = 10
@ -24,11 +22,11 @@ class BackupRepository(private val db: MangaDatabase) {
} }
offset += history.size offset += history.size
for (item in history) { for (item in history) {
val manga = item.manga.toJson() val manga = JsonSerializer(item.manga).toJson()
val tags = JSONArray() val tags = JSONArray()
item.tags.forEach { tags.put(it.toJson()) } item.tags.forEach { tags.put(JsonSerializer(it).toJson()) }
manga.put("tags", tags) manga.put("tags", tags)
val json = item.history.toJson() val json = JsonSerializer(item.history).toJson()
json.put("manga", manga) json.put("manga", manga)
entry.data.put(json) entry.data.put(json)
} }
@ -40,7 +38,7 @@ class BackupRepository(private val db: MangaDatabase) {
val entry = BackupEntry(BackupEntry.CATEGORIES, JSONArray()) val entry = BackupEntry(BackupEntry.CATEGORIES, JSONArray())
val categories = db.favouriteCategoriesDao.findAll() val categories = db.favouriteCategoriesDao.findAll()
for (item in categories) { for (item in categories) {
entry.data.put(item.toJson()) entry.data.put(JsonSerializer(item).toJson())
} }
return entry return entry
} }
@ -55,11 +53,11 @@ class BackupRepository(private val db: MangaDatabase) {
} }
offset += favourites.size offset += favourites.size
for (item in favourites) { for (item in favourites) {
val manga = item.manga.toJson() val manga = JsonSerializer(item.manga).toJson()
val tags = JSONArray() val tags = JSONArray()
item.tags.forEach { tags.put(it.toJson()) } item.tags.forEach { tags.put(JsonSerializer(it).toJson()) }
manga.put("tags", tags) manga.put("tags", tags)
val json = item.favourite.toJson() val json = JsonSerializer(item.favourite).toJson()
json.put("manga", manga) json.put("manga", manga)
entry.data.put(json) entry.data.put(json)
} }
@ -77,60 +75,54 @@ class BackupRepository(private val db: MangaDatabase) {
return entry return entry
} }
private fun MangaEntity.toJson(): JSONObject { suspend fun restoreHistory(entry: BackupEntry): CompositeResult {
val jo = JSONObject() val result = CompositeResult()
jo.put("id", id) for (item in entry.data.JSONIterator()) {
jo.put("title", title) val mangaJson = item.getJSONObject("manga")
jo.put("alt_title", altTitle) val manga = JsonDeserializer(mangaJson).toMangaEntity()
jo.put("url", url) val tags = mangaJson.getJSONArray("tags").mapJSON {
jo.put("public_url", publicUrl) JsonDeserializer(it).toTagEntity()
jo.put("rating", rating) }
jo.put("nsfw", isNsfw) val history = JsonDeserializer(item).toHistoryEntity()
jo.put("cover_url", coverUrl) result += runCatching {
jo.put("large_cover_url", largeCoverUrl) db.withTransaction {
jo.put("state", state) db.tagsDao.upsert(tags)
jo.put("author", author) db.mangaDao.upsert(manga, tags)
jo.put("source", source) db.historyDao.upsert(history)
return jo }
} }
}
private fun TagEntity.toJson(): JSONObject { return result
val jo = JSONObject()
jo.put("id", id)
jo.put("title", title)
jo.put("key", key)
jo.put("source", source)
return jo
}
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 { suspend fun restoreCategories(entry: BackupEntry): CompositeResult {
val jo = JSONObject() val result = CompositeResult()
jo.put("category_id", categoryId) for (item in entry.data.JSONIterator()) {
jo.put("created_at", createdAt) val category = JsonDeserializer(item).toFavouriteCategoryEntity()
jo.put("sort_key", sortKey) result += runCatching {
jo.put("title", title) db.favouriteCategoriesDao.upsert(category)
jo.put("order", order) }
jo.put("track", track) }
return jo return result
} }
private fun FavouriteEntity.toJson(): JSONObject { suspend fun restoreFavourites(entry: BackupEntry): CompositeResult {
val jo = JSONObject() val result = CompositeResult()
jo.put("manga_id", mangaId) for (item in entry.data.JSONIterator()) {
jo.put("category_id", categoryId) val mangaJson = item.getJSONObject("manga")
jo.put("created_at", createdAt) val manga = JsonDeserializer(mangaJson).toMangaEntity()
return jo 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 import androidx.room.PrimaryKey
@Entity(tableName = "manga") @Entity(tableName = "manga")
class MangaEntity( data class MangaEntity(
@PrimaryKey(autoGenerate = false) @PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "manga_id") val id: Long, @ColumnInfo(name = "manga_id") val id: Long,
@ColumnInfo(name = "title") val title: String, @ColumnInfo(name = "title") val title: String,

@ -5,7 +5,7 @@ import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@Entity(tableName = "tags") @Entity(tableName = "tags")
class TagEntity( data class TagEntity(
@PrimaryKey(autoGenerate = false) @PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "tag_id") val id: Long, @ColumnInfo(name = "tag_id") val id: Long,
@ColumnInfo(name = "title") val title: String, @ColumnInfo(name = "title") val title: String,

@ -5,7 +5,7 @@ import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
@Entity(tableName = "favourite_categories") @Entity(tableName = "favourite_categories")
class FavouriteCategoryEntity( data class FavouriteCategoryEntity(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "category_id") val categoryId: Int, @ColumnInfo(name = "category_id") val categoryId: Int,
@ColumnInfo(name = "created_at") val createdAt: Long, @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 = "manga_id", index = true) val mangaId: Long,
@ColumnInfo(name = "category_id", index = true) val categoryId: Long, @ColumnInfo(name = "category_id", index = true) val categoryId: Long,
@ColumnInfo(name = "created_at") val createdAt: 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) @PrimaryKey(autoGenerate = false)
@ColumnInfo(name = "manga_id") val mangaId: Long, @ColumnInfo(name = "manga_id") val mangaId: Long,
@ColumnInfo(name = "created_at") val createdAt: 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.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module import org.koin.dsl.module
import org.koitharu.kotatsu.core.backup.BackupRepository 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.core.prefs.AppSettings
import org.koitharu.kotatsu.settings.backup.BackupViewModel import org.koitharu.kotatsu.settings.backup.BackupViewModel
import org.koitharu.kotatsu.settings.backup.RestoreViewModel import org.koitharu.kotatsu.settings.backup.RestoreViewModel
@ -18,7 +17,6 @@ val settingsModule
get() = module { get() = module {
factory { BackupRepository(get()) } factory { BackupRepository(get()) }
factory { RestoreRepository(get()) }
single(createdAtStart = true) { AppSettings(androidContext()) } single(createdAtStart = true) { AppSettings(androidContext()) }
viewModel { BackupViewModel(get(), androidContext()) } viewModel { BackupViewModel(get(), androidContext()) }

@ -6,7 +6,10 @@ import android.app.backup.BackupDataOutput
import android.app.backup.FullBackupDataOutput import android.app.backup.FullBackupDataOutput
import android.os.ParcelFileDescriptor import android.os.ParcelFileDescriptor
import kotlinx.coroutines.runBlocking 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 org.koitharu.kotatsu.core.db.MangaDatabase
import java.io.* import java.io.*
@ -63,7 +66,7 @@ class AppBackupAgent : BackupAgent() {
} }
private fun restoreBackupFile(fd: FileDescriptor, size: Long) { private fun restoreBackupFile(fd: FileDescriptor, size: Long) {
val repository = RestoreRepository(MangaDatabase(applicationContext)) val repository = BackupRepository(MangaDatabase(applicationContext))
val tempFile = File.createTempFile("backup_", ".tmp") val tempFile = File.createTempFile("backup_", ".tmp")
FileInputStream(fd).use { input -> FileInputStream(fd).use { input ->
tempFile.outputStream().use { output -> tempFile.outputStream().use { output ->
@ -73,9 +76,9 @@ class AppBackupAgent : BackupAgent() {
val backup = BackupZipInput(tempFile) val backup = BackupZipInput(tempFile)
try { try {
runBlocking { runBlocking {
repository.upsertHistory(backup.getEntry(BackupEntry.HISTORY)) repository.restoreHistory(backup.getEntry(BackupEntry.HISTORY))
repository.upsertCategories(backup.getEntry(BackupEntry.CATEGORIES)) repository.restoreCategories(backup.getEntry(BackupEntry.CATEGORIES))
repository.upsertFavourites(backup.getEntry(BackupEntry.FAVOURITES)) repository.restoreFavourites(backup.getEntry(BackupEntry.FAVOURITES))
} }
} finally { } finally {
backup.close() backup.close()

@ -7,9 +7,9 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible import kotlinx.coroutines.runInterruptible
import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.base.ui.BaseViewModel
import org.koitharu.kotatsu.core.backup.BackupEntry 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.BackupZipInput
import org.koitharu.kotatsu.core.backup.CompositeResult 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.SingleLiveEvent
import org.koitharu.kotatsu.utils.progress.Progress import org.koitharu.kotatsu.utils.progress.Progress
import java.io.File import java.io.File
@ -17,7 +17,7 @@ import java.io.FileNotFoundException
class RestoreViewModel( class RestoreViewModel(
uri: Uri?, uri: Uri?,
private val repository: RestoreRepository, private val repository: BackupRepository,
context: Context context: Context
) : BaseViewModel() { ) : BaseViewModel() {
@ -44,13 +44,13 @@ class RestoreViewModel(
val result = CompositeResult() val result = CompositeResult()
progress.value = Progress(0, 3) progress.value = Progress(0, 3)
result += repository.upsertHistory(backup.getEntry(BackupEntry.HISTORY)) result += repository.restoreHistory(backup.getEntry(BackupEntry.HISTORY))
progress.value = Progress(1, 3) progress.value = Progress(1, 3)
result += repository.upsertCategories(backup.getEntry(BackupEntry.CATEGORIES)) result += repository.restoreCategories(backup.getEntry(BackupEntry.CATEGORIES))
progress.value = Progress(2, 3) progress.value = Progress(2, 3)
result += repository.upsertFavourites(backup.getEntry(BackupEntry.FAVOURITES)) result += repository.restoreFavourites(backup.getEntry(BackupEntry.FAVOURITES))
progress.value = Progress(3, 3) progress.value = Progress(3, 3)
onRestoreDone.call(result) 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)
}
}
Loading…
Cancel
Save