From 82dd23a870bab83d0016ace5396e5f46e5372d9e Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Tue, 1 Aug 2023 11:39:32 +0800 Subject: [PATCH] refactor: harden BCP47 functions --- ...801104436__fix_incorrect_language_codes.kt | 6 +++-- .../komga/domain/model/BCP47TagValidator.kt | 23 +++++++++++++++++++ .../komga/domain/model/SeriesMetadata.kt | 1 - .../metadata/comicrack/ComicInfoProvider.kt | 2 +- .../metadata/epub/EpubMetadataProvider.kt | 2 +- .../komga/infrastructure/validation/BCP47.kt | 17 +------------- .../model}/BCP47TagValidatorTest.kt | 12 ++++++---- 7 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 komga/src/main/kotlin/org/gotson/komga/domain/model/BCP47TagValidator.kt rename komga/src/test/kotlin/org/gotson/komga/{infrastructure/validation => domain/model}/BCP47TagValidatorTest.kt (80%) diff --git a/komga/src/flyway/kotlin/db/migration/sqlite/V20230801104436__fix_incorrect_language_codes.kt b/komga/src/flyway/kotlin/db/migration/sqlite/V20230801104436__fix_incorrect_language_codes.kt index 2d5e3bc915..847dd4ce63 100644 --- a/komga/src/flyway/kotlin/db/migration/sqlite/V20230801104436__fix_incorrect_language_codes.kt +++ b/komga/src/flyway/kotlin/db/migration/sqlite/V20230801104436__fix_incorrect_language_codes.kt @@ -36,10 +36,12 @@ class V20230801104436__fix_incorrect_language_codes : BaseJavaMigration() { } } - private fun normalize(value: String): String = - try { + private fun normalize(value: String?): String { + if (value.isNullOrBlank()) return "" + return try { ULocale.forLanguageTag(value).toLanguageTag() } catch (e: Exception) { "" } + } } diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/BCP47TagValidator.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/BCP47TagValidator.kt new file mode 100644 index 0000000000..b7086d7fb5 --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/BCP47TagValidator.kt @@ -0,0 +1,23 @@ +package org.gotson.komga.domain.model + +import com.ibm.icu.util.ULocale + +object BCP47TagValidator { + private val languages by lazy { ULocale.getISOLanguages().toSet() } + + fun isValid(value: String?): Boolean { + if (value == null) return false + return ULocale.forLanguageTag(value).let { + it.language.isNotBlank() && languages.contains(it.language) + } + } + + fun normalize(value: String?): String { + if (value.isNullOrBlank()) return "" + return try { + ULocale.forLanguageTag(value).toLanguageTag() + } catch (e: Exception) { + "" + } + } +} diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/SeriesMetadata.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/SeriesMetadata.kt index 713325f944..ebf361f563 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/model/SeriesMetadata.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/SeriesMetadata.kt @@ -1,6 +1,5 @@ package org.gotson.komga.domain.model -import org.gotson.komga.infrastructure.validation.BCP47TagValidator import org.gotson.komga.language.lowerNotBlank import java.time.LocalDateTime diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/comicrack/ComicInfoProvider.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/comicrack/ComicInfoProvider.kt index 30d13bf760..b263fd1a2e 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/comicrack/ComicInfoProvider.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/comicrack/ComicInfoProvider.kt @@ -4,6 +4,7 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper import mu.KotlinLogging import org.apache.commons.validator.routines.ISBNValidator import org.gotson.komga.domain.model.Author +import org.gotson.komga.domain.model.BCP47TagValidator import org.gotson.komga.domain.model.BookMetadataPatch import org.gotson.komga.domain.model.BookMetadataPatchCapability import org.gotson.komga.domain.model.BookWithMedia @@ -17,7 +18,6 @@ import org.gotson.komga.infrastructure.metadata.BookMetadataProvider import org.gotson.komga.infrastructure.metadata.SeriesMetadataFromBookProvider import org.gotson.komga.infrastructure.metadata.comicrack.dto.ComicInfo import org.gotson.komga.infrastructure.metadata.comicrack.dto.Manga -import org.gotson.komga.infrastructure.validation.BCP47TagValidator import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import java.net.URI diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/epub/EpubMetadataProvider.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/epub/EpubMetadataProvider.kt index 77dccd5103..9d43815346 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/epub/EpubMetadataProvider.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/metadata/epub/EpubMetadataProvider.kt @@ -2,6 +2,7 @@ package org.gotson.komga.infrastructure.metadata.epub import org.apache.commons.validator.routines.ISBNValidator import org.gotson.komga.domain.model.Author +import org.gotson.komga.domain.model.BCP47TagValidator import org.gotson.komga.domain.model.BookMetadataPatch import org.gotson.komga.domain.model.BookMetadataPatchCapability import org.gotson.komga.domain.model.BookWithMedia @@ -13,7 +14,6 @@ import org.gotson.komga.domain.model.SeriesMetadataPatch import org.gotson.komga.infrastructure.mediacontainer.EpubExtractor import org.gotson.komga.infrastructure.metadata.BookMetadataProvider import org.gotson.komga.infrastructure.metadata.SeriesMetadataFromBookProvider -import org.gotson.komga.infrastructure.validation.BCP47TagValidator import org.jsoup.Jsoup import org.jsoup.parser.Parser import org.jsoup.safety.Safelist diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/validation/BCP47.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/validation/BCP47.kt index 75c920fefe..0a6b962fa3 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/validation/BCP47.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/validation/BCP47.kt @@ -1,9 +1,9 @@ package org.gotson.komga.infrastructure.validation -import com.ibm.icu.util.ULocale import jakarta.validation.Constraint import jakarta.validation.ConstraintValidator import jakarta.validation.ConstraintValidatorContext +import org.gotson.komga.domain.model.BCP47TagValidator import kotlin.reflect.KClass @Constraint(validatedBy = [BCP47Validator::class]) @@ -23,19 +23,4 @@ class BCP47Validator : ConstraintValidator { } } -object BCP47TagValidator { - private val languages by lazy { ULocale.getISOLanguages().toSet() } - fun isValid(value: String): Boolean { - return ULocale.forLanguageTag(value).let { - it.language.isNotBlank() && languages.contains(it.language) - } - } - - fun normalize(value: String): String = - try { - ULocale.forLanguageTag(value).toLanguageTag() - } catch (e: Exception) { - "" - } -} diff --git a/komga/src/test/kotlin/org/gotson/komga/infrastructure/validation/BCP47TagValidatorTest.kt b/komga/src/test/kotlin/org/gotson/komga/domain/model/BCP47TagValidatorTest.kt similarity index 80% rename from komga/src/test/kotlin/org/gotson/komga/infrastructure/validation/BCP47TagValidatorTest.kt rename to komga/src/test/kotlin/org/gotson/komga/domain/model/BCP47TagValidatorTest.kt index 41701e3126..b35cfb2f54 100644 --- a/komga/src/test/kotlin/org/gotson/komga/infrastructure/validation/BCP47TagValidatorTest.kt +++ b/komga/src/test/kotlin/org/gotson/komga/domain/model/BCP47TagValidatorTest.kt @@ -1,4 +1,4 @@ -package org.gotson.komga.infrastructure.validation +package org.gotson.komga.domain.model import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.params.ParameterizedTest @@ -10,12 +10,14 @@ class BCP47TagValidatorTest { @ParameterizedTest @MethodSource("languagesNormalized") - fun `given source languageTag when normalizing then result is expected`(source: String, expected: String) { + fun `given source languageTag when normalizing then result is expected`(source: String?, expected: String) { assertThat(BCP47TagValidator.normalize(source)).isEqualTo(expected) } private fun languagesNormalized(): Stream = Stream.of( + Arguments.of(null, ""), + Arguments.of("", ""), Arguments.of("fra", "fr"), Arguments.of("fra-be", "fr-BE"), Arguments.of("JA", "ja"), @@ -26,12 +28,14 @@ class BCP47TagValidatorTest { @ParameterizedTest @MethodSource("languagesValid") - fun `given source languageTag when validating then result is expected`(source: String, expected: Boolean) { + fun `given source languageTag when validating then result is expected`(source: String?, expected: Boolean) { assertThat(BCP47TagValidator.isValid(source)).isEqualTo(expected) } - fun languagesValid(): Stream = + private fun languagesValid(): Stream = Stream.of( + Arguments.of(null, false), + Arguments.of("", false), Arguments.of("fra", true), Arguments.of("fra-BE", true), Arguments.of("en-us", true),