Ajout des tests des configurations
This commit is contained in:
parent
f376d66b2e
commit
feabcc5b76
|
@ -48,7 +48,7 @@ package:
|
|||
ARTIFACT_NAME: "ColorRecipesExplorer-backend-$CI_PIPELINE_IID"
|
||||
script:
|
||||
- docker rm $PACKAGE_CONTAINER_NAME || true
|
||||
- docker run --name $PACKAGE_CONTAINER_NAME $CI_REGISTRY_IMAGE_GRADLE gradle bootJar
|
||||
- docker run --name $PACKAGE_CONTAINER_NAME $CI_REGISTRY_IMAGE_GRADLE gradle bootJar -Pversion=$CI_PIPELINE_IID
|
||||
- docker cp $PACKAGE_CONTAINER_NAME:/usr/src/cre/build/libs/ColorRecipesExplorer.jar $ARTIFACT_NAME.jar
|
||||
- docker build -t $CI_REGISTRY_IMAGE_BACKEND --build-arg JDK_VERSION=$JDK_VERSION --build-arg PORT=$PORT --build-arg ARTIFACT_NAME=$ARTIFACT_NAME .
|
||||
- docker push $CI_REGISTRY_IMAGE_BACKEND
|
||||
|
@ -81,4 +81,4 @@ deploy:
|
|||
script:
|
||||
- ssh -p $DEPLOYMENT_SERVER_SSH_PORT $DEPLOYMENT_SERVER_USERNAME@$DEPLOYMENT_SERVER "docker stop $DEPLOYED_CONTAINER_NAME || true && docker rm $DEPLOYED_CONTAINER_NAME || true"
|
||||
- ssh -p $DEPLOYMENT_SERVER_SSH_PORT $DEPLOYMENT_SERVER_USERNAME@$DEPLOYMENT_SERVER "docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY && docker pull $CI_REGISTRY_IMAGE_BACKEND"
|
||||
- ssh -p $DEPLOYMENT_SERVER_SSH_PORT $DEPLOYMENT_SERVER_USERNAME@$DEPLOYMENT_SERVER "docker run -d -p $PORT:$PORT --name=$DEPLOYED_CONTAINER_NAME -v $DATA_VOLUME:/usr/bin/cre/data -e spring_profiles_active=$SPRING_PROFILES -e spring_datasource_username=$DB_USERNAME -e spring_datasource_password=$DB_PASSWORD -e spring_datasource_url=$DB_URL -e databaseupdater_username=$DB_UPDATE_USERNAME -e databaseupdater_password=$DB_UPDATE_PASSWORD $CI_REGISTRY_IMAGE_BACKEND"
|
||||
- ssh -p $DEPLOYMENT_SERVER_SSH_PORT $DEPLOYMENT_SERVER_USERNAME@$DEPLOYMENT_SERVER "docker run -d -p $PORT:$PORT --name=$DEPLOYED_CONTAINER_NAME -v $DATA_VOLUME:/usr/bin/cre/data -e spring_profiles_active=$SPRING_PROFILES -e $CI_REGISTRY_IMAGE_BACKEND"
|
||||
|
|
|
@ -62,6 +62,10 @@ dependencies {
|
|||
implementation("org.springframework.cloud:spring-cloud-starter:2.2.8.RELEASE")
|
||||
}
|
||||
|
||||
springBoot {
|
||||
buildInfo()
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
-1
|
|
@ -14,6 +14,7 @@ import org.springframework.context.annotation.Configuration
|
|||
import org.springframework.context.annotation.DependsOn
|
||||
import org.springframework.context.annotation.Profile
|
||||
import org.springframework.core.env.ConfigurableEnvironment
|
||||
import java.lang.RuntimeException
|
||||
import javax.sql.DataSource
|
||||
|
||||
const val SUPPORTED_DATABASE_VERSION = 5
|
||||
|
@ -44,7 +45,7 @@ class DataSourceConfiguration {
|
|||
username = databaseUsername
|
||||
password = databasePassword
|
||||
})
|
||||
} catch (ex: CreDatabaseException) {
|
||||
} catch (ex: Exception) {
|
||||
logger.error("Could not access database, restarting in emergency mode...", ex)
|
||||
emergencyMode = true
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ data class ConfigurationEntity(
|
|||
) {
|
||||
fun toConfiguration() =
|
||||
configuration(key.toConfigurationType(), content, lastUpdated)
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is ConfigurationEntity && key == other.key && content == other.content
|
||||
}
|
||||
|
||||
data class ConfigurationDto(
|
||||
|
|
|
@ -8,6 +8,7 @@ import dev.fyloz.colorrecipesexplorer.emergencyMode
|
|||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.ConfigurationRepository
|
||||
import dev.fyloz.colorrecipesexplorer.service.files.FileService
|
||||
import org.springframework.boot.info.BuildProperties
|
||||
import org.springframework.context.annotation.Lazy
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Service
|
||||
|
@ -51,6 +52,7 @@ interface ConfigurationService {
|
|||
|
||||
const val CONFIGURATION_LOGO_FILE_PATH = "images/logo"
|
||||
const val CONFIGURATION_ICON_FILE_PATH = "images/icon"
|
||||
const val CONFIGURATION_FORMATTED_LIST_DELIMITER = ';'
|
||||
|
||||
@Service
|
||||
class ConfigurationServiceImpl(
|
||||
|
@ -58,7 +60,8 @@ class ConfigurationServiceImpl(
|
|||
private val fileService: FileService,
|
||||
private val fileConfiguration: FileConfiguration,
|
||||
private val creProperties: CreProperties,
|
||||
private val databaseProperties: DatabaseUpdaterProperties
|
||||
private val databaseProperties: DatabaseUpdaterProperties,
|
||||
private val buildInfo: BuildProperties
|
||||
) : ConfigurationService {
|
||||
override fun getAll() =
|
||||
ConfigurationType.values().mapNotNull {
|
||||
|
@ -70,7 +73,7 @@ class ConfigurationServiceImpl(
|
|||
}
|
||||
|
||||
override fun getAll(formattedKeyList: String) =
|
||||
formattedKeyList.split(';').map(this::get)
|
||||
formattedKeyList.split(CONFIGURATION_FORMATTED_LIST_DELIMITER).map(this::get)
|
||||
|
||||
override fun get(key: String) =
|
||||
get(key.toConfigurationType())
|
||||
|
@ -131,25 +134,19 @@ class ConfigurationServiceImpl(
|
|||
ConfigurationType.TOUCH_UP_KIT_CACHE_PDF -> "true"
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
private fun getComputedConfiguration(key: ConfigurationType) = configuration(
|
||||
key, when (key) {
|
||||
ConfigurationType.EMERGENCY_MODE_ENABLED -> emergencyMode
|
||||
ConfigurationType.VERSION -> getAppVersion()
|
||||
ConfigurationType.DATABASE_SUPPORTED_VERSION -> SUPPORTED_DATABASE_VERSION
|
||||
ConfigurationType.JAVA_VERSION -> Runtime.version()
|
||||
ConfigurationType.OPERATING_SYSTEM -> "${System.getProperty("os.name")} ${System.getProperty("os.version")} ${
|
||||
System.getProperty(
|
||||
"os.arch"
|
||||
)
|
||||
}"
|
||||
else -> throw IllegalArgumentException("Cannot get the value of the configuration with the key ${key.key} because it is not a computed configuration")
|
||||
}.toString()
|
||||
)
|
||||
|
||||
const val APP_VERSION_PATH = "buildversion"
|
||||
|
||||
fun getAppVersion(): Int = with(File(APP_VERSION_PATH)) {
|
||||
this.readLines()[0].toInt()
|
||||
|
||||
private fun getComputedConfiguration(key: ConfigurationType) = configuration(
|
||||
key, when (key) {
|
||||
ConfigurationType.EMERGENCY_MODE_ENABLED -> emergencyMode
|
||||
ConfigurationType.VERSION -> buildInfo.version
|
||||
ConfigurationType.DATABASE_SUPPORTED_VERSION -> SUPPORTED_DATABASE_VERSION
|
||||
ConfigurationType.JAVA_VERSION -> Runtime.version()
|
||||
ConfigurationType.OPERATING_SYSTEM -> "${System.getProperty("os.name")} ${System.getProperty("os.version")} ${
|
||||
System.getProperty(
|
||||
"os.arch"
|
||||
)
|
||||
}"
|
||||
else -> throw IllegalArgumentException("Cannot get the value of the configuration with the key ${key.key} because it is not a computed configuration")
|
||||
}.toString()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
package dev.fyloz.colorrecipesexplorer.service
|
||||
|
||||
import dev.fyloz.colorrecipesexplorer.config.FileConfiguration
|
||||
import dev.fyloz.colorrecipesexplorer.model.*
|
||||
import dev.fyloz.colorrecipesexplorer.repository.ConfigurationRepository
|
||||
import io.mockk.*
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.assertThrows
|
||||
import java.time.LocalDateTime
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ConfigurationServiceTest {
|
||||
private val repository = mockk<ConfigurationRepository>()
|
||||
private val fileConfiguration = mockk<FileConfiguration>()
|
||||
private val service = spyk(ConfigurationServiceImpl(repository, mockk(), fileConfiguration, mockk(), mockk(), mockk()))
|
||||
|
||||
@AfterEach
|
||||
fun afterEach() {
|
||||
clearAllMocks()
|
||||
}
|
||||
|
||||
// getAll()
|
||||
|
||||
@Test
|
||||
fun `getAll() gets the Configuration of each ConfigurationType`() {
|
||||
every { service.get(any<ConfigurationType>()) } answers { throw ConfigurationNotSetException(this.args[0] as ConfigurationType) }
|
||||
|
||||
service.getAll()
|
||||
|
||||
verify {
|
||||
service.getAll()
|
||||
ConfigurationType.values().forEach {
|
||||
service.get(it)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAll() only returns set configurations`() {
|
||||
val unsetConfigurationTypes = listOf(
|
||||
ConfigurationType.INSTANCE_NAME,
|
||||
ConfigurationType.INSTANCE_LOGO_PATH,
|
||||
ConfigurationType.INSTANCE_ICON_PATH
|
||||
)
|
||||
|
||||
every { service.get(match<ConfigurationType> { it in unsetConfigurationTypes }) } answers {
|
||||
throw ConfigurationNotSetException(this.firstArg() as ConfigurationType)
|
||||
}
|
||||
every { service.get(match<ConfigurationType> { it !in unsetConfigurationTypes }) } answers {
|
||||
val type = firstArg<ConfigurationType>()
|
||||
configuration(type, type.key)
|
||||
}
|
||||
|
||||
val found = service.getAll()
|
||||
|
||||
assertFalse {
|
||||
found.any {
|
||||
it.type in unsetConfigurationTypes
|
||||
}
|
||||
}
|
||||
|
||||
verify {
|
||||
service.getAll()
|
||||
ConfigurationType.values().forEach {
|
||||
service.get(it)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getAll() only includes configurations matching the formatted formatted key list`() {
|
||||
val configurationTypes = listOf(
|
||||
ConfigurationType.INSTANCE_NAME,
|
||||
ConfigurationType.INSTANCE_LOGO_PATH,
|
||||
ConfigurationType.INSTANCE_ICON_PATH
|
||||
)
|
||||
val formattedKeyList = configurationTypes
|
||||
.map { it.key }
|
||||
.reduce { acc, s -> "$acc$CONFIGURATION_FORMATTED_LIST_DELIMITER$s" }
|
||||
|
||||
every { service.get(any<String>()) } answers {
|
||||
val key = firstArg<String>()
|
||||
configuration(key.toConfigurationType(), key)
|
||||
}
|
||||
|
||||
val found = service.getAll(formattedKeyList)
|
||||
|
||||
assertTrue {
|
||||
found.all { it.type in configurationTypes }
|
||||
}
|
||||
|
||||
verify {
|
||||
service.getAll(formattedKeyList)
|
||||
configurationTypes.forEach {
|
||||
service.get(it.key)
|
||||
}
|
||||
}
|
||||
confirmVerified(service)
|
||||
}
|
||||
|
||||
// get()
|
||||
|
||||
@Test
|
||||
fun `get(key) calls get() with the ConfigurationType matching the given key`() {
|
||||
val type = ConfigurationType.INSTANCE_ICON_PATH
|
||||
val key = type.key
|
||||
|
||||
every { service.get(type) } answers {
|
||||
val type = firstArg<ConfigurationType>()
|
||||
configuration(type, type.key)
|
||||
}
|
||||
|
||||
service.get(key)
|
||||
|
||||
verify {
|
||||
service.get(key)
|
||||
service.get(type)
|
||||
}
|
||||
confirmVerified(service)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get(type) gets in the repository when the given ConfigurationType is not computed or a file property`() {
|
||||
val type = ConfigurationType.INSTANCE_ICON_PATH
|
||||
|
||||
every { repository.findById(type.key) } returns Optional.of(
|
||||
ConfigurationEntity(type.key, type.key, LocalDateTime.now())
|
||||
)
|
||||
|
||||
val configuration = service.get(type)
|
||||
|
||||
assertTrue {
|
||||
configuration.key == type.key
|
||||
}
|
||||
|
||||
verify {
|
||||
service.get(type)
|
||||
repository.findById(type.key)
|
||||
}
|
||||
confirmVerified(service, repository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get(type) gets in the FileConfiguration when the gien ConfigurationType is a file property`() {
|
||||
val type = ConfigurationType.DATABASE_URL
|
||||
|
||||
every { fileConfiguration.get(type) } returns configuration(type, type.key)
|
||||
|
||||
val configuration = service.get(type)
|
||||
|
||||
assertTrue {
|
||||
configuration.key == type.key
|
||||
}
|
||||
|
||||
verify {
|
||||
service.get(type)
|
||||
fileConfiguration.get(type)
|
||||
}
|
||||
verify(exactly = 0) {
|
||||
repository.findById(type.key)
|
||||
}
|
||||
confirmVerified(service, fileConfiguration, repository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get(type) computes computed properties`() {
|
||||
val type = ConfigurationType.JAVA_VERSION
|
||||
|
||||
val configuration = service.get(type)
|
||||
|
||||
assertTrue {
|
||||
configuration.key == type.key
|
||||
}
|
||||
|
||||
verify {
|
||||
service.get(type)
|
||||
}
|
||||
verify(exactly = 0) {
|
||||
repository.findById(type.key)
|
||||
fileConfiguration.get(type)
|
||||
}
|
||||
confirmVerified(service, repository, fileConfiguration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get(type) throws ConfigurationNotSetException when the given ConfigurationType has no set configuration`() {
|
||||
val type = ConfigurationType.INSTANCE_ICON_PATH
|
||||
|
||||
every { repository.findById(type.key) } returns Optional.empty()
|
||||
|
||||
with(assertThrows<ConfigurationNotSetException> { service.get(type) }) {
|
||||
assertEquals(type, this.type)
|
||||
}
|
||||
|
||||
verify {
|
||||
service.get(type)
|
||||
repository.findById(type.key)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `set() set the configuration in the FileConfiguration when the given ConfigurationType is a file configuration`() {
|
||||
val type = ConfigurationType.DATABASE_URL
|
||||
val content = "url"
|
||||
|
||||
every { fileConfiguration.set(type, content) } just runs
|
||||
|
||||
service.set(type, content)
|
||||
|
||||
verify {
|
||||
service.set(type, content)
|
||||
fileConfiguration.set(type, content)
|
||||
}
|
||||
confirmVerified(service, fileConfiguration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `set() set the configuration in the repository when the given ConfigurationType is not a computed configuration of a file configuration`() {
|
||||
val type = ConfigurationType.INSTANCE_ICON_PATH
|
||||
val content = "path"
|
||||
val configuration = configuration(type, content)
|
||||
val entity = configuration.toEntity()
|
||||
|
||||
every { repository.save(entity) } returns entity
|
||||
|
||||
service.set(type, content)
|
||||
|
||||
verify {
|
||||
service.set(type, content)
|
||||
repository.save(entity)
|
||||
}
|
||||
confirmVerified(service, repository)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `set() throws CannotSetComputedConfigurationException when the given ConfigurationType is a computed configuration`() {
|
||||
val type = ConfigurationType.JAVA_VERSION
|
||||
val content = "5"
|
||||
|
||||
with(assertThrows<CannotSetComputedConfigurationException> { service.set(type, content) }) {
|
||||
assertEquals(type, this.type)
|
||||
}
|
||||
|
||||
verify {
|
||||
service.set(type, content)
|
||||
}
|
||||
confirmVerified(service)
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ class MaterialServiceTest :
|
|||
private val materialTypeService: MaterialTypeService = mock()
|
||||
private val fileService: FileService = mock()
|
||||
override val service: MaterialService =
|
||||
spy(MaterialServiceImpl(repository, recipeService, mixService, materialTypeService, fileService))
|
||||
spy(MaterialServiceImpl(repository, recipeService, mixService, materialTypeService, fileService, mock()))
|
||||
|
||||
override val entity: Material = material(id = 0L, name = "material")
|
||||
private val entityOutput = materialOutputDto(entity)
|
||||
|
|
|
@ -27,7 +27,7 @@ class RecipeServiceTest :
|
|||
private val groupService: GroupService = mock()
|
||||
private val recipeStepService: RecipeStepService = mock()
|
||||
override val service: RecipeService =
|
||||
spy(RecipeServiceImpl(repository, companyService, mixService, recipeStepService, groupService, mock()))
|
||||
spy(RecipeServiceImpl(repository, companyService, mixService, recipeStepService, groupService, mock(), mock()))
|
||||
|
||||
private val company: Company = company(id = 0L)
|
||||
override val entity: Recipe = recipe(id = 0L, name = "recipe", company = company)
|
||||
|
|
|
@ -21,7 +21,7 @@ private class TouchUpKitServiceTestContext {
|
|||
val creProperties = mockk<CreProperties> {
|
||||
every { cacheGeneratedFiles } returns false
|
||||
}
|
||||
val touchUpKitService = spyk(TouchUpKitServiceImpl(fileService, touchUpKitRepository, creProperties))
|
||||
val touchUpKitService = spyk(TouchUpKitServiceImpl(fileService, mockk(), touchUpKitRepository))
|
||||
val pdfDocumentData = mockk<ByteArrayResource>()
|
||||
val pdfDocument = mockk<PdfDocument> {
|
||||
mockkStatic(PdfDocument::toByteArrayResource)
|
||||
|
|
Loading…
Reference in New Issue