Implement Update of Library/Category (#235)

* Implement Update Controller tests

* Basic Threading and notify

* WIP

* Reworked using coroutines

* Use Map for JobSummary Tracking

* Change Tests

* Clean up

* Changes based on review

* Rethrow cancellationexception

* Clean up

* Fix Merge Error

* Actually handle messages

* Clean up

* Remove useless annotation
This commit is contained in:
Sascha Hahne
2021-11-10 20:08:41 +01:00
committed by GitHub
parent 14e02bee6c
commit 2cb2ded2d9
14 changed files with 419 additions and 0 deletions
@@ -0,0 +1,90 @@
package suwayomi.tachidesk.manga.controller
import io.javalin.http.Context
import io.javalin.http.HttpCode
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.runBlocking
import org.jetbrains.exposed.sql.insertAndGetId
import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.tachidesk.manga.impl.Category
import suwayomi.tachidesk.manga.impl.CategoryManga
import suwayomi.tachidesk.manga.impl.update.IUpdater
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
import suwayomi.tachidesk.manga.model.table.CategoryTable
import suwayomi.tachidesk.manga.model.table.MangaTable
import suwayomi.tachidesk.test.ApplicationTest
import suwayomi.tachidesk.test.clearTables
internal class UpdateControllerTest : ApplicationTest() {
private val ctx = mockk<Context>(relaxed = true)
@Test
fun `POST non existent Category Id should give error`() {
every { ctx.formParam("category") } returns "1"
UpdateController.categoryUpdate(ctx)
verify { ctx.status(HttpCode.BAD_REQUEST) }
val updater by DI.global.instance<IUpdater>()
assertEquals(0, updater.getStatus().value.numberOfJobs)
}
@Test
fun `POST existent Category Id should give success`() {
Category.createCategory("foo")
createLibraryManga("bar")
CategoryManga.addMangaToCategory(1, 1)
every { ctx.formParam("category") } returns "1"
UpdateController.categoryUpdate(ctx)
verify { ctx.status(HttpCode.OK) }
val updater by DI.global.instance<IUpdater>()
assertEquals(1, updater.getStatus().value.numberOfJobs)
}
@Test
fun `POST null or empty category should update library`() {
val fooCatId = Category.createCategory("foo")
val fooMangaId = createLibraryManga("foo")
CategoryManga.addMangaToCategory(fooMangaId, fooCatId)
val barCatId = Category.createCategory("bar")
val barMangaId = createLibraryManga("bar")
CategoryManga.addMangaToCategory(barMangaId, barCatId)
createLibraryManga("mangaInDefault")
every { ctx.formParam("category") } returns null
UpdateController.categoryUpdate(ctx)
verify { ctx.status(HttpCode.OK) }
val updater by DI.global.instance<IUpdater>()
assertEquals(3, updater.getStatus().value.numberOfJobs)
}
private fun createLibraryManga(
_title: String
): Int {
return transaction {
MangaTable.insertAndGetId {
it[title] = _title
it[url] = _title
it[sourceReference] = 1
it[defaultCategory] = true
it[inLibrary] = true
}.value
}
}
@AfterEach
internal fun tearDown() {
clearTables(
CategoryMangaTable,
MangaTable,
CategoryTable
)
val updater by DI.global.instance<IUpdater>()
runBlocking { updater.reset() }
}
}
@@ -0,0 +1,24 @@
package suwayomi.tachidesk.manga.impl.update
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
class TestUpdater : IUpdater {
private val updateQueue = ArrayList<UpdateJob>()
private var isRunning = false
override fun addMangaToQueue(manga: MangaDataClass) {
updateQueue.add(UpdateJob(manga))
isRunning = true
}
override fun getStatus(): StateFlow<UpdateStatus> {
return MutableStateFlow(UpdateStatus(updateQueue, isRunning))
}
override suspend fun reset() {
updateQueue.clear()
isRunning = false
}
}
@@ -18,6 +18,8 @@ import org.kodein.di.DI
import org.kodein.di.bind
import org.kodein.di.conf.global
import org.kodein.di.singleton
import suwayomi.tachidesk.manga.impl.update.IUpdater
import suwayomi.tachidesk.manga.impl.update.TestUpdater
import suwayomi.tachidesk.server.ApplicationDirs
import suwayomi.tachidesk.server.JavalinSetup
import suwayomi.tachidesk.server.ServerConfig
@@ -61,6 +63,7 @@ open class ApplicationTest {
DI.Module("Server") {
bind<ApplicationDirs>() with singleton { applicationDirs }
bind<JsonMapper>() with singleton { JavalinJackson() }
bind<IUpdater>() with singleton { TestUpdater() }
}
)