Merge branch 'devel' into feature/nextgen
This commit is contained in:
8
app/src/androidTest/assets/categories/simple.json
Normal file
8
app/src/androidTest/assets/categories/simple.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"id": 4,
|
||||
"title": "Read later",
|
||||
"sortKey": 1,
|
||||
"order": "NEWEST",
|
||||
"createdAt": 1335906000000,
|
||||
"isTrackingEnabled": true
|
||||
}
|
||||
35
app/src/androidTest/assets/manga/header.json
Normal file
35
app/src/androidTest/assets/manga/header.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"id": -2096681732556647985,
|
||||
"title": "Странствия Эманон",
|
||||
"url": "/stranstviia_emanon",
|
||||
"publicUrl": "https://readmanga.io/stranstviia_emanon",
|
||||
"rating": 0.9400894,
|
||||
"isNsfw": true,
|
||||
"coverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_p.jpg",
|
||||
"tags": [
|
||||
{
|
||||
"title": "Сверхъестественное",
|
||||
"key": "supernatural",
|
||||
"source": "READMANGA_RU"
|
||||
},
|
||||
{
|
||||
"title": "Сэйнэн",
|
||||
"key": "seinen",
|
||||
"source": "READMANGA_RU"
|
||||
},
|
||||
{
|
||||
"title": "Повседневность",
|
||||
"key": "slice_of_life",
|
||||
"source": "READMANGA_RU"
|
||||
},
|
||||
{
|
||||
"title": "Приключения",
|
||||
"key": "adventure",
|
||||
"source": "READMANGA_RU"
|
||||
}
|
||||
],
|
||||
"state": "FINISHED",
|
||||
"largeCoverUrl": "https://staticrm.rmr.rocks/uploads/pics/01/12/559_o.jpg",
|
||||
"description": null,
|
||||
"source": "READMANGA_RU"
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.koitharu.kotatsu
|
||||
|
||||
import android.app.Instrumentation
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
suspend fun Instrumentation.awaitForIdle() = suspendCoroutine<Unit> { cont ->
|
||||
waitForIdle { cont.resume(Unit) }
|
||||
}
|
||||
54
app/src/androidTest/java/org/koitharu/kotatsu/SampleData.kt
Normal file
54
app/src/androidTest/java/org/koitharu/kotatsu/SampleData.kt
Normal file
@@ -0,0 +1,54 @@
|
||||
package org.koitharu.kotatsu
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.squareup.moshi.*
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import okio.buffer
|
||||
import okio.source
|
||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object SampleData {
|
||||
|
||||
private val moshi = Moshi.Builder()
|
||||
.add(DateAdapter())
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
|
||||
val manga: Manga = loadAsset("manga/header.json", Manga::class)
|
||||
|
||||
val mangaDetails: Manga = loadAsset("manga/full.json", Manga::class)
|
||||
|
||||
val tag = mangaDetails.tags.elementAt(2)
|
||||
|
||||
val chapter = checkNotNull(mangaDetails.chapters)[2]
|
||||
|
||||
val favouriteCategory: FavouriteCategory = loadAsset("categories/simple.json", FavouriteCategory::class)
|
||||
|
||||
fun <T : Any> loadAsset(name: String, cls: KClass<T>): T {
|
||||
val assets = InstrumentationRegistry.getInstrumentation().context.assets
|
||||
return assets.open(name).use {
|
||||
moshi.adapter(cls.java).fromJson(it.source().buffer())
|
||||
} ?: throw RuntimeException("Cannot read asset from json \"$name\"")
|
||||
}
|
||||
|
||||
private class DateAdapter : JsonAdapter<Date>() {
|
||||
|
||||
@FromJson
|
||||
override fun fromJson(reader: JsonReader): Date? {
|
||||
val ms = reader.nextLong()
|
||||
return if (ms == 0L) {
|
||||
null
|
||||
} else {
|
||||
Date(ms)
|
||||
}
|
||||
}
|
||||
|
||||
@ToJson
|
||||
override fun toJson(writer: JsonWriter, value: Date?) {
|
||||
writer.value(value?.time ?: 0L)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,12 @@ package org.koitharu.kotatsu.core.db
|
||||
import androidx.room.testing.MigrationTestHelper
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import java.io.IOException
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koitharu.kotatsu.core.db.migrations.*
|
||||
import java.io.IOException
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MangaDatabaseTest {
|
||||
@@ -21,17 +22,15 @@ class MangaDatabaseTest {
|
||||
@Test
|
||||
@Throws(IOException::class)
|
||||
fun migrateAll() {
|
||||
helper.createDatabase(TEST_DB, 1).apply {
|
||||
// TODO execSQL("")
|
||||
close()
|
||||
}
|
||||
assertEquals(DATABASE_VERSION, migrations.last().endVersion)
|
||||
helper.createDatabase(TEST_DB, 1).close()
|
||||
for (migration in migrations) {
|
||||
helper.runMigrationsAndValidate(
|
||||
TEST_DB,
|
||||
migration.endVersion,
|
||||
true,
|
||||
migration
|
||||
)
|
||||
).close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +49,8 @@ class MangaDatabaseTest {
|
||||
Migration8To9(),
|
||||
Migration9To10(),
|
||||
Migration10To11(),
|
||||
Migration11To12(),
|
||||
Migration12To13(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.koitharu.kotatsu.core.os
|
||||
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.koitharu.kotatsu.SampleData
|
||||
import org.koitharu.kotatsu.awaitForIdle
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ShortcutsUpdaterTest : KoinTest {
|
||||
|
||||
private val historyRepository by inject<HistoryRepository>()
|
||||
private val shortcutsUpdater by inject<ShortcutsUpdater>()
|
||||
private val database by inject<MangaDatabase>()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
database.clearAllTables()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testUpdateShortcuts() = runTest {
|
||||
awaitUpdate()
|
||||
assertTrue(getShortcuts().isEmpty())
|
||||
historyRepository.addOrUpdate(
|
||||
manga = SampleData.manga,
|
||||
chapterId = SampleData.chapter.id,
|
||||
page = 4,
|
||||
scroll = 2,
|
||||
percent = 0.3f
|
||||
)
|
||||
awaitUpdate()
|
||||
|
||||
val shortcuts = getShortcuts()
|
||||
assertEquals(1, shortcuts.size)
|
||||
}
|
||||
|
||||
private fun getShortcuts(): List<ShortcutInfo> {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val manager = checkNotNull(context.getSystemService<ShortcutManager>())
|
||||
return manager.dynamicShortcuts.filterNot { it.id == "com.squareup.leakcanary.dynamic_shortcut" }
|
||||
}
|
||||
|
||||
private suspend fun awaitUpdate() {
|
||||
val instrumentation = InstrumentationRegistry.getInstrumentation()
|
||||
while (true) {
|
||||
instrumentation.awaitForIdle()
|
||||
if (shortcutsUpdater.await()) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.koitharu.kotatsu.settings.backup
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.get
|
||||
import org.koin.test.inject
|
||||
import org.koitharu.kotatsu.SampleData
|
||||
import org.koitharu.kotatsu.core.backup.BackupRepository
|
||||
import org.koitharu.kotatsu.core.db.MangaDatabase
|
||||
import org.koitharu.kotatsu.core.db.entity.toMangaTags
|
||||
import org.koitharu.kotatsu.favourites.domain.FavouritesRepository
|
||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||
import kotlin.test.*
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class AppBackupAgentTest : KoinTest {
|
||||
|
||||
private val historyRepository by inject<HistoryRepository>()
|
||||
private val favouritesRepository by inject<FavouritesRepository>()
|
||||
private val backupRepository by inject<BackupRepository>()
|
||||
private val database by inject<MangaDatabase>()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
database.clearAllTables()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBackupRestore() = runTest {
|
||||
val category = favouritesRepository.createCategory(
|
||||
title = SampleData.favouriteCategory.title,
|
||||
sortOrder = SampleData.favouriteCategory.order,
|
||||
isTrackerEnabled = SampleData.favouriteCategory.isTrackingEnabled,
|
||||
)
|
||||
favouritesRepository.addToCategory(categoryId = category.id, mangas = listOf(SampleData.manga))
|
||||
historyRepository.addOrUpdate(
|
||||
manga = SampleData.mangaDetails,
|
||||
chapterId = SampleData.mangaDetails.chapters!![2].id,
|
||||
page = 3,
|
||||
scroll = 40,
|
||||
percent = 0.2f,
|
||||
)
|
||||
val history = checkNotNull(historyRepository.getOne(SampleData.manga))
|
||||
|
||||
val agent = AppBackupAgent()
|
||||
val backup = agent.createBackupFile(get(), backupRepository)
|
||||
|
||||
database.clearAllTables()
|
||||
assertTrue(favouritesRepository.getAllManga().isEmpty())
|
||||
assertNull(historyRepository.getLastOrNull())
|
||||
|
||||
backup.inputStream().use {
|
||||
agent.restoreBackupFile(it.fd, backup.length(), backupRepository)
|
||||
}
|
||||
|
||||
assertEquals(category, favouritesRepository.getCategory(category.id))
|
||||
assertEquals(history, historyRepository.getOne(SampleData.manga))
|
||||
assertContentEquals(listOf(SampleData.manga), favouritesRepository.getManga(category.id))
|
||||
|
||||
val allTags = database.tagsDao.findTags(SampleData.tag.source.name).toMangaTags()
|
||||
assertContains(allTags, SampleData.tag)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,21 @@
|
||||
package org.koitharu.kotatsu.tracker.domain
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okio.buffer
|
||||
import okio.source
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.koin.test.KoinTest
|
||||
import org.koin.test.inject
|
||||
import org.koitharu.kotatsu.SampleData
|
||||
import org.koitharu.kotatsu.base.domain.MangaDataRepository
|
||||
import org.koitharu.kotatsu.history.domain.HistoryRepository
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TrackerTest : KoinTest {
|
||||
|
||||
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
private val mangaAdapter = moshi.adapter(Manga::class.java)
|
||||
private val historyRegistry by inject<HistoryRepository>()
|
||||
private val repository by inject<TrackingRepository>()
|
||||
private val dataRepository by inject<MangaDataRepository>()
|
||||
private val tracker by inject<Tracker>()
|
||||
@@ -178,10 +170,7 @@ class TrackerTest : KoinTest {
|
||||
}
|
||||
|
||||
private suspend fun loadManga(name: String): Manga {
|
||||
val assets = InstrumentationRegistry.getInstrumentation().context.assets
|
||||
val manga = assets.open("manga/$name").use {
|
||||
mangaAdapter.fromJson(it.source().buffer())
|
||||
} ?: throw RuntimeException("Cannot read manga from json \"$name\"")
|
||||
val manga = SampleData.loadAsset("manga/$name", Manga::class)
|
||||
dataRepository.storeManga(manga)
|
||||
return manga
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user