/* * This file is part of ETL-Processor * * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ package dev.dnpm.etl.processor.config import com.fasterxml.jackson.databind.ObjectMapper import dev.dnpm.etl.processor.consent.ConsentEvaluator import dev.dnpm.etl.processor.consent.GicsConsentService import dev.dnpm.etl.processor.consent.GicsGetBroadConsentService import dev.dnpm.etl.processor.consent.MtbFileConsentService import dev.dnpm.etl.processor.input.KafkaInputListener import dev.dnpm.etl.processor.monitoring.RequestRepository import dev.dnpm.etl.processor.output.KafkaMtbFileSender import dev.dnpm.etl.processor.output.RestMtbFileSender import dev.dnpm.etl.processor.pseudonym.AnonymizingGenerator import dev.dnpm.etl.processor.pseudonym.GpasPseudonymGenerator import dev.dnpm.etl.processor.pseudonym.GpasSoapPseudonymGenerator import dev.dnpm.etl.processor.security.TokenRepository import dev.dnpm.etl.processor.security.TokenService import dev.dnpm.etl.processor.services.RequestProcessor import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test import org.junit.jupiter.api.assertThrows import org.springframework.beans.factory.NoSuchBeanDefinitionException import org.springframework.beans.factory.getBean import org.springframework.boot.kafka.autoconfigure.KafkaAutoConfiguration import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.ApplicationContext import org.springframework.retry.support.RetryTemplate import org.springframework.security.crypto.password.PasswordEncoder import org.springframework.security.provisioning.InMemoryUserDetailsManager import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.bean.override.mockito.MockitoBean import tools.jackson.databind.json.JsonMapper @SpringBootTest @ContextConfiguration( classes = [ AppConfiguration::class, AppSecurityConfiguration::class, KafkaAutoConfiguration::class, AppKafkaConfiguration::class, AppRestConfiguration::class, ConsentEvaluator::class, ], ) @MockitoBean(types = [ObjectMapper::class, JsonMapper::class]) @TestPropertySource( properties = [ "app.pseudonymize.generator=BUILDIN", ], ) class AppConfigurationTest { @Nested @TestPropertySource(properties = ["app.rest.uri=http://localhost:9000"]) inner class AppConfigurationRestTest( private val context: ApplicationContext, ) { @Test fun shouldUseRestMtbFileSenderNotKafkaMtbFileSender() { assertThat(context.getBean()).isNotNull assertThrows { context.getBean() } } } @Nested @TestPropertySource( properties = [ "app.kafka.servers=localhost:9092", "app.kafka.output-topic=test", "app.kafka.output-response-topic=test-response", "app.kafka.group-id=test", ], ) @MockitoBean(types = [RequestRepository::class]) inner class AppConfigurationKafkaTest( private val context: ApplicationContext, ) { @Test fun shouldUseKafkaMtbFileSenderNotRestMtbFileSender() { assertThrows { context.getBean() } assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource( properties = [ "app.rest.uri=http://localhost:9000", "app.kafka.servers=localhost:9092", "app.kafka.output-topic=test", "app.kafka.output-response-topic=test-response", "app.kafka.group-id=test", ], ) inner class AppConfigurationRestInPrecedenceTest( private val context: ApplicationContext, ) { @Test fun shouldUseRestMtbFileSenderNotKafkaMtbFileSender() { assertThat(context.getBean()).isNotNull assertThrows { context.getBean() } } } @Nested @TestPropertySource( properties = [ "app.kafka.servers=localhost:9092", "app.kafka.output-topic=test", "app.kafka.output-response-topic=test-response", "app.kafka.group-id=test", ], ) inner class AppConfigurationWithoutKafkaInputTest( private val context: ApplicationContext, ) { @Test fun shouldNotUseKafkaInputListener() { assertThrows { context.getBean() } } } @Nested @TestPropertySource( properties = [ "app.kafka.servers=localhost:9092", "app.kafka.input-topic=test_input", "app.kafka.output-topic=test", "app.kafka.output-response-topic=test-response", "app.kafka.group-id=test", ], ) @MockitoBean(types = [RequestProcessor::class]) inner class AppConfigurationUsingKafkaInputTest( private val context: ApplicationContext, ) { @Test fun shouldUseKafkaInputListener() { assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource( properties = [ "app.transformations[0].path=consent.status", "app.transformations[0].from=rejected", "app.transformations[0].to=accept", ], ) inner class AppConfigurationTransformationTest( private val context: ApplicationContext, ) { @Test fun shouldRecognizeTransformations() { val appConfigProperties = context.getBean() assertThat(appConfigProperties).isNotNull assertThat(appConfigProperties.transformations).hasSize(1) } } @Nested inner class AppConfigurationPseudonymizeTest { @Nested @TestPropertySource(properties = ["app.pseudonymize.generator=buildin"]) inner class AppConfigurationPseudonymizeGeneratorBuildinTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource( properties = ["app.pseudonymize.generator=gpas", "app.pseudonymize.gpas.uri=http://localhost/"], ) inner class AppConfigurationPseudonymizeGeneratorGpasTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource( properties = [ "app.pseudonymize.generator=gpas", "app.pseudonymize.gpas.soap-endpoint=http://localhost/", ], ) inner class AppConfigurationPseudonymizeGeneratorGpasSoapTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource(properties = ["app.security.enable-tokens=true"]) @MockitoBean( types = [InMemoryUserDetailsManager::class, PasswordEncoder::class, TokenRepository::class], ) inner class AppConfigurationTokenEnabledTest( private val context: ApplicationContext, ) { @Test fun checkTokenService() { assertThat(context.getBean()).isNotNull } } @Nested @MockitoBean( types = [InMemoryUserDetailsManager::class, PasswordEncoder::class, TokenRepository::class], ) inner class AppConfigurationTokenDisabledTest( private val context: ApplicationContext, ) { @Test fun checkTokenService() { assertThrows { context.getBean() } } } } @Nested @TestPropertySource( properties = ["app.rest.uri=http://localhost:9000", "app.max-retry-attempts=5"], ) inner class AppConfigurationRetryTest( private val context: ApplicationContext, ) { private val maxRetryAttempts = 5 @Test fun shouldUseRetryTemplateWithConfiguredMaxAttempts() { val retryTemplate = context.getBean() assertThat(retryTemplate).isNotNull assertThrows { retryTemplate.execute { assertThat(it.retryCount).isLessThan(maxRetryAttempts) throw RuntimeException() } } } } @Nested @TestPropertySource( properties = [ "app.consent.service=GICS", "app.consent.gics.uri=http://localhost:9000", ], ) inner class AppConfigurationConsentGicsTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } @Nested @TestPropertySource( properties = [ "app.consent.service=GICS_GET_BC", "app.consent.gics.uri=http://localhost:9000", ], ) inner class AppConfigurationConsentGicsGetBcTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } @Nested inner class AppConfigurationConsentBuildinTest( private val context: ApplicationContext, ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean()).isNotNull } } }