fix(api): some metadata fields would not unset if set to null

This commit is contained in:
Gauthier Roebroeck 2021-03-10 14:30:19 +08:00
parent 6431b1f000
commit 1996071794
4 changed files with 88 additions and 12 deletions

View File

@ -0,0 +1,21 @@
package org.gotson.komga.infrastructure.validation
import org.hibernate.validator.constraints.CompositionType
import org.hibernate.validator.constraints.ConstraintComposition
import org.hibernate.validator.constraints.ISBN
import javax.validation.Constraint
import javax.validation.constraints.Null
import kotlin.reflect.KClass
@ConstraintComposition(CompositionType.OR)
@Constraint(validatedBy = [])
@Null
@Blank
@ISBN
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD, AnnotationTarget.PROPERTY_GETTER)
@Retention(AnnotationRetention.RUNTIME)
annotation class NullOrBlankOrISBN(
val message: String = "Must be null or blank or valid ISBN-13",
val groups: Array<KClass<out Any>> = [],
val payload: Array<KClass<out Any>> = []
)

View File

@ -428,7 +428,7 @@ class BookController(
existing.copy(
title = title ?: existing.title,
titleLock = titleLock ?: existing.titleLock,
summary = summary ?: existing.summary,
summary = if (isSet("summary")) summary ?: "" else existing.summary,
summaryLock = summaryLock ?: existing.summaryLock,
number = number ?: existing.number,
numberLock = numberLock ?: existing.numberLock,
@ -444,7 +444,7 @@ class BookController(
if (tags != null) tags!! else emptySet()
} else existing.tags,
tagsLock = tagsLock ?: existing.tagsLock,
isbn = isbn?.filter { it.isDigit() } ?: existing.isbn,
isbn = if (isSet("isbn")) isbn?.filter { it.isDigit() } ?: "" else existing.isbn,
isbnLock = isbnLock ?: existing.isbnLock
)
}

View File

@ -1,7 +1,7 @@
package org.gotson.komga.interfaces.rest.dto
import org.gotson.komga.infrastructure.validation.NullOrBlankOrISBN
import org.gotson.komga.infrastructure.validation.NullOrNotBlank
import org.hibernate.validator.constraints.ISBN
import java.time.LocalDate
import javax.validation.Valid
import javax.validation.constraints.NotBlank
@ -16,7 +16,10 @@ class BookMetadataUpdateDto {
var titleLock: Boolean? = null
var summary: String? = null
var summary: String?
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
var summaryLock: Boolean? = null
@ -30,7 +33,7 @@ class BookMetadataUpdateDto {
var numberSortLock: Boolean? = null
var releaseDate: LocalDate?
by Delegates.observable<LocalDate?>(null) { prop, _, _ ->
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
@ -38,21 +41,24 @@ class BookMetadataUpdateDto {
@get:Valid
var authors: List<AuthorUpdateDto>?
by Delegates.observable<List<AuthorUpdateDto>?>(null) { prop, _, _ ->
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
var authorsLock: Boolean? = null
var tags: Set<String>?
by Delegates.observable<Set<String>?>(null) { prop, _, _ ->
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
var tagsLock: Boolean? = null
@get:ISBN
var isbn: String? = null
@get:NullOrBlankOrISBN
var isbn: String?
by Delegates.observable(null) { prop, _, _ ->
isSet[prop.name] = true
}
var isbnLock: Boolean? = null
}

View File

@ -675,6 +675,47 @@ class BookControllerTest(
}
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
fun `given json with blank fields when updating metadata then fields with blanks are unset`() {
makeSeries(name = "series", libraryId = library.id).let { series ->
seriesLifecycle.createSeries(series).also { created ->
val books = listOf(makeBook("1.cbr", libraryId = library.id))
seriesLifecycle.addBooks(created, books)
}
}
val bookId = bookRepository.findAll().first().id
bookMetadataRepository.findById(bookId).let { metadata ->
val updated = metadata.copy(
summary = "summary",
isbn = "9781617290459",
)
bookMetadataRepository.update(updated)
}
val jsonString = """
{
"summary":"",
"isbn":""
}
""".trimIndent()
mockMvc.patch("/api/v1/books/$bookId/metadata") {
contentType = MediaType.APPLICATION_JSON
content = jsonString
}.andExpect {
status { isNoContent() }
}
val updatedMetadata = bookMetadataRepository.findById(bookId)
with(updatedMetadata) {
assertThat(summary).isBlank
assertThat(isbn).isBlank
}
}
@Test
@WithMockCustomUser(roles = [ROLE_ADMIN])
fun `given json with null fields when updating metadata then fields with null are unset`() {
@ -692,7 +733,9 @@ class BookControllerTest(
val updated = metadata.copy(
authors = metadata.authors.toMutableList().also { it.add(Author("Author", "role")) },
releaseDate = testDate,
tags = setOf("tag")
tags = setOf("tag"),
summary = "summary",
isbn = "9781617290459",
)
bookMetadataRepository.update(updated)
@ -708,7 +751,9 @@ class BookControllerTest(
{
"authors":null,
"releaseDate":null,
"tags":null
"tags":null,
"summary":null,
"isbn":null
}
""".trimIndent()
@ -724,6 +769,8 @@ class BookControllerTest(
assertThat(authors).isEmpty()
assertThat(releaseDate).isNull()
assertThat(tags).isEmpty()
assertThat(summary).isBlank
assertThat(isbn).isBlank
}
}
@ -749,7 +796,8 @@ class BookControllerTest(
numberLock = true,
numberSort = 2F,
numberSortLock = true,
title = "title"
title = "title",
isbn = "9781617290459",
)
bookMetadataRepository.update(updated)
@ -775,6 +823,7 @@ class BookControllerTest(
assertThat(number).isEqualTo("number")
assertThat(numberSort).isEqualTo(2F)
assertThat(title).isEqualTo("title")
assertThat(isbn).isEqualTo("9781617290459")
}
}
}