mirror of
https://github.com/gotson/komga.git
synced 2026-05-08 04:22:28 +02:00
feat(api): add v2 version of referential API
supports pagination some endpoints support filtering and search
This commit is contained in:
parent
8364321034
commit
b3c83a9190
12 changed files with 2483 additions and 98 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,6 @@
|
|||
CREATE VIEW SERIES_AND_BOOK_TAG AS
|
||||
SELECT BMAT.TAG, BMAT.SERIES_ID
|
||||
FROM BOOK_METADATA_AGGREGATION_TAG BMAT
|
||||
UNION ALL
|
||||
SELECT SMT.TAG, SMT.SERIES_ID
|
||||
FROM SERIES_METADATA_TAG SMT;
|
||||
|
|
@ -11,3 +11,9 @@ data class FilterBy(
|
|||
val type: FilterByEntity,
|
||||
val ids: Set<String>,
|
||||
)
|
||||
|
||||
enum class FilterTags {
|
||||
SERIES,
|
||||
BOOK,
|
||||
BOTH,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,40 +2,47 @@ package org.gotson.komga.domain.persistence
|
|||
|
||||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.model.FilterBy
|
||||
import org.gotson.komga.domain.model.FilterTags
|
||||
import org.gotson.komga.domain.model.SearchContext
|
||||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.Pageable
|
||||
import java.time.LocalDate
|
||||
|
||||
interface ReferentialRepository {
|
||||
@Deprecated("Use findAuthors instead")
|
||||
fun findAllAuthorsByName(
|
||||
search: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): List<Author>
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
fun findAllAuthorsByNameAndLibrary(
|
||||
search: String,
|
||||
libraryId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): List<Author>
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
fun findAllAuthorsByNameAndCollection(
|
||||
search: String,
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): List<Author>
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
fun findAllAuthorsByNameAndSeries(
|
||||
search: String,
|
||||
seriesId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): List<Author>
|
||||
|
||||
@Deprecated("Use findAuthorsNames instead")
|
||||
fun findAllAuthorsNamesByName(
|
||||
search: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): List<String>
|
||||
|
||||
@Deprecated("Use findAuthorsRoles instead")
|
||||
fun findAllAuthorsRoles(filterOnLibraryIds: Collection<String>?): List<String>
|
||||
|
||||
fun findAuthors(
|
||||
|
|
@ -46,116 +53,206 @@ interface ReferentialRepository {
|
|||
pageable: Pageable,
|
||||
): Page<Author>
|
||||
|
||||
fun findAuthorsRoles(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
fun findAuthorsNames(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
role: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
fun findAllGenres(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
fun findAllGenresByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
fun findAllGenresByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
fun findGenres(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesAndBookTags(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesAndBookTagsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesAndBookTagsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesTags(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesTagsByLibrary(
|
||||
libraryId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllSeriesTagsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllBookTags(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllBookTagsBySeries(
|
||||
seriesId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
fun findAllBookTagsByReadList(
|
||||
readListId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
fun findTags(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
filterTags: FilterTags,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
fun findAllLanguages(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
fun findAllLanguagesByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
fun findAllLanguagesByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
fun findLanguages(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
fun findAllPublishers(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
fun findAllPublishers(
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
fun findAllPublishersByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
fun findAllPublishersByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
fun findPublishers(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
fun findAllAgeRatings(filterOnLibraryIds: Collection<String>?): Set<Int?>
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
fun findAllAgeRatingsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<Int?>
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
fun findAllAgeRatingsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<Int?>
|
||||
|
||||
fun findAgeRatings(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<Int>
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
fun findAllSeriesReleaseDates(filterOnLibraryIds: Collection<String>?): Set<LocalDate>
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
fun findAllSeriesReleaseDatesByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<LocalDate>
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
fun findAllSeriesReleaseDatesByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<LocalDate>
|
||||
|
||||
fun findSeriesReleaseDates(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
fun findAllSharingLabels(filterOnLibraryIds: Collection<String>?): Set<String>
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
fun findAllSharingLabelsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
fun findAllSharingLabelsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<String>
|
||||
|
||||
fun findSharingLabels(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ private val logger = KotlinLogging.logger {}
|
|||
*/
|
||||
class BookSearchHelper(
|
||||
val context: SearchContext,
|
||||
) : ContentRestrictionsSearchHelper() {
|
||||
) {
|
||||
fun toCondition(searchCondition: SearchCondition.Book?): Pair<Condition, Set<RequiredJoin>> {
|
||||
val base = toCondition()
|
||||
val search = toConditionInternal(searchCondition)
|
||||
|
|
@ -27,7 +27,7 @@ class BookSearchHelper(
|
|||
}
|
||||
|
||||
fun toCondition(): Pair<Condition, Set<RequiredJoin>> {
|
||||
val restrictions = toConditionInternal(context.restrictions)
|
||||
val restrictions = ContentRestrictionsSearchHelper(context.restrictions).toCondition()
|
||||
val authorizedLibraries = toConditionInternal(context.libraryIds)
|
||||
return restrictions.first.and(authorizedLibraries.first) to (restrictions.second + authorizedLibraries.second)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ import org.gotson.komga.jooq.main.Tables
|
|||
import org.jooq.Condition
|
||||
import org.jooq.impl.DSL
|
||||
|
||||
abstract class ContentRestrictionsSearchHelper {
|
||||
protected fun toConditionInternal(restrictions: ContentRestrictions): Pair<Condition, Set<RequiredJoin>> {
|
||||
class ContentRestrictionsSearchHelper(
|
||||
val restrictions: ContentRestrictions,
|
||||
) {
|
||||
fun toCondition(): Pair<Condition, Set<RequiredJoin>> {
|
||||
val ageAllowed =
|
||||
if (restrictions.ageRestriction?.restriction == AllowExclude.ALLOW_ONLY) {
|
||||
Tables.SERIES_METADATA.AGE_RATING.isNotNull
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ private val logger = KotlinLogging.logger {}
|
|||
*/
|
||||
class SeriesSearchHelper(
|
||||
val context: SearchContext,
|
||||
) : ContentRestrictionsSearchHelper() {
|
||||
) {
|
||||
fun toCondition(searchCondition: SearchCondition.Series?): Pair<Condition, Set<RequiredJoin>> {
|
||||
val base = toCondition()
|
||||
val search = toConditionInternal(searchCondition)
|
||||
|
|
@ -25,7 +25,7 @@ class SeriesSearchHelper(
|
|||
}
|
||||
|
||||
fun toCondition(): Pair<Condition, Set<RequiredJoin>> {
|
||||
val restrictions = toConditionInternal(context.restrictions)
|
||||
val restrictions = ContentRestrictionsSearchHelper(context.restrictions).toCondition()
|
||||
val authorizedLibraries = toConditionInternal(context.libraryIds)
|
||||
return restrictions.first.and(authorizedLibraries.first) to (restrictions.second + authorizedLibraries.second)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import org.jooq.Condition
|
|||
import org.jooq.Field
|
||||
import org.jooq.SortField
|
||||
import org.jooq.impl.DSL
|
||||
import org.springframework.data.domain.PageImpl
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.util.zip.GZIPInputStream
|
||||
|
|
@ -136,3 +139,18 @@ fun ObjectMapper.deserializeMediaExtension(
|
|||
fun rlbAlias(readListId: String) = Tables.READLIST_BOOK.`as`("RLB_$readListId")
|
||||
|
||||
fun csAlias(collectionId: String) = Tables.COLLECTION_SERIES.`as`("CS_$collectionId")
|
||||
|
||||
fun <T> buildPage(
|
||||
items: List<T>,
|
||||
pageable: Pageable,
|
||||
count: Int,
|
||||
sort: Sort?,
|
||||
): PageImpl<T> =
|
||||
PageImpl(
|
||||
items,
|
||||
if (pageable.isPaged)
|
||||
PageRequest.of(pageable.pageNumber, pageable.pageSize, sort ?: pageable.sort)
|
||||
else
|
||||
PageRequest.of(0, maxOf(count, 20), sort ?: pageable.sort),
|
||||
count.toLong(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,24 +3,35 @@ package org.gotson.komga.infrastructure.jooq.main
|
|||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.model.FilterBy
|
||||
import org.gotson.komga.domain.model.FilterByEntity
|
||||
import org.gotson.komga.domain.model.FilterTags
|
||||
import org.gotson.komga.domain.model.SearchContext
|
||||
import org.gotson.komga.domain.persistence.ReferentialRepository
|
||||
import org.gotson.komga.infrastructure.jooq.ContentRestrictionsSearchHelper
|
||||
import org.gotson.komga.infrastructure.jooq.RequiredJoin
|
||||
import org.gotson.komga.infrastructure.jooq.SplitDslDaoBase
|
||||
import org.gotson.komga.infrastructure.jooq.buildPage
|
||||
import org.gotson.komga.infrastructure.jooq.udfStripAccents
|
||||
import org.gotson.komga.infrastructure.jooq.unicode3
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.gotson.komga.jooq.main.tables.records.BookMetadataAggregationAuthorRecord
|
||||
import org.gotson.komga.jooq.main.tables.records.BookMetadataAuthorRecord
|
||||
import org.gotson.komga.language.stripAccents
|
||||
import org.jooq.Condition
|
||||
import org.jooq.DSLContext
|
||||
import org.jooq.impl.DSL.noCondition
|
||||
import org.jooq.OrderField
|
||||
import org.jooq.SelectFieldOrAsterisk
|
||||
import org.jooq.TableField
|
||||
import org.jooq.impl.DSL
|
||||
import org.jooq.impl.DSL.select
|
||||
import org.jooq.impl.TableImpl
|
||||
import org.jooq.impl.TableRecordImpl
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.data.domain.Page
|
||||
import org.springframework.data.domain.PageImpl
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.data.domain.Sort.Order
|
||||
import org.springframework.stereotype.Component
|
||||
import java.time.LocalDate
|
||||
|
||||
|
|
@ -43,7 +54,9 @@ class ReferentialDao(
|
|||
private val cs = Tables.COLLECTION_SERIES
|
||||
private val rb = Tables.READLIST_BOOK
|
||||
private val sl = Tables.SERIES_METADATA_SHARING
|
||||
private val at = Tables.SERIES_AND_BOOK_TAG
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
override fun findAllAuthorsByName(
|
||||
search: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -58,6 +71,7 @@ class ReferentialDao(
|
|||
.fetchInto(a)
|
||||
.map { it.toDomain() }
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
override fun findAllAuthorsByNameAndLibrary(
|
||||
search: String,
|
||||
libraryId: String,
|
||||
|
|
@ -75,6 +89,7 @@ class ReferentialDao(
|
|||
.fetchInto(bmaa)
|
||||
.map { it.toDomain() }
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
override fun findAllAuthorsByNameAndCollection(
|
||||
search: String,
|
||||
collectionId: String,
|
||||
|
|
@ -93,6 +108,7 @@ class ReferentialDao(
|
|||
.fetchInto(bmaa)
|
||||
.map { it.toDomain() }
|
||||
|
||||
@Deprecated("Use findAuthors instead")
|
||||
override fun findAllAuthorsByNameAndSeries(
|
||||
search: String,
|
||||
seriesId: String,
|
||||
|
|
@ -115,55 +131,23 @@ class ReferentialDao(
|
|||
role: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<Author> {
|
||||
val query =
|
||||
dslRO
|
||||
.selectDistinct(bmaa.NAME, bmaa.ROLE)
|
||||
.from(bmaa)
|
||||
.apply { if (!context.libraryIds.isNullOrEmpty() || filterBy?.type == FilterByEntity.LIBRARY) leftJoin(s).on(bmaa.SERIES_ID.eq(s.ID)) }
|
||||
.apply { if (filterBy?.type == FilterByEntity.COLLECTION) leftJoin(cs).on(bmaa.SERIES_ID.eq(cs.SERIES_ID)) }
|
||||
.apply {
|
||||
if (filterBy?.type == FilterByEntity.READLIST)
|
||||
leftJoin(b)
|
||||
.on(bmaa.SERIES_ID.eq(b.SERIES_ID))
|
||||
.leftJoin(rb)
|
||||
.on(b.ID.eq(rb.BOOK_ID))
|
||||
}.where(noCondition())
|
||||
.apply { search?.let { and(bmaa.NAME.udfStripAccents().contains(search.stripAccents())) } }
|
||||
.apply { role?.let { and(bmaa.ROLE.eq(role)) } }
|
||||
.apply { context.libraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.apply {
|
||||
filterBy?.let {
|
||||
when (it.type) {
|
||||
FilterByEntity.LIBRARY -> and(s.LIBRARY_ID.`in`(it.ids))
|
||||
FilterByEntity.COLLECTION -> and(cs.COLLECTION_ID.`in`(it.ids))
|
||||
FilterByEntity.SERIES -> and(bmaa.SERIES_ID.`in`(it.ids))
|
||||
FilterByEntity.READLIST -> and(rb.READLIST_ID.`in`(it.ids))
|
||||
}
|
||||
}
|
||||
}
|
||||
): Page<Author> = findGeneric(context, search, filterBy, pageable, bmaa, bmaa.NAME, bmaa.SERIES_ID, { it?.toDomain() }, Sort.by("name"), listOf(bmaa.ROLE), role?.let { bmaa.ROLE.eq(role) })
|
||||
|
||||
val count = dslRO.fetchCount(query)
|
||||
val sort = bmaa.NAME.unicode3()
|
||||
override fun findAuthorsRoles(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> = findGeneric(context, null, filterBy, pageable, bmaa, null, bmaa.SERIES_ID, { it?.role }, Sort.by("role"), listOf(bmaa.ROLE), sortField = bmaa.ROLE)
|
||||
|
||||
val items =
|
||||
query
|
||||
.orderBy(sort)
|
||||
.apply { if (pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) }
|
||||
.fetchInto(a)
|
||||
.map { it.toDomain() }
|
||||
|
||||
val pageSort = pageable.sort
|
||||
return PageImpl(
|
||||
items,
|
||||
if (pageable.isPaged)
|
||||
PageRequest.of(pageable.pageNumber, pageable.pageSize, pageSort)
|
||||
else
|
||||
PageRequest.of(0, maxOf(count, 20), pageSort),
|
||||
count.toLong(),
|
||||
)
|
||||
}
|
||||
override fun findAuthorsNames(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
role: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> = findGeneric(context, search, filterBy, pageable, bmaa, bmaa.NAME, bmaa.SERIES_ID, { it?.name }, Sort.by("name"), listOf(bmaa.ROLE), role?.let { bmaa.ROLE.eq(role) })
|
||||
|
||||
@Deprecated("Use findAuthorsNames instead")
|
||||
override fun findAllAuthorsNamesByName(
|
||||
search: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -177,6 +161,7 @@ class ReferentialDao(
|
|||
.orderBy(a.NAME.unicode3())
|
||||
.fetch(a.NAME)
|
||||
|
||||
@Deprecated("Use findAuthorsRoles instead")
|
||||
override fun findAllAuthorsRoles(filterOnLibraryIds: Collection<String>?): List<String> =
|
||||
dslRO
|
||||
.selectDistinct(a.ROLE)
|
||||
|
|
@ -190,6 +175,7 @@ class ReferentialDao(
|
|||
}.orderBy(a.ROLE)
|
||||
.fetch(a.ROLE)
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
override fun findAllGenres(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.selectDistinct(g.GENRE)
|
||||
|
|
@ -203,6 +189,7 @@ class ReferentialDao(
|
|||
}.orderBy(g.GENRE.unicode3())
|
||||
.fetchSet(g.GENRE)
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
override fun findAllGenresByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -217,6 +204,7 @@ class ReferentialDao(
|
|||
.orderBy(g.GENRE.unicode3())
|
||||
.fetchSet(g.GENRE)
|
||||
|
||||
@Deprecated("Use findGenres instead")
|
||||
override fun findAllGenresByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -232,6 +220,18 @@ class ReferentialDao(
|
|||
.orderBy(g.GENRE.unicode3())
|
||||
.fetchSet(g.GENRE)
|
||||
|
||||
override fun findGenres(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, search, filterBy, pageable, g, g.GENRE, g.SERIES_ID, { it?.genre }, Sort.by("genre"))
|
||||
}
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesAndBookTags(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.select(bt.TAG.`as`("tag"))
|
||||
|
|
@ -245,6 +245,7 @@ class ReferentialDao(
|
|||
.sortedBy { it.stripAccents().lowercase() }
|
||||
.toSet()
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesAndBookTagsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -267,6 +268,7 @@ class ReferentialDao(
|
|||
.sortedBy { it.stripAccents().lowercase() }
|
||||
.toSet()
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesAndBookTagsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -293,6 +295,7 @@ class ReferentialDao(
|
|||
.sortedBy { it.stripAccents().lowercase() }
|
||||
.toSet()
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesTags(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.select(st.TAG)
|
||||
|
|
@ -306,6 +309,7 @@ class ReferentialDao(
|
|||
}.orderBy(st.TAG.unicode3())
|
||||
.fetchSet(st.TAG)
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesTagsByLibrary(
|
||||
libraryId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -320,6 +324,7 @@ class ReferentialDao(
|
|||
.orderBy(st.TAG.unicode3())
|
||||
.fetchSet(st.TAG)
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllBookTagsBySeries(
|
||||
seriesId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -334,6 +339,7 @@ class ReferentialDao(
|
|||
.orderBy(bt.TAG.unicode3())
|
||||
.fetchSet(bt.TAG)
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllBookTagsByReadList(
|
||||
readListId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -350,6 +356,20 @@ class ReferentialDao(
|
|||
.orderBy(bt.TAG.unicode3())
|
||||
.fetchSet(bt.TAG)
|
||||
|
||||
override fun findTags(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
filterTags: FilterTags,
|
||||
pageable: Pageable,
|
||||
): Page<String> =
|
||||
when (filterTags) {
|
||||
FilterTags.SERIES -> findGeneric(context, search, filterBy, pageable, st, st.TAG, st.SERIES_ID, { it?.tag }, Sort.by("tag"))
|
||||
FilterTags.BOOK -> findGeneric(context, search, filterBy, pageable, bmat, bmat.TAG, bmat.SERIES_ID, { it?.tag }, Sort.by("tag"))
|
||||
FilterTags.BOTH -> findGeneric(context, search, filterBy, pageable, at, at.TAG, at.SERIES_ID, { it?.tag }, Sort.by("tag"))
|
||||
}
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllSeriesTagsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -365,6 +385,7 @@ class ReferentialDao(
|
|||
.orderBy(st.TAG.unicode3())
|
||||
.fetchSet(st.TAG)
|
||||
|
||||
@Deprecated("Use findTags instead")
|
||||
override fun findAllBookTags(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.select(bt.TAG)
|
||||
|
|
@ -378,6 +399,7 @@ class ReferentialDao(
|
|||
}.orderBy(bt.TAG.unicode3())
|
||||
.fetchSet(bt.TAG)
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
override fun findAllLanguages(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.selectDistinct(sd.LANGUAGE)
|
||||
|
|
@ -388,6 +410,7 @@ class ReferentialDao(
|
|||
.orderBy(sd.LANGUAGE)
|
||||
.fetchSet(sd.LANGUAGE)
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
override fun findAllLanguagesByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -403,6 +426,7 @@ class ReferentialDao(
|
|||
.orderBy(sd.LANGUAGE)
|
||||
.fetchSet(sd.LANGUAGE)
|
||||
|
||||
@Deprecated("Use findLanguages instead")
|
||||
override fun findAllLanguagesByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -419,6 +443,18 @@ class ReferentialDao(
|
|||
.orderBy(sd.LANGUAGE)
|
||||
.fetchSet(sd.LANGUAGE)
|
||||
|
||||
override fun findLanguages(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, search, filterBy, pageable, sd, sd.LANGUAGE, sd.SERIES_ID, { it?.language }, Sort.by("language"), extraCondition = sd.LANGUAGE.ne(""))
|
||||
}
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
override fun findAllPublishers(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.selectDistinct(sd.PUBLISHER)
|
||||
|
|
@ -429,6 +465,7 @@ class ReferentialDao(
|
|||
.orderBy(sd.PUBLISHER.unicode3())
|
||||
.fetchSet(sd.PUBLISHER)
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
override fun findAllPublishers(
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
pageable: Pageable,
|
||||
|
|
@ -461,6 +498,7 @@ class ReferentialDao(
|
|||
)
|
||||
}
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
override fun findAllPublishersByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -476,6 +514,7 @@ class ReferentialDao(
|
|||
.orderBy(sd.PUBLISHER.unicode3())
|
||||
.fetchSet(sd.PUBLISHER)
|
||||
|
||||
@Deprecated("Use findPublishers instead")
|
||||
override fun findAllPublishersByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -492,6 +531,18 @@ class ReferentialDao(
|
|||
.orderBy(sd.PUBLISHER.unicode3())
|
||||
.fetchSet(sd.PUBLISHER)
|
||||
|
||||
override fun findPublishers(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, search, filterBy, pageable, sd, sd.PUBLISHER, sd.SERIES_ID, { it?.publisher }, Sort.by("publisher"), extraCondition = sd.PUBLISHER.ne(""))
|
||||
}
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
override fun findAllAgeRatings(filterOnLibraryIds: Collection<String>?): Set<Int?> =
|
||||
dslRO
|
||||
.selectDistinct(sd.AGE_RATING)
|
||||
|
|
@ -505,6 +556,7 @@ class ReferentialDao(
|
|||
}.orderBy(sd.AGE_RATING)
|
||||
.fetchSet(sd.AGE_RATING)
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
override fun findAllAgeRatingsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -519,6 +571,7 @@ class ReferentialDao(
|
|||
.orderBy(sd.AGE_RATING)
|
||||
.fetchSet(sd.AGE_RATING)
|
||||
|
||||
@Deprecated("Use findAgeRatings instead")
|
||||
override fun findAllAgeRatingsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -534,6 +587,17 @@ class ReferentialDao(
|
|||
.orderBy(sd.AGE_RATING)
|
||||
.fetchSet(sd.AGE_RATING)
|
||||
|
||||
override fun findAgeRatings(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<Int> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, null, filterBy, pageable, sd, null, sd.SERIES_ID, { it?.ageRating }, Sort.by("ageRating"), listOf(sd.AGE_RATING), sortField = sd.AGE_RATING)
|
||||
}
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
override fun findAllSeriesReleaseDates(filterOnLibraryIds: Collection<String>?): Set<LocalDate> =
|
||||
dslRO
|
||||
.selectDistinct(bma.RELEASE_DATE)
|
||||
|
|
@ -544,6 +608,7 @@ class ReferentialDao(
|
|||
.orderBy(bma.RELEASE_DATE.desc())
|
||||
.fetchSet(bma.RELEASE_DATE)
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
override fun findAllSeriesReleaseDatesByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -559,6 +624,7 @@ class ReferentialDao(
|
|||
.orderBy(bma.RELEASE_DATE.desc())
|
||||
.fetchSet(bma.RELEASE_DATE)
|
||||
|
||||
@Deprecated("Use findSeriesReleaseDates instead")
|
||||
override fun findAllSeriesReleaseDatesByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -575,6 +641,17 @@ class ReferentialDao(
|
|||
.orderBy(bma.RELEASE_DATE.desc())
|
||||
.fetchSet(bma.RELEASE_DATE)
|
||||
|
||||
override fun findSeriesReleaseDates(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, null, filterBy, pageable, bma, null, bma.SERIES_ID, { it?.releaseDate?.year?.toString() }, Sort.by(Order.desc("year")), listOf(bma.RELEASE_DATE), sortField = bma.RELEASE_DATE.desc())
|
||||
}
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
override fun findAllSharingLabels(filterOnLibraryIds: Collection<String>?): Set<String> =
|
||||
dslRO
|
||||
.selectDistinct(sl.LABEL)
|
||||
|
|
@ -588,6 +665,7 @@ class ReferentialDao(
|
|||
}.orderBy(sl.LABEL.unicode3())
|
||||
.fetchSet(sl.LABEL)
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
override fun findAllSharingLabelsByLibraries(
|
||||
libraryIds: Set<String>,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -602,6 +680,7 @@ class ReferentialDao(
|
|||
.orderBy(sl.LABEL.unicode3())
|
||||
.fetchSet(sl.LABEL)
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
override fun findAllSharingLabelsByCollection(
|
||||
collectionId: String,
|
||||
filterOnLibraryIds: Collection<String>?,
|
||||
|
|
@ -617,6 +696,89 @@ class ReferentialDao(
|
|||
.orderBy(sl.LABEL.unicode3())
|
||||
.fetchSet(sl.LABEL)
|
||||
|
||||
override fun findSharingLabels(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, search, filterBy, pageable, sl, sl.LABEL, sl.SERIES_ID, { it?.label }, Sort.by("label"))
|
||||
}
|
||||
|
||||
private fun <R : TableRecordImpl<*>, T : TableImpl<R>, O : Any> findGeneric(
|
||||
context: SearchContext,
|
||||
search: String?,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
table: T,
|
||||
searchableField: TableField<R, String>?,
|
||||
seriesIdField: TableField<*, String>,
|
||||
mapper: (R?) -> O?,
|
||||
sort: Sort,
|
||||
extraFields: List<SelectFieldOrAsterisk> = emptyList(),
|
||||
extraCondition: Condition? = DSL.noCondition(),
|
||||
sortField: OrderField<*>? = null,
|
||||
): Page<O> {
|
||||
val restrictionCondition = ContentRestrictionsSearchHelper(context.restrictions).toCondition()
|
||||
|
||||
val query =
|
||||
dslRO
|
||||
.selectDistinct(*(listOfNotNull(searchableField) + extraFields).toTypedArray())
|
||||
.from(table)
|
||||
.apply {
|
||||
restrictionCondition.second.forEach { join ->
|
||||
when (join) {
|
||||
RequiredJoin.SeriesMetadata -> if (table != sd) innerJoin(sd).on(seriesIdField.eq(sd.SERIES_ID))
|
||||
// shouldn't be required
|
||||
RequiredJoin.BookMetadata -> Unit
|
||||
RequiredJoin.BookMetadataAggregation -> Unit
|
||||
is RequiredJoin.Collection -> Unit
|
||||
RequiredJoin.Media -> Unit
|
||||
is RequiredJoin.ReadList -> Unit
|
||||
is RequiredJoin.ReadProgress -> Unit
|
||||
}
|
||||
}
|
||||
}.apply { if (!context.libraryIds.isNullOrEmpty() || filterBy?.type == FilterByEntity.LIBRARY) leftJoin(s).on(seriesIdField.eq(s.ID)) }
|
||||
.apply { if (filterBy?.type == FilterByEntity.COLLECTION) leftJoin(cs).on(seriesIdField.eq(cs.SERIES_ID)) }
|
||||
.apply {
|
||||
if (filterBy?.type == FilterByEntity.READLIST)
|
||||
leftJoin(b)
|
||||
.on(seriesIdField.eq(b.SERIES_ID))
|
||||
.leftJoin(rb)
|
||||
.on(b.ID.eq(rb.BOOK_ID))
|
||||
}.where(restrictionCondition.first)
|
||||
.apply { extraCondition?.let { and(it) } }
|
||||
.apply { if (search != null && searchableField != null) and(searchableField.udfStripAccents().contains(search.stripAccents())) }
|
||||
.apply { context.libraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.apply {
|
||||
filterBy?.let {
|
||||
when (it.type) {
|
||||
FilterByEntity.LIBRARY -> and(s.LIBRARY_ID.`in`(it.ids))
|
||||
FilterByEntity.COLLECTION -> and(cs.COLLECTION_ID.`in`(it.ids))
|
||||
FilterByEntity.SERIES -> and(seriesIdField.`in`(it.ids))
|
||||
FilterByEntity.READLIST -> and(rb.READLIST_ID.`in`(it.ids))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val count = dslRO.fetchCount(query)
|
||||
|
||||
val items =
|
||||
query
|
||||
.apply {
|
||||
if (sortField != null)
|
||||
orderBy(sortField)
|
||||
else if (searchableField != null)
|
||||
orderBy(searchableField.unicode3())
|
||||
}.apply { if (pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) }
|
||||
.fetchInto(table)
|
||||
.mapNotNull { mapper(it) }
|
||||
|
||||
return buildPage(items, pageable, count, sort)
|
||||
}
|
||||
|
||||
private fun BookMetadataAuthorRecord.toDomain(): Author =
|
||||
Author(
|
||||
name = name,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ReferentialV1Controller(
|
|||
private val referentialRepository: ReferentialRepository,
|
||||
) {
|
||||
@GetMapping("authors")
|
||||
@Deprecated("Use GET /v2/authors instead", ReplaceWith("getAuthors"))
|
||||
@Deprecated("Use GET /v2/authors instead")
|
||||
@Operation(summary = "List authors", description = "Use GET /api/v2/authors instead. Deprecated since 1.20.0.", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getAuthorsDeprecated(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
|
|
@ -39,20 +39,26 @@ class ReferentialV1Controller(
|
|||
}.map { it.toDto() }
|
||||
|
||||
@GetMapping("authors/names")
|
||||
@Operation(summary = "List authors' names")
|
||||
@Deprecated("Use GET /v2/authors/names instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List authors' names", description = "Use GET /v2/authors/names instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getAuthorsNames(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", defaultValue = "") search: String,
|
||||
): List<String> = referentialRepository.findAllAuthorsNamesByName(search, principal.user.getAuthorizedLibraryIds(null))
|
||||
|
||||
@GetMapping("authors/roles")
|
||||
@Operation(summary = "List authors' roles")
|
||||
@Deprecated("Use GET /v2/authors/roles instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List authors' roles", description = "Use GET /v2/authors/roles instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getAuthorsRoles(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
): List<String> = referentialRepository.findAllAuthorsRoles(principal.user.getAuthorizedLibraryIds(null))
|
||||
|
||||
@GetMapping("genres")
|
||||
@Operation(summary = "List genres", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/genres instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List genres", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getGenres(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -65,7 +71,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("sharing-labels")
|
||||
@Operation(summary = "List sharing labels", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/sharing-labels instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List sharing labels", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getSharingLabels(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -78,7 +86,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("tags")
|
||||
@Operation(summary = "List tags", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -91,7 +101,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("tags/book")
|
||||
@Operation(summary = "List book tags", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List book tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getBookTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "series_id", required = false) seriesId: String?,
|
||||
|
|
@ -106,7 +118,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("tags/series")
|
||||
@Operation(summary = "List series tags", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List series tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getSeriesTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryId: String?,
|
||||
|
|
@ -119,7 +133,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("languages")
|
||||
@Operation(summary = "List languages", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/languages instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List languages", description = "Use GET /v2/languages instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getLanguages(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -132,7 +148,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("publishers")
|
||||
@Operation(summary = "List publishers", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/publishers instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List publishers", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getPublishers(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -145,7 +163,9 @@ class ReferentialV1Controller(
|
|||
}
|
||||
|
||||
@GetMapping("age-ratings")
|
||||
@Operation(summary = "List age ratings", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/age-ratings instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List age ratings", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getAgeRatings(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -158,7 +178,9 @@ class ReferentialV1Controller(
|
|||
}.map { it?.toString() ?: "None" }.toSet()
|
||||
|
||||
@GetMapping("series/release-dates")
|
||||
@Operation(summary = "List series release dates", description = "Can be filtered by various criteria")
|
||||
@Deprecated("Use GET /v2/age-ratings instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List series release dates", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getSeriesReleaseDates(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.Parameter
|
|||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import org.gotson.komga.domain.model.FilterBy
|
||||
import org.gotson.komga.domain.model.FilterByEntity
|
||||
import org.gotson.komga.domain.model.FilterTags
|
||||
import org.gotson.komga.domain.model.SearchContext
|
||||
import org.gotson.komga.domain.persistence.ReferentialRepository
|
||||
import org.gotson.komga.infrastructure.openapi.OpenApiConfiguration
|
||||
|
|
@ -36,9 +37,9 @@ class ReferentialV2Controller(
|
|||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "role", required = false) role: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionId: String?,
|
||||
@RequestParam(name = "series_id", required = false) seriesId: String?,
|
||||
@RequestParam(name = "readlist_id", required = false) readListId: String?,
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "series_id", required = false) seriesIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "readlist_id", required = false) readListIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<AuthorDto> {
|
||||
|
|
@ -51,12 +52,302 @@ class ReferentialV2Controller(
|
|||
page.pageSize,
|
||||
)
|
||||
|
||||
return when {
|
||||
libraryIds.isNotEmpty() -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.LIBRARY, libraryIds), pageRequest)
|
||||
collectionId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.COLLECTION, setOf(collectionId)), pageRequest)
|
||||
seriesId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.SERIES, setOf(seriesId)), pageRequest)
|
||||
readListId != null -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, FilterBy(FilterByEntity.READLIST, setOf(readListId)), pageRequest)
|
||||
else -> referentialRepository.findAuthors(SearchContext(principal.user), search, role, null, pageRequest)
|
||||
}.map { it.toDto() }
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
seriesIds.isNotEmpty() -> FilterBy(FilterByEntity.SERIES, seriesIds)
|
||||
readListIds.isNotEmpty() -> FilterBy(FilterByEntity.READLIST, readListIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findAuthors(SearchContext(principal.user), search, role, filterBy, pageRequest).map { it.toDto() }
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("authors/roles")
|
||||
@Operation(summary = "List authors roles", description = "Can be filtered by various criteria")
|
||||
fun getAuthorsRoles(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "series_id", required = false) seriesIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "readlist_id", required = false) readListIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
seriesIds.isNotEmpty() -> FilterBy(FilterByEntity.SERIES, seriesIds)
|
||||
readListIds.isNotEmpty() -> FilterBy(FilterByEntity.READLIST, readListIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findAuthorsRoles(SearchContext(principal.user), filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("authors/names")
|
||||
@Operation(summary = "List authors names", description = "Can be filtered by various criteria")
|
||||
fun getAuthorsNames(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "role", required = false) role: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "series_id", required = false) seriesIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "readlist_id", required = false) readListIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
seriesIds.isNotEmpty() -> FilterBy(FilterByEntity.SERIES, seriesIds)
|
||||
readListIds.isNotEmpty() -> FilterBy(FilterByEntity.READLIST, readListIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findAuthorsNames(SearchContext(principal.user), search, role, filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("genres")
|
||||
@Operation(summary = "List genres", description = "Can be filtered by various criteria")
|
||||
fun getGenres(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findGenres(SearchContext(principal.user), search, filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("sharing-labels")
|
||||
@Operation(summary = "List sharing labels", description = "Can be filtered by various criteria")
|
||||
fun getSharingLabels(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findSharingLabels(SearchContext(principal.user), search, filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("languages")
|
||||
@Operation(summary = "List languages", description = "Can be filtered by various criteria")
|
||||
fun getLanguages(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findLanguages(SearchContext(principal.user), search, filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("publishers")
|
||||
@Operation(summary = "List publishers", description = "Can be filtered by various criteria")
|
||||
fun getPublishers(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findPublishers(SearchContext(principal.user), search, filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("tags")
|
||||
@Operation(summary = "List tags", description = "Can be filtered by various criteria")
|
||||
fun getTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "search", required = false) search: String?,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "series_id", required = false) seriesIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "readlist_id", required = false) readListIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "include", required = false) includeTags: FilterTags = FilterTags.BOTH,
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
seriesIds.isNotEmpty() -> FilterBy(FilterByEntity.SERIES, seriesIds)
|
||||
readListIds.isNotEmpty() -> FilterBy(FilterByEntity.READLIST, readListIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findTags(SearchContext(principal.user), search, filterBy, includeTags, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("series/release-dates")
|
||||
@Operation(summary = "List series release dates", description = "Can be filtered by various criteria")
|
||||
fun getSeriesReleaseDates(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<String> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findSeriesReleaseDates(SearchContext(principal.user), filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("age-ratings")
|
||||
@Operation(summary = "List age ratings", description = "Can be filtered by various criteria")
|
||||
fun getAgeRatings(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "unpaged", required = false) unpaged: Boolean = false,
|
||||
@Parameter(hidden = true) page: Pageable,
|
||||
): Page<Int> {
|
||||
val pageRequest =
|
||||
if (unpaged)
|
||||
Pageable.unpaged()
|
||||
else
|
||||
PageRequest.of(
|
||||
page.pageNumber,
|
||||
page.pageSize,
|
||||
)
|
||||
|
||||
val filterBy =
|
||||
when {
|
||||
libraryIds.isNotEmpty() -> FilterBy(FilterByEntity.LIBRARY, libraryIds)
|
||||
|
||||
collectionIds.isNotEmpty() -> FilterBy(FilterByEntity.COLLECTION, collectionIds)
|
||||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findAgeRatings(SearchContext(principal.user), filterBy, pageRequest)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,773 @@
|
|||
package org.gotson.komga.infrastructure.jooq.main
|
||||
|
||||
import com.ninjasquad.springmockk.MockkBean
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.gotson.komga.domain.model.AgeRestriction
|
||||
import org.gotson.komga.domain.model.AllowExclude
|
||||
import org.gotson.komga.domain.model.Author
|
||||
import org.gotson.komga.domain.model.ContentRestrictions
|
||||
import org.gotson.komga.domain.model.FilterBy
|
||||
import org.gotson.komga.domain.model.FilterByEntity
|
||||
import org.gotson.komga.domain.model.FilterTags
|
||||
import org.gotson.komga.domain.model.KomgaUser
|
||||
import org.gotson.komga.domain.model.SearchContext
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeLibrary
|
||||
import org.gotson.komga.domain.model.makeSeries
|
||||
import org.gotson.komga.domain.persistence.BookMetadataRepository
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.KomgaUserRepository
|
||||
import org.gotson.komga.domain.persistence.LibraryRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesRepository
|
||||
import org.gotson.komga.domain.service.BookLifecycle
|
||||
import org.gotson.komga.domain.service.KomgaUserLifecycle
|
||||
import org.gotson.komga.domain.service.LibraryLifecycle
|
||||
import org.gotson.komga.domain.service.SeriesLifecycle
|
||||
import org.gotson.komga.domain.service.SeriesMetadataLifecycle
|
||||
import org.junit.jupiter.api.AfterAll
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeAll
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.data.domain.Pageable
|
||||
import java.time.LocalDate
|
||||
|
||||
@SpringBootTest
|
||||
class ReferentialDaoTest(
|
||||
@Autowired private val referentialDao: ReferentialDao,
|
||||
@Autowired private val userRepository: KomgaUserRepository,
|
||||
@Autowired private val bookRepository: BookRepository,
|
||||
@Autowired private val seriesRepository: SeriesRepository,
|
||||
@Autowired private val seriesMetadataLifecycle: SeriesMetadataLifecycle,
|
||||
@Autowired private val bookMetadataRepository: BookMetadataRepository,
|
||||
@Autowired private val bookLifecycle: BookLifecycle,
|
||||
@Autowired private val userLifecycle: KomgaUserLifecycle,
|
||||
@Autowired private val seriesLifecycle: SeriesLifecycle,
|
||||
@Autowired private val libraryRepository: LibraryRepository,
|
||||
@Autowired private val libraryLifecycle: LibraryLifecycle,
|
||||
@Autowired private val seriesMetadataRepository: SeriesMetadataRepository,
|
||||
) {
|
||||
private val library1 = makeLibrary()
|
||||
private val library2 = makeLibrary()
|
||||
private val series1 = makeSeries("Series 1").copy(libraryId = library1.id)
|
||||
private val series2 = makeSeries("Series 2").copy(libraryId = library2.id)
|
||||
private val seriesEmpty = makeSeries("Series Empty").copy(libraryId = library2.id)
|
||||
private val seriesShared = makeSeries("Series Shared").copy(libraryId = library1.id)
|
||||
private val seriesAge10 = makeSeries("Series Age 10").copy(libraryId = library1.id)
|
||||
private val userAll = KomgaUser("user1@example.org", "p")
|
||||
private val userLib1 = KomgaUser("user2@example.org", "p", sharedLibrariesIds = setOf(library1.id), sharedAllLibraries = false)
|
||||
private val userLabelAllow = KomgaUser("user3@example.org", "p", restrictions = ContentRestrictions(labelsAllow = setOf("item_shared")))
|
||||
private val userAge10 = KomgaUser("user4@example.org", "p", restrictions = ContentRestrictions(ageRestriction = AgeRestriction(10, AllowExclude.ALLOW_ONLY)))
|
||||
|
||||
@MockkBean
|
||||
private lateinit var mockEventPublisher: ApplicationEventPublisher
|
||||
|
||||
@BeforeAll
|
||||
fun setup() {
|
||||
every { mockEventPublisher.publishEvent(any()) } just Runs
|
||||
libraryRepository.insert(library1)
|
||||
libraryRepository.insert(library2)
|
||||
seriesLifecycle.createSeries(series1)
|
||||
seriesLifecycle.createSeries(series2)
|
||||
seriesLifecycle.createSeries(seriesEmpty)
|
||||
seriesLifecycle.createSeries(seriesShared)
|
||||
seriesLifecycle.createSeries(seriesAge10)
|
||||
userRepository.insert(userAll)
|
||||
userRepository.insert(userLib1)
|
||||
userRepository.insert(userLabelAllow)
|
||||
userRepository.insert(userAge10)
|
||||
|
||||
// setup restrictions context
|
||||
seriesMetadataRepository.findById(seriesShared.id).let {
|
||||
seriesMetadataRepository.update(it.copy(sharingLabels = setOf("item_shared")))
|
||||
}
|
||||
|
||||
seriesMetadataRepository.findById(seriesAge10.id).let {
|
||||
seriesMetadataRepository.update(it.copy(ageRating = 10))
|
||||
}
|
||||
|
||||
// prepare metadata
|
||||
makeBook("1", libraryId = library1.id, seriesId = series1.id).let { book ->
|
||||
seriesLifecycle.addBooks(series1, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item1", "writer")), releaseDate = LocalDate.of(2001, 1, 1), tags = setOf("bt1")))
|
||||
}
|
||||
seriesMetadataRepository.findById(series1.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item1"), sharingLabels = setOf("item1"), language = "fr", publisher = "item1", ageRating = 18, tags = setOf("st1")))
|
||||
}
|
||||
}
|
||||
seriesMetadataLifecycle.aggregateMetadata(series1)
|
||||
|
||||
makeBook("2", libraryId = library2.id, seriesId = series2.id).let { book ->
|
||||
seriesLifecycle.addBooks(series2, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item2", "inker")), releaseDate = LocalDate.of(2002, 1, 1), tags = setOf("bt2")))
|
||||
}
|
||||
seriesMetadataRepository.findById(series2.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item2"), sharingLabels = setOf("item2"), language = "en", publisher = "item2", ageRating = 19, tags = setOf("st2")))
|
||||
}
|
||||
}
|
||||
seriesMetadataLifecycle.aggregateMetadata(series2)
|
||||
|
||||
makeBook("Empty", libraryId = library2.id, seriesId = seriesEmpty.id).let { book ->
|
||||
seriesLifecycle.addBooks(seriesEmpty, listOf(book))
|
||||
}
|
||||
seriesMetadataLifecycle.aggregateMetadata(seriesEmpty)
|
||||
|
||||
makeBook("shared", libraryId = library1.id, seriesId = seriesShared.id).let { book ->
|
||||
seriesLifecycle.addBooks(seriesShared, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item_shared", "penciller")), releaseDate = LocalDate.of(2003, 1, 1), tags = setOf("bt_shared")))
|
||||
}
|
||||
seriesMetadataRepository.findById(seriesShared.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item_shared"), language = "ja", publisher = "item_shared", tags = setOf("st_shared")))
|
||||
}
|
||||
}
|
||||
seriesMetadataLifecycle.aggregateMetadata(seriesShared)
|
||||
|
||||
makeBook("10", libraryId = library1.id, seriesId = seriesAge10.id).let { book ->
|
||||
seriesLifecycle.addBooks(seriesAge10, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item_10", "cover")), releaseDate = LocalDate.of(2004, 1, 1), tags = setOf("bt_10")))
|
||||
}
|
||||
seriesMetadataRepository.findById(seriesAge10.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item_10"), sharingLabels = setOf("item_10"), language = "sp", publisher = "item_10", tags = setOf("st_10")))
|
||||
}
|
||||
}
|
||||
seriesMetadataLifecycle.aggregateMetadata(seriesAge10)
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun resetMocks() {
|
||||
every { mockEventPublisher.publishEvent(any()) } just Runs
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun deleteBooks() {
|
||||
bookLifecycle.deleteMany(bookRepository.findAll())
|
||||
assertThat(bookRepository.count()).isEqualTo(0)
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
fun tearDown() {
|
||||
every { mockEventPublisher.publishEvent(any()) } just Runs
|
||||
userRepository.findAll().forEach {
|
||||
userLifecycle.deleteUser(it)
|
||||
}
|
||||
libraryRepository.findAll().forEach {
|
||||
libraryLifecycle.deleteLibrary(it)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Author {
|
||||
@Test
|
||||
fun `given search when getting authors then matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthors(context, "shared", null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given role when getting authors then matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthors(context, null, "writer", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting authors then only matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthors(context, null, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting authors then all authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthors(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item1", "item2", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findAuthors(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item1", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findAuthors(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findAuthors(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items.map { it.name }).containsExactlyInAnyOrder("item_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class AuthorName {
|
||||
@Test
|
||||
fun `given search when getting authors then matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsNames(context, "shared", null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given role when getting authors then matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsNames(context, null, "writer", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting authors then only matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsNames(context, null, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting authors then all authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsNames(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item2", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findAuthorsNames(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findAuthorsNames(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findAuthorsNames(context, null, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class AuthorRole {
|
||||
@Test
|
||||
fun `given filter by library when getting authors then only matching authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsRoles(context, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("inker")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting authors then all authors are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAuthorsRoles(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("writer", "inker", "penciller", "cover")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findAuthorsRoles(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("writer", "penciller", "cover")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findAuthorsRoles(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("penciller")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting authors then only allowed authors are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findAuthorsRoles(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("cover")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Genre {
|
||||
@Test
|
||||
fun `given search when getting genres then all genres are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findGenres(context, "shared", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting genres then only matching genres are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findGenres(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting genres then all genres are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findGenres(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item2", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting genres then only allowed genres are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findGenres(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting genres then only allowed genres are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findGenres(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting genres then only allowed genres are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findGenres(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class BookTag {
|
||||
@Test
|
||||
fun `given search when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, "shared", null, FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting tags then only matching tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt1", "bt2", "bt_shared", "bt_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt1", "bt_shared", "bt_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOOK, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("bt_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class SeriesTag {
|
||||
@Test
|
||||
fun `given search when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, "shared", null, FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting tags then only matching tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st1", "st2", "st_shared", "st_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st1", "st_shared", "st_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.SERIES, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class BothTag {
|
||||
@Test
|
||||
fun `given search when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, "shared", null, FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_shared", "bt_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting tags then only matching tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st2", "bt2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting tags then all tags are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st1", "st2", "st_shared", "st_10", "bt1", "bt2", "bt_shared", "bt_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st1", "st_shared", "st_10", "bt1", "bt_shared", "bt_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_shared", "bt_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting tags then only allowed tags are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findTags(context, null, null, FilterTags.BOTH, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("st_10", "bt_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class SharingLabel {
|
||||
@Test
|
||||
fun `given search when getting sharing labels then all sharing labels are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSharingLabels(context, "shared", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting sharing labels then only matching sharing labels are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSharingLabels(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting sharing labels then all sharing labels are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSharingLabels(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item2", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting sharing labels then only allowed sharing labels are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findSharingLabels(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting sharing labels then only allowed sharing labels are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findSharingLabels(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting sharing labels then only allowed sharing labels are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findSharingLabels(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Publisher {
|
||||
@Test
|
||||
fun `given search when getting publishers then all publishers are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findPublishers(context, "shared", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting publishers then only matching publishers are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findPublishers(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item2")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting publishers then all publishers are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findPublishers(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item2", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting publishers then only allowed publishers are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findPublishers(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item1", "item_shared", "item_10")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting publishers then only allowed publishers are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findPublishers(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_shared")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting publishers then only allowed publishers are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findPublishers(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("item_10")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class Language {
|
||||
@Test
|
||||
fun `given search when getting languages then all languages are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findLanguages(context, "j", null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("ja")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given filter by library when getting languages then only matching languages are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findLanguages(context, null, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("en")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting languages then all languages are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findLanguages(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("fr", "en", "ja", "sp")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting languages then only allowed languages are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findLanguages(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("fr", "ja", "sp")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting languages then only allowed languages are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findLanguages(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("ja")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting languages then only allowed languages are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findLanguages(context, null, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactlyInAnyOrder("sp")
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class AgeRating {
|
||||
@Test
|
||||
fun `given filter by library when getting age ratings then only matching age ratings are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAgeRatings(context, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly(19)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting age ratings then all age ratings are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findAgeRatings(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly(10, 18, 19)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting age ratings then only allowed age ratings are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findAgeRatings(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly(10, 18)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting age ratings then only allowed age ratings are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findAgeRatings(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting age ratings then only allowed age ratings are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findAgeRatings(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly(10)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class SeriesReleaseDate {
|
||||
@Test
|
||||
fun `given filter by library when getting series release dates then only matching series release dates are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2002")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user without restrictions when getting series release dates then all series release dates are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004", "2003", "2002", "2001")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004", "2003", "2001")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2003")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted age access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004")
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue