add settings module
This commit is contained in:
parent
0372d139ee
commit
3cb78ce44d
|
|
@ -106,3 +106,7 @@ Interceptor для логирования запросов/ответов.
|
|||
## common-geo-spatial4j-spring
|
||||
|
||||
Реализация интерфейса `GeoCalculator` с помощью библиотеки `spatial4j`
|
||||
|
||||
## settings-spring-jpa
|
||||
|
||||
Модуль для хранения настроек
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ subprojects {
|
|||
dependency("org.junit.jupiter:junit-jupiter-engine:5.4.2")
|
||||
|
||||
dependency("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
||||
dependency("org.mockito:mockito-inline:2.13.0")
|
||||
dependency("org.mockito:mockito-inline:3.11.0")
|
||||
|
||||
dependency("com.github.zafarkhaja:java-semver:0.9.0")
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
plugins {
|
||||
id("kotlin")
|
||||
id("kotlin-spring")
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":common"))
|
||||
implementation(project(":common-spring"))
|
||||
implementation(project(":common-spring-jpa"))
|
||||
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.liquibase:liquibase-core")
|
||||
|
||||
testImplementation(project(":common-spring-test-jpa"))
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
|
||||
testImplementation("org.testcontainers:testcontainers")
|
||||
testImplementation("org.testcontainers:postgresql")
|
||||
testImplementation("org.testcontainers:junit-jupiter")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-params")
|
||||
|
||||
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin")
|
||||
|
||||
testRuntimeOnly("org.postgresql:postgresql")
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package ru.touchin.settings.annotations
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class SettingMapper
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package ru.touchin.settings.configurations
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import ru.touchin.settings.annotations.SettingMapper
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(
|
||||
"ru.touchin.settings.services"
|
||||
)
|
||||
class SettingsConfiguration {
|
||||
|
||||
@Bean
|
||||
@SettingMapper
|
||||
fun getSettingMapper(): ObjectMapper {
|
||||
return ObjectMapper()
|
||||
.registerModule(KotlinModule())
|
||||
.setSerializationInclusion(JsonInclude.Include.ALWAYS)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package ru.touchin.settings.configurations
|
||||
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
|
||||
import ru.touchin.common.spring.jpa.EnableJpaAuditingExtra
|
||||
import ru.touchin.common.spring.jpa.liquibase.LiquibaseParams
|
||||
|
||||
@Configuration
|
||||
@ComponentScan("ru.touchin.common.spring.jpa.liquibase")
|
||||
@EntityScan("ru.touchin.settings.models")
|
||||
@EnableJpaRepositories(basePackages = ["ru.touchin.settings.repositories"])
|
||||
@EnableJpaAuditingExtra
|
||||
class SettingsDatabaseConfiguration {
|
||||
|
||||
companion object {
|
||||
const val SCHEMA: String = "settings"
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun liquibaseParams(): LiquibaseParams {
|
||||
return LiquibaseParams(
|
||||
schema = SCHEMA,
|
||||
changeLogPath = "settings/db/changelog/db.changelog-master.yaml",
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package ru.touchin.settings.dto
|
||||
|
||||
data class SystemSetting<T>(
|
||||
val key: String,
|
||||
val value: T,
|
||||
)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package ru.touchin.settings.exceptions
|
||||
|
||||
import ru.touchin.common.exceptions.CommonException
|
||||
|
||||
class CannotParseSettingValueException(value: String, clazz: Class<*>, exception: Throwable) : CommonException(
|
||||
"Cannot parse setting value: $value to ${clazz.simpleName}",
|
||||
exception,
|
||||
)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package ru.touchin.settings.exceptions
|
||||
|
||||
import ru.touchin.common.exceptions.CommonNotFoundException
|
||||
|
||||
class SettingNotFoundException(key: String) : CommonNotFoundException(
|
||||
"Setting not found key=$key"
|
||||
)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package ru.touchin.settings.models
|
||||
|
||||
import ru.touchin.common.spring.jpa.models.AuditableEntity
|
||||
import javax.persistence.Id
|
||||
import javax.persistence.MappedSuperclass
|
||||
|
||||
@MappedSuperclass
|
||||
open class AbstractSettingModel: AuditableEntity() {
|
||||
|
||||
@Id
|
||||
lateinit var key: String
|
||||
|
||||
lateinit var value: String
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package ru.touchin.settings.models
|
||||
|
||||
import ru.touchin.settings.configurations.SettingsDatabaseConfiguration.Companion.SCHEMA
|
||||
import javax.persistence.Entity
|
||||
import javax.persistence.Table
|
||||
|
||||
@Entity
|
||||
@Table(name = "system_settings", schema = SCHEMA)
|
||||
class SystemSettingModel : AbstractSettingModel()
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package ru.touchin.settings.repositories
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import ru.touchin.settings.exceptions.SettingNotFoundException
|
||||
import ru.touchin.settings.models.SystemSettingModel
|
||||
|
||||
interface SystemSettingsRepository: JpaRepository<SystemSettingModel, String>
|
||||
|
||||
fun SystemSettingsRepository.findByIdOrThrow(key: String): SystemSettingModel {
|
||||
return findByIdOrNull(key)
|
||||
?: throw SettingNotFoundException(key)
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package ru.touchin.settings.services
|
||||
|
||||
import ru.touchin.settings.dto.SystemSetting
|
||||
|
||||
interface SystemSettingsService {
|
||||
|
||||
fun <T> save(setting: SystemSetting<T>): SystemSetting<T>
|
||||
|
||||
fun <T> getOrNull(settingKey: String, clazz: Class<T>): SystemSetting<T>?
|
||||
|
||||
fun <T> get(settingKey: String, clazz: Class<T>): SystemSetting<T>
|
||||
|
||||
fun delete(settingKey: String)
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package ru.touchin.settings.services
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException
|
||||
import com.fasterxml.jackson.databind.JsonMappingException
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import ru.touchin.settings.annotations.SettingMapper
|
||||
import ru.touchin.settings.dto.SystemSetting
|
||||
import ru.touchin.settings.exceptions.CannotParseSettingValueException
|
||||
import ru.touchin.settings.models.SystemSettingModel
|
||||
import ru.touchin.settings.repositories.SystemSettingsRepository
|
||||
import ru.touchin.settings.repositories.findByIdOrThrow
|
||||
|
||||
@Service
|
||||
class SystemSettingsServiceImpl(
|
||||
private val systemSettingsRepository: SystemSettingsRepository,
|
||||
@SettingMapper
|
||||
private val settingsObjectMapper: ObjectMapper,
|
||||
) : SystemSettingsService {
|
||||
|
||||
@Transactional
|
||||
override fun <T> save(setting: SystemSetting<T>): SystemSetting<T> {
|
||||
val settingModel = systemSettingsRepository.findByIdOrNull(setting.key)
|
||||
?: SystemSettingModel().apply {
|
||||
key = setting.key
|
||||
}
|
||||
|
||||
settingModel.value = settingsObjectMapper.writeValueAsString(setting.value)
|
||||
|
||||
systemSettingsRepository.save(settingModel)
|
||||
|
||||
return setting
|
||||
}
|
||||
|
||||
private fun <T> createSetting(model: SystemSettingModel, clazz: Class<T>): SystemSetting<T> {
|
||||
val value = kotlin
|
||||
.runCatching {
|
||||
settingsObjectMapper.readValue(model.value, clazz)
|
||||
}
|
||||
.recoverCatching { exception ->
|
||||
when(exception) {
|
||||
is JsonProcessingException,
|
||||
is JsonMappingException -> {
|
||||
throw CannotParseSettingValueException(model.value, clazz, exception)
|
||||
}
|
||||
|
||||
else -> {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
}
|
||||
.getOrThrow()
|
||||
|
||||
return SystemSetting(
|
||||
key = model.key,
|
||||
value = value,
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
override fun <T> getOrNull(settingKey: String, clazz: Class<T>): SystemSetting<T>? {
|
||||
return systemSettingsRepository.findByIdOrNull(settingKey)
|
||||
?.let { createSetting(it, clazz) }
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
override fun <T> get(settingKey: String, clazz: Class<T>): SystemSetting<T> {
|
||||
return createSetting(systemSettingsRepository.findByIdOrThrow(settingKey), clazz)
|
||||
}
|
||||
|
||||
@Transactional
|
||||
override fun delete(settingKey: String) {
|
||||
return systemSettingsRepository.deleteById(settingKey)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
CREATE SCHEMA IF NOT EXISTS settings;
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: create_table__system_settings
|
||||
author: touchin
|
||||
preConditions:
|
||||
- onFail: MARK_RAN
|
||||
not:
|
||||
tableExists:
|
||||
tableName: system_settings
|
||||
changes:
|
||||
- createTable:
|
||||
tableName: system_settings
|
||||
columns:
|
||||
- column:
|
||||
name: key
|
||||
type: VARCHAR(128)
|
||||
constraints:
|
||||
nullable: false
|
||||
primaryKey: true
|
||||
primaryKeyName: PK_SYSTEM_SETTINGS
|
||||
- column:
|
||||
name: value
|
||||
type: VARCHAR(1024)
|
||||
constraints:
|
||||
nullable: false
|
||||
- column:
|
||||
name: created_at
|
||||
type: TIMESTAMP WITH TIME ZONE
|
||||
defaultValueDate: CURRENT_TIMESTAMP
|
||||
constraints:
|
||||
nullable: false
|
||||
- column:
|
||||
name: updated_at
|
||||
type: TIMESTAMP WITH TIME ZONE
|
||||
- column:
|
||||
name: created_by
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: updated_by
|
||||
type: VARCHAR(255)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package ru.touchin.settings
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
|
||||
import org.springframework.boot.test.context.TestConfiguration
|
||||
import org.springframework.context.annotation.ComponentScan
|
||||
import org.springframework.context.annotation.Import
|
||||
import org.springframework.context.annotation.Profile
|
||||
import ru.touchin.settings.configurations.SettingsDatabaseConfiguration
|
||||
|
||||
@Profile("test-slow")
|
||||
@EnableAutoConfiguration
|
||||
@TestConfiguration
|
||||
@ComponentScan
|
||||
@Import(SettingsDatabaseConfiguration::class)
|
||||
class SettingsSlowTestConfiguration {
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package ru.touchin.settings
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration
|
||||
import org.springframework.boot.test.context.TestConfiguration
|
||||
import org.springframework.context.annotation.Import
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import ru.touchin.settings.configurations.SettingsConfiguration
|
||||
|
||||
@SpringBootConfiguration
|
||||
@ContextConfiguration(classes = [SettingsConfiguration::class])
|
||||
@TestConfiguration
|
||||
@Import(SettingsConfiguration::class, SettingsSlowTestConfiguration::class)
|
||||
class SettingsTestApplication
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package ru.touchin.settings.repositories
|
||||
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import org.mockito.internal.matchers.apachecommons.ReflectionEquals
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import ru.touchin.common.spring.test.jpa.repository.RepositoryTest
|
||||
import ru.touchin.settings.exceptions.SettingNotFoundException
|
||||
import ru.touchin.settings.models.SystemSettingModel
|
||||
import javax.persistence.EntityManager
|
||||
|
||||
@RepositoryTest
|
||||
internal class SystemSettingRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
private lateinit var systemSettingsRepository: SystemSettingsRepository
|
||||
|
||||
@Autowired
|
||||
private lateinit var entityManager: EntityManager
|
||||
|
||||
@Test
|
||||
@DisplayName("Настройки должны сохраняться в базе")
|
||||
fun shouldBeSaved() {
|
||||
val setting = SystemSettingModel()
|
||||
.apply {
|
||||
key = "max.threads"
|
||||
value = "5"
|
||||
}
|
||||
|
||||
systemSettingsRepository.save(setting)
|
||||
|
||||
// если не вызывать clear, то репозиторий возвращает тот же самый объект и кеша
|
||||
entityManager.apply {
|
||||
flush()
|
||||
clear()
|
||||
}
|
||||
|
||||
val actualSetting = systemSettingsRepository.findByIdOrThrow(setting.key)
|
||||
|
||||
Assertions.assertTrue(ReflectionEquals(setting, "createdAt").matches(actualSetting))
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Если настройки не найдены, должна быть ошибка SettingNotFoundException")
|
||||
fun shouldBeSettingNotFoundException() {
|
||||
assertThrows<SettingNotFoundException> {
|
||||
systemSettingsRepository.findByIdOrThrow("missing")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
package ru.touchin.settings.services
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.doReturn
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.spy
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertNull
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.mockito.internal.matchers.apachecommons.ReflectionEquals
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import ru.touchin.settings.annotations.SettingMapper
|
||||
import ru.touchin.settings.dto.SystemSetting
|
||||
import ru.touchin.settings.models.SystemSettingModel
|
||||
import ru.touchin.settings.repositories.SystemSettingsRepository
|
||||
import java.util.*
|
||||
import javax.annotation.PostConstruct
|
||||
|
||||
internal data class UserObject(val name: String, val age: Int)
|
||||
|
||||
@ActiveProfiles("test")
|
||||
@SpringBootTest
|
||||
internal class SystemSettingsServiceImplDeserializationTest {
|
||||
|
||||
|
||||
@Autowired
|
||||
@SettingMapper
|
||||
private lateinit var settingMapper: ObjectMapper
|
||||
|
||||
private val systemSettingsRepository: SystemSettingsRepository = mock {}
|
||||
|
||||
private lateinit var systemSettingsService: SystemSettingsService
|
||||
|
||||
@PostConstruct
|
||||
fun init() {
|
||||
systemSettingsService = spy(
|
||||
SystemSettingsServiceImpl(
|
||||
systemSettingsRepository = systemSettingsRepository,
|
||||
settingsObjectMapper = settingMapper
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun <T> check(systemSetting: SystemSetting<T>, serializedValue: String, assert: (T, T) -> Unit = { e, a ->
|
||||
assertTrue(ReflectionEquals(e).matches(a))
|
||||
}) {
|
||||
doReturn(
|
||||
Optional.of(SystemSettingModel().apply {
|
||||
key = systemSetting.key
|
||||
value = serializedValue
|
||||
})
|
||||
).`when`(systemSettingsRepository).findById(any())
|
||||
|
||||
systemSetting.value
|
||||
?.let { actualValue ->
|
||||
val actualSystemSetting = systemSettingsService.get(systemSetting.key, actualValue::class.java)
|
||||
|
||||
assert(systemSetting.value, actualSystemSetting.value)
|
||||
}
|
||||
?: run {
|
||||
assertNull(systemSettingsService.get(systemSetting.key, ""::class.java).value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun stringShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.string",
|
||||
value = "hello"
|
||||
)
|
||||
|
||||
check(systemSetting, "\"hello\"") { expected, actual ->
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun intShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.int",
|
||||
value = 23
|
||||
)
|
||||
|
||||
check(systemSetting, "23")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nullShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.null",
|
||||
value = null
|
||||
)
|
||||
|
||||
check(systemSetting, "null")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun arrayShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.array",
|
||||
value = arrayOf(1,2,3)
|
||||
)
|
||||
|
||||
check(systemSetting, "[1,2,3]")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.list",
|
||||
value = listOf(1,2,3)
|
||||
)
|
||||
|
||||
check(systemSetting, "[1,2,3]") { expected, actual ->
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun objectShouldBeDeserialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.object",
|
||||
value = UserObject("mike", 32)
|
||||
)
|
||||
|
||||
check(systemSetting, "{\"name\":\"mike\",\"age\":32}")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
package ru.touchin.settings.services
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.nhaarman.mockitokotlin2.any
|
||||
import com.nhaarman.mockitokotlin2.argThat
|
||||
import com.nhaarman.mockitokotlin2.doAnswer
|
||||
import com.nhaarman.mockitokotlin2.doReturn
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.spy
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.test.context.ActiveProfiles
|
||||
import ru.touchin.settings.annotations.SettingMapper
|
||||
import ru.touchin.settings.dto.SystemSetting
|
||||
import ru.touchin.settings.models.SystemSettingModel
|
||||
import ru.touchin.settings.repositories.SystemSettingsRepository
|
||||
import java.util.*
|
||||
import javax.annotation.PostConstruct
|
||||
|
||||
@ActiveProfiles("test")
|
||||
@SpringBootTest
|
||||
internal class SystemSettingsServiceImplSerializationTest {
|
||||
|
||||
@Autowired
|
||||
@SettingMapper
|
||||
private lateinit var settingMapper: ObjectMapper
|
||||
|
||||
private val systemSettingsRepository: SystemSettingsRepository = mock {}
|
||||
|
||||
private lateinit var systemSettingsService: SystemSettingsService
|
||||
|
||||
@PostConstruct
|
||||
fun init() {
|
||||
systemSettingsService = spy(
|
||||
SystemSettingsServiceImpl(
|
||||
systemSettingsRepository = systemSettingsRepository,
|
||||
settingsObjectMapper = settingMapper
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun check(systemSetting: SystemSetting<*>, serializedValue: String) {
|
||||
doReturn(Optional.empty<SystemSettingModel>()).`when`(systemSettingsRepository).findById(any())
|
||||
doAnswer { it.getArgument(0) as SystemSettingModel }.`when`(systemSettingsRepository).save(any())
|
||||
|
||||
systemSettingsService.save(systemSetting)
|
||||
|
||||
verify(systemSettingsRepository).save(argThat {
|
||||
value == serializedValue
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun stringShouldBeSerialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.string",
|
||||
value = "hello"
|
||||
)
|
||||
|
||||
check(systemSetting, "\"hello\"")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun intShouldBeSerialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.int",
|
||||
value = 23
|
||||
)
|
||||
|
||||
check(systemSetting, "23")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nullShouldBeSerialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.null",
|
||||
value = null
|
||||
)
|
||||
|
||||
check(systemSetting, "null")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun arrayShouldBeSerialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.array",
|
||||
value = arrayOf(1,2,3)
|
||||
)
|
||||
|
||||
check(systemSetting, "[1,2,3]")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listShouldBeSerialized() {
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.list",
|
||||
value = listOf(1,2,3)
|
||||
)
|
||||
|
||||
check(systemSetting, "[1,2,3]")
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun objectShouldBeSerialized() {
|
||||
data class UserObject(val name: String, val age: Int)
|
||||
|
||||
val systemSetting = SystemSetting(
|
||||
key = "setting.object",
|
||||
value = UserObject("mike", 32)
|
||||
)
|
||||
|
||||
check(systemSetting, "{\"name\":\"mike\",\"age\":32}")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
spring:
|
||||
config:
|
||||
import: "test-slow.yml"
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
spring:
|
||||
config:
|
||||
import: "test.yml"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
databaseChangeLog:
|
||||
- changeset:
|
||||
id: 1
|
||||
author: test
|
||||
|
|
@ -36,3 +36,4 @@ include("exception-handler-spring-web")
|
|||
include("exception-handler-logger-spring-web")
|
||||
include("version-spring-web")
|
||||
include("response-wrapper-spring-web")
|
||||
include("settings-spring-jpa")
|
||||
|
|
|
|||
Loading…
Reference in New Issue