feat: parse Web element from ComicInfo.xml

closes #750
This commit is contained in:
Gauthier Roebroeck 2021-12-28 16:51:29 +08:00
parent 4f6f85c474
commit 5a464fd13e
10 changed files with 324 additions and 27 deletions

View file

@ -0,0 +1,10 @@
CREATE TABLE BOOK_METADATA_LINK
(
LABEL varchar NOT NULL,
URL varchar NOT NULL,
BOOK_ID varchar NOT NULL,
FOREIGN KEY (BOOK_ID) REFERENCES BOOK (ID)
);
alter table book_metadata
add column LINKS_LOCK boolean NOT NULL DEFAULT 0;

View file

@ -12,6 +12,7 @@ class BookMetadata(
val authors: List<Author> = emptyList(),
tags: Set<String> = emptySet(),
val isbn: String = "",
val links: List<WebLink> = emptyList(),
val titleLock: Boolean = false,
val summaryLock: Boolean = false,
@ -21,6 +22,7 @@ class BookMetadata(
val authorsLock: Boolean = false,
val tagsLock: Boolean = false,
val isbnLock: Boolean = false,
val linksLock: Boolean = false,
val bookId: String = "",
@ -42,6 +44,7 @@ class BookMetadata(
authors: List<Author> = this.authors.toList(),
tags: Set<String> = this.tags,
isbn: String = this.isbn,
links: List<WebLink> = this.links,
titleLock: Boolean = this.titleLock,
summaryLock: Boolean = this.summaryLock,
numberLock: Boolean = this.numberLock,
@ -50,9 +53,10 @@ class BookMetadata(
authorsLock: Boolean = this.authorsLock,
tagsLock: Boolean = this.tagsLock,
isbnLock: Boolean = this.isbnLock,
linksLock: Boolean = this.linksLock,
bookId: String = this.bookId,
createdDate: LocalDateTime = this.createdDate,
lastModifiedDate: LocalDateTime = this.lastModifiedDate
lastModifiedDate: LocalDateTime = this.lastModifiedDate,
) =
BookMetadata(
title = title,
@ -63,6 +67,7 @@ class BookMetadata(
authors = authors,
tags = tags,
isbn = isbn,
links = links,
titleLock = titleLock,
summaryLock = summaryLock,
numberLock = numberLock,
@ -71,11 +76,12 @@ class BookMetadata(
authorsLock = authorsLock,
tagsLock = tagsLock,
isbnLock = isbnLock,
linksLock = linksLock,
bookId = bookId,
createdDate = createdDate,
lastModifiedDate = lastModifiedDate
lastModifiedDate = lastModifiedDate,
)
override fun toString(): String =
"BookMetadata(numberSort=$numberSort, releaseDate=$releaseDate, authors=$authors, isbn='$isbn', titleLock=$titleLock, summaryLock=$summaryLock, numberLock=$numberLock, numberSortLock=$numberSortLock, releaseDateLock=$releaseDateLock, authorsLock=$authorsLock, tagsLock=$tagsLock, isbnLock=$isbnLock, bookId='$bookId', createdDate=$createdDate, lastModifiedDate=$lastModifiedDate, title='$title', summary='$summary', number='$number', tags=$tags)"
"BookMetadata(numberSort=$numberSort, releaseDate=$releaseDate, authors=$authors, isbn='$isbn', links=$links, titleLock=$titleLock, summaryLock=$summaryLock, numberLock=$numberLock, numberSortLock=$numberSortLock, releaseDateLock=$releaseDateLock, authorsLock=$authorsLock, tagsLock=$tagsLock, isbnLock=$isbnLock, linksLock=$linksLock, bookId='$bookId', createdDate=$createdDate, lastModifiedDate=$lastModifiedDate, title='$title', summary='$summary', number='$number', tags=$tags)"
}

View file

@ -10,6 +10,7 @@ data class BookMetadataPatch(
val releaseDate: LocalDate? = null,
val authors: List<Author>? = null,
val isbn: String? = null,
val links: List<WebLink>? = null,
val readLists: List<ReadListEntry> = emptyList()
) {
@ -30,4 +31,5 @@ enum class BookMetadataPatchCapability {
ISBN,
READ_LISTS,
THUMBNAILS,
LINKS,
}

View file

@ -0,0 +1,8 @@
package org.gotson.komga.domain.model
import java.net.URI
data class WebLink(
val label: String,
val url: URI,
)

View file

@ -23,6 +23,7 @@ class MetadataApplier {
releaseDate = getIfNotLocked(releaseDate, patch.releaseDate, releaseDateLock),
authors = getIfNotLocked(authors, patch.authors, authorsLock),
isbn = getIfNotLocked(isbn, patch.isbn, isbnLock),
links = getIfNotLocked(links, patch.links, linksLock),
)
}
@ -38,7 +39,7 @@ class MetadataApplier {
publisher = getIfNotLocked(publisher, patch.publisher, publisherLock),
language = getIfNotLocked(language, patch.language, languageLock),
genres = getIfNotLocked(genres, patch.genres, genresLock),
totalBookCount = getIfNotLocked(totalBookCount, patch.totalBookCount, totalBookCountLock)
totalBookCount = getIfNotLocked(totalBookCount, patch.totalBookCount, totalBookCountLock),
)
}
}

View file

@ -2,6 +2,7 @@ package org.gotson.komga.infrastructure.jooq
import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.BookMetadata
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.persistence.BookMetadataRepository
import org.gotson.komga.jooq.Tables
import org.gotson.komga.jooq.tables.records.BookMetadataAuthorRecord
@ -10,6 +11,7 @@ import org.jooq.DSLContext
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.net.URI
import java.time.LocalDateTime
import java.time.ZoneId
@ -22,6 +24,7 @@ class BookMetadataDao(
private val d = Tables.BOOK_METADATA
private val a = Tables.BOOK_METADATA_AUTHOR
private val bt = Tables.BOOK_METADATA_TAG
private val bl = Tables.BOOK_METADATA_LINK
private val groupFields = arrayOf(*d.fields(), *a.fields())
@ -41,9 +44,9 @@ class BookMetadataDao(
.where(d.BOOK_ID.`in`(bookIds))
.groupBy(*groupFields)
.fetchGroups(
{ it.into(d) }, { it.into(a) }
{ it.into(d) }, { it.into(a) },
).map { (dr, ar) ->
dr.toDomain(ar.filterNot { it.name == null }.map { it.toDomain() }, findTags(dr.bookId))
dr.toDomain(ar.filterNot { it.name == null }.map { it.toDomain() }, findTags(dr.bookId), findLinks(dr.bookId))
}
private fun findTags(bookId: String) =
@ -54,6 +57,13 @@ class BookMetadataDao(
.mapNotNull { it.tag }
.toSet()
private fun findLinks(bookId: String) =
dsl.select(bl.LABEL, bl.URL)
.from(bl)
.where(bl.BOOK_ID.eq(bookId))
.fetchInto(bl)
.map { WebLink(it.label, URI(it.url)) }
@Transactional
override fun insert(metadata: BookMetadata) {
insert(listOf(metadata))
@ -80,8 +90,9 @@ class BookMetadataDao(
d.AUTHORS_LOCK,
d.TAGS_LOCK,
d.ISBN,
d.ISBN_LOCK
).values(null as String?, null, null, null, null, null, null, null, null, null, null, null, null, null, null)
d.ISBN_LOCK,
d.LINKS_LOCK,
).values(null as String?, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null),
).also { step ->
chunk.forEach {
step.bind(
@ -99,7 +110,8 @@ class BookMetadataDao(
it.authorsLock,
it.tagsLock,
it.isbn,
it.isbnLock
it.isbnLock,
it.linksLock,
)
}
}.execute()
@ -107,6 +119,7 @@ class BookMetadataDao(
insertAuthors(metadatas)
insertTags(metadatas)
insertLinks(metadatas)
}
}
@ -136,6 +149,7 @@ class BookMetadataDao(
.set(d.TAGS_LOCK, metadata.tagsLock)
.set(d.ISBN, metadata.isbn)
.set(d.ISBN_LOCK, metadata.isbnLock)
.set(d.LINKS_LOCK, metadata.linksLock)
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
.where(d.BOOK_ID.eq(metadata.bookId))
.execute()
@ -146,9 +160,13 @@ class BookMetadataDao(
dsl.deleteFrom(bt)
.where(bt.BOOK_ID.eq(metadata.bookId))
.execute()
dsl.deleteFrom(bl)
.where(bl.BOOK_ID.eq(metadata.bookId))
.execute()
insertAuthors(listOf(metadata))
insertTags(listOf(metadata))
insertLinks(listOf(metadata))
}
private fun insertAuthors(metadatas: Collection<BookMetadata>) {
@ -156,7 +174,7 @@ class BookMetadataDao(
metadatas.chunked(batchSize).forEach { chunk ->
dsl.batch(
dsl.insertInto(a, a.BOOK_ID, a.NAME, a.ROLE)
.values(null as String?, null, null)
.values(null as String?, null, null),
).also { step ->
chunk.forEach { metadata ->
metadata.authors.forEach {
@ -173,7 +191,7 @@ class BookMetadataDao(
metadatas.chunked(batchSize).forEach { chunk ->
dsl.batch(
dsl.insertInto(bt, bt.BOOK_ID, bt.TAG)
.values(null as String?, null)
.values(null as String?, null),
).also { step ->
chunk.forEach { metadata ->
metadata.tags.forEach {
@ -185,10 +203,28 @@ class BookMetadataDao(
}
}
private fun insertLinks(metadatas: Collection<BookMetadata>) {
if (metadatas.any { it.links.isNotEmpty() }) {
metadatas.chunked(batchSize).forEach { chunk ->
dsl.batch(
dsl.insertInto(bl, bl.BOOK_ID, bl.LABEL, bl.URL)
.values(null as String?, null, null),
).also { step ->
chunk.forEach { metadata ->
metadata.links.forEach {
step.bind(metadata.bookId, it.label, it.url.toString())
}
}
}.execute()
}
}
}
@Transactional
override fun delete(bookId: String) {
dsl.deleteFrom(a).where(a.BOOK_ID.eq(bookId)).execute()
dsl.deleteFrom(bt).where(bt.BOOK_ID.eq(bookId)).execute()
dsl.deleteFrom(bl).where(bl.BOOK_ID.eq(bookId)).execute()
dsl.deleteFrom(d).where(d.BOOK_ID.eq(bookId)).execute()
}
@ -198,12 +234,13 @@ class BookMetadataDao(
dsl.deleteFrom(a).where(a.BOOK_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(bt).where(bt.BOOK_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(bl).where(bl.BOOK_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(d).where(d.BOOK_ID.`in`(dsl.selectTempStrings())).execute()
}
override fun count(): Long = dsl.fetchCount(d).toLong()
private fun BookMetadataRecord.toDomain(authors: List<Author>, tags: Set<String>) =
private fun BookMetadataRecord.toDomain(authors: List<Author>, tags: Set<String>, links: List<WebLink>) =
BookMetadata(
title = title,
summary = summary,
@ -213,6 +250,7 @@ class BookMetadataDao(
authors = authors,
tags = tags,
isbn = isbn,
links = links,
bookId = bookId,
@ -227,11 +265,12 @@ class BookMetadataDao(
authorsLock = authorsLock,
tagsLock = tagsLock,
isbnLock = isbnLock,
linksLock = linksLock,
)
private fun BookMetadataAuthorRecord.toDomain() =
Author(
name = name,
role = role
role = role,
)
}

View file

@ -8,6 +8,7 @@ import org.gotson.komga.domain.model.BookMetadataPatchCapability
import org.gotson.komga.domain.model.BookWithMedia
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.SeriesMetadataPatch
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.service.BookAnalyzer
import org.gotson.komga.infrastructure.metadata.BookMetadataProvider
import org.gotson.komga.infrastructure.metadata.SeriesMetadataFromBookProvider
@ -16,6 +17,7 @@ import org.gotson.komga.infrastructure.metadata.comicrack.dto.Manga
import org.gotson.komga.infrastructure.validation.BCP47TagValidator
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import java.net.URI
import java.time.LocalDate
private val logger = KotlinLogging.logger {}
@ -37,6 +39,7 @@ class ComicInfoProvider(
BookMetadataPatchCapability.RELEASE_DATE,
BookMetadataPatchCapability.AUTHORS,
BookMetadataPatchCapability.READ_LISTS,
BookMetadataPatchCapability.LINKS,
)
override fun getBookMetadataFromBook(book: BookWithMedia): BookMetadataPatch? {
@ -81,6 +84,16 @@ class ComicInfoProvider(
}
}
val link = comicInfo.web?.let {
try {
val uri = URI(it)
listOf(WebLink(uri.host, uri))
} catch (e: Exception) {
logger.error(e) { "Could not parse Web element as valid URI: $it" }
null
}
}
return BookMetadataPatch(
title = comicInfo.title?.ifBlank { null },
summary = comicInfo.summary?.ifBlank { null },
@ -88,7 +101,8 @@ class ComicInfoProvider(
numberSort = comicInfo.number?.toFloatOrNull(),
releaseDate = releaseDate,
authors = authors.ifEmpty { null },
readLists = readLists
readLists = readLists,
links = link,
)
}
return null

View file

@ -0,0 +1,190 @@
package org.gotson.komga.domain.service
import org.assertj.core.api.Assertions.assertThat
import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.BookMetadata
import org.gotson.komga.domain.model.BookMetadataPatch
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.SeriesMetadataPatch
import org.gotson.komga.domain.model.WebLink
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import java.net.URI
import java.time.LocalDate
class MetadataApplierTest {
private val metadataApplier = MetadataApplier()
@Nested
inner class Book {
@Test
fun `given locked metadata when applying patch then metadata is not changed`() {
val metadata = BookMetadata(
title = "title",
number = "1",
numberSort = 1F,
titleLock = true,
summaryLock = true,
numberLock = true,
numberSortLock = true,
releaseDateLock = true,
authorsLock = true,
tagsLock = true,
isbnLock = true,
linksLock = true,
)
val patch = BookMetadataPatch(
title = "new title",
summary = "new summary",
number = "2",
numberSort = 2F,
releaseDate = LocalDate.of(2020, 12, 2),
authors = listOf(Author("Marcel", "writer")),
isbn = "9782811632397",
links = listOf(WebLink("Comixology", URI("https://www.comixology.com/Sandman/digital-comic/727888"))),
)
val patched = metadataApplier.apply(patch, metadata)
assertThat(patched.title).isEqualTo(metadata.title)
assertThat(patched.number).isEqualTo(metadata.number)
assertThat(patched.numberSort).isEqualTo(metadata.numberSort)
assertThat(patched.summary).isEqualTo("")
assertThat(patched.authors).isEmpty()
assertThat(patched.releaseDate).isNull()
assertThat(patched.tags).isEmpty()
assertThat(patched.isbn).isEqualTo("")
assertThat(patched.links).isEmpty()
}
@Test
fun `given unlocked metadata when applying patch then metadata is changed`() {
val metadata = BookMetadata(
title = "title",
number = "1",
numberSort = 1F,
)
val patch = BookMetadataPatch(
title = "new title",
summary = "new summary",
number = "2",
numberSort = 2F,
releaseDate = LocalDate.of(2020, 12, 2),
authors = listOf(Author("Marcel", "writer")),
isbn = "9782811632397",
links = listOf(WebLink("Comixology", URI("https://www.comixology.com/Sandman/digital-comic/727888"))),
)
val patched = metadataApplier.apply(patch, metadata)
assertThat(patched.title).isEqualTo(patch.title)
assertThat(patched.number).isEqualTo(patch.number)
assertThat(patched.numberSort).isEqualTo(patch.numberSort)
assertThat(patched.summary).isEqualTo(patch.summary)
assertThat(patched.authors)
.hasSize(1)
.containsExactlyInAnyOrder(
Author("Marcel", "writer"),
)
assertThat(patched.releaseDate).isEqualTo(patch.releaseDate)
assertThat(patched.tags).isEmpty()
assertThat(patched.isbn).isEqualTo(patch.isbn)
assertThat(patched.links)
.hasSize(1)
.containsExactlyInAnyOrder(
WebLink("Comixology", URI("https://www.comixology.com/Sandman/digital-comic/727888")),
)
}
}
@Nested
inner class Series {
@Test
fun `given locked metadata when applying patch then metadata is not changed`() {
val metadata = SeriesMetadata(
title = "title",
statusLock = true,
titleLock = true,
titleSortLock = true,
summaryLock = true,
readingDirectionLock = true,
publisherLock = true,
ageRatingLock = true,
languageLock = true,
genresLock = true,
tagsLock = true,
totalBookCountLock = true,
)
val patch = SeriesMetadataPatch(
title = "new title",
titleSort = "new title sort",
status = SeriesMetadata.Status.ENDED,
summary = "new summary",
readingDirection = SeriesMetadata.ReadingDirection.VERTICAL,
publisher = "new publisher",
ageRating = 12,
language = "en",
genres = setOf("shonen"),
totalBookCount = 12,
collections = emptyList(),
)
val patched = metadataApplier.apply(patch, metadata)
assertThat(patched.title).isEqualTo(metadata.title)
assertThat(patched.titleSort).isEqualTo(metadata.titleSort)
assertThat(patched.status).isEqualTo(metadata.status)
assertThat(patched.summary).isEqualTo(metadata.summary)
assertThat(patched.readingDirection).isEqualTo(metadata.readingDirection)
assertThat(patched.publisher).isEqualTo(metadata.publisher)
assertThat(patched.ageRating).isEqualTo(metadata.ageRating)
assertThat(patched.language).isEqualTo(metadata.language)
assertThat(patched.genres).isEmpty()
assertThat(patched.totalBookCount).isNull()
assertThat(patched.tags).isEmpty()
}
@Test
fun `given unlocked metadata when applying patch then metadata is changed`() {
val metadata = SeriesMetadata(
title = "title",
)
val patch = SeriesMetadataPatch(
title = "new title",
titleSort = "new title sort",
status = SeriesMetadata.Status.ENDED,
summary = "new summary",
readingDirection = SeriesMetadata.ReadingDirection.VERTICAL,
publisher = "new publisher",
ageRating = 12,
language = "en",
genres = setOf("shonen"),
totalBookCount = 12,
collections = emptyList(),
)
val patched = metadataApplier.apply(patch, metadata)
assertThat(patched.title).isEqualTo(patch.title)
assertThat(patched.titleSort).isEqualTo(patch.titleSort)
assertThat(patched.status).isEqualTo(patch.status)
assertThat(patched.summary).isEqualTo(patch.summary)
assertThat(patched.readingDirection).isEqualTo(patch.readingDirection)
assertThat(patched.publisher).isEqualTo(patch.publisher)
assertThat(patched.ageRating).isEqualTo(patch.ageRating)
assertThat(patched.language).isEqualTo(patch.language)
assertThat(patched.totalBookCount).isEqualTo(patch.totalBookCount)
assertThat(patched.genres)
.hasSize(1)
.containsExactlyInAnyOrder("shonen")
assertThat(patched.tags).isEmpty()
}
}
}

View file

@ -4,6 +4,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.catchThrowable
import org.gotson.komga.domain.model.Author
import org.gotson.komga.domain.model.BookMetadata
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.model.makeBook
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.model.makeSeries
@ -18,6 +19,7 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import java.net.URI
import java.time.LocalDate
import java.time.LocalDateTime
@ -27,7 +29,7 @@ class BookMetadataDaoTest(
@Autowired private val bookMetadataDao: BookMetadataDao,
@Autowired private val bookRepository: BookRepository,
@Autowired private val seriesRepository: SeriesRepository,
@Autowired private val libraryRepository: LibraryRepository
@Autowired private val libraryRepository: LibraryRepository,
) {
private val library = makeLibrary()
private val series = makeSeries("Series")
@ -68,6 +70,7 @@ class BookMetadataDaoTest(
authors = listOf(Author("author", "role")),
tags = setOf("tag", "another"),
isbn = "987654321",
links = listOf(WebLink("Comicvine", URI("https://comicvine.gamespot.com/doctor-strange-30-a-gathering-of-fear/4000-18731/"))),
bookId = book.id,
titleLock = true,
summaryLock = true,
@ -98,6 +101,10 @@ class BookMetadataDaoTest(
}
assertThat(created.tags).containsAll(metadata.tags)
assertThat(created.isbn).isEqualTo(metadata.isbn)
with(created.links.first()) {
assertThat(label).isEqualTo(metadata.links.first().label)
assertThat(url).isEqualTo(metadata.links.first().url)
}
assertThat(created.titleLock).isEqualTo(metadata.titleLock)
assertThat(created.summaryLock).isEqualTo(metadata.summaryLock)
@ -107,6 +114,7 @@ class BookMetadataDaoTest(
assertThat(created.authorsLock).isEqualTo(metadata.authorsLock)
assertThat(created.tagsLock).isEqualTo(metadata.tagsLock)
assertThat(created.isbnLock).isEqualTo(metadata.isbnLock)
assertThat(created.linksLock).isEqualTo(metadata.linksLock)
}
@Test
@ -115,7 +123,7 @@ class BookMetadataDaoTest(
title = "Book",
number = "1",
numberSort = 1F,
bookId = book.id
bookId = book.id,
)
bookMetadataDao.insert(metadata)
@ -131,6 +139,7 @@ class BookMetadataDaoTest(
assertThat(created.authors).isEmpty()
assertThat(created.tags).isEmpty()
assertThat(created.isbn).isBlank
assertThat(created.links).isEmpty()
assertThat(created.titleLock).isFalse
assertThat(created.summaryLock).isFalse
@ -140,6 +149,7 @@ class BookMetadataDaoTest(
assertThat(created.authorsLock).isFalse
assertThat(created.tagsLock).isFalse
assertThat(created.isbnLock).isFalse
assertThat(created.linksLock).isFalse
}
@Test
@ -152,7 +162,8 @@ class BookMetadataDaoTest(
releaseDate = LocalDate.now(),
authors = listOf(Author("author", "role")),
tags = setOf("tag"),
bookId = book.id
links = listOf(WebLink("Comicvine", URI("https://comicvine.gamespot.com/doctor-strange-30-a-gathering-of-fear/4000-18731/"))),
bookId = book.id,
)
bookMetadataDao.insert(metadata)
@ -167,6 +178,7 @@ class BookMetadataDaoTest(
authors = listOf(Author("author2", "role2")),
tags = setOf("another"),
isbn = "987654321",
links = listOf(WebLink("Bedetheque", URI("https://www.bedetheque.com/BD-AD-Grand-Riviere-Tome-1-Terre-d-election-12596.html"))),
titleLock = true,
summaryLock = true,
numberLock = true,
@ -175,6 +187,7 @@ class BookMetadataDaoTest(
authorsLock = true,
tagsLock = true,
isbnLock = true,
linksLock = true,
)
}
@ -201,10 +214,13 @@ class BookMetadataDaoTest(
assertThat(modified.authorsLock).isEqualTo(updated.authorsLock)
assertThat(modified.tagsLock).isEqualTo(updated.tagsLock)
assertThat(modified.isbnLock).isEqualTo(updated.isbnLock)
assertThat(modified.linksLock).isEqualTo(updated.linksLock)
assertThat(modified.tags).containsAll(updated.tags)
assertThat(modified.authors.first().name).isEqualTo(updated.authors.first().name)
assertThat(modified.authors.first().role).isEqualTo(updated.authors.first().role)
assertThat(modified.links.first().label).isEqualTo(updated.links.first().label)
assertThat(modified.links.first().url).isEqualTo(updated.links.first().url)
}
@Test
@ -216,7 +232,7 @@ class BookMetadataDaoTest(
numberSort = 1F,
releaseDate = LocalDate.now(),
authors = listOf(Author("author", "role")),
bookId = book.id
bookId = book.id,
)
bookMetadataDao.insert(metadata)

View file

@ -8,6 +8,7 @@ import org.gotson.komga.domain.model.BookMetadataPatch
import org.gotson.komga.domain.model.BookWithMedia
import org.gotson.komga.domain.model.Media
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.model.makeBook
import org.gotson.komga.domain.service.BookAnalyzer
import org.gotson.komga.infrastructure.metadata.comicrack.dto.AgeRating
@ -18,6 +19,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
import java.net.URI
import java.time.LocalDate
import java.util.stream.Stream
@ -34,7 +36,7 @@ class ComicInfoProviderTest {
private val media = Media(
status = Media.Status.READY,
mediaType = "application/zip",
files = listOf("ComicInfo.xml")
files = listOf("ComicInfo.xml"),
)
@Nested
@ -51,6 +53,7 @@ class ComicInfoProviderTest {
alternateSeries = "story arc"
alternateNumber = "5"
storyArc = "one, two, three"
web = "https://www.comixology.com/Sandman/digital-comic/727888"
}
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
@ -71,6 +74,11 @@ class ComicInfoProviderTest {
BookMetadataPatch.ReadListEntry("two"),
BookMetadataPatch.ReadListEntry("three"),
)
assertThat(links).hasSize(1)
assertThat(links).containsExactlyInAnyOrder(
WebLink("www.comixology.com", URI("https://www.comixology.com/Sandman/digital-comic/727888")),
)
}
}
@ -88,7 +96,7 @@ class ComicInfoProviderTest {
with(patch!!) {
assertThat(readLists).hasSize(1)
assertThat(readLists).containsExactlyInAnyOrder(
BookMetadataPatch.ReadListEntry("one", 6)
BookMetadataPatch.ReadListEntry("one", 6),
)
}
}
@ -419,13 +427,16 @@ class ComicInfoProviderTest {
}
}
fun computeSeriesFromSeriesAndVolumeArguments() = Stream.of(
Arguments.of("", null, null),
Arguments.of(null, null, null),
Arguments.of("Series", null, "Series"),
Arguments.of("Series", 1, "Series"),
Arguments.of("Series", 10, "Series (10)"),
)
companion object {
@JvmStatic
fun computeSeriesFromSeriesAndVolumeArguments(): Stream<Arguments> = Stream.of(
Arguments.of("", null, null),
Arguments.of(null, null, null),
Arguments.of("Series", null, "Series"),
Arguments.of("Series", 1, "Series"),
Arguments.of("Series", 10, "Series (10)"),
)
}
@ParameterizedTest
@MethodSource("computeSeriesFromSeriesAndVolumeArguments")