diff options
Diffstat (limited to 'src/integrationTest')
15 files changed, 1143 insertions, 1200 deletions
diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/AbstractTestcontainerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/AbstractTestcontainerTest.kt index 13b57d0..136691e 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/AbstractTestcontainerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/AbstractTestcontainerTest.kt @@ -25,13 +25,13 @@ import org.testcontainers.containers.PostgreSQLContainer import org.testcontainers.junit.jupiter.Container abstract class AbstractTestcontainerTest { - companion object { @Container - val dbContainer = CustomPostgreSQLContainer("postgres:10-alpine") - .withDatabaseName("test") - .withUsername("test") - .withPassword("test") ?: throw RuntimeException("Failed to create testcontainer!") + val dbContainer = + CustomPostgreSQLContainer("postgres:10-alpine") + .withDatabaseName("test") + .withUsername("test") + .withPassword("test") ?: throw RuntimeException("Failed to create testcontainer!") @DynamicPropertySource @JvmStatic @@ -41,11 +41,12 @@ abstract class AbstractTestcontainerTest { registry.add("spring.datasource.password", dbContainer::getPassword) } } - } -class CustomPostgreSQLContainer(dockerImageName: String) : PostgreSQLContainer<CustomPostgreSQLContainer>(dockerImageName) { +class CustomPostgreSQLContainer( + dockerImageName: String, +) : PostgreSQLContainer<CustomPostgreSQLContainer>(dockerImageName) { override fun stop() { // Keep Testcontainer alive until JVM destroys it } -}
\ No newline at end of file +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorApplicationTests.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorApplicationTests.kt index 1206c99..7826702 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorApplicationTests.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorApplicationTests.kt @@ -48,98 +48,95 @@ import org.testcontainers.junit.jupiter.Testcontainers @SpringBootTest @MockitoBean(types = [MtbFileSender::class]) @TestPropertySource( - properties = [ - "app.rest.uri=http://example.com", - "app.pseudonymize.generator=buildin", - "app.consent.service=none" - ] + properties = + [ + "app.rest.uri=http://example.com", + "app.pseudonymize.generator=buildin", + "app.consent.service=none", + ] ) class EtlProcessorApplicationTests : AbstractTestcontainerTest() { - @Test - fun contextLoadsIfMtbFileSenderConfigured(@Autowired context: ApplicationContext) { - // Simply check bean configuration - assertThat(context).isNotNull - } + @Test + fun contextLoadsIfMtbFileSenderConfigured(@Autowired context: ApplicationContext) { + // Simply check bean configuration + assertThat(context).isNotNull + } - @Nested - @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) - @AutoConfigureMockMvc - @TestPropertySource( - properties = [ - "app.pseudonymize.generator=buildin", - "app.consent.service=none", - "app.transformations[0].path=diagnoses[*].code.version", - "app.transformations[0].from=2013", - "app.transformations[0].to=2014", - ] - ) - inner class TransformationTest { + @Nested + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) + @AutoConfigureMockMvc + @TestPropertySource( + properties = + [ + "app.pseudonymize.generator=buildin", + "app.consent.service=none", + "app.transformations[0].path=diagnoses[*].code.version", + "app.transformations[0].from=2013", + "app.transformations[0].to=2014", + ] + ) + inner class TransformationTest { - @MockitoBean - private lateinit var mtbFileSender: MtbFileSender + @MockitoBean private lateinit var mtbFileSender: MtbFileSender - @Autowired - private lateinit var mockMvc: MockMvc + @Autowired private lateinit var mockMvc: MockMvc - @Autowired - private lateinit var objectMapper: ObjectMapper + @Autowired private lateinit var objectMapper: ObjectMapper - @BeforeEach - fun setup(@Autowired requestRepository: RequestRepository) { - requestRepository.deleteAll() - } + @BeforeEach + fun setup(@Autowired requestRepository: RequestRepository) { + requestRepository.deleteAll() + } - @Test - fun mtbFileIsTransformed() { - doAnswer { - MtbFileSender.Response(RequestStatus.SUCCESS) - }.whenever(mtbFileSender).send(any<DnpmV2MtbFileRequest>()) + @Test + fun mtbFileIsTransformed() { + doAnswer { MtbFileSender.Response(RequestStatus.SUCCESS) } + .whenever(mtbFileSender) + .send(any<DnpmV2MtbFileRequest>()) - val mtbFile = Mtb.builder() - .patient( - Patient.builder() - .id("TEST_12345678") - .build() - ) - .metadata( - MvhMetadata - .builder() - .modelProjectConsent( - ModelProjectConsent - .builder() - .provisions( - listOf(Provision.builder().type(ConsentProvision.PERMIT).purpose(ModelProjectConsentPurpose.SEQUENCING).build()) - ).build() - ) - .build() - ) - .diagnoses( - listOf( - MtbDiagnosis.builder() - .id("1234") - .patient(Reference.builder().id("TEST_12345678").build()) - .code(Coding.builder().code("F79.9").version("2013").build()) - .build(), - ) - ) - .build() + val mtbFile = + Mtb.builder() + .patient(Patient.builder().id("TEST_12345678").build()) + .metadata( + MvhMetadata.builder() + .modelProjectConsent( + ModelProjectConsent.builder() + .provisions( + listOf( + Provision.builder() + .type(ConsentProvision.PERMIT) + .purpose(ModelProjectConsentPurpose.SEQUENCING) + .build() + ) + ) + .build() + ) + .build() + ) + .diagnoses( + listOf( + MtbDiagnosis.builder() + .id("1234") + .patient(Reference.builder().id("TEST_12345678").build()) + .code(Coding.builder().code("F79.9").version("2013").build()) + .build(), + ) + ) + .build() - mockMvc.post("/mtbfile") { - content = objectMapper.writeValueAsString(mtbFile) - contentType = MediaType.APPLICATION_JSON - }.andExpect { - status { - isAccepted() - } - } + mockMvc + .post("/mtbfile") { + content = objectMapper.writeValueAsString(mtbFile) + contentType = MediaType.APPLICATION_JSON + } + .andExpect { status { isAccepted() } } - val captor = argumentCaptor<DnpmV2MtbFileRequest>() - verify(mtbFileSender).send(captor.capture()) - assertThat(captor.firstValue.content.diagnoses).hasSize(1).allMatch { diagnosis -> - diagnosis.code.version == "2014" - } - } + val captor = argumentCaptor<DnpmV2MtbFileRequest>() + verify(mtbFileSender).send(captor.capture()) + assertThat(captor.firstValue.content.diagnoses).hasSize(1).allMatch { diagnosis -> + diagnosis.code.version == "2014" + } } - + } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt index 308d0cc..1ebf458 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt @@ -9,65 +9,79 @@ import org.junit.jupiter.api.Test import org.springframework.data.repository.Repository class EtlProcessorArchTest { - private lateinit var noTestClasses: JavaClasses @BeforeEach fun setUp() { - this.noTestClasses = ClassFileImporter() - .withImportOption { !(it.contains("/test/") || it.contains("/integrationTest/")) } - .importPackages("dev.dnpm.etl.processor") + this.noTestClasses = + ClassFileImporter() + .withImportOption { !(it.contains("/test/") || it.contains("/integrationTest/")) } + .importPackages("dev.dnpm.etl.processor") } @Test fun noClassesInInputPackageShouldDependOnMonitoringPackage() { - val rule = noClasses() - .that() - .resideInAPackage("..input") - .should().dependOnClassesThat() - .resideInAnyPackage("..monitoring") + val rule = + noClasses() + .that() + .resideInAPackage("..input") + .should() + .dependOnClassesThat() + .resideInAnyPackage("..monitoring") rule.check(noTestClasses) } @Test fun noClassesInInputPackageShouldDependOnRepositories() { - val rule = noClasses() - .that() - .resideInAPackage("..input") - .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + val rule = + noClasses() + .that() + .resideInAPackage("..input") + .should() + .dependOnClassesThat() + .haveSimpleNameEndingWith("Repository") rule.check(noTestClasses) } @Test fun noClassesInOutputPackageShouldDependOnRepositories() { - val rule = noClasses() - .that() - .resideInAPackage("..output") - .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + val rule = + noClasses() + .that() + .resideInAPackage("..output") + .should() + .dependOnClassesThat() + .haveSimpleNameEndingWith("Repository") rule.check(noTestClasses) } @Test fun noClassesInWebPackageShouldDependOnRepositories() { - val rule = noClasses() - .that() - .resideInAPackage("..web") - .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + val rule = + noClasses() + .that() + .resideInAPackage("..web") + .should() + .dependOnClassesThat() + .haveSimpleNameEndingWith("Repository") rule.check(noTestClasses) } @Test fun repositoryClassNamesShouldEndWithRepository() { - val rule = classes() - .that() - .areInterfaces().and().areAssignableTo(Repository::class.java) - .should().haveSimpleNameEndingWith("Repository") + val rule = + classes() + .that() + .areInterfaces() + .and() + .areAssignableTo(Repository::class.java) + .should() + .haveSimpleNameEndingWith("Repository") rule.check(noTestClasses) } - -}
\ No newline at end of file +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/AppConfigurationTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/AppConfigurationTest.kt index 5e25428..f9fe2d4 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/AppConfigurationTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/AppConfigurationTest.kt @@ -50,127 +50,136 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean @SpringBootTest @ContextConfiguration( - classes = [ - AppConfiguration::class, - AppSecurityConfiguration::class, - KafkaAutoConfiguration::class, - AppKafkaConfiguration::class, - AppRestConfiguration::class, - ConsentEvaluator::class - ] + classes = + [ + AppConfiguration::class, + AppSecurityConfiguration::class, + KafkaAutoConfiguration::class, + AppKafkaConfiguration::class, + AppRestConfiguration::class, + ConsentEvaluator::class, + ], ) @MockitoBean(types = [ObjectMapper::class]) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - ] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + ], ) class AppConfigurationTest { - @Nested - @TestPropertySource( - properties = [ - "app.rest.uri=http://localhost:9000" - ] - ) - inner class AppConfigurationRestTest(private val context: ApplicationContext) { - + @TestPropertySource(properties = ["app.rest.uri=http://localhost:9000"]) + inner class AppConfigurationRestTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseRestMtbFileSenderNotKafkaMtbFileSender() { assertThat(context.getBean(RestMtbFileSender::class.java)).isNotNull - assertThrows<NoSuchBeanDefinitionException> { context.getBean(KafkaMtbFileSender::class.java) } + assertThrows<NoSuchBeanDefinitionException> { + context.getBean(KafkaMtbFileSender::class.java) + } } - } @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" - ] + 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) { - + inner class AppConfigurationKafkaTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseKafkaMtbFileSenderNotRestMtbFileSender() { assertThrows<NoSuchBeanDefinitionException> { context.getBean(RestMtbFileSender::class.java) } assertThat(context.getBean(KafkaMtbFileSender::class.java)).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" - ] + 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) { - + inner class AppConfigurationRestInPrecedenceTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseRestMtbFileSenderNotKafkaMtbFileSender() { assertThat(context.getBean(RestMtbFileSender::class.java)).isNotNull - assertThrows<NoSuchBeanDefinitionException> { context.getBean(KafkaMtbFileSender::class.java) } + assertThrows<NoSuchBeanDefinitionException> { + context.getBean(KafkaMtbFileSender::class.java) + } } - } @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" - ] + 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) { - + inner class AppConfigurationWithoutKafkaInputTest( + private val context: ApplicationContext, + ) { @Test fun shouldNotUseKafkaInputListener() { - assertThrows<NoSuchBeanDefinitionException> { context.getBean(KafkaInputListener::class.java) } + assertThrows<NoSuchBeanDefinitionException> { + context.getBean(KafkaInputListener::class.java) + } } - } @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" - ] + 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) { - + inner class AppConfigurationUsingKafkaInputTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseKafkaInputListener() { assertThat(context.getBean(KafkaInputListener::class.java)).isNotNull } - } @Nested @TestPropertySource( - properties = [ - "app.transformations[0].path=consent.status", - "app.transformations[0].from=rejected", - "app.transformations[0].to=accept", - ] + properties = + [ + "app.transformations[0].path=consent.status", + "app.transformations[0].from=rejected", + "app.transformations[0].to=accept", + ], ) - inner class AppConfigurationTransformationTest(private val context: ApplicationContext) { - + inner class AppConfigurationTransformationTest( + private val context: ApplicationContext, + ) { @Test fun shouldRecognizeTransformations() { val appConfigProperties = context.getBean(AppConfigProperties::class.java) @@ -178,109 +187,87 @@ class AppConfigurationTest { 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) { - + @TestPropertySource(properties = ["app.pseudonymize.generator=buildin"]) + inner class AppConfigurationPseudonymizeGeneratorBuildinTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean(AnonymizingGenerator::class.java)).isNotNull } - } @Nested @TestPropertySource( - properties = [ - "app.pseudonymize.generator=gpas", - "app.pseudonymize.gpas.uri=http://localhost/" - ] + properties = + ["app.pseudonymize.generator=gpas", "app.pseudonymize.gpas.uri=http://localhost/"], ) - inner class AppConfigurationPseudonymizeGeneratorGpasTest(private val context: ApplicationContext) { - + inner class AppConfigurationPseudonymizeGeneratorGpasTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean(GpasPseudonymGenerator::class.java)).isNotNull } - } @Nested @TestPropertySource( - properties = [ - "app.pseudonymize.generator=gpas", - "app.pseudonymize.gpas.soap-endpoint=http://localhost/" - ] + properties = + [ + "app.pseudonymize.generator=gpas", + "app.pseudonymize.gpas.soap-endpoint=http://localhost/", + ], ) - inner class AppConfigurationPseudonymizeGeneratorGpasSoapTest(private val context: ApplicationContext) { - + inner class AppConfigurationPseudonymizeGeneratorGpasSoapTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean(GpasSoapPseudonymGenerator::class.java)).isNotNull } - } @Nested - @TestPropertySource( - properties = [ - "app.security.enable-tokens=true" - ] - ) + @TestPropertySource(properties = ["app.security.enable-tokens=true"]) @MockitoBean( - types = [ - InMemoryUserDetailsManager::class, - PasswordEncoder::class, - TokenRepository::class - ] + types = [InMemoryUserDetailsManager::class, PasswordEncoder::class, TokenRepository::class], ) - inner class AppConfigurationTokenEnabledTest(private val context: ApplicationContext) { - + inner class AppConfigurationTokenEnabledTest( + private val context: ApplicationContext, + ) { @Test fun checkTokenService() { assertThat(context.getBean(TokenService::class.java)).isNotNull } - } @Nested @MockitoBean( - types = [ - InMemoryUserDetailsManager::class, - PasswordEncoder::class, - TokenRepository::class - ] + types = [InMemoryUserDetailsManager::class, PasswordEncoder::class, TokenRepository::class], ) - inner class AppConfigurationTokenDisabledTest(private val context: ApplicationContext) { - + inner class AppConfigurationTokenDisabledTest( + private val context: ApplicationContext, + ) { @Test fun checkTokenService() { assertThrows<NoSuchBeanDefinitionException> { context.getBean(TokenService::class.java) } } - } - } @Nested @TestPropertySource( - properties = [ - "app.rest.uri=http://localhost:9000", - "app.max-retry-attempts=5" - ] + properties = ["app.rest.uri=http://localhost:9000", "app.max-retry-attempts=5"], ) - inner class AppConfigurationRetryTest(private val context: ApplicationContext) { - + inner class AppConfigurationRetryTest( + private val context: ApplicationContext, + ) { private val maxRetryAttempts = 5 @Test @@ -295,33 +282,32 @@ class AppConfigurationTest { } } } - } @Nested @TestPropertySource( - properties = [ - "app.consent.service=GICS", - "app.consent.gics.uri=http://localhost:9000", - ] + properties = + [ + "app.consent.service=GICS", + "app.consent.gics.uri=http://localhost:9000", + ], ) - inner class AppConfigurationConsentGicsTest(private val context: ApplicationContext) { - + inner class AppConfigurationConsentGicsTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean(GicsConsentService::class.java)).isNotNull } - } @Nested - inner class AppConfigurationConsentBuildinTest(private val context: ApplicationContext) { - + inner class AppConfigurationConsentBuildinTest( + private val context: ApplicationContext, + ) { @Test fun shouldUseConfiguredGenerator() { assertThat(context.getBean(MtbFileConsentService::class.java)).isNotNull } - } - } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/GPasConfigPropertiesTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/GPasConfigPropertiesTest.kt index 66e0660..bda5b79 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/GPasConfigPropertiesTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/config/GPasConfigPropertiesTest.kt @@ -7,17 +7,16 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.runner.ApplicationContextRunner import org.springframework.test.context.ContextConfiguration - @SpringBootTest @ContextConfiguration( - classes = [ - GPasConfigProperties::class, - ] + classes = + [ + GPasConfigProperties::class, + ], ) class GPasConfigPropertiesTest { - @EnableConfigurationProperties(GPasConfigProperties::class) - class TestConfig {} + class TestConfig @Test fun shouldUseConfiguredPatientDomainIfPidDomainGiven() { @@ -25,9 +24,8 @@ class GPasConfigPropertiesTest { .withUserConfiguration(TestConfig::class.java) .withPropertyValues( "app.pseudonymize.gpas.uri=http://localhost/", - "app.pseudonymize.gpas.pid-domain=test-pid-domain" - ) - .run { context -> + "app.pseudonymize.gpas.pid-domain=test-pid-domain", + ).run { context -> val properties = context.getBean(GPasConfigProperties::class.java) assertThat(properties).isNotNull @@ -41,14 +39,12 @@ class GPasConfigPropertiesTest { .withUserConfiguration(TestConfig::class.java) .withPropertyValues( "app.pseudonymize.gpas.uri=http://localhost/", - "app.pseudonymize.gpas.patient-domain=test-patient-domain" - ) - .run { context -> + "app.pseudonymize.gpas.patient-domain=test-patient-domain", + ).run { context -> val properties = context.getBean(GPasConfigProperties::class.java) assertThat(properties).isNotNull assertThat(properties.patientDomain).isEqualTo("test-patient-domain") } } - -}
\ No newline at end of file +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt index 6ca420f..5ee6922 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt @@ -23,8 +23,7 @@ import org.mockito.ArgumentMatchers @Suppress("UNCHECKED_CAST") inline fun <reified T> anyValueClass(): T { - val unboxedClass = T::class.java.declaredFields.first().type - return ArgumentMatchers.any(unboxedClass as Class<T>) - ?: T::class.java.getDeclaredMethod("box-impl", unboxedClass) - .invoke(null, null) as T -}
\ No newline at end of file + val unboxedClass = T::class.java.declaredFields.first().type + return ArgumentMatchers.any(unboxedClass as Class<T>) + ?: T::class.java.getDeclaredMethod("box-impl", unboxedClass).invoke(null, null) as T +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt index 5f2d7ca..e966898 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt @@ -29,6 +29,8 @@ import dev.dnpm.etl.processor.security.TokenRepository import dev.dnpm.etl.processor.security.UserRoleRepository import dev.dnpm.etl.processor.services.RequestProcessor import dev.pcvolkmer.mv64e.mtb.* +import java.time.Instant +import java.util.* import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested import org.junit.jupiter.api.Test @@ -48,180 +50,177 @@ import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.delete import org.springframework.test.web.servlet.post -import java.time.Instant -import java.util.* @WebMvcTest(controllers = [MtbFileRestController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - MtbFileRestController::class, - AppSecurityConfiguration::class, - MtbFileConsentService::class - ] + classes = + [ + MtbFileRestController::class, + AppSecurityConfiguration::class, + MtbFileConsentService::class, + ] ) -@MockitoBean(types = [TokenRepository::class, RequestProcessor::class, ConsentEvaluator::class]) +@MockitoBean(types = [TokenRepository::class, RequestProcessor::class, ConsentEvaluator::class]) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret", - "app.security.enable-tokens=true" - ] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + "app.security.enable-tokens=true", + ] ) class MtbFileRestControllerTest { - lateinit var mockMvc: MockMvc - lateinit var requestProcessor: RequestProcessor - lateinit var consentEvaluator: ConsentEvaluator - - @BeforeEach - fun setup( - @Autowired mockMvc: MockMvc, - @Autowired requestProcessor: RequestProcessor, - @Autowired consentEvaluator: ConsentEvaluator - ) { - this.mockMvc = mockMvc - this.requestProcessor = requestProcessor - this.consentEvaluator = consentEvaluator - - doAnswer { - ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true) - }.whenever(consentEvaluator).check(any()) - } - - @Test - fun testShouldGrantPermissionToSendMtbFile() { - mockMvc.post("/mtbfile") { - with(user("onkostarserver").roles("MTBFILE")) - contentType = MediaType.APPLICATION_JSON - content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isAccepted() } + lateinit var mockMvc: MockMvc + lateinit var requestProcessor: RequestProcessor + lateinit var consentEvaluator: ConsentEvaluator + + @BeforeEach + fun setup( + @Autowired mockMvc: MockMvc, + @Autowired requestProcessor: RequestProcessor, + @Autowired consentEvaluator: ConsentEvaluator, + ) { + this.mockMvc = mockMvc + this.requestProcessor = requestProcessor + this.consentEvaluator = consentEvaluator + + doAnswer { ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true) } + .whenever(consentEvaluator) + .check(any()) + } + + @Test + fun testShouldGrantPermissionToSendMtbFile() { + mockMvc + .post("/mtbfile") { + with(user("onkostarserver").roles("MTBFILE")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) } - - verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) - } - + .andExpect { status { isAccepted() } } + + verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) + } + + @Test + fun testShouldGrantPermissionToSendMtbFileToAdminUser() { + mockMvc + .post("/mtbfile") { + with(user("onkostarserver").roles("ADMIN")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + } + .andExpect { status { isAccepted() } } + + verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) + } + + @Test + fun testShouldDenyPermissionToSendMtbFile() { + mockMvc + .post("/mtbfile") { + with(anonymous()) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + } + .andExpect { status { isUnauthorized() } } + + verify(requestProcessor, never()).processMtbFile(any<Mtb>()) + } + + @Test + fun testShouldDenyPermissionToSendMtbFileForUser() { + mockMvc + .post("/mtbfile") { + with(user("fakeuser").roles("USER")) + contentType = MediaType.APPLICATION_JSON + content = ObjectMapper().writeValueAsString(mtbFile) + } + .andExpect { status { isForbidden() } } + + verify(requestProcessor, never()).processMtbFile(any<Mtb>()) + } + + @Test + fun testShouldGrantPermissionToDeletePatientData() { + mockMvc + .delete("/mtbfile/12345678") { with(user("onkostarserver").roles("MTBFILE")) } + .andExpect { status { isAccepted() } } + + verify(requestProcessor, times(1)) + .processDeletion(anyValueClass(), eq(TtpConsentStatus.UNKNOWN_CHECK_FILE)) + } + + @Test + fun testShouldDenyPermissionToDeletePatientData() { + mockMvc + .delete("/mtbfile/12345678") { with(anonymous()) } + .andExpect { status { isUnauthorized() } } + + verify(requestProcessor, never()).processDeletion(anyValueClass(), any()) + } + + @Nested + @MockitoBean(types = [UserRoleRepository::class, ClientRegistrationRepository::class]) + @TestPropertySource( + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + "app.security.enable-tokens=true", + "app.security.enable-oidc=true", + ] + ) + inner class WithOidcEnabled { @Test fun testShouldGrantPermissionToSendMtbFileToAdminUser() { - mockMvc.post("/mtbfile") { + mockMvc + .post("/mtbfile") { with(user("onkostarserver").roles("ADMIN")) contentType = MediaType.APPLICATION_JSON content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isAccepted() } - } - - verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) - } - - @Test - fun testShouldDenyPermissionToSendMtbFile() { - mockMvc.post("/mtbfile") { - with(anonymous()) - contentType = MediaType.APPLICATION_JSON - content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isUnauthorized() } - } + } + .andExpect { status { isAccepted() } } - verify(requestProcessor, never()).processMtbFile(any<Mtb>()) + verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) } @Test - fun testShouldDenyPermissionToSendMtbFileForUser() { - mockMvc.post("/mtbfile") { - with(user("fakeuser").roles("USER")) + fun testShouldGrantPermissionToSendMtbFileToUser() { + mockMvc + .post("/mtbfile") { + with(user("onkostarserver").roles("USER")) contentType = MediaType.APPLICATION_JSON content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isForbidden() } - } - - verify(requestProcessor, never()).processMtbFile(any<Mtb>()) - } - - @Test - fun testShouldGrantPermissionToDeletePatientData() { - mockMvc.delete("/mtbfile/12345678") { - with(user("onkostarserver").roles("MTBFILE")) - }.andExpect { - status { isAccepted() } - } + } + .andExpect { status { isAccepted() } } - verify(requestProcessor, times(1)).processDeletion(anyValueClass(), eq(TtpConsentStatus.UNKNOWN_CHECK_FILE)) + verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) } + } - @Test - fun testShouldDenyPermissionToDeletePatientData() { - mockMvc.delete("/mtbfile/12345678") { - with(anonymous()) - }.andExpect { - status { isUnauthorized() } - } + companion object { - verify(requestProcessor, never()).processDeletion(anyValueClass(), any()) - } - - @Nested - @MockitoBean(types = [UserRoleRepository::class, ClientRegistrationRepository::class]) - @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret", - "app.security.enable-tokens=true", - "app.security.enable-oidc=true" - ] - ) - inner class WithOidcEnabled { - @Test - fun testShouldGrantPermissionToSendMtbFileToAdminUser() { - mockMvc.post("/mtbfile") { - with(user("onkostarserver").roles("ADMIN")) - contentType = MediaType.APPLICATION_JSON - content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isAccepted() } - } - - verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) - } - - @Test - fun testShouldGrantPermissionToSendMtbFileToUser() { - mockMvc.post("/mtbfile") { - with(user("onkostarserver").roles("USER")) - contentType = MediaType.APPLICATION_JSON - content = ObjectMapper().writeValueAsString(mtbFile) - }.andExpect { - status { isAccepted() } - } - - verify(requestProcessor, times(1)).processMtbFile(any<Mtb>()) - } - } - - companion object { - - val mtbFile = Mtb.builder() - .patient( - Patient.builder() - .id("PID") - .build() - ) + val mtbFile = + Mtb.builder() + .patient(Patient.builder().id("PID").build()) .episodesOfCare( listOf( MtbEpisodeOfCare.builder() .id("1") .patient(Reference.builder().id("PID").build()) - .period(PeriodDate.builder().start(Date.from(Instant.parse("2023-08-08T02:00:00.00Z"))).build()) + .period( + PeriodDate.builder() + .start(Date.from(Instant.parse("2023-08-08T02:00:00.00Z"))) + .build() + ) .build() ) ) .build() - - } - + } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/monitoring/RequestRepositoryTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/monitoring/RequestRepositoryTest.kt index 428bca9..428a99d 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/monitoring/RequestRepositoryTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/monitoring/RequestRepositoryTest.kt @@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.monitoring import dev.dnpm.etl.processor.* import dev.dnpm.etl.processor.output.MtbFileSender +import java.time.Instant import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith @@ -32,7 +33,6 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.transaction.annotation.Transactional import org.testcontainers.junit.jupiter.Testcontainers -import java.time.Instant @Testcontainers @ExtendWith(SpringExtension::class) @@ -41,35 +41,30 @@ import java.time.Instant @Transactional @MockitoBean(types = [MtbFileSender::class]) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=buildin", - "app.rest.uri=http://example.com" - ] + properties = ["app.pseudonymize.generator=buildin", "app.rest.uri=http://example.com"] ) class RequestRepositoryTest : AbstractTestcontainerTest() { - private lateinit var requestRepository: RequestRepository + private lateinit var requestRepository: RequestRepository - @BeforeEach - fun setUp( - @Autowired requestRepository: RequestRepository - ) { - this.requestRepository = requestRepository - } + @BeforeEach + fun setUp(@Autowired requestRepository: RequestRepository) { + this.requestRepository = requestRepository + } - @Test - fun shouldSaveRequest() { - val request = Request( + @Test + fun shouldSaveRequest() { + val request = + Request( randomRequestId(), PatientPseudonym("TEST_12345678901"), PatientId("P1"), Fingerprint("0123456789abcdef1"), RequestType.MTB_FILE, RequestStatus.WARNING, - Instant.parse("2023-07-07T00:00:00Z") + Instant.parse("2023-07-07T00:00:00Z"), ) - requestRepository.save(request) - } - -}
\ No newline at end of file + requestRepository.save(request) + } +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGeneratorTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGeneratorTest.kt index 578810e..cccd614 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGeneratorTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGeneratorTest.kt @@ -41,7 +41,6 @@ import java.io.IOException import java.net.URI class GpasPseudonymGeneratorTest { - private lateinit var mockRestServiceServer: MockRestServiceServer private lateinit var generator: GpasPseudonymGenerator private lateinit var restTemplate: RestTemplate @@ -50,14 +49,8 @@ class GpasPseudonymGeneratorTest { @BeforeEach fun setup() { val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build() - val gPasConfigProperties = GPasConfigProperties( - CONFIGURED_URI, - null, - null, - "test", "test2", - null, - null - ) + val gPasConfigProperties = + GPasConfigProperties(CONFIGURED_URI, null, null, "test", "test2", null, null) this.restTemplate = RestTemplate() this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate) @@ -71,13 +64,8 @@ class GpasPseudonymGeneratorTest { .expect(method(HttpMethod.POST)) .andExpect(requestTo(EXPECTED_URI)) .andRespond { - withStatus(HttpStatus.OK).body( - getDummyResponseBody( - "1234", - "test", - "test1234ABCDEF567890" - ) - ) + withStatus(HttpStatus.OK) + .body(getDummyResponseBody("1234", "test", "test1234ABCDEF567890")) .createResponse(it) } @@ -89,9 +77,7 @@ class GpasPseudonymGeneratorTest { this.mockRestServiceServer .expect(method(HttpMethod.POST)) .andExpect(requestTo(EXPECTED_URI)) - .andRespond { - withException(IOException("Simulated IO error")).createResponse(it) - } + .andRespond { withException(IOException("Simulated IO error")).createResponse(it) } assertThrows<PseudonymRequestFailed> { this.generator.generate("ID1234") } } @@ -105,52 +91,56 @@ class GpasPseudonymGeneratorTest { withStatus(HttpStatus.FOUND) .header( HttpHeaders.LOCATION, - $$"https://localhost/ttp-fhir/fhir/gpas/$pseudonymizeAllowCreate" - ) - .createResponse(it) + $$"https://localhost/ttp-fhir/fhir/gpas/$pseudonymizeAllowCreate", + ).createResponse(it) } assertThrows<PseudonymRequestFailed> { this.generator.generate("ID1234") } } companion object { - const val CONFIGURED_URI = "https://localhost/ttp-fhir/fhir/gpas" - val EXPECTED_URI = URIBuilder(URI.create(CONFIGURED_URI)).appendPath($$"$pseudonymizeAllowCreate") - .build()!! + val EXPECTED_URI = + URIBuilder(URI.create(CONFIGURED_URI)).appendPath($$"$pseudonymizeAllowCreate").build()!! - fun getDummyResponseBody(original: String, target: String, pseudonym: String) = """{ - "resourceType": "Parameters", - "parameter": [ + fun getDummyResponseBody( + original: String, + target: String, + pseudonym: String, + ) = """ { - "name": "pseudonym", - "part": [ - { - "name": "original", - "valueIdentifier": { - "system": "https://ths-greifswald.de/gpas", - "value": "$original" - } - }, - { - "name": "target", - "valueIdentifier": { - "system": "https://ths-greifswald.de/gpas", - "value": "$target" - } - }, + "resourceType": "Parameters", + "parameter": [ { "name": "pseudonym", - "valueIdentifier": { - "system": "https://ths-greifswald.de/gpas", - "value": "$pseudonym" - } + "part": [ + { + "name": "original", + "valueIdentifier": { + "system": "https://ths-greifswald.de/gpas", + "value": "$original" + } + }, + { + "name": "target", + "valueIdentifier": { + "system": "https://ths-greifswald.de/gpas", + "value": "$target" + } + }, + { + "name": "pseudonym", + "valueIdentifier": { + "system": "https://ths-greifswald.de/gpas", + "value": "$pseudonym" + } + } + ] } ] } - ] - }""".trimIndent() - + + """.trimIndent() } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/services/RequestServiceIntegrationTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/services/RequestServiceIntegrationTest.kt index 9fcdc16..d9489f2 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/services/RequestServiceIntegrationTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/services/RequestServiceIntegrationTest.kt @@ -25,6 +25,7 @@ import dev.dnpm.etl.processor.monitoring.RequestRepository import dev.dnpm.etl.processor.monitoring.RequestStatus import dev.dnpm.etl.processor.monitoring.RequestType import dev.dnpm.etl.processor.output.MtbFileSender +import java.time.Instant import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -36,7 +37,6 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.transaction.annotation.Transactional import org.testcontainers.junit.jupiter.Testcontainers -import java.time.Instant @Testcontainers @ExtendWith(SpringExtension::class) @@ -44,101 +44,95 @@ import java.time.Instant @Transactional @MockitoBean(types = [MtbFileSender::class]) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=buildin", - "app.rest.uri=http://example.com" - ] + properties = ["app.pseudonymize.generator=buildin", "app.rest.uri=http://example.com"] ) class RequestServiceIntegrationTest : AbstractTestcontainerTest() { - private lateinit var requestRepository: RequestRepository - - private lateinit var requestService: RequestService - - @BeforeEach - fun setup( - @Autowired requestRepository: RequestRepository - ) { - this.requestRepository = requestRepository - this.requestService = RequestService(requestRepository) - } - - @Test - fun shouldResultInEmptyRequestList() { - val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM) - - assertThat(actual).isEmpty() - } - - private fun setupTestData() { - // Prepare DB - this.requestRepository.saveAll( - listOf( - Request( - randomRequestId(), - PatientPseudonym("TEST_12345678901"), - PatientId("P1"), - Fingerprint("0123456789abcdef1"), - RequestType.MTB_FILE, - RequestStatus.SUCCESS, - Instant.parse("2023-07-07T02:00:00Z") - ), - // Should be ignored - wrong patient ID --> - Request( - randomRequestId(), - PatientPseudonym("TEST_12345678902"), - PatientId("P2"), - Fingerprint("0123456789abcdef2"), - RequestType.MTB_FILE, - RequestStatus.WARNING, - Instant.parse("2023-08-08T00:00:00Z") - ), - // <-- - Request( - randomRequestId(), - PatientPseudonym("TEST_12345678901"), - PatientId("P2"), - Fingerprint("0123456789abcdee1"), - RequestType.DELETE, - RequestStatus.SUCCESS, - Instant.parse("2023-08-08T02:00:00Z") - ) - ) + private lateinit var requestRepository: RequestRepository + + private lateinit var requestService: RequestService + + @BeforeEach + fun setup(@Autowired requestRepository: RequestRepository) { + this.requestRepository = requestRepository + this.requestService = RequestService(requestRepository) + } + + @Test + fun shouldResultInEmptyRequestList() { + val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM) + + assertThat(actual).isEmpty() + } + + private fun setupTestData() { + // Prepare DB + this.requestRepository.saveAll( + listOf( + Request( + randomRequestId(), + PatientPseudonym("TEST_12345678901"), + PatientId("P1"), + Fingerprint("0123456789abcdef1"), + RequestType.MTB_FILE, + RequestStatus.SUCCESS, + Instant.parse("2023-07-07T02:00:00Z"), + ), + // Should be ignored - wrong patient ID --> + Request( + randomRequestId(), + PatientPseudonym("TEST_12345678902"), + PatientId("P2"), + Fingerprint("0123456789abcdef2"), + RequestType.MTB_FILE, + RequestStatus.WARNING, + Instant.parse("2023-08-08T00:00:00Z"), + ), + // <-- + Request( + randomRequestId(), + PatientPseudonym("TEST_12345678901"), + PatientId("P2"), + Fingerprint("0123456789abcdee1"), + RequestType.DELETE, + RequestStatus.SUCCESS, + Instant.parse("2023-08-08T02:00:00Z"), + ), ) - } - - @Test - fun shouldResultInSortedRequestList() { - setupTestData() + ) + } - val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM) + @Test + fun shouldResultInSortedRequestList() { + setupTestData() - assertThat(actual).hasSize(2) - assertThat(actual[0].fingerprint).isEqualTo(Fingerprint("0123456789abcdee1")) - assertThat(actual[1].fingerprint).isEqualTo(Fingerprint("0123456789abcdef1")) - } + val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM) - @Test - fun shouldReturnDeleteRequestAsLastRequest() { - setupTestData() + assertThat(actual).hasSize(2) + assertThat(actual[0].fingerprint).isEqualTo(Fingerprint("0123456789abcdee1")) + assertThat(actual[1].fingerprint).isEqualTo(Fingerprint("0123456789abcdef1")) + } - val actual = requestService.isLastRequestWithKnownStatusDeletion(TEST_PATIENT_PSEUDONYM) + @Test + fun shouldReturnDeleteRequestAsLastRequest() { + setupTestData() - assertThat(actual).isTrue() - } + val actual = requestService.isLastRequestWithKnownStatusDeletion(TEST_PATIENT_PSEUDONYM) - @Test - fun shouldReturnLastMtbFileRequest() { - setupTestData() + assertThat(actual).isTrue() + } - val actual = requestService.lastMtbFileRequestForPatientPseudonym(TEST_PATIENT_PSEUDONYM) + @Test + fun shouldReturnLastMtbFileRequest() { + setupTestData() - assertThat(actual).isNotNull - assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef1")) - } + val actual = requestService.lastMtbFileRequestForPatientPseudonym(TEST_PATIENT_PSEUDONYM) - companion object { - val TEST_PATIENT_PSEUDONYM = PatientPseudonym("TEST_12345678901") - } + assertThat(actual).isNotNull + assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef1")) + } -}
\ No newline at end of file + companion object { + val TEST_PATIENT_PSEUDONYM = PatientPseudonym("TEST_12345678901") + } +} diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt index 8e5d38e..c081319 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/ConfigControllerTest.kt @@ -32,6 +32,7 @@ import dev.dnpm.etl.processor.security.TokenService import dev.dnpm.etl.processor.security.UserRoleService import dev.dnpm.etl.processor.services.RequestProcessor import dev.dnpm.etl.processor.services.TransformationService +import java.time.Instant import org.assertj.core.api.Assertions.assertThat import org.htmlunit.WebClient import org.htmlunit.html.HtmlPage @@ -64,320 +65,288 @@ import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder import org.springframework.web.context.WebApplicationContext import reactor.core.publisher.Sinks import reactor.test.StepVerifier -import java.time.Instant abstract class MockSink : Sinks.Many<Boolean> @WebMvcTest(controllers = [ConfigController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - ConfigController::class, - AppConfiguration::class, - AppSecurityConfiguration::class - ] -) -@TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN" - ] + classes = [ConfigController::class, AppConfiguration::class, AppSecurityConfiguration::class] ) +@TestPropertySource(properties = ["app.pseudonymize.generator=BUILDIN"]) @MockitoBean(name = "configsUpdateProducer", types = [MockSink::class]) @MockitoBean( - types = [ - Generator::class, - MtbFileSender::class, - RequestProcessor::class, - TransformationService::class, - GPasConnectionCheckService::class, - RestConnectionCheckService::class, - GIcsConnectionCheckService::class - ] + types = + [ + Generator::class, + MtbFileSender::class, + RequestProcessor::class, + TransformationService::class, + GPasConnectionCheckService::class, + RestConnectionCheckService::class, + GIcsConnectionCheckService::class, + ] ) class ConfigControllerTest { - private lateinit var mockMvc: MockMvc - private lateinit var webClient: WebClient + private lateinit var mockMvc: MockMvc + private lateinit var webClient: WebClient + + private lateinit var requestProcessor: RequestProcessor + private lateinit var connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult> + + @BeforeEach + fun setup( + @Autowired mockMvc: MockMvc, + @Autowired requestProcessor: RequestProcessor, + @Autowired connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>, + ) { + this.mockMvc = mockMvc + this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() + this.requestProcessor = requestProcessor + this.connectionCheckUpdateProducer = connectionCheckUpdateProducer + + webClient.options.isThrowExceptionOnScriptError = false + } + + @Test + fun testShouldRequestConfigPageIfLoggedIn() { + mockMvc + .get("/configs") { + with(user("admin").roles("ADMIN")) + accept(MediaType.TEXT_HTML) + } + .andExpect { + status { isOk() } + view { name("configs") } + } + } + + @Test + fun testShouldRedirectToLoginPageIfNotLoggedIn() { + mockMvc + .get("/configs") { + with(anonymous()) + accept(MediaType.TEXT_HTML) + } + .andExpect { + status { isFound() } + header { stringValues(HttpHeaders.LOCATION, "http://localhost/login") } + } + } - private lateinit var requestProcessor: RequestProcessor - private lateinit var connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult> + @Nested + @TestPropertySource( + properties = ["app.security.enable-tokens=true", "app.security.admin-user=admin"] + ) + @MockitoBean(types = [TokenService::class]) + inner class WithTokensEnabled { + private lateinit var tokenService: TokenService @BeforeEach - fun setup( - @Autowired mockMvc: MockMvc, - @Autowired requestProcessor: RequestProcessor, - @Autowired connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult> - ) { - this.mockMvc = mockMvc - this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() - this.requestProcessor = requestProcessor - this.connectionCheckUpdateProducer = connectionCheckUpdateProducer - - webClient.options.isThrowExceptionOnScriptError = false + fun setup(@Autowired tokenService: TokenService) { + webClient.options.isThrowExceptionOnScriptError = false + + this.tokenService = tokenService } @Test - fun testShouldRequestConfigPageIfLoggedIn() { - mockMvc.get("/configs") { + fun testShouldSaveNewToken() { + mockMvc + .post("/configs/tokens") { with(user("admin").roles("ADMIN")) accept(MediaType.TEXT_HTML) - }.andExpect { - status { isOk() } - view { name("configs") } - } + contentType = MediaType.APPLICATION_FORM_URLENCODED + content = "name=Testtoken" + } + .andExpect { + status { is2xxSuccessful() } + view { name("configs/tokens") } + } + + val captor = argumentCaptor<String>() + verify(tokenService, times(1)).addToken(captor.capture()) + + assertThat(captor.firstValue).isEqualTo("Testtoken") } @Test - fun testShouldRedirectToLoginPageIfNotLoggedIn() { - mockMvc.get("/configs") { - with(anonymous()) + fun testShouldNotSaveTokenWithExstingName() { + whenever(tokenService.addToken(anyString())) + .thenReturn(Result.failure(RuntimeException("Testfailure"))) + + mockMvc + .post("/configs/tokens") { + with(user("admin").roles("ADMIN")) accept(MediaType.TEXT_HTML) - }.andExpect { - status { isFound() } - header { - stringValues(HttpHeaders.LOCATION, "http://localhost/login") - } - } + contentType = MediaType.APPLICATION_FORM_URLENCODED + content = "name=Testtoken" + } + .andExpect { + status { is2xxSuccessful() } + view { name("configs/tokens") } + } + + val captor = argumentCaptor<String>() + verify(tokenService, times(1)).addToken(captor.capture()) + + assertThat(captor.firstValue).isEqualTo("Testtoken") } - @Nested - @TestPropertySource( - properties = [ - "app.security.enable-tokens=true", - "app.security.admin-user=admin" - ] - ) - @MockitoBean( - types = [ - TokenService::class - ] - ) - inner class WithTokensEnabled { - private lateinit var tokenService: TokenService - - @BeforeEach - fun setup( - @Autowired tokenService: TokenService - ) { - webClient.options.isThrowExceptionOnScriptError = false - - this.tokenService = tokenService - } - - @Test - fun testShouldSaveNewToken() { - mockMvc.post("/configs/tokens") { - with(user("admin").roles("ADMIN")) - accept(MediaType.TEXT_HTML) - contentType = MediaType.APPLICATION_FORM_URLENCODED - content = "name=Testtoken" - }.andExpect { - status { is2xxSuccessful() } - view { name("configs/tokens") } - } - - val captor = argumentCaptor<String>() - verify(tokenService, times(1)).addToken(captor.capture()) - - assertThat(captor.firstValue).isEqualTo("Testtoken") - } - - @Test - fun testShouldNotSaveTokenWithExstingName() { - whenever(tokenService.addToken(anyString())).thenReturn( - Result.failure( - RuntimeException( - "Testfailure" - ) - ) - ) - - mockMvc.post("/configs/tokens") { - with(user("admin").roles("ADMIN")) - accept(MediaType.TEXT_HTML) - contentType = MediaType.APPLICATION_FORM_URLENCODED - content = "name=Testtoken" - }.andExpect { - status { is2xxSuccessful() } - view { name("configs/tokens") } - } - - val captor = argumentCaptor<String>() - verify(tokenService, times(1)).addToken(captor.capture()) - - assertThat(captor.firstValue).isEqualTo("Testtoken") - } - - @Test - fun testShouldDeleteToken() { - mockMvc.delete("/configs/tokens/42") { - with(user("admin").roles("ADMIN")) - accept(MediaType.TEXT_HTML) - }.andExpect { - status { is2xxSuccessful() } - view { name("configs/tokens") } - } - - val captor = argumentCaptor<Long>() - verify(tokenService, times(1)).deleteToken(captor.capture()) + @Test + fun testShouldDeleteToken() { + mockMvc + .delete("/configs/tokens/42") { + with(user("admin").roles("ADMIN")) + accept(MediaType.TEXT_HTML) + } + .andExpect { + status { is2xxSuccessful() } + view { name("configs/tokens") } + } - assertThat(captor.firstValue).isEqualTo(42) - } + val captor = argumentCaptor<Long>() + verify(tokenService, times(1)).deleteToken(captor.capture()) - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldRenderConfigPageWithTokens() { - val page = webClient.getPage<HtmlPage>("http://localhost/configs") - assertThat( - page.getElementById("tokens") - ).isNotNull - } + assertThat(captor.firstValue).isEqualTo(42) } - @Nested - @TestPropertySource( - properties = [ - "app.security.enable-tokens=false" - ] - ) - inner class WithTokensDisabled { - @BeforeEach - fun setup() { - webClient.options.isThrowExceptionOnScriptError = false - } - - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldRenderConfigPageWithoutTokens() { - val page = webClient.getPage<HtmlPage>("http://localhost/configs") - assertThat( - page.getElementById("tokens") - ).isNull() - } + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldRenderConfigPageWithTokens() { + val page = webClient.getPage<HtmlPage>("http://localhost/configs") + assertThat(page.getElementById("tokens")).isNotNull } + } - @Nested - @TestPropertySource( - properties = [ - "app.security.enable-tokens=false", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret" - ] - ) - @MockitoBean( - types = [ - UserRoleService::class - ] - ) - inner class WithUserRolesEnabled { - private lateinit var userRoleService: UserRoleService + @Nested + @TestPropertySource(properties = ["app.security.enable-tokens=false"]) + inner class WithTokensDisabled { + @BeforeEach + fun setup() { + webClient.options.isThrowExceptionOnScriptError = false + } - @BeforeEach - fun setup( - @Autowired userRoleService: UserRoleService - ) { - webClient.options.isThrowExceptionOnScriptError = false + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldRenderConfigPageWithoutTokens() { + val page = webClient.getPage<HtmlPage>("http://localhost/configs") + assertThat(page.getElementById("tokens")).isNull() + } + } + + @Nested + @TestPropertySource( + properties = + [ + "app.security.enable-tokens=false", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + ] + ) + @MockitoBean(types = [UserRoleService::class]) + inner class WithUserRolesEnabled { + private lateinit var userRoleService: UserRoleService - this.userRoleService = userRoleService - } + @BeforeEach + fun setup(@Autowired userRoleService: UserRoleService) { + webClient.options.isThrowExceptionOnScriptError = false - @Test - fun testShouldDeleteUserRole() { - mockMvc.delete("/configs/userroles/42") { - with(user("admin").roles("ADMIN")) - accept(MediaType.TEXT_HTML) - }.andExpect { - status { is2xxSuccessful() } - view { name("configs/userroles") } - } + this.userRoleService = userRoleService + } - val captor = argumentCaptor<Long>() - verify(userRoleService, times(1)).deleteUserRole(captor.capture()) + @Test + fun testShouldDeleteUserRole() { + mockMvc + .delete("/configs/userroles/42") { + with(user("admin").roles("ADMIN")) + accept(MediaType.TEXT_HTML) + } + .andExpect { + status { is2xxSuccessful() } + view { name("configs/userroles") } + } - assertThat(captor.firstValue).isEqualTo(42) - } + val captor = argumentCaptor<Long>() + verify(userRoleService, times(1)).deleteUserRole(captor.capture()) - @Test - fun testShouldUpdateUserRole() { - mockMvc.put("/configs/userroles/42") { - with(user("admin").roles("ADMIN")) - accept(MediaType.TEXT_HTML) - contentType = MediaType.APPLICATION_FORM_URLENCODED - content = "role=ADMIN" - }.andExpect { - status { is2xxSuccessful() } - view { name("configs/userroles") } - } - - val idCaptor = argumentCaptor<Long>() - val roleCaptor = argumentCaptor<Role>() - verify(userRoleService, times(1)).updateUserRole( - idCaptor.capture(), - roleCaptor.capture() - ) - - assertThat(idCaptor.firstValue).isEqualTo(42) - assertThat(roleCaptor.firstValue).isEqualTo(Role.ADMIN) - } + assertThat(captor.firstValue).isEqualTo(42) + } - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldRenderConfigPageWithUserRoles() { - val page = webClient.getPage<HtmlPage>("http://localhost/configs") - assertThat( - page.getElementById("userroles") - ).isNotNull - } + @Test + fun testShouldUpdateUserRole() { + mockMvc + .put("/configs/userroles/42") { + with(user("admin").roles("ADMIN")) + accept(MediaType.TEXT_HTML) + contentType = MediaType.APPLICATION_FORM_URLENCODED + content = "role=ADMIN" + } + .andExpect { + status { is2xxSuccessful() } + view { name("configs/userroles") } + } + + val idCaptor = argumentCaptor<Long>() + val roleCaptor = argumentCaptor<Role>() + verify(userRoleService, times(1)).updateUserRole(idCaptor.capture(), roleCaptor.capture()) + + assertThat(idCaptor.firstValue).isEqualTo(42) + assertThat(roleCaptor.firstValue).isEqualTo(Role.ADMIN) } - @Nested - inner class WithUserRolesDisabled { - @BeforeEach - fun setup() { - webClient.options.isThrowExceptionOnScriptError = false - } + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldRenderConfigPageWithUserRoles() { + val page = webClient.getPage<HtmlPage>("http://localhost/configs") + assertThat(page.getElementById("userroles")).isNotNull + } + } - @Test - fun testShouldRenderConfigPageWithoutUserRoles() { - val page = webClient.getPage<HtmlPage>("http://localhost/configs") - assertThat( - page.getElementById("userroles") - ).isNull() - } + @Nested + inner class WithUserRolesDisabled { + @BeforeEach + fun setup() { + webClient.options.isThrowExceptionOnScriptError = false } - @Nested - inner class SseTest { - private lateinit var webClient: WebTestClient + @Test + fun testShouldRenderConfigPageWithoutUserRoles() { + val page = webClient.getPage<HtmlPage>("http://localhost/configs") + assertThat(page.getElementById("userroles")).isNull() + } + } - @BeforeEach - fun setup( - applicationContext: WebApplicationContext - ) { - this.webClient = MockMvcWebTestClient - .bindToApplicationContext(applicationContext).build() - } + @Nested + inner class SseTest { + private lateinit var webClient: WebTestClient - @Test - fun testShouldRequestGPasSSE() { - val expectedEvent = - ConnectionCheckResult.GPasConnectionCheckResult(true, Instant.now(), Instant.now()) - - connectionCheckUpdateProducer.tryEmitNext(expectedEvent) - connectionCheckUpdateProducer.emitComplete { _, _ -> true } - - val result = - webClient.get().uri("http://localhost/configs/events").accept(TEXT_EVENT_STREAM) - .exchange() - .expectStatus().isOk() - .expectHeader().contentType(TEXT_EVENT_STREAM) - .returnResult(ConnectionCheckResult.GPasConnectionCheckResult::class.java) - - StepVerifier.create(result.responseBody) - .expectNext(expectedEvent) - .expectComplete() - .verify() - } + @BeforeEach + fun setup(applicationContext: WebApplicationContext) { + this.webClient = MockMvcWebTestClient.bindToApplicationContext(applicationContext).build() } + @Test + fun testShouldRequestGPasSSE() { + val expectedEvent = + ConnectionCheckResult.GPasConnectionCheckResult(true, Instant.now(), Instant.now()) + + connectionCheckUpdateProducer.tryEmitNext(expectedEvent) + connectionCheckUpdateProducer.emitComplete { _, _ -> true } + + val result = + webClient + .get() + .uri("http://localhost/configs/events") + .accept(TEXT_EVENT_STREAM) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentType(TEXT_EVENT_STREAM) + .returnResult(ConnectionCheckResult.GPasConnectionCheckResult::class.java) + + StepVerifier.create(result.responseBody).expectNext(expectedEvent).expectComplete().verify() + } + } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/HomeControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/HomeControllerTest.kt index 628112c..33fc9d2 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/HomeControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/HomeControllerTest.kt @@ -27,6 +27,9 @@ import dev.dnpm.etl.processor.monitoring.Request import dev.dnpm.etl.processor.monitoring.RequestStatus import dev.dnpm.etl.processor.monitoring.RequestType import dev.dnpm.etl.processor.services.RequestService +import java.io.IOException +import java.time.Instant +import java.util.* import org.assertj.core.api.Assertions.assertThat import org.htmlunit.WebClient import org.htmlunit.html.HtmlPage @@ -51,261 +54,248 @@ import org.springframework.test.context.junit.jupiter.SpringExtension import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.get import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder -import java.io.IOException -import java.time.Instant -import java.util.* @WebMvcTest(controllers = [HomeController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - HomeController::class, - AppConfiguration::class, - AppSecurityConfiguration::class - ] + classes = [HomeController::class, AppConfiguration::class, AppSecurityConfiguration::class] ) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret" - ] -) -@MockitoBean( - types = [RequestService::class] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + ] ) +@MockitoBean(types = [RequestService::class]) class HomeControllerTest { - private lateinit var mockMvc: MockMvc - private lateinit var webClient: WebClient + private lateinit var mockMvc: MockMvc + private lateinit var webClient: WebClient - @BeforeEach - fun setup( - @Autowired mockMvc: MockMvc, - @Autowired requestService: RequestService - ) { - this.mockMvc = mockMvc - this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() + @BeforeEach + fun setup(@Autowired mockMvc: MockMvc, @Autowired requestService: RequestService) { + this.mockMvc = mockMvc + this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() - whenever(requestService.findAll(any<Pageable>())).thenReturn(Page.empty()) - } + whenever(requestService.findAll(any<Pageable>())).thenReturn(Page.empty()) + } - @Test - fun testShouldRequestHomePage() { - mockMvc.get("/").andExpect { - status { isOk() } - view { name("index") } - } + @Test + fun testShouldRequestHomePage() { + mockMvc.get("/").andExpect { + status { isOk() } + view { name("index") } } + } - @Nested - inner class WithRequests { - - private lateinit var requestService: RequestService - - @BeforeEach - fun setup( - @Autowired requestService: RequestService - ) { - this.requestService = requestService - } - - @Test - fun testShouldShowHomePage() { - whenever(requestService.findAll(any<Pageable>())).thenReturn( - PageImpl( - listOf( - Request( - 2L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("ashdkasdh"), - RequestType.MTB_FILE, - RequestStatus.SUCCESS - ), - Request( - 1L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("asdasdasd"), - RequestType.MTB_FILE, - RequestStatus.ERROR - ) - ) - ) - ) - - val page = webClient.getPage<HtmlPage>("http://localhost/") - assertThat(page.querySelectorAll("tbody tr")).hasSize(2) - assertThat(page.querySelectorAll("div.notification.info")).isEmpty() - } - - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldShowRequestDetails() { - val requestId = randomRequestId() - - whenever(requestService.findByUuid(anyValueClass())).thenReturn( - Optional.of( - Request( - 2L, - requestId, - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("ashdkasdh"), - RequestType.MTB_FILE, - RequestStatus.SUCCESS, - Instant.now(), - Report("Test") - ) - ) - ) - - val page = webClient.getPage<HtmlPage>("http://localhost/report/${requestId.value}") - assertThat(page.querySelectorAll("tbody tr")).hasSize(1) - assertThat(page.querySelectorAll("div.notification.info")).isEmpty() - } - - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldShowPatientDetails() { - whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn( - PageImpl( - listOf( - Request( - 2L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("ashdkasdh"), - RequestType.MTB_FILE, - RequestStatus.SUCCESS - ), - Request( - 1L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("asdasdasd"), - RequestType.MTB_FILE, - RequestStatus.ERROR - ) - ) - ) - ) - - val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") - assertThat(page.querySelectorAll("tbody tr")).hasSize(2) - assertThat(page.querySelectorAll("div.notification.info")).isEmpty() - } + @Nested + inner class WithRequests { - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldShowPatientPseudonym() { - whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn( - PageImpl( - listOf( - Request( - 2L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("ashdkasdh"), - RequestType.MTB_FILE, - RequestStatus.SUCCESS - ), - Request( - 1L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("asdasdasd"), - RequestType.MTB_FILE, - RequestStatus.ERROR - ) - ) - ) - ) + private lateinit var requestService: RequestService - val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") - assertThat(page.querySelectorAll("h2 > span")).hasSize(1) - assertThat(page.querySelectorAll("h2 > span").first().textContent).isEqualTo("PSEUDO1") - } + @BeforeEach + fun setup(@Autowired requestService: RequestService) { + this.requestService = requestService + } + @Test + fun testShouldShowHomePage() { + whenever(requestService.findAll(any<Pageable>())) + .thenReturn( + PageImpl( + listOf( + Request( + 2L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("ashdkasdh"), + RequestType.MTB_FILE, + RequestStatus.SUCCESS, + ), + Request( + 1L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("asdasdasd"), + RequestType.MTB_FILE, + RequestStatus.ERROR, + ), + ) + ) + ) + + val page = webClient.getPage<HtmlPage>("http://localhost/") + assertThat(page.querySelectorAll("tbody tr")).hasSize(2) + assertThat(page.querySelectorAll("div.notification.info")).isEmpty() } - @Nested - inner class WithoutRequests { + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldShowRequestDetails() { + val requestId = randomRequestId() + + whenever(requestService.findByUuid(anyValueClass())) + .thenReturn( + Optional.of( + Request( + 2L, + requestId, + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("ashdkasdh"), + RequestType.MTB_FILE, + RequestStatus.SUCCESS, + Instant.now(), + Report("Test"), + ) + ) + ) + + val page = webClient.getPage<HtmlPage>("http://localhost/report/${requestId.value}") + assertThat(page.querySelectorAll("tbody tr")).hasSize(1) + assertThat(page.querySelectorAll("div.notification.info")).isEmpty() + } - private lateinit var requestService: RequestService + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldShowPatientDetails() { + whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())) + .thenReturn( + PageImpl( + listOf( + Request( + 2L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("ashdkasdh"), + RequestType.MTB_FILE, + RequestStatus.SUCCESS, + ), + Request( + 1L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("asdasdasd"), + RequestType.MTB_FILE, + RequestStatus.ERROR, + ), + ) + ) + ) + + val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") + assertThat(page.querySelectorAll("tbody tr")).hasSize(2) + assertThat(page.querySelectorAll("div.notification.info")).isEmpty() + } - @BeforeEach - fun setup( - @Autowired requestService: RequestService - ) { - this.requestService = requestService + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldShowPatientPseudonym() { + whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())) + .thenReturn( + PageImpl( + listOf( + Request( + 2L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("ashdkasdh"), + RequestType.MTB_FILE, + RequestStatus.SUCCESS, + ), + Request( + 1L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("asdasdasd"), + RequestType.MTB_FILE, + RequestStatus.ERROR, + ), + ) + ) + ) + + val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") + assertThat(page.querySelectorAll("h2 > span")).hasSize(1) + assertThat(page.querySelectorAll("h2 > span").first().textContent).isEqualTo("PSEUDO1") + } + } - whenever(requestService.findAll(any<Pageable>())).thenReturn(Page.empty()) - } + @Nested + inner class WithoutRequests { - @Test - fun testShouldShowHomePage() { - val page = webClient.getPage<HtmlPage>("http://localhost/") - assertThat(page.querySelectorAll("tbody tr")).isEmpty() - assertThat(page.querySelectorAll("div.notification.info")).hasSize(1) - } + private lateinit var requestService: RequestService - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldThrowNotFoundExceptionForUnknownReport() { - val requestId = randomRequestId() + @BeforeEach + fun setup(@Autowired requestService: RequestService) { + this.requestService = requestService - whenever(requestService.findByUuid(anyValueClass())).thenReturn( - Optional.empty() - ) + whenever(requestService.findAll(any<Pageable>())).thenReturn(Page.empty()) + } - assertThrows<IOException> { - webClient.getPage<HtmlPage>("http://localhost/report/${requestId.value}") - }.also { - assertThat(it).hasRootCauseInstanceOf(NotFoundException::class.java) - } - } + @Test + fun testShouldShowHomePage() { + val page = webClient.getPage<HtmlPage>("http://localhost/") + assertThat(page.querySelectorAll("tbody tr")).isEmpty() + assertThat(page.querySelectorAll("div.notification.info")).hasSize(1) + } - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldShowEmptyPatientDetails() { - whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn(Page.empty()) + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldThrowNotFoundExceptionForUnknownReport() { + val requestId = randomRequestId() - val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") - assertThat(page.querySelectorAll("tbody tr")).isEmpty() - assertThat(page.querySelectorAll("div.notification.info")).hasSize(1) - } + whenever(requestService.findByUuid(anyValueClass())).thenReturn(Optional.empty()) - @Test - @WithMockUser(username = "admin", roles = ["ADMIN"]) - fun testShouldShowNoConsentStatusBadge() { - whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn( - PageImpl( - listOf( - Request( - 1L, - randomRequestId(), - PatientPseudonym("PSEUDO1"), - PatientId("PATIENT1"), - Fingerprint("ashdkasdh"), - RequestType.MTB_FILE, - RequestStatus.NO_CONSENT - ) - ) - ) - ) + assertThrows<IOException> { + webClient.getPage<HtmlPage>("http://localhost/report/${requestId.value}") + } + .also { assertThat(it).hasRootCauseInstanceOf(NotFoundException::class.java) } + } - val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") - assertThat(page.querySelectorAll("tbody tr")).hasSize(1) - assertThat(page.querySelectorAll("tbody tr > td > small").first().textContent).isEqualTo("NO_CONSENT") - } + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldShowEmptyPatientDetails() { + whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())) + .thenReturn(Page.empty()) + + val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") + assertThat(page.querySelectorAll("tbody tr")).isEmpty() + assertThat(page.querySelectorAll("div.notification.info")).hasSize(1) } + @Test + @WithMockUser(username = "admin", roles = ["ADMIN"]) + fun testShouldShowNoConsentStatusBadge() { + whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())) + .thenReturn( + PageImpl( + listOf( + Request( + 1L, + randomRequestId(), + PatientPseudonym("PSEUDO1"), + PatientId("PATIENT1"), + Fingerprint("ashdkasdh"), + RequestType.MTB_FILE, + RequestStatus.NO_CONSENT, + ) + ) + ) + ) + + val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1") + assertThat(page.querySelectorAll("tbody tr")).hasSize(1) + assertThat(page.querySelectorAll("tbody tr > td > small").first().textContent) + .isEqualTo("NO_CONSENT") + } + } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/LoginControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/LoginControllerTest.kt index 54ad6e8..bd8014a 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/LoginControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/LoginControllerTest.kt @@ -42,30 +42,26 @@ import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder @WebMvcTest(controllers = [LoginController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - LoginController::class, - AppConfiguration::class, - AppSecurityConfiguration::class - ] + classes = [LoginController::class, AppConfiguration::class, AppSecurityConfiguration::class], ) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret", - "app.security.enable-tokens=true" - ] -) -@MockitoBean( - types = [TokenService::class] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + "app.security.enable-tokens=true", + ], ) +@MockitoBean(types = [TokenService::class]) class LoginControllerTest { - private lateinit var mockMvc: MockMvc private lateinit var webClient: WebClient @BeforeEach - fun setup(@Autowired mockMvc: MockMvc) { + fun setup( + @Autowired mockMvc: MockMvc, + ) { this.mockMvc = mockMvc this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() } @@ -82,7 +78,11 @@ class LoginControllerTest { fun testShouldShowLoginForm() { val page = webClient.getPage<HtmlPage>("http://localhost/login") assertThat( - page.getElementsByTagName("main").first().firstElementChild.getAttribute("class") + page + .getElementsByTagName("main") + .first() + .firstElementChild + .getAttribute("class"), ).isEqualTo("login-form") } } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt index b55a702..f91e3cf 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsControllerTest.kt @@ -38,26 +38,25 @@ import org.springframework.test.web.servlet.htmlunit.MockMvcWebClientBuilder @WebMvcTest(controllers = [StatisticsController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - StatisticsController::class, - AppConfiguration::class, - AppSecurityConfiguration::class - ] + classes = + [StatisticsController::class, AppConfiguration::class, AppSecurityConfiguration::class], ) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret" - ] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + ], ) class StatisticsControllerTest { - private lateinit var mockMvc: MockMvc private lateinit var webClient: WebClient @BeforeEach - fun setup(@Autowired mockMvc: MockMvc) { + fun setup( + @Autowired mockMvc: MockMvc, + ) { this.mockMvc = mockMvc this.webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build() } @@ -69,5 +68,4 @@ class StatisticsControllerTest { view { name("statistics") } } } - } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsRestControllerTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsRestControllerTest.kt index f0c3b63..16a9464 100644 --- a/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsRestControllerTest.kt +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/web/StatisticsRestControllerTest.kt @@ -57,28 +57,22 @@ import java.time.Instant import java.time.ZoneId import java.time.temporal.ChronoUnit - @WebMvcTest(controllers = [StatisticsRestController::class]) @ExtendWith(value = [MockitoExtension::class, SpringExtension::class]) @ContextConfiguration( - classes = [ - StatisticsRestController::class, - AppConfiguration::class, - AppSecurityConfiguration::class - ] + classes = + [StatisticsRestController::class, AppConfiguration::class, AppSecurityConfiguration::class], ) @TestPropertySource( - properties = [ - "app.pseudonymize.generator=BUILDIN", - "app.security.admin-user=admin", - "app.security.admin-password={noop}very-secret" - ] -) -@MockitoBean( - types = [RequestService::class] + properties = + [ + "app.pseudonymize.generator=BUILDIN", + "app.security.admin-user=admin", + "app.security.admin-password={noop}very-secret", + ], ) +@MockitoBean(types = [RequestService::class]) class StatisticsRestControllerTest { - private lateinit var mockMvc: MockMvc private lateinit var statisticsUpdateProducer: Sinks.Many<Any> @@ -88,7 +82,7 @@ class StatisticsRestControllerTest { fun setup( @Autowired mockMvc: MockMvc, @Autowired statisticsUpdateProducer: Sinks.Many<Any>, - @Autowired requestService: RequestService + @Autowired requestService: RequestService, ) { this.mockMvc = mockMvc this.statisticsUpdateProducer = statisticsUpdateProducer @@ -100,40 +94,38 @@ class StatisticsRestControllerTest { @Test fun testShouldRequestStatesForMtbFiles() { doAnswer { _ -> - listOf( - CountedState(42, RequestStatus.WARNING), - CountedState(1, RequestStatus.UNKNOWN) - ) - }.whenever(requestService).countStates() + listOf(CountedState(42, RequestStatus.WARNING), CountedState(1, RequestStatus.UNKNOWN)) + }.whenever(requestService) + .countStates() mockMvc.get("/statistics/requeststates").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(2)) - jsonPath("$[0].name", equalTo(RequestStatus.WARNING.name)) - jsonPath("$[0].value", equalTo(42)) - jsonPath("$[1].name", equalTo(RequestStatus.UNKNOWN.name)) - jsonPath("$[1].value", equalTo(1)) - } + status { isOk() } + .also { + jsonPath("$", hasSize<Int>(2)) + jsonPath("$[0].name", equalTo(RequestStatus.WARNING.name)) + jsonPath("$[0].value", equalTo(42)) + jsonPath("$[1].name", equalTo(RequestStatus.UNKNOWN.name)) + jsonPath("$[1].value", equalTo(1)) + } } } @Test fun testShouldRequestStatesForDeletes() { doAnswer { _ -> - listOf( - CountedState(42, RequestStatus.SUCCESS), - CountedState(1, RequestStatus.ERROR) - ) - }.whenever(requestService).countDeleteStates() + listOf(CountedState(42, RequestStatus.SUCCESS), CountedState(1, RequestStatus.ERROR)) + }.whenever(requestService) + .countDeleteStates() mockMvc.get("/statistics/requeststates?delete=true").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(2)) - jsonPath("$[0].name", equalTo(RequestStatus.SUCCESS.name)) - jsonPath("$[0].value", equalTo(42)) - jsonPath("$[1].name", equalTo(RequestStatus.ERROR.name)) - jsonPath("$[1].value", equalTo(1)) - } + status { isOk() } + .also { + jsonPath("$", hasSize<Int>(2)) + jsonPath("$[0].name", equalTo(RequestStatus.SUCCESS.name)) + jsonPath("$[0].value", equalTo(42)) + jsonPath("$[1].name", equalTo(RequestStatus.ERROR.name)) + jsonPath("$[1].value", equalTo(1)) + } } } } @@ -143,47 +135,44 @@ class StatisticsRestControllerTest { @Test fun testShouldRequestPatientStatesForMtbFiles() { doAnswer { _ -> - listOf( - CountedState(42, RequestStatus.WARNING), - CountedState(1, RequestStatus.UNKNOWN) - ) - }.whenever(requestService).findPatientUniqueStates() + listOf(CountedState(42, RequestStatus.WARNING), CountedState(1, RequestStatus.UNKNOWN)) + }.whenever(requestService) + .findPatientUniqueStates() mockMvc.get("/statistics/requestpatientstates").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(2)) - jsonPath("$[0].name", equalTo(RequestStatus.WARNING.name)) - jsonPath("$[0].value", equalTo(42)) - jsonPath("$[1].name", equalTo(RequestStatus.UNKNOWN.name)) - jsonPath("$[1].value", equalTo(1)) - } + status { isOk() } + .also { + jsonPath("$", hasSize<Int>(2)) + jsonPath("$[0].name", equalTo(RequestStatus.WARNING.name)) + jsonPath("$[0].value", equalTo(42)) + jsonPath("$[1].name", equalTo(RequestStatus.UNKNOWN.name)) + jsonPath("$[1].value", equalTo(1)) + } } } @Test fun testShouldRequestPatientStatesForDeletes() { doAnswer { _ -> - listOf( - CountedState(42, RequestStatus.SUCCESS), - CountedState(1, RequestStatus.ERROR) - ) - }.whenever(requestService).findPatientUniqueDeleteStates() + listOf(CountedState(42, RequestStatus.SUCCESS), CountedState(1, RequestStatus.ERROR)) + }.whenever(requestService) + .findPatientUniqueDeleteStates() mockMvc.get("/statistics/requestpatientstates?delete=true").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(2)) - jsonPath("$[0].name", equalTo(RequestStatus.SUCCESS.name)) - jsonPath("$[0].value", equalTo(42)) - jsonPath("$[1].name", equalTo(RequestStatus.ERROR.name)) - jsonPath("$[1].value", equalTo(1)) - } + status { isOk() } + .also { + jsonPath("$", hasSize<Int>(2)) + jsonPath("$[0].name", equalTo(RequestStatus.SUCCESS.name)) + jsonPath("$[0].value", equalTo(42)) + jsonPath("$[1].name", equalTo(RequestStatus.ERROR.name)) + jsonPath("$[1].value", equalTo(1)) + } } } } @Nested inner class LastMonthStatesTest { - @BeforeEach fun setup() { val zoneId = ZoneId.of("Europe/Berlin") @@ -197,7 +186,12 @@ class StatisticsRestControllerTest { Fingerprint("0123456789abcdef1"), RequestType.MTB_FILE, RequestStatus.SUCCESS, - Instant.now().atZone(zoneId).truncatedTo(ChronoUnit.DAYS).minus(2, ChronoUnit.DAYS).toInstant() + Instant + .now() + .atZone(zoneId) + .truncatedTo(ChronoUnit.DAYS) + .minus(2, ChronoUnit.DAYS) + .toInstant(), ), Request( 2, @@ -207,7 +201,12 @@ class StatisticsRestControllerTest { Fingerprint("0123456789abcdef2"), RequestType.MTB_FILE, RequestStatus.WARNING, - Instant.now().atZone(zoneId).truncatedTo(ChronoUnit.DAYS).minus(2, ChronoUnit.DAYS).toInstant() + Instant + .now() + .atZone(zoneId) + .truncatedTo(ChronoUnit.DAYS) + .minus(2, ChronoUnit.DAYS) + .toInstant(), ), Request( 3, @@ -217,7 +216,12 @@ class StatisticsRestControllerTest { Fingerprint("0123456789abcdee1"), RequestType.DELETE, RequestStatus.ERROR, - Instant.now().atZone(zoneId).truncatedTo(ChronoUnit.DAYS).minus(1, ChronoUnit.DAYS).toInstant() + Instant + .now() + .atZone(zoneId) + .truncatedTo(ChronoUnit.DAYS) + .minus(1, ChronoUnit.DAYS) + .toInstant(), ), Request( 4, @@ -227,7 +231,12 @@ class StatisticsRestControllerTest { Fingerprint("0123456789abcdef2"), RequestType.MTB_FILE, RequestStatus.DUPLICATION, - Instant.now().atZone(zoneId).truncatedTo(ChronoUnit.DAYS).minus(1, ChronoUnit.DAYS).toInstant() + Instant + .now() + .atZone(zoneId) + .truncatedTo(ChronoUnit.DAYS) + .minus(1, ChronoUnit.DAYS) + .toInstant(), ), Request( 5, @@ -237,49 +246,54 @@ class StatisticsRestControllerTest { Fingerprint("0123456789abcdef2"), RequestType.DELETE, RequestStatus.UNKNOWN, - Instant.now().atZone(zoneId).truncatedTo(ChronoUnit.DAYS).toInstant() + Instant + .now() + .atZone(zoneId) + .truncatedTo(ChronoUnit.DAYS) + .toInstant(), ), ) - }.whenever(requestService).findAll() + }.whenever(requestService) + .findAll() } @Test fun testShouldRequestLastMonthForMtbFiles() { mockMvc.get("/statistics/requestslastmonth").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(31)) - }.also { - jsonPath("$[28].nameValues.error", equalTo(0)) - jsonPath("$[28].nameValues.warning", equalTo(1)) - jsonPath("$[28].nameValues.success", equalTo(1)) - jsonPath("$[28].nameValues.duplication", equalTo(0)) - jsonPath("$[28].nameValues.unknown", equalTo(0)) - jsonPath("$[29].nameValues.error", equalTo(0)) - jsonPath("$[29].nameValues.warning", equalTo(0)) - jsonPath("$[29].nameValues.success", equalTo(0)) - jsonPath("$[29].nameValues.duplication", equalTo(1)) - jsonPath("$[29].nameValues.unknown", equalTo(0)) - } + status { isOk() } + .also { jsonPath("$", hasSize<Int>(31)) } + .also { + jsonPath("$[28].nameValues.error", equalTo(0)) + jsonPath("$[28].nameValues.warning", equalTo(1)) + jsonPath("$[28].nameValues.success", equalTo(1)) + jsonPath("$[28].nameValues.duplication", equalTo(0)) + jsonPath("$[28].nameValues.unknown", equalTo(0)) + jsonPath("$[29].nameValues.error", equalTo(0)) + jsonPath("$[29].nameValues.warning", equalTo(0)) + jsonPath("$[29].nameValues.success", equalTo(0)) + jsonPath("$[29].nameValues.duplication", equalTo(1)) + jsonPath("$[29].nameValues.unknown", equalTo(0)) + } } } @Test fun testShouldRequestLastMonthForDeletes() { mockMvc.get("/statistics/requestslastmonth?delete=true").andExpect { - status { isOk() }.also { - jsonPath("$", hasSize<Int>(31)) - }.also { - jsonPath("$[29].nameValues.error", equalTo(1)) - jsonPath("$[29].nameValues.warning", equalTo(0)) - jsonPath("$[29].nameValues.success", equalTo(0)) - jsonPath("$[29].nameValues.duplication", equalTo(0)) - jsonPath("$[29].nameValues.unknown", equalTo(0)) - jsonPath("$[30].nameValues.error", equalTo(0)) - jsonPath("$[30].nameValues.warning", equalTo(0)) - jsonPath("$[30].nameValues.success", equalTo(0)) - jsonPath("$[30].nameValues.duplication", equalTo(0)) - jsonPath("$[30].nameValues.unknown", equalTo(1)) - } + status { isOk() } + .also { jsonPath("$", hasSize<Int>(31)) } + .also { + jsonPath("$[29].nameValues.error", equalTo(1)) + jsonPath("$[29].nameValues.warning", equalTo(0)) + jsonPath("$[29].nameValues.success", equalTo(0)) + jsonPath("$[29].nameValues.duplication", equalTo(0)) + jsonPath("$[29].nameValues.unknown", equalTo(0)) + jsonPath("$[30].nameValues.error", equalTo(0)) + jsonPath("$[30].nameValues.warning", equalTo(0)) + jsonPath("$[30].nameValues.success", equalTo(0)) + jsonPath("$[30].nameValues.duplication", equalTo(0)) + jsonPath("$[30].nameValues.unknown", equalTo(1)) + } } } } @@ -289,26 +303,27 @@ class StatisticsRestControllerTest { private lateinit var webClient: WebTestClient @BeforeEach - fun setup( - applicationContext: WebApplicationContext, - ) { - this.webClient = MockMvcWebTestClient - .bindToApplicationContext(applicationContext).build() + fun setup(applicationContext: WebApplicationContext) { + this.webClient = MockMvcWebTestClient.bindToApplicationContext(applicationContext).build() } @Test fun testShouldRequestSSE() { statisticsUpdateProducer.emitComplete { _, _ -> true } - val result = webClient.get().uri("http://localhost/statistics/events").accept(TEXT_EVENT_STREAM).exchange() - .expectStatus().isOk() - .expectHeader().contentType(TEXT_EVENT_STREAM) - .returnResult(String::class.java) + val result = + webClient + .get() + .uri("http://localhost/statistics/events") + .accept(TEXT_EVENT_STREAM) + .exchange() + .expectStatus() + .isOk() + .expectHeader() + .contentType(TEXT_EVENT_STREAM) + .returnResult(String::class.java) - StepVerifier.create(result.responseBody) - .expectComplete() - .verify() + StepVerifier.create(result.responseBody).expectComplete().verify() } } - } |
