feat: add links field in series metadata

Closes: #938
This commit is contained in:
Gauthier Roebroeck 2023-01-13 15:10:40 +08:00
parent 7303606c36
commit f9f02a395b
11 changed files with 238 additions and 9 deletions

View File

@ -31,6 +31,10 @@
<v-icon left class="hidden-xs-only">mdi-tag-multiple</v-icon>
{{ $t('dialog.edit_series.tab_tags') }}
</v-tab>
<v-tab class="justify-start" v-if="single">
<v-icon left class="hidden-xs-only">mdi-link</v-icon>
{{ $t('dialog.edit_books.tab_links') }}
</v-tab>
<v-tab class="justify-start" v-if="single">
<v-icon left class="hidden-xs-only">mdi-image</v-icon>
{{ $t('dialog.edit_series.tab_poster') }}
@ -320,6 +324,77 @@
</v-card>
</v-tab-item>
<!-- Tab: Links -->
<v-tab-item v-if="single">
<v-card flat min-height="100">
<v-container fluid>
<!-- Links -->
<v-form
v-model="linksValid"
ref="linksForm"
>
<v-row
v-for="(link, i) in form.links"
:key="i"
>
<v-col cols="4" class="py-0">
<v-text-field v-model="form.links[i].label"
:label="$t('dialog.edit_books.field_link_label')"
filled
dense
:rules="[linksLabelRules]"
@input="$v.form.links.$touch()"
@blur="$v.form.links.$touch()"
@change="form.linksLock = true"
>
<template v-slot:prepend>
<v-icon :color="form.linksLock ? 'secondary' : ''"
@click="form.linksLock = !form.linksLock"
>
{{ form.linksLock ? 'mdi-lock' : 'mdi-lock-open' }}
</v-icon>
</template>
</v-text-field>
</v-col>
<v-col cols="8" class="py-0">
<v-text-field v-model="form.links[i].url"
:label="$t('dialog.edit_books.field_link_url')"
filled
dense
:rules="[linksUrlRules]"
@input="$v.form.links.$touch()"
@blur="$v.form.links.$touch()"
@change="form.linksLock = true"
>
<template v-slot:append-outer>
<v-icon @click="form.links.splice(i, 1)">mdi-delete</v-icon>
</template>
</v-text-field>
</v-col>
</v-row>
</v-form>
<v-row>
<v-spacer/>
<v-col cols="auto">
<v-btn
elevation="2"
fab
small
bottom
right
color="primary"
@click="form.links.push({label:'', url:''})"
>
<v-icon>mdi-plus</v-icon>
</v-btn>
</v-col>
</v-row>
</v-container>
</v-card>
</v-tab-item>
<!-- Tab: Thumbnails -->
<v-tab-item v-if="single">
<v-card flat>
@ -424,6 +499,7 @@ export default Vue.extend({
return {
modal: false,
tab: 0,
linksValid: false,
form: {
status: '',
statusLock: false,
@ -449,6 +525,8 @@ export default Vue.extend({
totalBookCountLock: false,
sharingLabels: [],
sharingLabelsLock: false,
links: [],
linksLock: false,
},
mixed: {
status: false,
@ -522,6 +600,7 @@ export default Vue.extend({
readingDirection: {},
publisher: {},
totalBookCount: {minValue: minValue(1)},
links: {},
},
},
computed: {
@ -566,6 +645,20 @@ export default Vue.extend({
},
},
methods: {
linksLabelRules(label: string): boolean | string {
if (!!this.$_.trim(label)) return true
return this.$t('common.required').toString()
},
linksUrlRules(value: string): boolean | string {
let url
try {
url = new URL(value)
} catch (_) {
return this.$t('dialog.edit_books.field_link_url_error_url').toString()
}
if (url.protocol === 'http:' || url.protocol === 'https:') return true
return this.$t('dialog.edit_books.field_link_url_error_protocol').toString()
},
async loadAvailableTags() {
this.tagsAvailable = await this.$komgaReferential.getTags()
},
@ -584,7 +677,8 @@ export default Vue.extend({
},
dialogReset(series: SeriesDto | SeriesDto[]) {
this.tab = 0
this.$v.$reset()
this.$v.$reset();
(this.$refs.linksForm as any)?.resetValidation()
if (Array.isArray(series) && series.length === 0) return
if (Array.isArray(series) && series.length > 0) {
const status = this.$_.uniq(series.map(x => x.metadata.status))
@ -636,10 +730,13 @@ export default Vue.extend({
const sharingLabelsLock = this.$_.uniq(series.map(x => x.metadata.sharingLabelsLock))
this.form.sharingLabelsLock = sharingLabelsLock.length > 1 ? false : sharingLabelsLock[0]
this.form.links = []
} else {
this.form.genres = []
this.form.tags = []
this.form.sharingLabels = []
this.form.links = []
this.$_.merge(this.form, (series as SeriesDto).metadata)
this.poster.selectedThumbnail = ''
this.poster.deleteQueue = []
@ -657,7 +754,7 @@ export default Vue.extend({
}
},
validateForm(): any {
if (!this.$v.$invalid) {
if (!this.$v.$invalid && (!this.single || !this.$refs.linksForm || (this.$refs.linksForm as any).validate())) {
const metadata = {
statusLock: this.form.statusLock,
readingDirectionLock: this.form.readingDirectionLock,
@ -668,6 +765,7 @@ export default Vue.extend({
tagsLock: this.form.tagsLock,
totalBookCountLock: this.form.totalBookCountLock,
sharingLabelsLock: this.form.sharingLabelsLock,
linksLock: this.form.linksLock,
}
if (this.$v.form?.status?.$dirty) {
@ -725,6 +823,10 @@ export default Vue.extend({
if (this.$v.form?.totalBookCount?.$dirty) {
this.$_.merge(metadata, {totalBookCount: this.form.totalBookCount})
}
if (this.$v.form?.links?.$dirty || this.form.links.length != (this.series as SeriesDto).metadata.links?.length) {
this.$_.merge(metadata, {links: this.form.links})
}
}
return metadata

View File

@ -1,4 +1,4 @@
import {AuthorDto} from '@/types/komga-books'
import {AuthorDto, WebLinkDto} from '@/types/komga-books'
import {Context} from '@/types/context'
export interface SeriesDto {
@ -47,6 +47,8 @@ export interface SeriesMetadataDto {
totalBookCountLock: boolean,
sharingLabels: string[],
sharingLabelsLock: boolean,
links?: WebLinkDto[],
linksLock?: boolean
}
export interface SeriesBooksMetadataDto {
@ -84,6 +86,8 @@ export interface SeriesMetadataUpdateDto {
totalBookCountLock: boolean,
sharingLabels?: string[],
sharingLabelsLock: boolean,
links?: WebLinkDto[],
linksLock?: boolean,
}
export interface GroupCountDto {

View File

@ -331,6 +331,32 @@
</v-col>
</v-row>
<v-row v-if="series.metadata.links.length > 0" class="align-center text-caption">
<v-col class="py-1" cols="4" sm="3" md="2" xl="1">{{ $t('browse_book.links') }}</v-col>
<v-col class="py-1" cols="8" sm="9" md="10" xl="11">
<v-chip
v-for="(link, i) in series.metadata.links"
:href="link.url"
target="_blank"
class="me-2"
label
small
outlined
link
:key="i"
>
{{ link.label }}
<v-icon
x-small
color="grey"
class="ps-1"
>
mdi-open-in-new
</v-icon>
</v-chip>
</v-col>
</v-row>
<v-divider v-if="series.booksMetadata.authors.length > 0" class="my-3"/>
<v-row class="align-center text-caption"
v-for="role in displayedRoles"

View File

@ -0,0 +1,13 @@
CREATE TABLE SERIES_METADATA_LINK
(
LABEL varchar NOT NULL,
URL varchar NOT NULL,
SERIES_ID varchar NOT NULL,
FOREIGN KEY (SERIES_ID) REFERENCES SERIES (ID)
);
alter table series_metadata
add column LINKS_LOCK boolean NOT NULL DEFAULT 0;
create index idx__series_metadata_link__series_id
on SERIES_METADATA_LINK (SERIES_ID);

View File

@ -16,6 +16,7 @@ class SeriesMetadata(
tags: Set<String> = emptySet(),
val totalBookCount: Int? = null,
sharingLabels: Set<String> = emptySet(),
val links: List<WebLink> = emptyList(),
val statusLock: Boolean = false,
val titleLock: Boolean = false,
@ -29,6 +30,7 @@ class SeriesMetadata(
val tagsLock: Boolean = false,
val totalBookCountLock: Boolean = false,
val sharingLabelsLock: Boolean = false,
val linksLock: Boolean = false,
val seriesId: String = "",
@ -57,6 +59,7 @@ class SeriesMetadata(
tags: Set<String> = this.tags,
totalBookCount: Int? = this.totalBookCount,
sharingLabels: Set<String> = this.sharingLabels,
links: List<WebLink> = this.links,
statusLock: Boolean = this.statusLock,
titleLock: Boolean = this.titleLock,
titleSortLock: Boolean = this.titleSortLock,
@ -69,6 +72,7 @@ class SeriesMetadata(
tagsLock: Boolean = this.tagsLock,
totalBookCountLock: Boolean = this.totalBookCountLock,
sharingLabelsLock: Boolean = this.sharingLabelsLock,
linksLock: Boolean = this.linksLock,
seriesId: String = this.seriesId,
createdDate: LocalDateTime = this.createdDate,
lastModifiedDate: LocalDateTime = this.lastModifiedDate,
@ -86,6 +90,7 @@ class SeriesMetadata(
tags = tags,
totalBookCount = totalBookCount,
sharingLabels = sharingLabels,
links = links,
statusLock = statusLock,
titleLock = titleLock,
titleSortLock = titleSortLock,
@ -98,6 +103,7 @@ class SeriesMetadata(
tagsLock = tagsLock,
totalBookCountLock = totalBookCountLock,
sharingLabelsLock = sharingLabelsLock,
linksLock = linksLock,
seriesId = seriesId,
createdDate = createdDate,
lastModifiedDate = lastModifiedDate,
@ -115,5 +121,5 @@ class SeriesMetadata(
}
override fun toString(): String =
"SeriesMetadata(status=$status, readingDirection=$readingDirection, ageRating=$ageRating, totalBookCount=$totalBookCount, statusLock=$statusLock, titleLock=$titleLock, titleSortLock=$titleSortLock, summaryLock=$summaryLock, readingDirectionLock=$readingDirectionLock, publisherLock=$publisherLock, ageRatingLock=$ageRatingLock, languageLock=$languageLock, genresLock=$genresLock, tagsLock=$tagsLock, totalBookCountLock=$totalBookCountLock, sharingLabelsLock=$sharingLabelsLock, seriesId='$seriesId', createdDate=$createdDate, lastModifiedDate=$lastModifiedDate, title='$title', titleSort='$titleSort', summary='$summary', publisher='$publisher', language='$language', tags=$tags, genres=$genres, sharingLabels=$sharingLabels)"
"SeriesMetadata(status=$status, readingDirection=$readingDirection, ageRating=$ageRating, totalBookCount=$totalBookCount, links=$links, statusLock=$statusLock, titleLock=$titleLock, titleSortLock=$titleSortLock, summaryLock=$summaryLock, readingDirectionLock=$readingDirectionLock, publisherLock=$publisherLock, ageRatingLock=$ageRatingLock, languageLock=$languageLock, genresLock=$genresLock, tagsLock=$tagsLock, totalBookCountLock=$totalBookCountLock, sharingLabelsLock=$sharingLabelsLock, linksLock=$linksLock, seriesId='$seriesId', createdDate=$createdDate, lastModifiedDate=$lastModifiedDate, title='$title', titleSort='$titleSort', summary='$summary', publisher='$publisher', language='$language', tags=$tags, genres=$genres, sharingLabels=$sharingLabels)"
}

View File

@ -15,6 +15,7 @@ import org.gotson.komga.interfaces.api.rest.dto.BookMetadataAggregationDto
import org.gotson.komga.interfaces.api.rest.dto.GroupCountDto
import org.gotson.komga.interfaces.api.rest.dto.SeriesDto
import org.gotson.komga.interfaces.api.rest.dto.SeriesMetadataDto
import org.gotson.komga.interfaces.api.rest.dto.WebLinkDto
import org.gotson.komga.jooq.Tables
import org.gotson.komga.jooq.tables.records.BookMetadataAggregationRecord
import org.gotson.komga.jooq.tables.records.SeriesMetadataRecord
@ -60,6 +61,7 @@ class SeriesDtoDao(
private val g = Tables.SERIES_METADATA_GENRE
private val st = Tables.SERIES_METADATA_TAG
private val sl = Tables.SERIES_METADATA_SHARING
private val slk = Tables.SERIES_METADATA_LINK
private val bma = Tables.BOOK_METADATA_AGGREGATION
private val bmaa = Tables.BOOK_METADATA_AGGREGATION_AUTHOR
private val bmat = Tables.BOOK_METADATA_AGGREGATION_TAG
@ -227,6 +229,7 @@ class SeriesDtoDao(
lateinit var genres: Map<String, List<String>>
lateinit var tags: Map<String, List<String>>
lateinit var sharingLabels: Map<String, List<String>>
lateinit var links: Map<String, List<WebLinkDto>>
lateinit var aggregatedAuthors: Map<String, List<AuthorDto>>
lateinit var aggregatedTags: Map<String, List<String>>
transactionTemplate.executeWithoutResult {
@ -243,6 +246,10 @@ class SeriesDtoDao(
.where(sl.SERIES_ID.`in`(dsl.selectTempStrings()))
.groupBy({ it.seriesId }, { it.label })
links = dsl.selectFrom(slk)
.where(slk.SERIES_ID.`in`(dsl.selectTempStrings()))
.groupBy({ it.seriesId }, { WebLinkDto(it.label, it.url) })
aggregatedAuthors = dsl.selectFrom(bmaa)
.where(bmaa.SERIES_ID.`in`(dsl.selectTempStrings()))
.filter { it.name != null }
@ -268,7 +275,7 @@ class SeriesDtoDao(
booksReadCount,
booksUnreadCount,
booksInProgressCount,
dr.toDto(genres[sr.id].orEmpty().toSet(), tags[sr.id].orEmpty().toSet(), sharingLabels[sr.id].orEmpty().toSet()),
dr.toDto(genres[sr.id].orEmpty().toSet(), tags[sr.id].orEmpty().toSet(), sharingLabels[sr.id].orEmpty().toSet(), links[sr.id].orEmpty()),
bmar.toDto(aggregatedAuthors[sr.id].orEmpty(), aggregatedTags[sr.id].orEmpty().toSet()),
)
}
@ -365,7 +372,7 @@ class SeriesDtoDao(
deleted = deletedDate != null,
)
private fun SeriesMetadataRecord.toDto(genres: Set<String>, tags: Set<String>, sharingLabels: Set<String>) =
private fun SeriesMetadataRecord.toDto(genres: Set<String>, tags: Set<String>, sharingLabels: Set<String>, links: List<WebLinkDto>) =
SeriesMetadataDto(
status = status,
statusLock = statusLock,
@ -393,6 +400,8 @@ class SeriesDtoDao(
totalBookCountLock = totalBookCountLock,
sharingLabels = sharingLabels,
sharingLabelsLock = sharingLabelsLock,
links = links,
linksLock = linksLock,
)
private fun BookMetadataAggregationRecord.toDto(authors: List<AuthorDto>, tags: Set<String>) =

View File

@ -1,6 +1,7 @@
package org.gotson.komga.infrastructure.jooq
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
import org.gotson.komga.jooq.Tables
import org.gotson.komga.jooq.tables.records.SeriesMetadataRecord
@ -8,6 +9,7 @@ import org.jooq.DSLContext
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.net.URI
import java.time.LocalDateTime
import java.time.ZoneId
@ -21,12 +23,13 @@ class SeriesMetadataDao(
private val g = Tables.SERIES_METADATA_GENRE
private val st = Tables.SERIES_METADATA_TAG
private val sl = Tables.SERIES_METADATA_SHARING
private val slk = Tables.SERIES_METADATA_LINK
override fun findById(seriesId: String): SeriesMetadata =
findOne(seriesId)!!.toDomain(findGenres(seriesId), findTags(seriesId), findSharingLabels(seriesId))
findOne(seriesId)!!.toDomain(findGenres(seriesId), findTags(seriesId), findSharingLabels(seriesId), findLinks(seriesId))
override fun findByIdOrNull(seriesId: String): SeriesMetadata? =
findOne(seriesId)?.toDomain(findGenres(seriesId), findTags(seriesId), findSharingLabels(seriesId))
findOne(seriesId)?.toDomain(findGenres(seriesId), findTags(seriesId), findSharingLabels(seriesId), findLinks(seriesId))
private fun findOne(seriesId: String) =
dsl.selectFrom(d)
@ -50,6 +53,12 @@ class SeriesMetadataDao(
.from(sl)
.where(sl.SERIES_ID.eq(seriesId))
.fetchSet(sl.LABEL)
private fun findLinks(seriesId: String) =
dsl.select(slk.LABEL, slk.URL)
.from(slk)
.where(slk.SERIES_ID.eq(seriesId))
.fetchInto(slk)
.map { WebLink(it.label, URI(it.url)) }
@Transactional
override fun insert(metadata: SeriesMetadata) {
@ -76,11 +85,13 @@ class SeriesMetadataDao(
.set(d.TOTAL_BOOK_COUNT, metadata.totalBookCount)
.set(d.TOTAL_BOOK_COUNT_LOCK, metadata.totalBookCountLock)
.set(d.SHARING_LABELS_LOCK, metadata.sharingLabelsLock)
.set(d.LINKS_LOCK, metadata.linksLock)
.execute()
insertGenres(metadata)
insertTags(metadata)
insertSharingLabels(metadata)
insertLinks(metadata)
}
@Transactional
@ -107,6 +118,7 @@ class SeriesMetadataDao(
.set(d.TOTAL_BOOK_COUNT, metadata.totalBookCount)
.set(d.TOTAL_BOOK_COUNT_LOCK, metadata.totalBookCountLock)
.set(d.SHARING_LABELS_LOCK, metadata.sharingLabelsLock)
.set(d.LINKS_LOCK, metadata.linksLock)
.set(d.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
.where(d.SERIES_ID.eq(metadata.seriesId))
.execute()
@ -123,9 +135,14 @@ class SeriesMetadataDao(
.where(sl.SERIES_ID.eq(metadata.seriesId))
.execute()
dsl.deleteFrom(slk)
.where(slk.SERIES_ID.eq(metadata.seriesId))
.execute()
insertGenres(metadata)
insertTags(metadata)
insertSharingLabels(metadata)
insertLinks(metadata)
}
private fun insertGenres(metadata: SeriesMetadata) {
@ -173,11 +190,27 @@ class SeriesMetadataDao(
}
}
private fun insertLinks(metadata: SeriesMetadata) {
if (metadata.links.isNotEmpty()) {
metadata.links.chunked(batchSize).forEach { chunk ->
dsl.batch(
dsl.insertInto(slk, slk.SERIES_ID, slk.LABEL, slk.URL)
.values(null as String?, null, null),
).also { step ->
chunk.forEach {
step.bind(metadata.seriesId, it.label, it.url.toString())
}
}.execute()
}
}
}
@Transactional
override fun delete(seriesId: String) {
dsl.deleteFrom(g).where(g.SERIES_ID.eq(seriesId)).execute()
dsl.deleteFrom(st).where(st.SERIES_ID.eq(seriesId)).execute()
dsl.deleteFrom(sl).where(sl.SERIES_ID.eq(seriesId)).execute()
dsl.deleteFrom(slk).where(slk.SERIES_ID.eq(seriesId)).execute()
dsl.deleteFrom(d).where(d.SERIES_ID.eq(seriesId)).execute()
}
@ -188,12 +221,13 @@ class SeriesMetadataDao(
dsl.deleteFrom(g).where(g.SERIES_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(st).where(st.SERIES_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(sl).where(sl.SERIES_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(slk).where(slk.SERIES_ID.`in`(dsl.selectTempStrings())).execute()
dsl.deleteFrom(d).where(d.SERIES_ID.`in`(dsl.selectTempStrings())).execute()
}
override fun count(): Long = dsl.fetchCount(d).toLong()
private fun SeriesMetadataRecord.toDomain(genres: Set<String>, tags: Set<String>, sharingLabels: Set<String>) =
private fun SeriesMetadataRecord.toDomain(genres: Set<String>, tags: Set<String>, sharingLabels: Set<String>, links: List<WebLink>) =
SeriesMetadata(
status = SeriesMetadata.Status.valueOf(status),
title = title,
@ -209,6 +243,7 @@ class SeriesMetadataDao(
tags = tags,
totalBookCount = totalBookCount,
sharingLabels = sharingLabels,
links = links,
statusLock = statusLock,
titleLock = titleLock,
@ -222,6 +257,7 @@ class SeriesMetadataDao(
tagsLock = tagsLock,
totalBookCountLock = totalBookCountLock,
sharingLabelsLock = sharingLabelsLock,
linksLock = linksLock,
seriesId = seriesId,

View File

@ -30,6 +30,7 @@ import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.SeriesSearch
import org.gotson.komga.domain.model.SeriesSearchWithReadProgress
import org.gotson.komga.domain.model.ThumbnailSeries
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.persistence.BookRepository
import org.gotson.komga.domain.persistence.SeriesCollectionRepository
import org.gotson.komga.domain.persistence.SeriesMetadataRepository
@ -88,6 +89,7 @@ import org.springframework.web.multipart.MultipartFile
import org.springframework.web.server.ResponseStatusException
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody
import java.io.OutputStream
import java.net.URI
import java.nio.charset.StandardCharsets.UTF_8
import java.util.zip.Deflater
import javax.validation.Valid
@ -544,6 +546,10 @@ class SeriesController(
if (sharingLabels != null) sharingLabels!! else emptySet()
} else existing.sharingLabels,
sharingLabelsLock = sharingLabelsLock ?: existing.sharingLabelsLock,
links = if (isSet("links")) {
if (links != null) links!!.map { WebLink(it.label!!, URI(it.url!!)) } else emptyList()
} else existing.links,
linksLock = linksLock ?: existing.linksLock,
)
}
seriesMetadataRepository.update(updated)

View File

@ -52,6 +52,8 @@ data class SeriesMetadataDto(
val totalBookCountLock: Boolean,
val sharingLabels: Set<String>,
val sharingLabelsLock: Boolean,
val links: List<WebLinkDto>,
val linksLock: Boolean,
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
val created: LocalDateTime,

View File

@ -3,6 +3,7 @@ package org.gotson.komga.interfaces.api.rest.dto
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.infrastructure.validation.NullOrBlankOrBCP47
import org.gotson.komga.infrastructure.validation.NullOrNotBlank
import javax.validation.Valid
import javax.validation.constraints.Positive
import javax.validation.constraints.PositiveOrZero
import kotlin.properties.Delegates
@ -81,4 +82,12 @@ class SeriesMetadataUpdateDto {
}
var sharingLabelsLock: Boolean? = null
@get:Valid
var links: List<WebLinkUpdateDto>?
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
var linksLock: Boolean? = null
}

View File

@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.jooq
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.catchThrowable
import org.gotson.komga.domain.model.SeriesMetadata
import org.gotson.komga.domain.model.WebLink
import org.gotson.komga.domain.model.makeLibrary
import org.gotson.komga.domain.model.makeSeries
import org.gotson.komga.domain.persistence.LibraryRepository
@ -15,6 +16,7 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit.jupiter.SpringExtension
import java.net.URI
import java.time.LocalDateTime
@ExtendWith(SpringExtension::class)
@ -63,6 +65,7 @@ class SeriesMetadataDaoTest(
language = "en",
totalBookCount = 5,
sharingLabels = setOf("kids"),
links = listOf(WebLink("Comicvine", URI("https://comicvine.gamespot.com/doctor-strange/4050-2676/"))),
titleLock = true,
titleSortLock = true,
summaryLock = true,
@ -74,6 +77,7 @@ class SeriesMetadataDaoTest(
tagsLock = true,
totalBookCountLock = true,
sharingLabelsLock = true,
linksLock = true,
seriesId = series.id,
)
@ -96,6 +100,10 @@ class SeriesMetadataDaoTest(
assertThat(created.tags).containsAll(metadata.tags)
assertThat(created.totalBookCount).isEqualTo(metadata.totalBookCount)
assertThat(created.sharingLabels).containsAll(metadata.sharingLabels)
with(created.links.first()) {
assertThat(label).isEqualTo(metadata.links.first().label)
assertThat(url).isEqualTo(metadata.links.first().url)
}
assertThat(created.titleLock).isEqualTo(metadata.titleLock)
assertThat(created.titleSortLock).isEqualTo(metadata.titleSortLock)
@ -109,6 +117,7 @@ class SeriesMetadataDaoTest(
assertThat(created.tagsLock).isEqualTo(metadata.tagsLock)
assertThat(created.totalBookCountLock).isEqualTo(metadata.totalBookCountLock)
assertThat(created.sharingLabelsLock).isEqualTo(metadata.sharingLabelsLock)
assertThat(created.linksLock).isEqualTo(metadata.linksLock)
}
@Test
@ -140,6 +149,7 @@ class SeriesMetadataDaoTest(
assertThat(created.tags).isEmpty()
assertThat(created.totalBookCount).isNull()
assertThat(created.sharingLabels).isEmpty()
assertThat(created.links).isEmpty()
assertThat(created.titleLock).isFalse
assertThat(created.titleSortLock).isFalse
@ -153,6 +163,7 @@ class SeriesMetadataDaoTest(
assertThat(created.tagsLock).isFalse
assertThat(created.totalBookCountLock).isFalse
assertThat(created.sharingLabelsLock).isFalse
assertThat(created.linksLock).isFalse
}
@Test
@ -205,6 +216,7 @@ class SeriesMetadataDaoTest(
tags = setOf("tag"),
totalBookCount = 3,
sharingLabels = setOf("kids"),
links = listOf(WebLink("Comicvine", URI("https://comicvine.gamespot.com/doctor-strange/4050-2676/"))),
seriesId = series.id,
)
seriesMetadataDao.insert(metadata)
@ -226,6 +238,7 @@ class SeriesMetadataDaoTest(
tags = setOf("Another"),
totalBookCount = 8,
sharingLabels = setOf("adult"),
links = emptyList(),
statusLock = true,
titleLock = true,
titleSortLock = true,
@ -238,6 +251,7 @@ class SeriesMetadataDaoTest(
tagsLock = true,
totalBookCountLock = true,
sharingLabelsLock = true,
linksLock = true,
)
}
@ -261,6 +275,7 @@ class SeriesMetadataDaoTest(
assertThat(modified.tags).containsAll(updated.tags)
assertThat(modified.totalBookCount).isEqualTo(updated.totalBookCount)
assertThat(modified.sharingLabels).containsAll(updated.sharingLabels)
assertThat(modified.links).isEmpty()
assertThat(modified.titleLock).isTrue
assertThat(modified.titleSortLock).isTrue
@ -274,5 +289,6 @@ class SeriesMetadataDaoTest(
assertThat(modified.tagsLock).isTrue
assertThat(modified.totalBookCountLock).isTrue
assertThat(modified.sharingLabelsLock).isTrue
assertThat(modified.linksLock).isTrue
}
}