summaryrefslogtreecommitdiff
path: root/src/test/kotlin/dev
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2025-11-11 09:36:17 +0100
committerGitHub2025-11-11 09:36:17 +0100
commit8c3143081f5f535671bc7b0c7d98302549b9a1da (patch)
tree1402d033ef7b13ab6befddf2b8d1f385f79d410b /src/test/kotlin/dev
parent76a16e22bb9fba21d02b0584ec83e046196da045 (diff)
chore: use spotless for kotlin code (#191)
Diffstat (limited to 'src/test/kotlin/dev')
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/consent/ConsentProcessorTest.kt58
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/consent/Dnpm21BasedConsentEvaluatorTest.kt461
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/helpers.kt7
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt337
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt325
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckServiceTest.kt139
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/monitoring/ReportServiceTest.kt46
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSenderTest.kt343
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSenderTest.kt430
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/pseudonym/ExtensionsTest.kt367
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeServiceTest.kt105
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/security/TokenServiceTest.kt174
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/security/UserRoleServiceTest.kt211
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/ConsentProcessorTest.kt378
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/ReportServiceTest.kt109
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/RequestProcessorTest.kt676
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/RequestServiceTest.kt184
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/ResponseProcessorTest.kt141
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/TransformationServiceTest.kt209
-rw-r--r--src/test/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessorTest.kt69
20 files changed, 2390 insertions, 2379 deletions
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/consent/ConsentProcessorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/consent/ConsentProcessorTest.kt
index 5a86a29..1140425 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/consent/ConsentProcessorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/consent/ConsentProcessorTest.kt
@@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.config.AppConfigProperties
import dev.dnpm.etl.processor.config.GIcsConfigProperties
import dev.dnpm.etl.processor.services.ConsentProcessor
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.Consent
@@ -14,45 +15,46 @@ import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
-import java.util.*
@ExtendWith(MockitoExtension::class)
class ConsentProcessorTest {
- lateinit var consentProcessor: ConsentProcessor
+ lateinit var consentProcessor: ConsentProcessor
- val objectMapper = ObjectMapper()
- val fhirContext = FhirContext.forR4()
+ val objectMapper = ObjectMapper()
+ val fhirContext = FhirContext.forR4()
- @BeforeEach
- fun setup(
- @Mock consentService: IConsentService
- ) {
- val appConfigProperties = AppConfigProperties()
- val gIcsConfigProperties = GIcsConfigProperties("http://localhost")
+ @BeforeEach
+ fun setup(@Mock consentService: IConsentService) {
+ val appConfigProperties = AppConfigProperties()
+ val gIcsConfigProperties = GIcsConfigProperties("http://localhost")
- this.consentProcessor = ConsentProcessor(
+ this.consentProcessor =
+ ConsentProcessor(
appConfigProperties,
gIcsConfigProperties,
objectMapper,
fhirContext,
- consentService
+ consentService,
)
- }
-
- @ParameterizedTest
- @CsvSource(value = [
- "permittedConsentBundle.json,permit",
- "deniedConsentBundle.json,deny"
- ])
- fun checkGetProvisionTypeByPolicyCode(filename: String, expected: String) {
- val bundle = fhirContext.newJsonParser().parseResource(
- this.javaClass.classLoader.getResourceAsStream(filename)
+ }
+
+ @ParameterizedTest
+ @CsvSource(value = ["permittedConsentBundle.json,permit", "deniedConsentBundle.json,deny"])
+ fun checkGetProvisionTypeByPolicyCode(filename: String, expected: String) {
+ val bundle =
+ fhirContext
+ .newJsonParser()
+ .parseResource(this.javaClass.classLoader.getResourceAsStream(filename))
+ assertThat(bundle).isInstanceOf(Bundle::class.java)
+
+ val actual =
+ consentProcessor.getProvisionTypeByPolicyCode(
+ bundle as Bundle,
+ Date(),
+ ConsentDomain.BROAD_CONSENT,
)
- assertThat(bundle).isInstanceOf(Bundle::class.java)
-
- val actual = consentProcessor.getProvisionTypeByPolicyCode(bundle as Bundle, Date(), ConsentDomain.BROAD_CONSENT)
- assertThat(actual).isEqualTo(Consent.ConsentProvisionType.valueOf(expected.uppercase()))
- }
-} \ No newline at end of file
+ assertThat(actual).isEqualTo(Consent.ConsentProvisionType.valueOf(expected.uppercase()))
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/consent/Dnpm21BasedConsentEvaluatorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/consent/Dnpm21BasedConsentEvaluatorTest.kt
index adbec2f..85a8b3e 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/consent/Dnpm21BasedConsentEvaluatorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/consent/Dnpm21BasedConsentEvaluatorTest.kt
@@ -21,6 +21,8 @@ package dev.dnpm.etl.processor.consent
import dev.dnpm.etl.processor.ArgProvider
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
@@ -32,256 +34,269 @@ import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.whenever
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class Dnpm21BasedConsentEvaluatorTest {
- @Nested
- inner class WithGicsConsentEnabled {
+ @Nested
+ inner class WithGicsConsentEnabled {
- lateinit var consentService: GicsConsentService
- lateinit var consentEvaluator: ConsentEvaluator
+ lateinit var consentService: GicsConsentService
+ lateinit var consentEvaluator: ConsentEvaluator
- @BeforeEach
- fun setUp(
- @Mock consentService: GicsConsentService
- ) {
- this.consentService = consentService
- this.consentEvaluator = ConsentEvaluator(consentService)
- }
+ @BeforeEach
+ fun setUp(@Mock consentService: GicsConsentService) {
+ this.consentService = consentService
+ this.consentEvaluator = ConsentEvaluator(consentService)
+ }
- @ParameterizedTest
- @ArgumentsSource(WithGicsMtbFileProvider::class)
- fun test(
- mtbFile: Mtb,
- ttpConsentStatus: TtpConsentStatus,
- expectedConsentEvaluation: ConsentEvaluation
- ) {
- whenever(consentService.getTtpBroadConsentStatus(anyString())).thenReturn(
- ttpConsentStatus
- )
- assertThat(consentEvaluator.check(mtbFile)).isEqualTo(expectedConsentEvaluation)
- }
+ @ParameterizedTest
+ @ArgumentsSource(WithGicsMtbFileProvider::class)
+ fun test(
+ mtbFile: Mtb,
+ ttpConsentStatus: TtpConsentStatus,
+ expectedConsentEvaluation: ConsentEvaluation,
+ ) {
+ whenever(consentService.getTtpBroadConsentStatus(anyString())).thenReturn(ttpConsentStatus)
+ assertThat(consentEvaluator.check(mtbFile)).isEqualTo(expectedConsentEvaluation)
}
+ }
- @Nested
- inner class WithFileConsentOnly {
+ @Nested
+ inner class WithFileConsentOnly {
- lateinit var consentService: MtbFileConsentService
- lateinit var consentEvaluator: ConsentEvaluator
+ lateinit var consentService: MtbFileConsentService
+ lateinit var consentEvaluator: ConsentEvaluator
- @BeforeEach
- fun setUp() {
- this.consentService = MtbFileConsentService()
- this.consentEvaluator = ConsentEvaluator(consentService)
- }
+ @BeforeEach
+ fun setUp() {
+ this.consentService = MtbFileConsentService()
+ this.consentEvaluator = ConsentEvaluator(consentService)
+ }
- @ParameterizedTest
- @ArgumentsSource(MtbFileProvider::class)
- fun test(mtbFile: Mtb, expectedConsentEvaluation: ConsentEvaluation) {
- assertThat(consentEvaluator.check(mtbFile)).isEqualTo(expectedConsentEvaluation)
- }
+ @ParameterizedTest
+ @ArgumentsSource(MtbFileProvider::class)
+ fun test(mtbFile: Mtb, expectedConsentEvaluation: ConsentEvaluation) {
+ assertThat(consentEvaluator.check(mtbFile)).isEqualTo(expectedConsentEvaluation)
}
+ }
- // Util classes
+ // Util classes
- class WithGicsMtbFileProvider : ArgProvider(
- // Has file ModelProjectConsent and broad consent => consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true)
- ),
- // Has file ModelProjectConsent and broad consent missing => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.BROAD_CONSENT_MISSING,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING, false)
- ),
- // Has file ModelProjectConsent and broad consent missing or rejected => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED, false)
- ),
- // Has file ModelProjectConsent and MV consent => consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT, true)
- ),
- // Has file ModelProjectConsent and MV consent rejected => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED, false)
- ),
- // Has file ModelProjectConsent and MV consent missing => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.GENOM_DE_CONSENT_MISSING,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_MISSING, false)
- ),
- // Has file ModelProjectConsent and no broad consent result => consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.UNKNOWN_CHECK_FILE,
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, true)
- ),
- // Has file ModelProjectConsent and failed to ask => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- TtpConsentStatus.FAILED_TO_ASK,
- ConsentEvaluation(TtpConsentStatus.FAILED_TO_ASK, false)
- ),
- // File ModelProjectConsent rejected and broad consent => consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true)
- ),
- // File ModelProjectConsent rejected and broad consent missing => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.BROAD_CONSENT_MISSING,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING, false)
- ),
- // File ModelProjectConsent rejected and broad consent missing or rejected => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
- ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED, false)
- ),
- // File ModelProjectConsent rejected and MV consent => consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT, true)
- ),
- // File ModelProjectConsent rejected and MV consent rejected => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED, false)
- ),
- // File ModelProjectConsent rejected and MV consent missing => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.GENOM_DE_CONSENT_MISSING,
- ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_MISSING, false)
- ),
- // File ModelProjectConsent rejected and no broad consent result => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.UNKNOWN_CHECK_FILE,
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- ),
- // File ModelProjectConsent rejected and failed to ask => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- TtpConsentStatus.FAILED_TO_ASK,
- ConsentEvaluation(TtpConsentStatus.FAILED_TO_ASK, false)
- )
- ) {
+ class WithGicsMtbFileProvider :
+ ArgProvider(
+ // Has file ModelProjectConsent and broad consent => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.BROAD_CONSENT_GIVEN,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true),
+ ),
+ // Has file ModelProjectConsent and broad consent missing => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.BROAD_CONSENT_MISSING,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING, false),
+ ),
+ // Has file ModelProjectConsent and broad consent missing or rejected => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED, false),
+ ),
+ // Has file ModelProjectConsent and MV consent => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT, true),
+ ),
+ // Has file ModelProjectConsent and MV consent rejected => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED, false),
+ ),
+ // Has file ModelProjectConsent and MV consent missing => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.GENOM_DE_CONSENT_MISSING,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_MISSING, false),
+ ),
+ // Has file ModelProjectConsent and no broad consent result => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, true),
+ ),
+ // Has file ModelProjectConsent and failed to ask => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ TtpConsentStatus.FAILED_TO_ASK,
+ ConsentEvaluation(TtpConsentStatus.FAILED_TO_ASK, false),
+ ),
+ // File ModelProjectConsent rejected and broad consent => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.BROAD_CONSENT_GIVEN,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true),
+ ),
+ // File ModelProjectConsent rejected and broad consent missing => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.BROAD_CONSENT_MISSING,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING, false),
+ ),
+ // File ModelProjectConsent rejected and broad consent missing or rejected => no consent
+ // given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
+ ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED, false),
+ ),
+ // File ModelProjectConsent rejected and MV consent => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_SEQUENCING_PERMIT, true),
+ ),
+ // File ModelProjectConsent rejected and MV consent rejected => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_SEQUENCING_REJECTED, false),
+ ),
+ // File ModelProjectConsent rejected and MV consent missing => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.GENOM_DE_CONSENT_MISSING,
+ ConsentEvaluation(TtpConsentStatus.GENOM_DE_CONSENT_MISSING, false),
+ ),
+ // File ModelProjectConsent rejected and no broad consent result => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ // File ModelProjectConsent rejected and failed to ask => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ TtpConsentStatus.FAILED_TO_ASK,
+ ConsentEvaluation(TtpConsentStatus.FAILED_TO_ASK, false),
+ ),
+ ) {
- companion object {
- fun buildMtb(consentProvision: ConsentProvision): Mtb {
- return Mtb.builder()
- .patient(
- Patient.builder().id("TEST_12345678")
- .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z"))).gender(
- GenderCoding.builder().code(GenderCodingCode.MALE).build()
- ).build()
- )
- .metadata(
- MvhMetadata.builder().modelProjectConsent(
- ModelProjectConsent.builder().provisions(
+ companion object {
+ fun buildMtb(consentProvision: ConsentProvision): Mtb {
+ return Mtb.builder()
+ .patient(
+ Patient.builder()
+ .id("TEST_12345678")
+ .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z")))
+ .gender(GenderCoding.builder().code(GenderCodingCode.MALE).build())
+ .build()
+ )
+ .metadata(
+ MvhMetadata.builder()
+ .modelProjectConsent(
+ ModelProjectConsent.builder()
+ .provisions(
listOf(
- Provision.builder().date(Date()).type(consentProvision)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .date(Date())
+ .type(consentProvision)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
- ).build()
- )
- .episodesOfCare(
- listOf(
- MtbEpisodeOfCare.builder().id("1")
- .patient(Reference.builder().id("TEST_12345678").build())
- .build()
- )
+ )
+ .build()
)
.build()
- }
- }
+ )
+ .episodesOfCare(
+ listOf(
+ MtbEpisodeOfCare.builder()
+ .id("1")
+ .patient(Reference.builder().id("TEST_12345678").build())
+ .build()
+ )
+ )
+ .build()
+ }
}
+ }
- class MtbFileProvider : ArgProvider(
- // Has file consent => consent given
- Arguments.of(
- buildMtb(ConsentProvision.PERMIT),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, true)
- ),
- // File consent rejected => no consent given
- Arguments.of(
- buildMtb(ConsentProvision.DENY),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- ),
- // policy REIDENTIFICATION has no effect on ConsentEvaluation
- Arguments.of(
- buildMtb(ModelProjectConsentPurpose.REIDENTIFICATION, ConsentProvision.DENY),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- ), Arguments.of(
- buildMtb(ModelProjectConsentPurpose.REIDENTIFICATION, ConsentProvision.PERMIT),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- ),
- // policy CASE_IDENTIFICATION has no effect on ConsentEvaluation
- Arguments.of(
- buildMtb(ModelProjectConsentPurpose.CASE_IDENTIFICATION, ConsentProvision.DENY),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- ), Arguments.of(
- buildMtb(ModelProjectConsentPurpose.CASE_IDENTIFICATION, ConsentProvision.PERMIT),
- ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false)
- )
- ) {
+ class MtbFileProvider :
+ ArgProvider(
+ // Has file consent => consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.PERMIT),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, true),
+ ),
+ // File consent rejected => no consent given
+ Arguments.of(
+ buildMtb(ConsentProvision.DENY),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ // policy REIDENTIFICATION has no effect on ConsentEvaluation
+ Arguments.of(
+ buildMtb(ModelProjectConsentPurpose.REIDENTIFICATION, ConsentProvision.DENY),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ Arguments.of(
+ buildMtb(ModelProjectConsentPurpose.REIDENTIFICATION, ConsentProvision.PERMIT),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ // policy CASE_IDENTIFICATION has no effect on ConsentEvaluation
+ Arguments.of(
+ buildMtb(ModelProjectConsentPurpose.CASE_IDENTIFICATION, ConsentProvision.DENY),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ Arguments.of(
+ buildMtb(ModelProjectConsentPurpose.CASE_IDENTIFICATION, ConsentProvision.PERMIT),
+ ConsentEvaluation(TtpConsentStatus.UNKNOWN_CHECK_FILE, false),
+ ),
+ ) {
- companion object {
- fun buildMtb(consentProvision: ConsentProvision): Mtb {
- return buildMtb(ModelProjectConsentPurpose.SEQUENCING, consentProvision)
- }
+ companion object {
+ fun buildMtb(consentProvision: ConsentProvision): Mtb {
+ return buildMtb(ModelProjectConsentPurpose.SEQUENCING, consentProvision)
+ }
- fun buildMtb(
- policy: ModelProjectConsentPurpose,
- consentProvision: ConsentProvision
- ): Mtb {
- return Mtb.builder()
- .patient(
- Patient.builder().id("TEST_12345678")
- .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z"))).gender(
- GenderCoding.builder().code(GenderCodingCode.MALE).build()
- ).build()
- )
- .metadata(
- MvhMetadata.builder().modelProjectConsent(
- ModelProjectConsent.builder().provisions(
+ fun buildMtb(policy: ModelProjectConsentPurpose, consentProvision: ConsentProvision): Mtb {
+ return Mtb.builder()
+ .patient(
+ Patient.builder()
+ .id("TEST_12345678")
+ .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z")))
+ .gender(GenderCoding.builder().code(GenderCodingCode.MALE).build())
+ .build()
+ )
+ .metadata(
+ MvhMetadata.builder()
+ .modelProjectConsent(
+ ModelProjectConsent.builder()
+ .provisions(
listOf(
- Provision.builder().date(Date()).type(consentProvision)
- .purpose(policy).build()
+ Provision.builder()
+ .date(Date())
+ .type(consentProvision)
+ .purpose(policy)
+ .build()
)
- ).build()
- ).build()
- )
- .episodesOfCare(
- listOf(
- MtbEpisodeOfCare.builder().id("1")
- .patient(Reference.builder().id("TEST_12345678").build())
- .build()
- )
+ )
+ .build()
)
.build()
- }
- }
+ )
+ .episodesOfCare(
+ listOf(
+ MtbEpisodeOfCare.builder()
+ .id("1")
+ .patient(Reference.builder().id("TEST_12345678").build())
+ .build()
+ )
+ )
+ .build()
+ }
}
-
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/helpers.kt b/src/test/kotlin/dev/dnpm/etl/processor/helpers.kt
index 2dfb1e1..495bf38 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/helpers.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/helpers.kt
@@ -19,13 +19,12 @@
package dev.dnpm.etl.processor
+import java.util.stream.Stream
import org.junit.jupiter.api.extension.ExtensionContext
import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.ArgumentsProvider
-import java.util.stream.Stream
open class ArgProvider(vararg val data: Arguments) : ArgumentsProvider {
- override fun provideArguments(
- context: ExtensionContext?
- ): Stream<out Arguments> = Stream.of(*data)
+ override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> =
+ Stream.of(*data)
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt
index 7f07766..da05fba 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/input/KafkaInputListenerTest.kt
@@ -26,6 +26,7 @@ import dev.dnpm.etl.processor.consent.ConsentEvaluator
import dev.dnpm.etl.processor.consent.TtpConsentStatus
import dev.dnpm.etl.processor.services.RequestProcessor
import dev.pcvolkmer.mv64e.mtb.*
+import java.util.*
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.apache.kafka.common.header.internals.RecordHeader
import org.apache.kafka.common.header.internals.RecordHeaders
@@ -36,267 +37,241 @@ import org.junit.jupiter.api.extension.ExtendWith
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
-import java.util.*
@ExtendWith(MockitoExtension::class)
class KafkaInputListenerTest {
- private lateinit var requestProcessor: RequestProcessor
- private lateinit var consentEvaluator: ConsentEvaluator
- private lateinit var objectMapper: ObjectMapper
+ private lateinit var requestProcessor: RequestProcessor
+ private lateinit var consentEvaluator: ConsentEvaluator
+ private lateinit var objectMapper: ObjectMapper
- private lateinit var kafkaInputListener: KafkaInputListener
+ private lateinit var kafkaInputListener: KafkaInputListener
- @BeforeEach
- fun setup(
- @Mock requestProcessor: RequestProcessor,
- @Mock consentEvaluator: ConsentEvaluator,
- ) {
- this.requestProcessor = requestProcessor
- this.consentEvaluator = consentEvaluator
- this.objectMapper = ObjectMapper()
+ @BeforeEach
+ fun setup(
+ @Mock requestProcessor: RequestProcessor,
+ @Mock consentEvaluator: ConsentEvaluator,
+ ) {
+ this.requestProcessor = requestProcessor
+ this.consentEvaluator = consentEvaluator
+ this.objectMapper = ObjectMapper()
- this.kafkaInputListener = KafkaInputListener(requestProcessor, consentEvaluator, objectMapper)
- }
+ this.kafkaInputListener = KafkaInputListener(requestProcessor, consentEvaluator, objectMapper)
+ }
- @Test
- fun shouldProcessMtbFileRequest() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- true
- )
- )
+ @Test
+ fun shouldProcessMtbFileRequest() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true))
- val mtbFile = Mtb.builder()
+ val mtbFile =
+ Mtb.builder()
.patient(Patient.builder().id("DUMMY_12345678").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
listOf(
- Provision.builder().type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
+ )
+ .build()
)
.build()
)
.build()
- kafkaInputListener.onMessage(
- ConsumerRecord(
- "testtopic",
- 0,
- 0,
- "",
- this.objectMapper.writeValueAsString(mtbFile)
- )
- )
+ kafkaInputListener.onMessage(
+ ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile))
+ )
- verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
- }
+ verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
+ }
- @Test
- fun shouldProcessDeleteRequest() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- false
- )
- )
+ @Test
+ fun shouldProcessDeleteRequest() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, false))
- val mtbFile = Mtb.builder()
+ val mtbFile =
+ Mtb.builder()
.patient(Patient.builder().id("DUMMY_12345678").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
listOf(
- Provision.builder().type(ConsentProvision.DENY)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .type(ConsentProvision.DENY)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
+ )
+ .build()
)
.build()
)
.build()
- kafkaInputListener.onMessage(
- ConsumerRecord(
- "testtopic",
- 0,
- 0,
- "",
- this.objectMapper.writeValueAsString(mtbFile)
- )
- )
+ kafkaInputListener.onMessage(
+ ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile))
+ )
- verify(requestProcessor, times(1)).processDeletion(
- anyValueClass(),
- eq(TtpConsentStatus.UNKNOWN_CHECK_FILE)
- )
- }
+ verify(requestProcessor, times(1))
+ .processDeletion(anyValueClass(), eq(TtpConsentStatus.UNKNOWN_CHECK_FILE))
+ }
- @Test
- fun shouldProcessMtbFileRequestWithExistingRequestId() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- true
- )
- )
+ @Test
+ fun shouldProcessMtbFileRequestWithExistingRequestId() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true))
- val mtbFile = Mtb.builder()
+ val mtbFile =
+ Mtb.builder()
.patient(Patient.builder().id("DUMMY_12345678").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
listOf(
- Provision.builder().type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
+ )
+ .build()
)
.build()
)
.build()
- val headers = RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
- kafkaInputListener.onMessage(
- ConsumerRecord(
- "testtopic",
- 0,
- 0,
- -1L,
- TimestampType.NO_TIMESTAMP_TYPE,
- -1,
- -1,
- "",
- this.objectMapper.writeValueAsString(mtbFile),
- headers,
- Optional.empty()
- )
+ val headers =
+ RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
+ kafkaInputListener.onMessage(
+ ConsumerRecord(
+ "testtopic",
+ 0,
+ 0,
+ -1L,
+ TimestampType.NO_TIMESTAMP_TYPE,
+ -1,
+ -1,
+ "",
+ this.objectMapper.writeValueAsString(mtbFile),
+ headers,
+ Optional.empty(),
)
+ )
- verify(requestProcessor, times(1)).processMtbFile(any<Mtb>(), anyValueClass())
- }
+ verify(requestProcessor, times(1)).processMtbFile(any<Mtb>(), anyValueClass())
+ }
- @Test
- fun shouldProcessDeleteRequestWithExistingRequestId() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- false
- )
- )
+ @Test
+ fun shouldProcessDeleteRequestWithExistingRequestId() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, false))
- val mtbFile = Mtb.builder()
+ val mtbFile =
+ Mtb.builder()
.patient(Patient.builder().id("DUMMY_12345678").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
listOf(
- Provision.builder().type(ConsentProvision.DENY)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .type(ConsentProvision.DENY)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
+ )
+ .build()
)
.build()
)
.build()
- val headers = RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
- kafkaInputListener.onMessage(
- ConsumerRecord(
- "testtopic",
- 0,
- 0,
- -1L,
- TimestampType.NO_TIMESTAMP_TYPE,
- -1,
- -1,
- "",
- this.objectMapper.writeValueAsString(mtbFile),
- headers,
- Optional.empty()
- )
- )
- verify(requestProcessor, times(1)).processDeletion(
- anyValueClass(), anyValueClass(), eq(
- TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
+ val headers =
+ RecordHeaders(listOf(RecordHeader("requestId", UUID.randomUUID().toString().toByteArray())))
+ kafkaInputListener.onMessage(
+ ConsumerRecord(
+ "testtopic",
+ 0,
+ 0,
+ -1L,
+ TimestampType.NO_TIMESTAMP_TYPE,
+ -1,
+ -1,
+ "",
+ this.objectMapper.writeValueAsString(mtbFile),
+ headers,
+ Optional.empty(),
)
- }
+ )
+ verify(requestProcessor, times(1))
+ .processDeletion(anyValueClass(), anyValueClass(), eq(TtpConsentStatus.UNKNOWN_CHECK_FILE))
+ }
- @Test
- fun shouldProcessDnpmV2Request() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- false
- )
- )
+ @Test
+ fun shouldProcessDnpmV2Request() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, false))
- val mtbFile = Mtb.builder()
+ val mtbFile =
+ Mtb.builder()
.patient(Patient.builder().id("DUMMY_12345678").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
listOf(
- Provision.builder().type(ConsentProvision.DENY)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ Provision.builder()
+ .type(ConsentProvision.DENY)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
)
- ).build()
+ )
+ .build()
)
.build()
)
.build()
- val headers = RecordHeaders(
+ val headers =
+ RecordHeaders(
listOf(
RecordHeader("requestId", UUID.randomUUID().toString().toByteArray()),
- RecordHeader("contentType", CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
- )
- )
- kafkaInputListener.onMessage(
- ConsumerRecord(
- "testtopic",
- 0,
- 0,
- -1L,
- TimestampType.NO_TIMESTAMP_TYPE,
- -1,
- -1,
- "",
- this.objectMapper.writeValueAsString(mtbFile),
- headers,
- Optional.empty()
+ RecordHeader(
+ "contentType",
+ CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray(),
+ ),
)
)
- verify(requestProcessor, times(1)).processDeletion(
- anyValueClass(), anyValueClass(), eq(
- TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
+ kafkaInputListener.onMessage(
+ ConsumerRecord(
+ "testtopic",
+ 0,
+ 0,
+ -1L,
+ TimestampType.NO_TIMESTAMP_TYPE,
+ -1,
+ -1,
+ "",
+ this.objectMapper.writeValueAsString(mtbFile),
+ headers,
+ Optional.empty(),
)
- }
-
+ )
+ verify(requestProcessor, times(1))
+ .processDeletion(anyValueClass(), anyValueClass(), eq(TtpConsentStatus.UNKNOWN_CHECK_FILE))
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt
index ae9e4e2..95858f4 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/input/MtbFileRestControllerTest.kt
@@ -27,6 +27,8 @@ import dev.dnpm.etl.processor.consent.ConsentEvaluator
import dev.dnpm.etl.processor.consent.TtpConsentStatus
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
@@ -46,181 +48,176 @@ import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.delete
import org.springframework.test.web.servlet.post
import org.springframework.test.web.servlet.setup.MockMvcBuilders
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class MtbFileRestControllerTest {
- private val objectMapper = ObjectMapper()
-
- @Nested
- inner class RequestsForDnpmDataModel21 {
-
- private lateinit var mockMvc: MockMvc
-
- private lateinit var requestProcessor: RequestProcessor
- private lateinit var consentEvaluator: ConsentEvaluator
-
- @BeforeEach
- fun setup(
- @Mock requestProcessor: RequestProcessor,
- @Mock consentEvaluator: ConsentEvaluator
- ) {
- this.requestProcessor = requestProcessor
- this.consentEvaluator = consentEvaluator
- val controller = MtbFileRestController(
- requestProcessor,
- consentEvaluator
- )
- this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
- }
-
- @Test
- fun shouldRespondPostRequest() {
- whenever(consentEvaluator.check(any())).thenReturn(
- ConsentEvaluation(
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- true
- )
- )
-
- val mtbFileContent =
- ClassPathResource("mv64e-mtb-fake-patient.json").inputStream.readAllBytes().toString(Charsets.UTF_8)
-
- mockMvc.post("/mtb") {
- content = mtbFileContent
- contentType = CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON
- }.andExpect {
- status {
- isAccepted()
- }
- }
-
- verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
- }
-
- @ParameterizedTest
- @ArgumentsSource(Dnpm21MtbFile::class)
- fun shouldProcessPostRequest(mtb: Mtb, broadConsent: TtpConsentStatus, shouldProcess: String) {
- whenever(consentEvaluator.check(any<Mtb>())).thenReturn(
- ConsentEvaluation(
- broadConsent,
- shouldProcess == "process"
- )
- )
-
- mockMvc.post("/mtbfile") {
- content = objectMapper.writeValueAsString(mtb)
- contentType = CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON
- }.andExpect {
- status {
- isAccepted()
- }
- }
-
- if (shouldProcess == "process") {
- verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
- } else {
- verify(requestProcessor, times(1)).processDeletion(
- anyValueClass(),
- org.mockito.kotlin.eq(broadConsent)
- )
- }
- }
-
- @Test
- fun shouldProcessDeleteRequest() {
- mockMvc.delete("/mtbfile/TEST_12345678").andExpect {
- status {
- isAccepted()
- }
- }
-
- verify(requestProcessor, times(1)).processDeletion(
- anyValueClass(),
- org.mockito.kotlin.eq(TtpConsentStatus.UNKNOWN_CHECK_FILE)
- )
- verify(consentEvaluator, times(0)).check(any<Mtb>())
- }
+ private val objectMapper = ObjectMapper()
+
+ @Nested
+ inner class RequestsForDnpmDataModel21 {
+
+ private lateinit var mockMvc: MockMvc
+
+ private lateinit var requestProcessor: RequestProcessor
+ private lateinit var consentEvaluator: ConsentEvaluator
+
+ @BeforeEach
+ fun setup(@Mock requestProcessor: RequestProcessor, @Mock consentEvaluator: ConsentEvaluator) {
+ this.requestProcessor = requestProcessor
+ this.consentEvaluator = consentEvaluator
+ val controller = MtbFileRestController(requestProcessor, consentEvaluator)
+ this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build()
+ }
+
+ @Test
+ fun shouldRespondPostRequest() {
+ whenever(consentEvaluator.check(any()))
+ .thenReturn(ConsentEvaluation(TtpConsentStatus.BROAD_CONSENT_GIVEN, true))
+
+ val mtbFileContent =
+ ClassPathResource("mv64e-mtb-fake-patient.json")
+ .inputStream
+ .readAllBytes()
+ .toString(Charsets.UTF_8)
+
+ mockMvc
+ .post("/mtb") {
+ content = mtbFileContent
+ contentType = CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON
+ }
+ .andExpect { status { isAccepted() } }
+
+ verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
}
+
+ @ParameterizedTest
+ @ArgumentsSource(Dnpm21MtbFile::class)
+ fun shouldProcessPostRequest(mtb: Mtb, broadConsent: TtpConsentStatus, shouldProcess: String) {
+ whenever(consentEvaluator.check(any<Mtb>()))
+ .thenReturn(ConsentEvaluation(broadConsent, shouldProcess == "process"))
+
+ mockMvc
+ .post("/mtbfile") {
+ content = objectMapper.writeValueAsString(mtb)
+ contentType = CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON
+ }
+ .andExpect { status { isAccepted() } }
+
+ if (shouldProcess == "process") {
+ verify(requestProcessor, times(1)).processMtbFile(any<Mtb>())
+ } else {
+ verify(requestProcessor, times(1))
+ .processDeletion(anyValueClass(), org.mockito.kotlin.eq(broadConsent))
+ }
+ }
+
+ @Test
+ fun shouldProcessDeleteRequest() {
+ mockMvc.delete("/mtbfile/TEST_12345678").andExpect { status { isAccepted() } }
+
+ verify(requestProcessor, times(1))
+ .processDeletion(
+ anyValueClass(),
+ org.mockito.kotlin.eq(TtpConsentStatus.UNKNOWN_CHECK_FILE),
+ )
+ verify(consentEvaluator, times(0)).check(any<Mtb>())
+ }
+ }
}
-class Dnpm21MtbFile : ArgProvider(
- // No Metadata and no broad consent => delete
- Arguments.of(
- buildMtb(null),
- TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
- "delete"
- ),
- // No Metadata and broad consent given => process
- Arguments.of(
- buildMtb(null),
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- "process"
- ),
- // No model project consent and no broad consent => delete
- Arguments.of(
- buildMtb(MvhMetadata.builder().modelProjectConsent(ModelProjectConsent.builder().build()).build()),
- TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
- "delete"
- ),
- // No model project consent and broad consent given => process
- Arguments.of(
- buildMtb(MvhMetadata.builder().modelProjectConsent(ModelProjectConsent.builder().build()).build()),
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- "process"
- ),
- // Model project consent given and no broad consent => process
- Arguments.of(
- buildMtb(
- MvhMetadata.builder().modelProjectConsent(
- ModelProjectConsent.builder().provisions(
- listOf(
- Provision.builder().date(Date()).type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
- )
- ).build()
- ).build()
+class Dnpm21MtbFile :
+ ArgProvider(
+ // No Metadata and no broad consent => delete
+ Arguments.of(buildMtb(null), TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED, "delete"),
+ // No Metadata and broad consent given => process
+ Arguments.of(buildMtb(null), TtpConsentStatus.BROAD_CONSENT_GIVEN, "process"),
+ // No model project consent and no broad consent => delete
+ Arguments.of(
+ buildMtb(
+ MvhMetadata.builder()
+ .modelProjectConsent(ModelProjectConsent.builder().build())
+ .build()
+ ),
+ TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED,
+ "delete",
+ ),
+ // No model project consent and broad consent given => process
+ Arguments.of(
+ buildMtb(
+ MvhMetadata.builder()
+ .modelProjectConsent(ModelProjectConsent.builder().build())
+ .build()
+ ),
+ TtpConsentStatus.BROAD_CONSENT_GIVEN,
+ "process",
),
- TtpConsentStatus.UNKNOWN_CHECK_FILE,
- "process"
- ),
- // Model project consent given and broad consent given => process
- Arguments.of(
- buildMtb(
- MvhMetadata.builder().modelProjectConsent(
- ModelProjectConsent.builder().provisions(
- listOf(
- Provision.builder().date(Date()).type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.SEQUENCING).build()
+ // Model project consent given and no broad consent => process
+ Arguments.of(
+ buildMtb(
+ MvhMetadata.builder()
+ .modelProjectConsent(
+ ModelProjectConsent.builder()
+ .provisions(
+ listOf(
+ Provision.builder()
+ .date(Date())
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
+ )
+ )
+ .build()
)
- ).build()
- ).build()
+ .build()
+ ),
+ TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ "process",
),
- TtpConsentStatus.BROAD_CONSENT_GIVEN,
- "process"
- )
-) {
-
- companion object {
- fun buildMtb(metadata: MvhMetadata?): Mtb {
- return Mtb.builder()
- .patient(
- Patient.builder().id("TEST_12345678")
- .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z"))).gender(
- GenderCoding.builder().code(GenderCodingCode.MALE).build()
- ).build()
- )
- .metadata(metadata)
- .episodesOfCare(
- listOf(
- MtbEpisodeOfCare.builder().id("1")
- .patient(Reference.builder().id("TEST_12345678").build())
+ // Model project consent given and broad consent given => process
+ Arguments.of(
+ buildMtb(
+ MvhMetadata.builder()
+ .modelProjectConsent(
+ ModelProjectConsent.builder()
+ .provisions(
+ listOf(
+ Provision.builder()
+ .date(Date())
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
+ )
+ )
.build()
)
- )
- .build()
- }
+ .build()
+ ),
+ TtpConsentStatus.BROAD_CONSENT_GIVEN,
+ "process",
+ ),
+ ) {
+
+ companion object {
+ fun buildMtb(metadata: MvhMetadata?): Mtb {
+ return Mtb.builder()
+ .patient(
+ Patient.builder()
+ .id("TEST_12345678")
+ .birthDate(Date.from(Instant.parse("2000-08-08T12:34:56Z")))
+ .gender(GenderCoding.builder().code(GenderCodingCode.MALE).build())
+ .build()
+ )
+ .metadata(metadata)
+ .episodesOfCare(
+ listOf(
+ MtbEpisodeOfCare.builder()
+ .id("1")
+ .patient(Reference.builder().id("TEST_12345678").build())
+ .build()
+ )
+ )
+ .build()
}
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckServiceTest.kt
index a6d855c..a380d2a 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckServiceTest.kt
@@ -22,10 +22,8 @@ import reactor.test.StepVerifier
@ExtendWith(MockitoExtension::class)
class ConnectionCheckServiceTest {
-
@Nested
inner class RestConnectionCheckServiceTest {
-
lateinit var mockRestServiceServer: MockRestServiceServer
lateinit var service: RestConnectionCheckService
lateinit var sink: Sinks.Many<ConnectionCheckResult>
@@ -33,11 +31,12 @@ class ConnectionCheckServiceTest {
@BeforeEach
fun setUp() {
val restTemplate = RestTemplate()
- val restTargetProperties = RestTargetProperties(
- "http://localhost/api",
- "user",
- "password",
- )
+ val restTargetProperties =
+ RestTargetProperties(
+ "http://localhost/api",
+ "user",
+ "password",
+ )
this.sink = Sinks.many().multicast().onBackpressureBuffer()
this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
@@ -65,12 +64,12 @@ class ConnectionCheckServiceTest {
withSuccess("OK", MediaType.APPLICATION_JSON),
)
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isTrue()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isTrue() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -81,18 +80,14 @@ class ConnectionCheckServiceTest {
@Test
fun shouldEmitUnavailable() {
- this.mockRestServiceServer
- .expect(method(HttpMethod.GET))
- .andRespond(
- withServerError()
- )
+ this.mockRestServiceServer.expect(method(HttpMethod.GET)).andRespond(withServerError())
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isFalse()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isFalse() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -104,7 +99,6 @@ class ConnectionCheckServiceTest {
@Nested
inner class GPasConnectionCheckServiceTest {
-
lateinit var mockRestServiceServer: MockRestServiceServer
lateinit var service: GPasConnectionCheckService
lateinit var sink: Sinks.Many<ConnectionCheckResult>
@@ -112,15 +106,16 @@ class ConnectionCheckServiceTest {
@BeforeEach
fun setUp() {
val restTemplate = RestTemplate()
- val gpasTargetProperties = GPasConfigProperties(
- "http://localhost/gpas",
- null,
- null,
- "patientDomain",
- "genomDeTanDomain",
- "username",
- "password",
- )
+ val gpasTargetProperties =
+ GPasConfigProperties(
+ "http://localhost/gpas",
+ null,
+ null,
+ "patientDomain",
+ "genomDeTanDomain",
+ "username",
+ "password",
+ )
this.sink = Sinks.many().multicast().onBackpressureBuffer()
this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
@@ -149,12 +144,12 @@ class ConnectionCheckServiceTest {
withSuccess("OK", MediaType.APPLICATION_JSON),
)
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isTrue()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isTrue() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -165,18 +160,14 @@ class ConnectionCheckServiceTest {
@Test
fun shouldEmitUnavailable() {
- this.mockRestServiceServer
- .expect(method(HttpMethod.GET))
- .andRespond(
- withServerError()
- )
+ this.mockRestServiceServer.expect(method(HttpMethod.GET)).andRespond(withServerError())
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isFalse()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isFalse() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -188,7 +179,6 @@ class ConnectionCheckServiceTest {
@Nested
inner class GIcsConnectionCheckServiceTest {
-
lateinit var mockRestServiceServer: MockRestServiceServer
lateinit var service: GIcsConnectionCheckService
lateinit var sink: Sinks.Many<ConnectionCheckResult>
@@ -197,11 +187,12 @@ class ConnectionCheckServiceTest {
fun setUp() {
val restTemplate = RestTemplate()
- val gicsTargetProperties = GIcsConfigProperties(
- "http://localhost/gics",
- "username",
- "password",
- )
+ val gicsTargetProperties =
+ GIcsConfigProperties(
+ "http://localhost/gics",
+ "username",
+ "password",
+ )
this.sink = Sinks.many().multicast().onBackpressureBuffer()
this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
@@ -220,7 +211,6 @@ class ConnectionCheckServiceTest {
this.service.check()
this.mockRestServiceServer.verify()
-
}
@Test
@@ -231,12 +221,12 @@ class ConnectionCheckServiceTest {
withSuccess("OK", MediaType.APPLICATION_JSON),
)
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isTrue()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isTrue() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -247,18 +237,14 @@ class ConnectionCheckServiceTest {
@Test
fun shouldEmitUnavailable() {
- this.mockRestServiceServer
- .expect(method(HttpMethod.GET))
- .andRespond(
- withServerError()
- )
+ this.mockRestServiceServer.expect(method(HttpMethod.GET)).andRespond(withServerError())
- val verifier = StepVerifier.create(sink.asFlux())
- .assertNext {
- assertThat(it.available).isFalse()
- }
- .expectComplete()
- .verifyLater()
+ val verifier =
+ StepVerifier
+ .create(sink.asFlux())
+ .assertNext { assertThat(it.available).isFalse() }
+ .expectComplete()
+ .verifyLater()
this.service.check()
@@ -267,5 +253,4 @@ class ConnectionCheckServiceTest {
verifier.verify()
}
}
-
-} \ No newline at end of file
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ReportServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ReportServiceTest.kt
index 4bf1321..74d1138 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ReportServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/monitoring/ReportServiceTest.kt
@@ -1,36 +1,36 @@
package dev.dnpm.etl.processor.monitoring
import dev.dnpm.etl.processor.config.JacksonConfig
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
-import java.util.*
class ReportServiceTest {
- lateinit var service: ReportService
+ lateinit var service: ReportService
- @BeforeEach
- fun setUp() {
- val jacksonConfig = JacksonConfig()
- service = ReportService(jacksonConfig.objectMapper())
- }
+ @BeforeEach
+ fun setUp() {
+ val jacksonConfig = JacksonConfig()
+ service = ReportService(jacksonConfig.objectMapper())
+ }
- @Test
- fun shouldParseDataQualityReport() {
- val dataQualityReport = Objects.requireNonNull(this.javaClass.classLoader.getResource("dip-response.json"))
+ @Test
+ fun shouldParseDataQualityReport() {
+ val dataQualityReport =
+ Objects.requireNonNull(this.javaClass.classLoader.getResource("dip-response.json"))
.readText()
- val actual = service.deserialize(dataQualityReport)
-
- assertThat(actual).isNotNull
- assertThat(actual).hasSize(6)
- assertThat(actual[0].severity).isEqualTo(ReportService.Severity.FATAL)
- assertThat(actual[1].severity).isEqualTo(ReportService.Severity.ERROR)
- assertThat(actual[2].severity).isEqualTo(ReportService.Severity.WARNING)
- assertThat(actual[3].severity).isEqualTo(ReportService.Severity.WARNING)
- assertThat(actual[4].severity).isEqualTo(ReportService.Severity.WARNING)
- assertThat(actual[5].severity).isEqualTo(ReportService.Severity.INFO)
- }
-
-} \ No newline at end of file
+ val actual = service.deserialize(dataQualityReport)
+
+ assertThat(actual).isNotNull
+ assertThat(actual).hasSize(6)
+ assertThat(actual[0].severity).isEqualTo(ReportService.Severity.FATAL)
+ assertThat(actual[1].severity).isEqualTo(ReportService.Severity.ERROR)
+ assertThat(actual[2].severity).isEqualTo(ReportService.Severity.WARNING)
+ assertThat(actual[3].severity).isEqualTo(ReportService.Severity.WARNING)
+ assertThat(actual[4].severity).isEqualTo(ReportService.Severity.WARNING)
+ assertThat(actual[5].severity).isEqualTo(ReportService.Severity.INFO)
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSenderTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSenderTest.kt
index 022b8dd..b1cd5fa 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSenderTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSenderTest.kt
@@ -26,6 +26,10 @@ import dev.dnpm.etl.processor.RequestId
import dev.dnpm.etl.processor.config.KafkaProperties
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
+import java.util.concurrent.CompletableFuture.completedFuture
+import java.util.concurrent.ExecutionException
import org.apache.kafka.clients.producer.ProducerRecord
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
@@ -41,203 +45,208 @@ import org.springframework.kafka.core.KafkaTemplate
import org.springframework.kafka.support.SendResult
import org.springframework.retry.policy.SimpleRetryPolicy
import org.springframework.retry.support.RetryTemplateBuilder
-import java.time.Instant
-import java.util.*
-import java.util.concurrent.CompletableFuture.completedFuture
-import java.util.concurrent.ExecutionException
@ExtendWith(MockitoExtension::class)
class KafkaMtbFileSenderTest {
- @Nested
- inner class BwhcV1Record {
+ @Nested
+ inner class BwhcV1Record {
- private lateinit var kafkaTemplate: KafkaTemplate<String, String>
+ private lateinit var kafkaTemplate: KafkaTemplate<String, String>
- private lateinit var kafkaMtbFileSender: KafkaMtbFileSender
+ private lateinit var kafkaMtbFileSender: KafkaMtbFileSender
- private lateinit var objectMapper: ObjectMapper
+ private lateinit var objectMapper: ObjectMapper
- @BeforeEach
- fun setup(
- @Mock kafkaTemplate: KafkaTemplate<String, String>
- ) {
- val kafkaProperties = KafkaProperties("testtopic")
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
+ @BeforeEach
+ fun setup(@Mock kafkaTemplate: KafkaTemplate<String, String>) {
+ val kafkaProperties = KafkaProperties("testtopic")
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
- this.objectMapper = ObjectMapper()
- this.kafkaTemplate = kafkaTemplate
+ this.objectMapper = ObjectMapper()
+ this.kafkaTemplate = kafkaTemplate
- this.kafkaMtbFileSender = KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, objectMapper)
- }
-
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
- fun shouldSendDeleteRequestAndReturnExpectedState(testData: TestData) {
- doAnswer {
- if (null != testData.exception) {
- throw testData.exception
- }
- completedFuture(SendResult<String, String>(null, null))
- }.whenever(kafkaTemplate).send(any<ProducerRecord<String, String>>())
-
- val response = kafkaMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
- assertThat(response.status).isEqualTo(testData.requestStatus)
- }
-
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
- fun shouldRetryOnDeleteKafkaSendError(testData: TestData) {
- val kafkaProperties = KafkaProperties("testtopic")
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(3)).build()
- this.kafkaMtbFileSender = KafkaMtbFileSender(this.kafkaTemplate, kafkaProperties, retryTemplate, this.objectMapper)
-
- doAnswer {
- if (null != testData.exception) {
- throw testData.exception
- }
- completedFuture(SendResult<String, String>(null, null))
- }.whenever(kafkaTemplate).send(any<ProducerRecord<String, String>>())
-
- kafkaMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
+ this.kafkaMtbFileSender =
+ KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, objectMapper)
+ }
- val expectedCount = when (testData.exception) {
- // OK - No Retry
- null -> times(1)
- // Request failed - Retry max 3 times
- else -> times(3)
+ @ParameterizedTest
+ @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
+ fun shouldSendDeleteRequestAndReturnExpectedState(testData: TestData) {
+ doAnswer {
+ if (null != testData.exception) {
+ throw testData.exception
}
+ completedFuture(SendResult<String, String>(null, null))
+ }
+ .whenever(kafkaTemplate)
+ .send(any<ProducerRecord<String, String>>())
- verify(kafkaTemplate, expectedCount).send(any<ProducerRecord<String, String>>())
- }
-
+ val response = kafkaMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
+ assertThat(response.status).isEqualTo(testData.requestStatus)
}
- @Nested
- inner class DnpmV2Record {
-
- private lateinit var kafkaTemplate: KafkaTemplate<String, String>
+ @ParameterizedTest
+ @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
+ fun shouldRetryOnDeleteKafkaSendError(testData: TestData) {
+ val kafkaProperties = KafkaProperties("testtopic")
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(3)).build()
+ this.kafkaMtbFileSender =
+ KafkaMtbFileSender(this.kafkaTemplate, kafkaProperties, retryTemplate, this.objectMapper)
+
+ doAnswer {
+ if (null != testData.exception) {
+ throw testData.exception
+ }
+ completedFuture(SendResult<String, String>(null, null))
+ }
+ .whenever(kafkaTemplate)
+ .send(any<ProducerRecord<String, String>>())
+
+ kafkaMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
+
+ val expectedCount =
+ when (testData.exception) {
+ // OK - No Retry
+ null -> times(1)
+ // Request failed - Retry max 3 times
+ else -> times(3)
+ }
+
+ verify(kafkaTemplate, expectedCount).send(any<ProducerRecord<String, String>>())
+ }
+ }
- private lateinit var kafkaMtbFileSender: KafkaMtbFileSender
+ @Nested
+ inner class DnpmV2Record {
- private lateinit var objectMapper: ObjectMapper
+ private lateinit var kafkaTemplate: KafkaTemplate<String, String>
- @BeforeEach
- fun setup(
- @Mock kafkaTemplate: KafkaTemplate<String, String>
- ) {
- val kafkaProperties = KafkaProperties("testtopic")
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
+ private lateinit var kafkaMtbFileSender: KafkaMtbFileSender
- this.objectMapper = ObjectMapper()
- this.kafkaTemplate = kafkaTemplate
+ private lateinit var objectMapper: ObjectMapper
- this.kafkaMtbFileSender = KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, objectMapper)
- }
+ @BeforeEach
+ fun setup(@Mock kafkaTemplate: KafkaTemplate<String, String>) {
+ val kafkaProperties = KafkaProperties("testtopic")
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
- fun shouldSendMtbFileRequestAndReturnExpectedState(testData: TestData) {
- doAnswer {
- if (null != testData.exception) {
- throw testData.exception
- }
- completedFuture(SendResult<String, String>(null, null))
- }.whenever(kafkaTemplate).send(any<ProducerRecord<String, String>>())
-
- val response = kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
- assertThat(response.status).isEqualTo(testData.requestStatus)
- }
-
- @Test
- fun shouldSendMtbFileRequestWithCorrectKeyAndHeaderAndBody() {
- doAnswer {
- completedFuture(SendResult<String, String>(null, null))
- }.whenever(kafkaTemplate).send(any<ProducerRecord<String, String>>())
-
- kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
-
- val captor = argumentCaptor<ProducerRecord<String, String>>()
- verify(kafkaTemplate, times(1)).send(captor.capture())
- assertThat(captor.firstValue.key()).isNotNull
- assertThat(captor.firstValue.key()).isEqualTo("{\"pid\": \"PID\"}")
- assertThat(captor.firstValue.headers().headers("contentType")).isNotNull
- assertThat(captor.firstValue.headers().headers("contentType")?.firstOrNull()?.value()).isEqualTo(CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
- assertThat(captor.firstValue.headers().headers("requestId")).isNotNull
- assertThat(captor.firstValue.headers().headers("requestId")?.firstOrNull()?.value()).isEqualTo(TEST_REQUEST_ID.value.toByteArray())
- assertThat(captor.firstValue.value()).isNotNull
- assertThat(captor.firstValue.value()).isEqualTo(objectMapper.writeValueAsString(dnmpV2kafkaRecordData(TEST_REQUEST_ID)))
- }
-
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
- fun shouldRetryOnMtbFileKafkaSendError(testData: TestData) {
- val kafkaProperties = KafkaProperties("testtopic")
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(3)).build()
- this.kafkaMtbFileSender = KafkaMtbFileSender(this.kafkaTemplate, kafkaProperties, retryTemplate, this.objectMapper)
-
- doAnswer {
- if (null != testData.exception) {
- throw testData.exception
- }
- completedFuture(SendResult<String, String>(null, null))
- }.whenever(kafkaTemplate).send(any<ProducerRecord<String, String>>())
+ this.objectMapper = ObjectMapper()
+ this.kafkaTemplate = kafkaTemplate
- kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
+ this.kafkaMtbFileSender =
+ KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, objectMapper)
+ }
- val expectedCount = when (testData.exception) {
- // OK - No Retry
- null -> times(1)
- // Request failed - Retry max 3 times
- else -> times(3)
+ @ParameterizedTest
+ @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
+ fun shouldSendMtbFileRequestAndReturnExpectedState(testData: TestData) {
+ doAnswer {
+ if (null != testData.exception) {
+ throw testData.exception
}
+ completedFuture(SendResult<String, String>(null, null))
+ }
+ .whenever(kafkaTemplate)
+ .send(any<ProducerRecord<String, String>>())
- verify(kafkaTemplate, expectedCount).send(any<ProducerRecord<String, String>>())
- }
+ val response = kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
+ assertThat(response.status).isEqualTo(testData.requestStatus)
+ }
+ @Test
+ fun shouldSendMtbFileRequestWithCorrectKeyAndHeaderAndBody() {
+ doAnswer { completedFuture(SendResult<String, String>(null, null)) }
+ .whenever(kafkaTemplate)
+ .send(any<ProducerRecord<String, String>>())
+
+ kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
+
+ val captor = argumentCaptor<ProducerRecord<String, String>>()
+ verify(kafkaTemplate, times(1)).send(captor.capture())
+ assertThat(captor.firstValue.key()).isNotNull
+ assertThat(captor.firstValue.key()).isEqualTo("{\"pid\": \"PID\"}")
+ assertThat(captor.firstValue.headers().headers("contentType")).isNotNull
+ assertThat(captor.firstValue.headers().headers("contentType")?.firstOrNull()?.value())
+ .isEqualTo(CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
+ assertThat(captor.firstValue.headers().headers("requestId")).isNotNull
+ assertThat(captor.firstValue.headers().headers("requestId")?.firstOrNull()?.value())
+ .isEqualTo(TEST_REQUEST_ID.value.toByteArray())
+ assertThat(captor.firstValue.value()).isNotNull
+ assertThat(captor.firstValue.value())
+ .isEqualTo(objectMapper.writeValueAsString(dnmpV2kafkaRecordData(TEST_REQUEST_ID)))
}
- companion object {
- val TEST_REQUEST_ID = RequestId("TestId")
- val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
-
- fun dnpmV2MtbFile(): Mtb {
- return Mtb().apply {
- this.patient = dev.pcvolkmer.mv64e.mtb.Patient().apply {
- this.id = "PID"
- this.birthDate = Date.from(Instant.now())
- this.gender = GenderCoding().apply {
- this.code = GenderCodingCode.MALE
- }
- }
- this.episodesOfCare = listOf(
- MtbEpisodeOfCare().apply {
- this.id = "1"
- this.patient = Reference().apply {
- this.id = "PID"
- }
- this.period = PeriodDate().apply {
- this.start = Date.from(Instant.now())
- }
- }
- )
+ @ParameterizedTest
+ @MethodSource("dev.dnpm.etl.processor.output.KafkaMtbFileSenderTest#requestWithResponseSource")
+ fun shouldRetryOnMtbFileKafkaSendError(testData: TestData) {
+ val kafkaProperties = KafkaProperties("testtopic")
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(3)).build()
+ this.kafkaMtbFileSender =
+ KafkaMtbFileSender(this.kafkaTemplate, kafkaProperties, retryTemplate, this.objectMapper)
+
+ doAnswer {
+ if (null != testData.exception) {
+ throw testData.exception
}
- }
-
- fun dnmpV2kafkaRecordData(requestId: RequestId): Mtb {
- return DnpmV2MtbFileRequest(requestId, dnpmV2MtbFile()).content
- }
-
- data class TestData(val requestStatus: RequestStatus, val exception: Throwable? = null)
-
- @JvmStatic
- fun requestWithResponseSource(): Set<TestData> {
- return setOf(
- TestData(RequestStatus.UNKNOWN),
- TestData(RequestStatus.ERROR, InterruptedException("Test interrupted")),
- TestData(RequestStatus.ERROR, ExecutionException(RuntimeException("Test execution aborted")))
+ completedFuture(SendResult<String, String>(null, null))
+ }
+ .whenever(kafkaTemplate)
+ .send(any<ProducerRecord<String, String>>())
+
+ kafkaMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
+
+ val expectedCount =
+ when (testData.exception) {
+ // OK - No Retry
+ null -> times(1)
+ // Request failed - Retry max 3 times
+ else -> times(3)
+ }
+
+ verify(kafkaTemplate, expectedCount).send(any<ProducerRecord<String, String>>())
+ }
+ }
+
+ companion object {
+ val TEST_REQUEST_ID = RequestId("TestId")
+ val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
+
+ fun dnpmV2MtbFile(): Mtb {
+ return Mtb().apply {
+ this.patient =
+ dev.pcvolkmer.mv64e.mtb.Patient().apply {
+ this.id = "PID"
+ this.birthDate = Date.from(Instant.now())
+ this.gender = GenderCoding().apply { this.code = GenderCodingCode.MALE }
+ }
+ this.episodesOfCare =
+ listOf(
+ MtbEpisodeOfCare().apply {
+ this.id = "1"
+ this.patient = Reference().apply { this.id = "PID" }
+ this.period = PeriodDate().apply { this.start = Date.from(Instant.now()) }
+ }
)
- }
+ }
}
+ fun dnmpV2kafkaRecordData(requestId: RequestId): Mtb {
+ return DnpmV2MtbFileRequest(requestId, dnpmV2MtbFile()).content
+ }
+
+ data class TestData(val requestStatus: RequestStatus, val exception: Throwable? = null)
+
+ @JvmStatic
+ fun requestWithResponseSource(): Set<TestData> {
+ return setOf(
+ TestData(RequestStatus.UNKNOWN),
+ TestData(RequestStatus.ERROR, InterruptedException("Test interrupted")),
+ TestData(
+ RequestStatus.ERROR,
+ ExecutionException(RuntimeException("Test execution aborted")),
+ ),
+ )
+ }
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSenderTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSenderTest.kt
index 1b27a62..2ab0218 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSenderTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSenderTest.kt
@@ -30,6 +30,8 @@ import dev.dnpm.etl.processor.config.RestTargetProperties
import dev.dnpm.etl.processor.monitoring.ReportService
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
@@ -38,7 +40,6 @@ import org.junit.jupiter.params.provider.MethodSource
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
-import org.springframework.http.MediaType
import org.springframework.retry.backoff.NoBackOffPolicy
import org.springframework.retry.policy.SimpleRetryPolicy
import org.springframework.retry.support.RetryTemplateBuilder
@@ -47,224 +48,252 @@ import org.springframework.test.web.client.MockRestServiceServer
import org.springframework.test.web.client.match.MockRestRequestMatchers.*
import org.springframework.test.web.client.response.MockRestResponseCreators.withStatus
import org.springframework.web.client.RestTemplate
-import java.time.Instant
-import java.util.*
class RestDipMtbFileSenderTest {
- @Nested
- inner class DnpmV2ContentRequest {
+ @Nested
+ inner class DnpmV2ContentRequest {
- private lateinit var mockRestServiceServer: MockRestServiceServer
+ private lateinit var mockRestServiceServer: MockRestServiceServer
- private lateinit var restMtbFileSender: RestMtbFileSender
+ private lateinit var restMtbFileSender: RestMtbFileSender
- private var reportService = ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
+ private var reportService =
+ ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
- @BeforeEach
- fun setup() {
- val restTemplate = RestTemplate()
- val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
+ @BeforeEach
+ fun setup() {
+ val restTemplate = RestTemplate()
+ val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
- this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
-
- this.restMtbFileSender = RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
- }
-
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#mtbFileRequestWithResponseSource")
- fun shouldReturnExpectedResponseForDnpmV2MtbFilePost(requestWithResponse: RequestWithResponse) {
- this.mockRestServiceServer
- .expect(method(HttpMethod.POST))
- .andExpect(requestTo("http://localhost:9000/api/mtb/etl/patient-record"))
- .andExpect(header(HttpHeaders.CONTENT_TYPE, CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE))
- .andRespond {
- withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
- }
+ this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
- val response = restMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
- assertThat(response.status).isEqualTo(requestWithResponse.response.status)
- assertThat(response.body).isEqualTo(requestWithResponse.response.body)
- }
+ this.restMtbFileSender =
+ RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
+ }
+ @ParameterizedTest
+ @MethodSource(
+ "dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#mtbFileRequestWithResponseSource"
+ )
+ fun shouldReturnExpectedResponseForDnpmV2MtbFilePost(requestWithResponse: RequestWithResponse) {
+ this.mockRestServiceServer
+ .expect(method(HttpMethod.POST))
+ .andExpect(requestTo("http://localhost:9000/api/mtb/etl/patient-record"))
+ .andExpect(
+ header(
+ HttpHeaders.CONTENT_TYPE,
+ CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE,
+ )
+ )
+ .andRespond {
+ withStatus(requestWithResponse.httpStatus)
+ .body(requestWithResponse.body)
+ .createResponse(it)
+ }
+
+ val response = restMtbFileSender.send(DnpmV2MtbFileRequest(TEST_REQUEST_ID, dnpmV2MtbFile()))
+ assertThat(response.status).isEqualTo(requestWithResponse.response.status)
+ assertThat(response.body).isEqualTo(requestWithResponse.response.body)
}
+ }
- @Nested
- inner class DeleteRequest {
+ @Nested
+ inner class DeleteRequest {
- private lateinit var mockRestServiceServer: MockRestServiceServer
+ private lateinit var mockRestServiceServer: MockRestServiceServer
- private lateinit var restMtbFileSender: RestMtbFileSender
+ private lateinit var restMtbFileSender: RestMtbFileSender
- private var reportService = ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
+ private var reportService =
+ ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
- @BeforeEach
- fun setup() {
- val restTemplate = RestTemplate()
- val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
- val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
+ @BeforeEach
+ fun setup() {
+ val restTemplate = RestTemplate()
+ val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
+ val retryTemplate = RetryTemplateBuilder().customPolicy(SimpleRetryPolicy(1)).build()
- this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
+ this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
- this.restMtbFileSender =
- RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
- }
+ this.restMtbFileSender =
+ RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
+ }
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#deleteRequestWithResponseSource")
- fun shouldReturnExpectedResponseForDelete(requestWithResponse: RequestWithResponse) {
- this.mockRestServiceServer
- .expect(method(HttpMethod.DELETE))
- .andExpect(requestTo("http://localhost:9000/api/mtb/etl/patient/${TEST_PATIENT_PSEUDONYM.value}"))
- .andRespond {
- withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
- }
+ @ParameterizedTest
+ @MethodSource(
+ "dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#deleteRequestWithResponseSource"
+ )
+ fun shouldReturnExpectedResponseForDelete(requestWithResponse: RequestWithResponse) {
+ this.mockRestServiceServer
+ .expect(method(HttpMethod.DELETE))
+ .andExpect(
+ requestTo("http://localhost:9000/api/mtb/etl/patient/${TEST_PATIENT_PSEUDONYM.value}")
+ )
+ .andRespond {
+ withStatus(requestWithResponse.httpStatus)
+ .body(requestWithResponse.body)
+ .createResponse(it)
+ }
+
+ val response = restMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
+ assertThat(response.status).isEqualTo(requestWithResponse.response.status)
+ assertThat(response.body).isEqualTo(requestWithResponse.response.body)
+ }
- val response = restMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
- assertThat(response.status).isEqualTo(requestWithResponse.response.status)
- assertThat(response.body).isEqualTo(requestWithResponse.response.body)
- }
-
- @ParameterizedTest
- @MethodSource("dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#deleteRequestWithResponseSource")
- fun shouldRetryOnDeleteHttpRequestError(requestWithResponse: RequestWithResponse) {
- val restTemplate = RestTemplate()
- val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
- val retryTemplate = AppConfiguration().retryTemplate(AppConfigProperties())
- retryTemplate.setBackOffPolicy(NoBackOffPolicy())
-
- this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
- this.restMtbFileSender =
- RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
-
- val expectedCount = when (requestWithResponse.httpStatus) {
- // OK - No Retry
- HttpStatus.OK, HttpStatus.CREATED, HttpStatus.UNPROCESSABLE_ENTITY, HttpStatus.BAD_REQUEST -> ExpectedCount.max(
- 1
- )
- // Request failed - Retry max 3 times
- else -> ExpectedCount.max(3)
+ @ParameterizedTest
+ @MethodSource(
+ "dev.dnpm.etl.processor.output.RestDipMtbFileSenderTest#deleteRequestWithResponseSource"
+ )
+ fun shouldRetryOnDeleteHttpRequestError(requestWithResponse: RequestWithResponse) {
+ val restTemplate = RestTemplate()
+ val restTargetProperties = RestTargetProperties("http://localhost:9000/api", null, null)
+ val retryTemplate = AppConfiguration().retryTemplate(AppConfigProperties())
+ retryTemplate.setBackOffPolicy(NoBackOffPolicy())
+
+ this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate)
+ this.restMtbFileSender =
+ RestDipMtbFileSender(restTemplate, restTargetProperties, retryTemplate, reportService)
+
+ val expectedCount =
+ when (requestWithResponse.httpStatus) {
+ // OK - No Retry
+ HttpStatus.OK,
+ HttpStatus.CREATED,
+ HttpStatus.UNPROCESSABLE_ENTITY,
+ HttpStatus.BAD_REQUEST -> ExpectedCount.max(1)
+ // Request failed - Retry max 3 times
+ else -> ExpectedCount.max(3)
+ }
+
+ this.mockRestServiceServer
+ .expect(expectedCount, method(HttpMethod.DELETE))
+ .andExpect(
+ requestTo("http://localhost:9000/api/mtb/etl/patient/${TEST_PATIENT_PSEUDONYM.value}")
+ )
+ .andRespond {
+ withStatus(requestWithResponse.httpStatus)
+ .body(requestWithResponse.body)
+ .createResponse(it)
+ }
+
+ val response = restMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
+ assertThat(response.status).isEqualTo(requestWithResponse.response.status)
+ assertThat(response.body).isEqualTo(requestWithResponse.response.body)
+ }
+ }
+
+ companion object {
+ data class RequestWithResponse(
+ val httpStatus: HttpStatus,
+ val body: String,
+ val response: MtbFileSender.Response,
+ )
+
+ val TEST_REQUEST_ID = RequestId("TestId")
+ val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
+
+ fun dnpmV2MtbFile(): Mtb {
+ return Mtb().apply {
+ this.patient =
+ dev.pcvolkmer.mv64e.mtb.Patient().apply {
+ this.id = "PID"
+ this.birthDate = Date.from(Instant.now())
+ this.gender = GenderCoding().apply { this.code = GenderCodingCode.MALE }
}
-
- this.mockRestServiceServer
- .expect(expectedCount, method(HttpMethod.DELETE))
- .andExpect(requestTo("http://localhost:9000/api/mtb/etl/patient/${TEST_PATIENT_PSEUDONYM.value}"))
- .andRespond {
- withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
+ this.episodesOfCare =
+ listOf(
+ MtbEpisodeOfCare().apply {
+ this.id = "1"
+ this.patient = Reference().apply { this.id = "PID" }
+ this.period = PeriodDate().apply { this.start = Date.from(Instant.now()) }
}
+ )
+ }
+ }
- val response = restMtbFileSender.send(DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
- assertThat(response.status).isEqualTo(requestWithResponse.response.status)
- assertThat(response.body).isEqualTo(requestWithResponse.response.body)
- }
-
+ private const val ERROR_RESPONSE_BODY = "Sonstiger Fehler bei der Übertragung"
+
+ /**
+ * Synthetic http responses with related request status Also see:
+ * https://ibmi-intra.cs.uni-tuebingen.de/display/ZPM/bwHC+REST+API
+ */
+ @JvmStatic
+ fun mtbFileRequestWithResponseSource(): Set<RequestWithResponse> {
+ return setOf(
+ RequestWithResponse(
+ HttpStatus.OK,
+ responseBodyWithMaxSeverity(ReportService.Severity.INFO),
+ MtbFileSender.Response(
+ RequestStatus.SUCCESS,
+ responseBodyWithMaxSeverity(ReportService.Severity.INFO),
+ ),
+ ),
+ RequestWithResponse(
+ HttpStatus.CREATED,
+ responseBodyWithMaxSeverity(ReportService.Severity.WARNING),
+ MtbFileSender.Response(
+ RequestStatus.WARNING,
+ responseBodyWithMaxSeverity(ReportService.Severity.WARNING),
+ ),
+ ),
+ RequestWithResponse(
+ HttpStatus.BAD_REQUEST,
+ responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
+ MtbFileSender.Response(
+ RequestStatus.ERROR,
+ responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
+ ),
+ ),
+ RequestWithResponse(
+ HttpStatus.UNPROCESSABLE_ENTITY,
+ responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
+ MtbFileSender.Response(
+ RequestStatus.ERROR,
+ responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
+ ),
+ ),
+ // Some more errors not mentioned in documentation
+ RequestWithResponse(
+ HttpStatus.NOT_FOUND,
+ ERROR_RESPONSE_BODY,
+ MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY),
+ ),
+ RequestWithResponse(
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ ERROR_RESPONSE_BODY,
+ MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY),
+ ),
+ )
}
- companion object {
- data class RequestWithResponse(
- val httpStatus: HttpStatus,
- val body: String,
- val response: MtbFileSender.Response
- )
-
- val TEST_REQUEST_ID = RequestId("TestId")
- val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
-
- fun dnpmV2MtbFile(): Mtb {
- return Mtb().apply {
- this.patient = dev.pcvolkmer.mv64e.mtb.Patient().apply {
- this.id = "PID"
- this.birthDate = Date.from(Instant.now())
- this.gender = GenderCoding().apply {
- this.code = GenderCodingCode.MALE
- }
- }
- this.episodesOfCare = listOf(
- MtbEpisodeOfCare().apply {
- this.id = "1"
- this.patient = Reference().apply {
- this.id = "PID"
- }
- this.period = PeriodDate().apply {
- this.start = Date.from(Instant.now())
- }
- }
- )
- }
- }
-
- private const val ERROR_RESPONSE_BODY = "Sonstiger Fehler bei der Übertragung"
-
- /**
- * Synthetic http responses with related request status
- * Also see: https://ibmi-intra.cs.uni-tuebingen.de/display/ZPM/bwHC+REST+API
- */
- @JvmStatic
- fun mtbFileRequestWithResponseSource(): Set<RequestWithResponse> {
- return setOf(
- RequestWithResponse(
- HttpStatus.OK,
- responseBodyWithMaxSeverity(ReportService.Severity.INFO),
- MtbFileSender.Response(
- RequestStatus.SUCCESS,
- responseBodyWithMaxSeverity(ReportService.Severity.INFO)
- )
- ),
- RequestWithResponse(
- HttpStatus.CREATED,
- responseBodyWithMaxSeverity(ReportService.Severity.WARNING),
- MtbFileSender.Response(RequestStatus.WARNING, responseBodyWithMaxSeverity(ReportService.Severity.WARNING))
- ),
- RequestWithResponse(
- HttpStatus.BAD_REQUEST,
- responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
- MtbFileSender.Response(RequestStatus.ERROR, responseBodyWithMaxSeverity(ReportService.Severity.ERROR))
- ),
- RequestWithResponse(
- HttpStatus.UNPROCESSABLE_ENTITY,
- responseBodyWithMaxSeverity(ReportService.Severity.ERROR),
- MtbFileSender.Response(RequestStatus.ERROR, responseBodyWithMaxSeverity(ReportService.Severity.ERROR))
- ),
- // Some more errors not mentioned in documentation
- RequestWithResponse(
- HttpStatus.NOT_FOUND,
- ERROR_RESPONSE_BODY,
- MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY)
- ),
- RequestWithResponse(
- HttpStatus.INTERNAL_SERVER_ERROR,
- ERROR_RESPONSE_BODY,
- MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY)
- )
- )
- }
-
- /**
- * Synthetic http responses with related request status
- * Also see: https://ibmi-intra.cs.uni-tuebingen.de/display/ZPM/bwHC+REST+API
- */
- @JvmStatic
- fun deleteRequestWithResponseSource(): Set<RequestWithResponse> {
- return setOf(
- RequestWithResponse(HttpStatus.OK, "", MtbFileSender.Response(RequestStatus.SUCCESS)),
- // Some more errors not mentioned in documentation
- RequestWithResponse(
- HttpStatus.NOT_FOUND,
- "what????",
- MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY)
- ),
- RequestWithResponse(
- HttpStatus.INTERNAL_SERVER_ERROR,
- "what????",
- MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY)
- )
- )
- }
+ /**
+ * Synthetic http responses with related request status Also see:
+ * https://ibmi-intra.cs.uni-tuebingen.de/display/ZPM/bwHC+REST+API
+ */
+ @JvmStatic
+ fun deleteRequestWithResponseSource(): Set<RequestWithResponse> {
+ return setOf(
+ RequestWithResponse(HttpStatus.OK, "", MtbFileSender.Response(RequestStatus.SUCCESS)),
+ // Some more errors not mentioned in documentation
+ RequestWithResponse(
+ HttpStatus.NOT_FOUND,
+ "what????",
+ MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY),
+ ),
+ RequestWithResponse(
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ "what????",
+ MtbFileSender.Response(RequestStatus.ERROR, ERROR_RESPONSE_BODY),
+ ),
+ )
+ }
- fun responseBodyWithMaxSeverity(severity: ReportService.Severity): String {
- return when (severity) {
- ReportService.Severity.INFO -> """
+ fun responseBodyWithMaxSeverity(severity: ReportService.Severity): String {
+ return when (severity) {
+ ReportService.Severity.INFO ->
+ """
{
"patient": "PID",
"issues": [
@@ -273,7 +302,8 @@ class RestDipMtbFileSenderTest {
}
"""
- ReportService.Severity.WARNING -> """
+ ReportService.Severity.WARNING ->
+ """
{
"patient": "PID",
"issues": [
@@ -283,7 +313,8 @@ class RestDipMtbFileSenderTest {
}
"""
- ReportService.Severity.ERROR -> """
+ ReportService.Severity.ERROR ->
+ """
{
"patient": "PID",
"issues": [
@@ -294,7 +325,8 @@ class RestDipMtbFileSenderTest {
}
"""
- ReportService.Severity.FATAL -> """
+ ReportService.Severity.FATAL ->
+ """
{
"patient": "PID",
"issues": [
@@ -305,9 +337,7 @@ class RestDipMtbFileSenderTest {
]
}
"""
- }
- }
+ }
}
-
-
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/ExtensionsTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/ExtensionsTest.kt
index c302362..a0b3b24 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/ExtensionsTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/ExtensionsTest.kt
@@ -28,6 +28,8 @@ import dev.dnpm.etl.processor.consent.MtbFileConsentService
import dev.dnpm.etl.processor.services.ConsentProcessor
import dev.dnpm.etl.processor.services.ConsentProcessorTest
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.hl7.fhir.r4.model.Bundle
import org.junit.jupiter.api.Nested
@@ -40,231 +42,212 @@ import org.mockito.kotlin.anyValueClass
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.whenever
import org.springframework.core.io.ClassPathResource
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class ExtensionsTest {
- fun getObjectMapper(): ObjectMapper {
- return JacksonConfig().objectMapper()
- }
-
- @Nested
- inner class UsingDnpmV2Datamodel {
+ fun getObjectMapper(): ObjectMapper {
+ return JacksonConfig().objectMapper()
+ }
- val FAKE_MTB_FILE_PATH = "mv64e-mtb-fake-patient.json"
- val CLEAN_PATIENT_ID = "644bae7a-56f6-4ee8-b02f-c532e65af5b1"
+ @Nested
+ inner class UsingDnpmV2Datamodel {
- private fun fakeMtbFile(): Mtb {
- val mtbFile = ClassPathResource(FAKE_MTB_FILE_PATH).inputStream
- return getObjectMapper().readValue(mtbFile, Mtb::class.java)
- }
+ val FAKE_MTB_FILE_PATH = "mv64e-mtb-fake-patient.json"
+ val CLEAN_PATIENT_ID = "644bae7a-56f6-4ee8-b02f-c532e65af5b1"
- private fun Mtb.serialized(): String {
- return getObjectMapper().writeValueAsString(this)
- }
-
- @Test
- fun shouldNotContainCleanPatientId(@Mock pseudonymizeService: PseudonymizeService) {
- doAnswer {
- it.arguments[0]
- "PSEUDO-ID"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- val mtbFile = fakeMtbFile()
- mtbFile.ensureMetaDataIsInitialized()
- addConsentData(mtbFile)
+ private fun fakeMtbFile(): Mtb {
+ val mtbFile = ClassPathResource(FAKE_MTB_FILE_PATH).inputStream
+ return getObjectMapper().readValue(mtbFile, Mtb::class.java)
+ }
- mtbFile.pseudonymizeWith(pseudonymizeService)
+ private fun Mtb.serialized(): String {
+ return getObjectMapper().writeValueAsString(this)
+ }
- assertThat(mtbFile.patient.id).isEqualTo("PSEUDO-ID")
- assertThat(mtbFile.serialized()).doesNotContain(CLEAN_PATIENT_ID)
- }
+ @Test
+ fun shouldNotContainCleanPatientId(@Mock pseudonymizeService: PseudonymizeService) {
+ doAnswer {
+ it.arguments[0]
+ "PSEUDO-ID"
+ }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
- private fun addConsentData(mtbFile: Mtb) {
- val gIcsConfigProperties = GIcsConfigProperties("", "", "")
- val appConfigProperties = AppConfigProperties(emptyList())
+ val mtbFile = fakeMtbFile()
+ mtbFile.ensureMetaDataIsInitialized()
+ addConsentData(mtbFile)
- val bundle = Bundle()
- val dummyConsent = ConsentProcessorTest.getDummyGenomDeConsent()
- dummyConsent.patient.reference = "Patient/$CLEAN_PATIENT_ID"
- bundle.addEntry().resource = dummyConsent
+ mtbFile.pseudonymizeWith(pseudonymizeService)
- ConsentProcessor(
- appConfigProperties,
- gIcsConfigProperties,
- JacksonConfig().objectMapper(),
- FhirContext.forR4(),
- MtbFileConsentService()
- ).embedBroadConsentResources(mtbFile, bundle)
+ assertThat(mtbFile.patient.id).isEqualTo("PSEUDO-ID")
+ assertThat(mtbFile.serialized()).doesNotContain(CLEAN_PATIENT_ID)
+ }
- }
+ private fun addConsentData(mtbFile: Mtb) {
+ val gIcsConfigProperties = GIcsConfigProperties("", "", "")
+ val appConfigProperties = AppConfigProperties(emptyList())
+
+ val bundle = Bundle()
+ val dummyConsent = ConsentProcessorTest.getDummyGenomDeConsent()
+ dummyConsent.patient.reference = "Patient/$CLEAN_PATIENT_ID"
+ bundle.addEntry().resource = dummyConsent
+
+ ConsentProcessor(
+ appConfigProperties,
+ gIcsConfigProperties,
+ JacksonConfig().objectMapper(),
+ FhirContext.forR4(),
+ MtbFileConsentService(),
+ )
+ .embedBroadConsentResources(mtbFile, bundle)
+ }
- @Test
- fun shouldNotThrowExceptionOnNullValues(@Mock pseudonymizeService: PseudonymizeService) {
- doAnswer {
- it.arguments[0]
- "PSEUDO-ID"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- "TESTDOMAIN"
- }.whenever(pseudonymizeService).prefix()
-
- val mtbFile = Mtb().apply {
- this.patient = Patient().apply {
- this.id = "PID"
- this.birthDate = Date.from(Instant.now())
- this.gender = GenderCoding().apply {
- this.code = GenderCodingCode.MALE
- }
+ @Test
+ fun shouldNotThrowExceptionOnNullValues(@Mock pseudonymizeService: PseudonymizeService) {
+ doAnswer {
+ it.arguments[0]
+ "PSEUDO-ID"
+ }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { "TESTDOMAIN" }.whenever(pseudonymizeService).prefix()
+
+ val mtbFile =
+ Mtb().apply {
+ this.patient =
+ Patient().apply {
+ this.id = "PID"
+ this.birthDate = Date.from(Instant.now())
+ this.gender = GenderCoding().apply { this.code = GenderCodingCode.MALE }
}
- this.episodesOfCare = listOf(
+ this.episodesOfCare =
+ listOf(
MtbEpisodeOfCare().apply {
- this.id = "1"
- this.patient = Reference().apply {
- this.id = "PID"
- }
- this.period = PeriodDate().apply {
- this.start = Date.from(Instant.now())
- }
+ this.id = "1"
+ this.patient = Reference().apply { this.id = "PID" }
+ this.period = PeriodDate().apply { this.start = Date.from(Instant.now()) }
}
)
- }
+ }
- mtbFile.pseudonymizeWith(pseudonymizeService)
- mtbFile.anonymizeContentWith(pseudonymizeService)
+ mtbFile.pseudonymizeWith(pseudonymizeService)
+ mtbFile.anonymizeContentWith(pseudonymizeService)
- assertThat(mtbFile.episodesOfCare).hasSize(1)
- assertThat(mtbFile.episodesOfCare.map { it.id }).isNotNull
- }
-
- @Test
- fun shouldNotContainAnyUuidAfterRehashingOfIds(@Mock pseudonymizeService: PseudonymizeService) {
- doAnswer {
- it.arguments[0]
- "PSEUDO-ID"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- "TESTDOMAIN"
- }.whenever(pseudonymizeService).prefix()
-
- val mtbFile = fakeMtbFile()
-
- /**
- * replace hex values with random long, so our test does not match false positives
- */
- mtbFile.ngsReports.forEach { report ->
- report.results.simpleVariants.forEach { simpleVariant ->
- simpleVariant.externalIds.forEach { extIdValue ->
- extIdValue.value =
- Math.random().toLong().toString()
- }
- }
- }
- mtbFile.ngsReports.forEach { report ->
- report.results.rnaFusions.forEach { simpleVariant ->
- simpleVariant.externalIds.forEach { extIdValue ->
- extIdValue.value =
- Math.random().toLong().toString()
- }
- simpleVariant.fusionPartner3Prime?.transcriptId?.value =
- Math.random().toLong().toString()
- simpleVariant.fusionPartner5Prime?.transcriptId?.value =
- Math.random().toLong().toString()
- simpleVariant.externalIds?.forEach {
- it?.value = Math.random().toLong().toString()
- }
- }
- }
-
- mtbFile.pseudonymizeWith(pseudonymizeService)
- mtbFile.anonymizeContentWith(pseudonymizeService)
-
- val pattern =
- "\"[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\"".toRegex()
- .toPattern()
- val input = mtbFile.serialized()
- val matcher = pattern.matcher(input)
-
- assertThrows<IllegalStateException> {
- matcher.find()
- val posSt = "check at pos: " + matcher.start().toString() + ", " + matcher.end()
- println(posSt + " with " + matcher.group())
- }.also {
- assertThat(it.message).isEqualTo("No match found")
- }
- }
+ assertThat(mtbFile.episodesOfCare).hasSize(1)
+ assertThat(mtbFile.episodesOfCare.map { it.id }).isNotNull
}
@Test
- fun shouldUseSameAnonymIdForDiagnosisAndDiagnosisReferences(@Mock pseudonymizeService: PseudonymizeService) {
-
- doAnswer {
+ fun shouldNotContainAnyUuidAfterRehashingOfIds(@Mock pseudonymizeService: PseudonymizeService) {
+ doAnswer {
it.arguments[0]
"PSEUDO-ID"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
+ }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { "TESTDOMAIN" }.whenever(pseudonymizeService).prefix()
- doAnswer {
- "TESTDOMAIN"
- }.whenever(pseudonymizeService).prefix()
+ val mtbFile = fakeMtbFile()
- val mtbFile = Mtb().apply {
- this.patient = Patient().apply {
+ /** replace hex values with random long, so our test does not match false positives */
+ mtbFile.ngsReports.forEach { report ->
+ report.results.simpleVariants.forEach { simpleVariant ->
+ simpleVariant.externalIds.forEach { extIdValue ->
+ extIdValue.value = Math.random().toLong().toString()
+ }
+ }
+ }
+ mtbFile.ngsReports.forEach { report ->
+ report.results.rnaFusions.forEach { simpleVariant ->
+ simpleVariant.externalIds.forEach { extIdValue ->
+ extIdValue.value = Math.random().toLong().toString()
+ }
+ simpleVariant.fusionPartner3Prime?.transcriptId?.value = Math.random().toLong().toString()
+ simpleVariant.fusionPartner5Prime?.transcriptId?.value = Math.random().toLong().toString()
+ simpleVariant.externalIds?.forEach { it?.value = Math.random().toLong().toString() }
+ }
+ }
+
+ mtbFile.pseudonymizeWith(pseudonymizeService)
+ mtbFile.anonymizeContentWith(pseudonymizeService)
+
+ val pattern =
+ "\"[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\"".toRegex().toPattern()
+ val input = mtbFile.serialized()
+ val matcher = pattern.matcher(input)
+
+ assertThrows<IllegalStateException> {
+ matcher.find()
+ val posSt = "check at pos: " + matcher.start().toString() + ", " + matcher.end()
+ println(posSt + " with " + matcher.group())
+ }
+ .also { assertThat(it.message).isEqualTo("No match found") }
+ }
+ }
+
+ @Test
+ fun shouldUseSameAnonymIdForDiagnosisAndDiagnosisReferences(
+ @Mock pseudonymizeService: PseudonymizeService
+ ) {
+
+ doAnswer {
+ it.arguments[0]
+ "PSEUDO-ID"
+ }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { "TESTDOMAIN" }.whenever(pseudonymizeService).prefix()
+
+ val mtbFile =
+ Mtb().apply {
+ this.patient =
+ Patient().apply {
this.id = "PID"
this.birthDate = Date.from(Instant.now())
- this.gender = GenderCoding().apply {
- this.code = GenderCodingCode.MALE
- }
- }
- this.diagnoses = listOf(
- MtbDiagnosis().apply {
- this.id = "Diagnosis-1"
- }
- )
- this.episodesOfCare = listOf(
- MtbEpisodeOfCare().apply {
+ this.gender = GenderCoding().apply { this.code = GenderCodingCode.MALE }
+ }
+ this.diagnoses = listOf(MtbDiagnosis().apply { this.id = "Diagnosis-1" })
+ this.episodesOfCare =
+ listOf(
+ MtbEpisodeOfCare().apply {
this.id = "Episode-1"
- this.diagnoses = listOf(
- Reference().apply {
- this.id = "Diagnosis-1"
- }
- )
- }
- )
- this.guidelineTherapies = listOf(
- MtbSystemicTherapy().apply {
+ this.diagnoses = listOf(Reference().apply { this.id = "Diagnosis-1" })
+ }
+ )
+ this.guidelineTherapies =
+ listOf(
+ MtbSystemicTherapy().apply {
this.id = "Systemic-Therapy-1"
- this.reason = Reference().apply {
- this.id = "Diagnosis-1"
- }
- }
- )
- this.guidelineProcedures = listOf(
- OncoProcedure().apply {
+ this.reason = Reference().apply { this.id = "Diagnosis-1" }
+ }
+ )
+ this.guidelineProcedures =
+ listOf(
+ OncoProcedure().apply {
this.id = "Onco-Procedure-1"
- this.reason = Reference().apply {
- this.id = "Diagnosis-1"
- }
- }
- )
- this.specimens = listOf(
- TumorSpecimen().apply {
+ this.reason = Reference().apply { this.id = "Diagnosis-1" }
+ }
+ )
+ this.specimens =
+ listOf(
+ TumorSpecimen().apply {
this.id = "Specimen-1"
- this.diagnosis = Reference().apply {
- this.id = "Diagnosis-1"
- }
- }
- )
+ this.diagnosis = Reference().apply { this.id = "Diagnosis-1" }
+ }
+ )
}
- mtbFile.pseudonymizeWith(pseudonymizeService)
- mtbFile.anonymizeContentWith(pseudonymizeService)
+ mtbFile.pseudonymizeWith(pseudonymizeService)
+ mtbFile.anonymizeContentWith(pseudonymizeService)
- assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.episodesOfCare.first().diagnoses.first().id)
- assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.guidelineTherapies.first().reason.id)
- assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.guidelineProcedures.first().reason.id)
- assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.specimens.first().diagnosis.id)
- }
+ assertThat(mtbFile.diagnoses.first().id)
+ .isEqualTo(mtbFile.episodesOfCare.first().diagnoses.first().id)
+ assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.guidelineTherapies.first().reason.id)
+ assertThat(mtbFile.diagnoses.first().id)
+ .isEqualTo(mtbFile.guidelineProcedures.first().reason.id)
+ assertThat(mtbFile.diagnoses.first().id).isEqualTo(mtbFile.specimens.first().diagnosis.id)
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeServiceTest.kt
index 8ee19bc..7da0247 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeServiceTest.kt
@@ -21,6 +21,8 @@ package dev.dnpm.etl.processor.pseudonym
import dev.dnpm.etl.processor.config.PseudonymizeConfigProperties
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
@@ -29,72 +31,67 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.whenever
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class PseudonymizeServiceTest {
- private val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
- .episodesOfCare(
- listOf(
- MtbEpisodeOfCare.builder()
- .id("1")
- .patient(Reference.builder().id("123").build())
- .period(PeriodDate.builder().start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z"))).build())
- .build()
- )
- )
- .build()
-
- @Test
- fun shouldNotUsePseudonymPrefixForGpas(@Mock generator: GpasPseudonymGenerator) {
- doAnswer {
- it.arguments[0]
- }.whenever(generator).generate(anyString())
-
- val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
-
- mtbFile.pseudonymizeWith(pseudonymizeService)
-
- assertThat(mtbFile.patient.id).isEqualTo("123")
- }
+ private val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
+ .episodesOfCare(
+ listOf(
+ MtbEpisodeOfCare.builder()
+ .id("1")
+ .patient(Reference.builder().id("123").build())
+ .period(
+ PeriodDate.builder()
+ .start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z")))
+ .build()
+ )
+ .build()
+ )
+ )
+ .build()
- @Test
- fun sanitizeFileName() {
- val result = GpasPseudonymGenerator.sanitizeValue("l://a\\bs;1*2?3>")
+ @Test
+ fun shouldNotUsePseudonymPrefixForGpas(@Mock generator: GpasPseudonymGenerator) {
+ doAnswer { it.arguments[0] }.whenever(generator).generate(anyString())
- assertThat(result).isEqualTo("l___a_bs_1_2_3_")
- }
+ val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
- @Test
- fun shouldUsePseudonymPrefixForBuiltin(@Mock generator: AnonymizingGenerator) {
- doAnswer {
- it.arguments[0]
- }.whenever(generator).generate(anyString())
+ mtbFile.pseudonymizeWith(pseudonymizeService)
- val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
+ assertThat(mtbFile.patient.id).isEqualTo("123")
+ }
- mtbFile.pseudonymizeWith(pseudonymizeService)
+ @Test
+ fun sanitizeFileName() {
+ val result = GpasPseudonymGenerator.sanitizeValue("l://a\\bs;1*2?3>")
- assertThat(mtbFile.patient.id).isEqualTo("UNKNOWN_123")
- }
+ assertThat(result).isEqualTo("l___a_bs_1_2_3_")
+ }
+
+ @Test
+ fun shouldUsePseudonymPrefixForBuiltin(@Mock generator: AnonymizingGenerator) {
+ doAnswer { it.arguments[0] }.whenever(generator).generate(anyString())
+
+ val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
+
+ mtbFile.pseudonymizeWith(pseudonymizeService)
+
+ assertThat(mtbFile.patient.id).isEqualTo("UNKNOWN_123")
+ }
- @Test
- fun shouldReturnDifferentValues() {
- val ag = AnonymizingGenerator()
+ @Test
+ fun shouldReturnDifferentValues() {
+ val ag = AnonymizingGenerator()
- val tans = HashSet<String>()
+ val tans = HashSet<String>()
- (1..1000).forEach { i ->
- val tan = ag.generateGenomDeTan("12345")
- assertThat(tan).hasSize(64)
- assertThat(tans.add(tan)).`as`("never the same result!").isTrue
- }
+ (1..1000).forEach { i ->
+ val tan = ag.generateGenomDeTan("12345")
+ assertThat(tan).hasSize(64)
+ assertThat(tans.add(tan)).`as`("never the same result!").isTrue
}
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/security/TokenServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/security/TokenServiceTest.kt
index b93e9f5..e9a1650 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/security/TokenServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/security/TokenServiceTest.kt
@@ -19,6 +19,8 @@
package dev.dnpm.etl.processor.security
+import java.util.*
+import java.util.function.Consumer
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -30,124 +32,128 @@ import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import org.springframework.security.crypto.password.PasswordEncoder
import org.springframework.security.provisioning.InMemoryUserDetailsManager
-import java.util.*
-import java.util.function.Consumer
@ExtendWith(MockitoExtension::class)
class TokenServiceTest {
- private lateinit var userDetailsManager: InMemoryUserDetailsManager
- private lateinit var passwordEncoder: PasswordEncoder
- private lateinit var tokenRepository: TokenRepository
+ private lateinit var userDetailsManager: InMemoryUserDetailsManager
+ private lateinit var passwordEncoder: PasswordEncoder
+ private lateinit var tokenRepository: TokenRepository
- private lateinit var tokenService: TokenService
+ private lateinit var tokenService: TokenService
- @BeforeEach
- fun setup(
- @Mock userDetailsManager: InMemoryUserDetailsManager,
- @Mock passwordEncoder: PasswordEncoder,
- @Mock tokenRepository: TokenRepository
- ) {
- this.userDetailsManager = userDetailsManager
- this.passwordEncoder = passwordEncoder
- this.tokenRepository = tokenRepository
+ @BeforeEach
+ fun setup(
+ @Mock userDetailsManager: InMemoryUserDetailsManager,
+ @Mock passwordEncoder: PasswordEncoder,
+ @Mock tokenRepository: TokenRepository,
+ ) {
+ this.userDetailsManager = userDetailsManager
+ this.passwordEncoder = passwordEncoder
+ this.tokenRepository = tokenRepository
- this.tokenService = TokenService(userDetailsManager, passwordEncoder, tokenRepository)
- }
+ this.tokenService = TokenService(userDetailsManager, passwordEncoder, tokenRepository)
+ }
- @Test
- fun shouldEncodePasswordForNewToken() {
- doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
+ @Test
+ fun shouldEncodePasswordForNewToken() {
+ doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
- val actual = this.tokenService.addToken("Test Token")
+ val actual = this.tokenService.addToken("Test Token")
- assertThat(actual).satisfies(
+ assertThat(actual)
+ .satisfies(
Consumer { assertThat(it.isSuccess).isTrue() },
- Consumer { assertThat(it.getOrNull()).matches("testtoken:[A-Za-z0-9]{48}$") }
+ Consumer { assertThat(it.getOrNull()).matches("testtoken:[A-Za-z0-9]{48}$") },
)
- }
+ }
- @Test
- fun shouldContainAlphanumTokenUserPart() {
- doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
+ @Test
+ fun shouldContainAlphanumTokenUserPart() {
+ doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
- val actual = this.tokenService.addToken("Test Token")
+ val actual = this.tokenService.addToken("Test Token")
- assertThat(actual).satisfies(
+ assertThat(actual)
+ .satisfies(
Consumer { assertThat(it.isSuccess).isTrue() },
- Consumer { assertThat(it.getOrDefault("")).startsWith("testtoken:") }
+ Consumer { assertThat(it.getOrDefault("")).startsWith("testtoken:") },
)
- }
+ }
- @Test
- fun shouldNotAllowSameTokenUserPartTwice() {
- doReturn(true).whenever(userDetailsManager).userExists(anyString())
+ @Test
+ fun shouldNotAllowSameTokenUserPartTwice() {
+ doReturn(true).whenever(userDetailsManager).userExists(anyString())
- val actual = this.tokenService.addToken("Test Token")
+ val actual = this.tokenService.addToken("Test Token")
- assertThat(actual).satisfies(Consumer { assertThat(it.isFailure).isTrue() })
- verify(tokenRepository, never()).save(any())
- }
+ assertThat(actual).satisfies(Consumer { assertThat(it.isFailure).isTrue() })
+ verify(tokenRepository, never()).save(any())
+ }
- @Test
- fun shouldSaveNewToken() {
- doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
+ @Test
+ fun shouldSaveNewToken() {
+ doAnswer { "{test}verysecret" }.whenever(passwordEncoder).encode(anyString())
- val actual = this.tokenService.addToken("Test Token")
+ val actual = this.tokenService.addToken("Test Token")
- val captor = argumentCaptor<Token>()
- verify(tokenRepository, times(1)).save(captor.capture())
+ val captor = argumentCaptor<Token>()
+ verify(tokenRepository, times(1)).save(captor.capture())
- assertThat(actual).satisfies(Consumer { assertThat(it.isSuccess).isTrue() })
- assertThat(captor.firstValue).satisfies(
+ assertThat(actual).satisfies(Consumer { assertThat(it.isSuccess).isTrue() })
+ assertThat(captor.firstValue)
+ .satisfies(
Consumer { assertThat(it.name).isEqualTo("Test Token") },
Consumer { assertThat(it.username).isEqualTo("testtoken") },
- Consumer { assertThat(it.password).isEqualTo("{test}verysecret") }
+ Consumer { assertThat(it.password).isEqualTo("{test}verysecret") },
)
- }
-
- @Test
- fun shouldDeleteExistingToken() {
- doAnswer {
- val id = it.arguments[0] as Long
- Optional.of(Token(id, "Test Token", "testtoken", "{test}hsdajfgadskjhfgsdkfjg"))
- }.whenever(tokenRepository).findById(anyLong())
-
- this.tokenService.deleteToken(42)
-
- val stringCaptor = argumentCaptor<String>()
- verify(userDetailsManager, times(1)).deleteUser(stringCaptor.capture())
- assertThat(stringCaptor.firstValue).isEqualTo("testtoken")
-
- val tokenCaptor = argumentCaptor<Token>()
- verify(tokenRepository, times(1)).delete(tokenCaptor.capture())
- assertThat(tokenCaptor.firstValue.id).isEqualTo(42)
- }
-
- @Test
- fun shouldReturnAllTokensFromRepository() {
- val expected = listOf(
+ }
+
+ @Test
+ fun shouldDeleteExistingToken() {
+ doAnswer {
+ val id = it.arguments[0] as Long
+ Optional.of(Token(id, "Test Token", "testtoken", "{test}hsdajfgadskjhfgsdkfjg"))
+ }
+ .whenever(tokenRepository)
+ .findById(anyLong())
+
+ this.tokenService.deleteToken(42)
+
+ val stringCaptor = argumentCaptor<String>()
+ verify(userDetailsManager, times(1)).deleteUser(stringCaptor.capture())
+ assertThat(stringCaptor.firstValue).isEqualTo("testtoken")
+
+ val tokenCaptor = argumentCaptor<Token>()
+ verify(tokenRepository, times(1)).delete(tokenCaptor.capture())
+ assertThat(tokenCaptor.firstValue.id).isEqualTo(42)
+ }
+
+ @Test
+ fun shouldReturnAllTokensFromRepository() {
+ val expected =
+ listOf(
Token(1, "Test Token 1", "testtoken1", "{test}hsdajfgadskjhfgsdkfjg"),
- Token(2, "Test Token 2", "testtoken2", "{test}asdasdasdasdasdasdasd")
+ Token(2, "Test Token 2", "testtoken2", "{test}asdasdasdasdasdasdasd"),
)
- doReturn(expected).whenever(tokenRepository).findAll()
+ doReturn(expected).whenever(tokenRepository).findAll()
- assertThat(tokenService.findAll()).isEqualTo(expected)
- }
+ assertThat(tokenService.findAll()).isEqualTo(expected)
+ }
- @Test
- fun shouldAddAllTokensFromRepositoryToUserDataManager() {
- val expected = listOf(
+ @Test
+ fun shouldAddAllTokensFromRepositoryToUserDataManager() {
+ val expected =
+ listOf(
Token(1, "Test Token 1", "testtoken1", "{test}hsdajfgadskjhfgsdkfjg"),
- Token(2, "Test Token 2", "testtoken2", "{test}asdasdasdasdasdasdasd")
+ Token(2, "Test Token 2", "testtoken2", "{test}asdasdasdasdasdasdasd"),
)
- doReturn(expected).whenever(tokenRepository).findAll()
-
- tokenService.setup()
+ doReturn(expected).whenever(tokenRepository).findAll()
- verify(userDetailsManager, times(expected.size)).createUser(any())
- }
+ tokenService.setup()
-} \ No newline at end of file
+ verify(userDetailsManager, times(expected.size)).createUser(any())
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/security/UserRoleServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/security/UserRoleServiceTest.kt
index 39ba7c0..7743069 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/security/UserRoleServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/security/UserRoleServiceTest.kt
@@ -19,6 +19,8 @@
package dev.dnpm.etl.processor.security
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
@@ -32,161 +34,148 @@ import org.springframework.security.core.session.SessionRegistry
import org.springframework.security.oauth2.core.oidc.OidcIdToken
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser
import org.springframework.security.oauth2.core.oidc.user.OidcUser
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class UserRoleServiceTest {
- private lateinit var userRoleRepository: UserRoleRepository
- private lateinit var sessionRegistry: SessionRegistry
+ private lateinit var userRoleRepository: UserRoleRepository
+ private lateinit var sessionRegistry: SessionRegistry
- private lateinit var userRoleService: UserRoleService
+ private lateinit var userRoleService: UserRoleService
- @BeforeEach
- fun setup(
- @Mock userRoleRepository: UserRoleRepository,
- @Mock sessionRegistry: SessionRegistry
- ) {
- this.userRoleRepository = userRoleRepository
- this.sessionRegistry = sessionRegistry
-
- this.userRoleService = UserRoleService(userRoleRepository, sessionRegistry)
- }
+ @BeforeEach
+ fun setup(@Mock userRoleRepository: UserRoleRepository, @Mock sessionRegistry: SessionRegistry) {
+ this.userRoleRepository = userRoleRepository
+ this.sessionRegistry = sessionRegistry
- @Test
- fun shouldDelegateFindAllToRepository() {
- userRoleService.findAll()
+ this.userRoleService = UserRoleService(userRoleRepository, sessionRegistry)
+ }
- verify(userRoleRepository, times(1)).findAll()
- }
+ @Test
+ fun shouldDelegateFindAllToRepository() {
+ userRoleService.findAll()
- @Nested
- inner class WithExistingUserRole {
+ verify(userRoleRepository, times(1)).findAll()
+ }
- @BeforeEach
- fun setup() {
- doAnswer { invocation ->
- Optional.of(
- UserRole(invocation.getArgument(0), "patrick.tester", Role.USER)
- )
- }.whenever(userRoleRepository).findById(any<Long>())
+ @Nested
+ inner class WithExistingUserRole {
- doAnswer { _ ->
- listOf(
- dummyPrincipal()
- )
- }.whenever(sessionRegistry).allPrincipals
- }
+ @BeforeEach
+ fun setup() {
+ doAnswer { invocation ->
+ Optional.of(UserRole(invocation.getArgument(0), "patrick.tester", Role.USER))
+ }
+ .whenever(userRoleRepository)
+ .findById(any<Long>())
+
+ doAnswer { _ -> listOf(dummyPrincipal()) }.whenever(sessionRegistry).allPrincipals
+ }
- @Test
- fun shouldUpdateUserRole() {
- userRoleService.updateUserRole(1, Role.ADMIN)
+ @Test
+ fun shouldUpdateUserRole() {
+ userRoleService.updateUserRole(1, Role.ADMIN)
- val userRoleCaptor = argumentCaptor<UserRole>()
- verify(userRoleRepository, times(1)).save(userRoleCaptor.capture())
+ val userRoleCaptor = argumentCaptor<UserRole>()
+ verify(userRoleRepository, times(1)).save(userRoleCaptor.capture())
- assertThat(userRoleCaptor.firstValue.id).isEqualTo(1L)
- assertThat(userRoleCaptor.firstValue.role).isEqualTo(Role.ADMIN)
- }
+ assertThat(userRoleCaptor.firstValue.id).isEqualTo(1L)
+ assertThat(userRoleCaptor.firstValue.role).isEqualTo(Role.ADMIN)
+ }
- @Test
- fun shouldExpireSessionOnUpdate() {
- val dummySessions = dummySessions()
- whenever(sessionRegistry.getAllSessions(any(), any<Boolean>())).thenReturn(
- dummySessions
- )
+ @Test
+ fun shouldExpireSessionOnUpdate() {
+ val dummySessions = dummySessions()
+ whenever(sessionRegistry.getAllSessions(any(), any<Boolean>())).thenReturn(dummySessions)
- assertThat(dummySessions.filter { it.isExpired }).hasSize(0)
+ assertThat(dummySessions.filter { it.isExpired }).hasSize(0)
- userRoleService.updateUserRole(1, Role.ADMIN)
+ userRoleService.updateUserRole(1, Role.ADMIN)
- verify(sessionRegistry, times(1)).getAllSessions(any<OidcUser>(), any<Boolean>())
+ verify(sessionRegistry, times(1)).getAllSessions(any<OidcUser>(), any<Boolean>())
- assertThat(dummySessions.filter { it.isExpired }).hasSize(2)
- }
+ assertThat(dummySessions.filter { it.isExpired }).hasSize(2)
+ }
- @Test
- fun shouldDeleteUserRole() {
- userRoleService.deleteUserRole(1)
+ @Test
+ fun shouldDeleteUserRole() {
+ userRoleService.deleteUserRole(1)
- val userRoleCaptor = argumentCaptor<UserRole>()
- verify(userRoleRepository, times(1)).delete(userRoleCaptor.capture())
+ val userRoleCaptor = argumentCaptor<UserRole>()
+ verify(userRoleRepository, times(1)).delete(userRoleCaptor.capture())
- assertThat(userRoleCaptor.firstValue.id).isEqualTo(1L)
- assertThat(userRoleCaptor.firstValue.role).isEqualTo(Role.USER)
- }
+ assertThat(userRoleCaptor.firstValue.id).isEqualTo(1L)
+ assertThat(userRoleCaptor.firstValue.role).isEqualTo(Role.USER)
+ }
- @Test
- fun shouldExpireSessionOnDelete() {
- val dummySessions = dummySessions()
- whenever(sessionRegistry.getAllSessions(any(), any<Boolean>())).thenReturn(
- dummySessions
- )
+ @Test
+ fun shouldExpireSessionOnDelete() {
+ val dummySessions = dummySessions()
+ whenever(sessionRegistry.getAllSessions(any(), any<Boolean>())).thenReturn(dummySessions)
- assertThat(dummySessions.filter { it.isExpired }).hasSize(0)
+ assertThat(dummySessions.filter { it.isExpired }).hasSize(0)
- userRoleService.deleteUserRole(1)
+ userRoleService.deleteUserRole(1)
- verify(sessionRegistry, times(1)).getAllSessions(any<OidcUser>(), any<Boolean>())
+ verify(sessionRegistry, times(1)).getAllSessions(any<OidcUser>(), any<Boolean>())
- assertThat(dummySessions.filter { it.isExpired }).hasSize(2)
- }
+ assertThat(dummySessions.filter { it.isExpired }).hasSize(2)
}
+ }
- @Nested
- inner class WithoutExistingUserRole {
-
- @BeforeEach
- fun setup() {
- doAnswer { _ ->
- Optional.empty<UserRole>()
- }.whenever(userRoleRepository).findById(any<Long>())
- }
+ @Nested
+ inner class WithoutExistingUserRole {
- @Test
- fun shouldNotUpdateUserRole() {
- userRoleService.updateUserRole(1, Role.ADMIN)
+ @BeforeEach
+ fun setup() {
+ doAnswer { _ -> Optional.empty<UserRole>() }
+ .whenever(userRoleRepository)
+ .findById(any<Long>())
+ }
- verify(userRoleRepository, never()).save(any<UserRole>())
- }
+ @Test
+ fun shouldNotUpdateUserRole() {
+ userRoleService.updateUserRole(1, Role.ADMIN)
- @Test
- fun shouldNotExpireSessionOnUpdate() {
- userRoleService.updateUserRole(1, Role.ADMIN)
+ verify(userRoleRepository, never()).save(any<UserRole>())
+ }
- verify(sessionRegistry, never()).getAllSessions(any<OidcUser>(), any<Boolean>())
- }
+ @Test
+ fun shouldNotExpireSessionOnUpdate() {
+ userRoleService.updateUserRole(1, Role.ADMIN)
- @Test
- fun shouldNotDeleteUserRole() {
- userRoleService.deleteUserRole(1)
+ verify(sessionRegistry, never()).getAllSessions(any<OidcUser>(), any<Boolean>())
+ }
- verify(userRoleRepository, never()).delete(any<UserRole>())
- }
+ @Test
+ fun shouldNotDeleteUserRole() {
+ userRoleService.deleteUserRole(1)
- @Test
- fun shouldNotExpireSessionOnDelete() {
- userRoleService.deleteUserRole(1)
+ verify(userRoleRepository, never()).delete(any<UserRole>())
+ }
- verify(sessionRegistry, never()).getAllSessions(any<OidcUser>(), any<Boolean>())
- }
+ @Test
+ fun shouldNotExpireSessionOnDelete() {
+ userRoleService.deleteUserRole(1)
+ verify(sessionRegistry, never()).getAllSessions(any<OidcUser>(), any<Boolean>())
}
+ }
-
- companion object {
- private fun dummyPrincipal() = DefaultOidcUser(
+ companion object {
+ private fun dummyPrincipal() =
+ DefaultOidcUser(
listOf(),
OidcIdToken(
"anytokenvalue",
Instant.now(),
Instant.now().plusSeconds(10),
- mapOf("sub" to "testsub", "preferred_username" to "patrick.tester")
- )
+ mapOf("sub" to "testsub", "preferred_username" to "patrick.tester"),
+ ),
)
- private fun dummySessions() = listOf(
+ private fun dummySessions() =
+ listOf(
SessionInformation(
dummyPrincipal(),
"SESSIONID1",
@@ -196,7 +185,7 @@ class UserRoleServiceTest {
dummyPrincipal(),
"SESSIONID2",
Date.from(Instant.now()),
- )
+ ),
)
- }
-} \ No newline at end of file
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/ConsentProcessorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/ConsentProcessorTest.kt
index bbc8b1a..3e54e71 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/ConsentProcessorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/ConsentProcessorTest.kt
@@ -10,6 +10,11 @@ import dev.dnpm.etl.processor.consent.GicsConsentService
import dev.pcvolkmer.mv64e.mtb.Mtb
import dev.pcvolkmer.mv64e.mtb.MvhSubmissionType
import dev.pcvolkmer.mv64e.mtb.Patient
+import java.io.IOException
+import java.io.InputStream
+import java.time.Instant
+import java.time.OffsetDateTime
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.hl7.fhir.r4.model.Bundle
import org.hl7.fhir.r4.model.CodeableConcept
@@ -28,205 +33,194 @@ import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever
import org.springframework.core.io.ClassPathResource
-import java.io.IOException
-import java.io.InputStream
-import java.time.Instant
-import java.time.OffsetDateTime
-import java.util.*
@ExtendWith(MockitoExtension::class)
class ConsentProcessorTest {
- private lateinit var appConfigProperties: AppConfigProperties
- private lateinit var gicsConsentService: GicsConsentService
- private lateinit var objectMapper: ObjectMapper
- private lateinit var gIcsConfigProperties: GIcsConfigProperties
- private lateinit var fhirContext: FhirContext
- private lateinit var consentProcessor: ConsentProcessor
-
- @BeforeEach
- fun setups(
- @Mock gicsConsentService: GicsConsentService,
- ) {
-
- this.gIcsConfigProperties = GIcsConfigProperties("https://gics.example.com")
- val jacksonConfig = JacksonConfig()
- this.objectMapper = jacksonConfig.objectMapper()
- this.fhirContext = JacksonConfig.fhirContext()
- this.gicsConsentService = gicsConsentService
- this.appConfigProperties = AppConfigProperties(emptyList())
- this.consentProcessor =
- ConsentProcessor(
- appConfigProperties,
- gIcsConfigProperties,
- objectMapper,
- fhirContext,
- gicsConsentService
- )
+ private lateinit var appConfigProperties: AppConfigProperties
+ private lateinit var gicsConsentService: GicsConsentService
+ private lateinit var objectMapper: ObjectMapper
+ private lateinit var gIcsConfigProperties: GIcsConfigProperties
+ private lateinit var fhirContext: FhirContext
+ private lateinit var consentProcessor: ConsentProcessor
+
+ @BeforeEach
+ fun setups(
+ @Mock gicsConsentService: GicsConsentService,
+ ) {
+
+ this.gIcsConfigProperties = GIcsConfigProperties("https://gics.example.com")
+ val jacksonConfig = JacksonConfig()
+ this.objectMapper = jacksonConfig.objectMapper()
+ this.fhirContext = JacksonConfig.fhirContext()
+ this.gicsConsentService = gicsConsentService
+ this.appConfigProperties = AppConfigProperties(emptyList())
+ this.consentProcessor =
+ ConsentProcessor(
+ appConfigProperties,
+ gIcsConfigProperties,
+ objectMapper,
+ fhirContext,
+ gicsConsentService,
+ )
+ }
+
+ @Test
+ fun consentOk() {
+ assertThat(consentProcessor.toString()).isNotNull
+ // prep gICS response
+ doAnswer { getDummyBroadConsentBundle() }
+ .whenever(gicsConsentService)
+ .getConsent(any(), any(), eq(ConsentDomain.BROAD_CONSENT))
+
+ doAnswer { Bundle() }
+ .whenever(gicsConsentService)
+ .getConsent(any(), any(), eq(ConsentDomain.MODELLVORHABEN_64E))
+
+ val inputMtb =
+ Mtb.builder()
+ .patient(Patient.builder().id("d611d429-5003-11f0-a144-661e92ac9503").build())
+ .build()
+ val checkResult = consentProcessor.consentGatedCheckAndTryEmbedding(inputMtb)
+
+ assertThat(checkResult).isTrue
+ assertThat(inputMtb.metadata.researchConsents).isNotEmpty
+ }
+
+ companion object {
+ fun getDummyGenomDeConsent(): Consent {
+ val consent = Consent()
+ consent.id = "consent 1 id"
+ consent.patient.reference = "Patient/1234-pat1"
+
+ consent.provision.setType(Consent.ConsentProvisionType.fromCode("deny"))
+ consent.provision.period.start = Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
+ consent.provision.period.end = Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
+
+ val addProvision1 = consent.provision.addProvision()
+ addProvision1.setType(Consent.ConsentProvisionType.fromCode("permit"))
+ addProvision1.period.start = Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
+ addProvision1.period.end = Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
+ addProvision1.code.addLast(
+ CodeableConcept(
+ Coding(
+ "https://ths-greifswald.de/fhir/CodeSystem/gics/Policy/GenomDE_MV",
+ "Teilnahme",
+ "Teilnahme am Modellvorhaben und Einwilligung zur Genomsequenzierung",
+ )
+ )
+ )
+
+ val addProvision2 = consent.provision.addProvision()
+ addProvision2.setType(Consent.ConsentProvisionType.fromCode("deny"))
+ addProvision2.period.start = Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
+ addProvision2.period.end = Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
+ addProvision2.code.addLast(
+ CodeableConcept(
+ Coding(
+ "https://ths-greifswald.de/fhir/CodeSystem/gics/Policy/GenomDE_MV",
+ "Rekontaktierung",
+ "Re-Identifizierung meiner Daten über die Vertrauensstelle beim Robert Koch-Institut und in die erneute Kontaktaufnahme durch meine behandelnde Ärztin oder meinen behandelnden Arzt",
+ )
+ )
+ )
+ return consent
}
-
- @Test
- fun consentOk() {
- assertThat(consentProcessor.toString()).isNotNull
- // prep gICS response
- doAnswer { getDummyBroadConsentBundle() }.whenever(gicsConsentService)
- .getConsent(any(), any(), eq(ConsentDomain.BROAD_CONSENT))
-
- doAnswer { Bundle() }.whenever(gicsConsentService)
- .getConsent(any(), any(), eq(ConsentDomain.MODELLVORHABEN_64E))
-
- val inputMtb = Mtb.builder()
- .patient(Patient.builder().id("d611d429-5003-11f0-a144-661e92ac9503").build()).build()
- val checkResult = consentProcessor.consentGatedCheckAndTryEmbedding(inputMtb)
-
- assertThat(checkResult).isTrue
- assertThat(inputMtb.metadata.researchConsents).isNotEmpty
+ }
+
+ @ParameterizedTest
+ @CsvSource(
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,PERMIT,expect permit",
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,PERMIT,expect permit date is exactly on start",
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2055-08-15T00:00:00+02:00,PERMIT,expect permit date is exactly on end",
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2021-08-15T00:00:00+02:00,NULL,date is before start",
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2060-08-15T00:00:00+02:00,NULL,date is after end",
+ "2.16.840.1.113883.3.1937.777.24.5.3.27,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,DENY,provision is denied",
+ "unknownCode,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,NULL,code does not exist - therefore expect NULL",
+ "2.16.840.1.113883.3.1937.777.24.5.3.8,XXXX,2025-08-15T00:00:00+02:00,NULL,system not found - therefore expect NULL",
+ )
+ fun getProvisionTypeByPolicyCode(
+ code: String?,
+ system: String?,
+ timeStamp: String,
+ expected: String?,
+ desc: String?,
+ ) {
+ val testData = getDummyBroadConsentBundle()
+
+ val requestDate = Date.from(OffsetDateTime.parse(timeStamp).toInstant())
+
+ val result: Consent.ConsentProvisionType =
+ consentProcessor.getProvisionTypeByPolicyCode(testData, code, system, requestDate)
+ assertThat(result).isNotNull()
+
+ assertThat(result).`as`(desc).isEqualTo(Consent.ConsentProvisionType.valueOf(expected!!))
+ }
+
+ @Test
+ fun getProvisionTypeOnEmptyConsent() {
+ val emptyResources = Bundle().addEntry(Bundle.BundleEntryComponent().setResource(Consent()))
+
+ val requestDate = Date.from(OffsetDateTime.parse("2025-08-15T00:00:00+02:00").toInstant())
+
+ val result: Consent.ConsentProvisionType =
+ consentProcessor.getProvisionTypeByPolicyCode(
+ emptyResources,
+ "anyCode",
+ "anySystem",
+ requestDate,
+ )
+ assertThat(result).isNotNull()
+
+ assertThat(result)
+ .`as`("empty consent resource - expect NULL")
+ .isEqualTo(Consent.ConsentProvisionType.NULL)
+ }
+
+ fun getDummyBroadConsentBundle(): Bundle {
+ val bundle: InputStream?
+ try {
+ bundle = ClassPathResource("fake_broadConsent_gics_response_permit.json").getInputStream()
+ } catch (e: IOException) {
+ throw RuntimeException(e)
}
- companion object {
- fun getDummyGenomDeConsent(): Consent {
- val consent = Consent()
- consent.id = "consent 1 id"
- consent.patient.reference = "Patient/1234-pat1"
-
- consent.provision.setType(
- Consent.ConsentProvisionType.fromCode(
- "deny"
- )
- )
- consent.provision.period.start =
- Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
- consent.provision.period.end =
- Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
-
- val addProvision1 = consent.provision.addProvision()
- addProvision1.setType(Consent.ConsentProvisionType.fromCode("permit"))
- addProvision1.period.start = Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
- addProvision1.period.end = Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
- addProvision1.code.addLast(
- CodeableConcept(
- Coding(
- "https://ths-greifswald.de/fhir/CodeSystem/gics/Policy/GenomDE_MV",
- "Teilnahme",
- "Teilnahme am Modellvorhaben und Einwilligung zur Genomsequenzierung"
- )
- )
- )
-
- val addProvision2 = consent.provision.addProvision()
- addProvision2.setType(Consent.ConsentProvisionType.fromCode("deny"))
- addProvision2.period.start = Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))
- addProvision2.period.end = Date.from(Instant.parse("3000-01-01T00:00:00.00Z"))
- addProvision2.code.addLast(
- CodeableConcept(
- Coding(
- "https://ths-greifswald.de/fhir/CodeSystem/gics/Policy/GenomDE_MV",
- "Rekontaktierung",
- "Re-Identifizierung meiner Daten über die Vertrauensstelle beim Robert Koch-Institut und in die erneute Kontaktaufnahme durch meine behandelnde Ärztin oder meinen behandelnden Arzt"
- )
- )
- )
- return consent
+ return FhirContext.forR4().newJsonParser().parseResource<Bundle>(Bundle::class.java, bundle)
+ }
+
+ @ParameterizedTest
+ @ValueSource(booleans = [true, false])
+ fun mvSubmissionTypeIsSet(isTestSubmission: Boolean) {
+ appConfigProperties.genomDeTestSubmission = isTestSubmission
+ val fixture =
+ ConsentProcessor(
+ appConfigProperties,
+ gIcsConfigProperties,
+ objectMapper,
+ fhirContext,
+ gicsConsentService,
+ )
+
+ doAnswer { getDummyBroadConsentBundle() }
+ .whenever(gicsConsentService)
+ .getConsent(any(), any(), eq(ConsentDomain.BROAD_CONSENT))
+
+ doAnswer {
+ Bundle().addEntry(Bundle.BundleEntryComponent().setResource(getDummyGenomDeConsent()))
}
+ .whenever(gicsConsentService)
+ .getConsent(any(), any(), eq(ConsentDomain.MODELLVORHABEN_64E))
+
+ val inputMtb =
+ Mtb.builder()
+ .patient(Patient.builder().id("d611d429-5003-11f0-a144-661e92ac9503").build())
+ .build()
+ val checkResult = fixture.consentGatedCheckAndTryEmbedding(inputMtb)
+ assertThat(checkResult).isNotNull
+
+ if (isTestSubmission) assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.TEST)
+ else {
+ assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.INITIAL)
}
-
- @ParameterizedTest
- @CsvSource(
- "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,PERMIT,expect permit",
- "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,PERMIT,expect permit date is exactly on start",
- "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2055-08-15T00:00:00+02:00,PERMIT,expect permit date is exactly on end",
- "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2021-08-15T00:00:00+02:00,NULL,date is before start",
- "2.16.840.1.113883.3.1937.777.24.5.3.8,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2060-08-15T00:00:00+02:00,NULL,date is after end",
- "2.16.840.1.113883.3.1937.777.24.5.3.27,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,DENY,provision is denied",
- "unknownCode,urn:oid:2.16.840.1.113883.3.1937.777.24.5.3,2025-08-15T00:00:00+02:00,NULL,code does not exist - therefore expect NULL",
- "2.16.840.1.113883.3.1937.777.24.5.3.8,XXXX,2025-08-15T00:00:00+02:00,NULL,system not found - therefore expect NULL",
- )
- fun getProvisionTypeByPolicyCode(
- code: String?, system: String?, timeStamp: String, expected: String?,
- desc: String?
- ) {
- val testData = getDummyBroadConsentBundle()
-
- val requestDate = Date.from(OffsetDateTime.parse(timeStamp).toInstant())
-
- val result: Consent.ConsentProvisionType =
- consentProcessor.getProvisionTypeByPolicyCode(testData, code, system, requestDate)
- assertThat(result).isNotNull()
-
-
- assertThat(result).`as`(desc)
- .isEqualTo(Consent.ConsentProvisionType.valueOf(expected!!))
- }
-
- @Test
- fun getProvisionTypeOnEmptyConsent(
- ) {
- val emptyResources = Bundle().addEntry(Bundle.BundleEntryComponent().setResource(Consent()))
-
- val requestDate = Date.from(OffsetDateTime.parse("2025-08-15T00:00:00+02:00").toInstant())
-
- val result: Consent.ConsentProvisionType =
- consentProcessor.getProvisionTypeByPolicyCode(
- emptyResources,
- "anyCode",
- "anySystem",
- requestDate
- )
- assertThat(result).isNotNull()
-
-
- assertThat(result).`as`("empty consent resource - expect NULL")
- .isEqualTo(Consent.ConsentProvisionType.NULL)
- }
-
- fun getDummyBroadConsentBundle(): Bundle {
- val bundle: InputStream?
- try {
- bundle = ClassPathResource(
- "fake_broadConsent_gics_response_permit.json"
- ).getInputStream()
- } catch (e: IOException) {
- throw RuntimeException(e)
- }
-
- return FhirContext.forR4().newJsonParser()
- .parseResource<Bundle>(Bundle::class.java, bundle)
- }
-
- @ParameterizedTest
- @ValueSource(booleans = [true, false])
- fun mvSubmissionTypeIsSet(isTestSubmission: Boolean) {
- appConfigProperties.genomDeTestSubmission = isTestSubmission
- val fixture =
- ConsentProcessor(
- appConfigProperties,
- gIcsConfigProperties,
- objectMapper,
- fhirContext,
- gicsConsentService
- )
-
- doAnswer { getDummyBroadConsentBundle() }.whenever(gicsConsentService)
- .getConsent(any(), any(), eq(ConsentDomain.BROAD_CONSENT))
-
- doAnswer {
- Bundle().addEntry(
- Bundle.BundleEntryComponent().setResource(getDummyGenomDeConsent())
- )
- }.whenever(gicsConsentService)
- .getConsent(any(), any(), eq(ConsentDomain.MODELLVORHABEN_64E))
-
- val inputMtb = Mtb.builder()
- .patient(Patient.builder().id("d611d429-5003-11f0-a144-661e92ac9503").build()).build()
- val checkResult = fixture.consentGatedCheckAndTryEmbedding(inputMtb)
- assertThat(checkResult).isNotNull
-
- if (isTestSubmission)
- assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.TEST)
- else {
- assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.INITIAL)
- }
-
- }
-
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/ReportServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/ReportServiceTest.kt
index fc95808..4308fed 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/ReportServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/ReportServiceTest.kt
@@ -32,17 +32,18 @@ import org.junit.jupiter.params.provider.Arguments
import org.junit.jupiter.params.provider.MethodSource
class ReportServiceTest {
-
private lateinit var reportService: ReportService
@BeforeEach
fun setup() {
- this.reportService = ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
+ this.reportService =
+ ReportService(ObjectMapper().registerModule(KotlinModule.Builder().build()))
}
@Test
fun shouldParseDataQualityReport() {
- val json = """
+ val json =
+ """
{
"patient": "4711",
"issues": [
@@ -52,7 +53,7 @@ class ReportServiceTest {
{ "severity": "fatal", "message": "Fatal Message" }
]
}
- """.trimIndent()
+ """.trimIndent()
val actual = this.reportService.deserialize(json)
@@ -71,7 +72,10 @@ class ReportServiceTest {
@ParameterizedTest
@MethodSource("testData")
- fun shouldParseDataQualityReport(json: String, requestStatus: RequestStatus) {
+ fun shouldParseDataQualityReport(
+ json: String,
+ requestStatus: RequestStatus,
+ ) {
val actual = this.reportService.deserialize(json)
assertThat(actual.asRequestStatus()).isEqualTo(requestStatus)
}
@@ -88,74 +92,71 @@ class ReportServiceTest {
}
companion object {
-
@JvmStatic
- fun testData(): Set<Arguments> {
- return setOf(
+ fun testData(): Set<Arguments> =
+ setOf(
Arguments.of(
"""
- {
- "patient": "4711",
- "issues": [
- { "severity": "info", "message": "Info Message" },
- { "severity": "warning", "message": "Warning Message" },
- { "severity": "error", "message": "Error Message" },
- { "severity": "fatal", "message": "Fatal Message" }
- ]
- }
+ {
+ "patient": "4711",
+ "issues": [
+ { "severity": "info", "message": "Info Message" },
+ { "severity": "warning", "message": "Warning Message" },
+ { "severity": "error", "message": "Error Message" },
+ { "severity": "fatal", "message": "Fatal Message" }
+ ]
+ }
""".trimIndent(),
- RequestStatus.ERROR
+ RequestStatus.ERROR,
),
Arguments.of(
"""
- {
- "patient": "4711",
- "issues": [
- { "severity": "info", "message": "Info Message" },
- { "severity": "warning", "message": "Warning Message" },
- { "severity": "error", "message": "Error Message" }
- ]
- }
+ {
+ "patient": "4711",
+ "issues": [
+ { "severity": "info", "message": "Info Message" },
+ { "severity": "warning", "message": "Warning Message" },
+ { "severity": "error", "message": "Error Message" }
+ ]
+ }
""".trimIndent(),
- RequestStatus.ERROR
+ RequestStatus.ERROR,
),
Arguments.of(
"""
- {
- "patient": "4711",
- "issues": [
- { "severity": "error", "message": "Error Message" }
- { "severity": "info", "message": "Info Message" }
- ]
- }
+ {
+ "patient": "4711",
+ "issues": [
+ { "severity": "error", "message": "Error Message" }
+ { "severity": "info", "message": "Info Message" }
+ ]
+ }
""".trimIndent(),
- RequestStatus.ERROR
+ RequestStatus.ERROR,
),
Arguments.of(
"""
- {
- "patient": "4711",
- "issues": [
- { "severity": "info", "message": "Info Message" },
- { "severity": "warning", "message": "Warning Message" }
- ]
- }
+ {
+ "patient": "4711",
+ "issues": [
+ { "severity": "info", "message": "Info Message" },
+ { "severity": "warning", "message": "Warning Message" }
+ ]
+ }
""".trimIndent(),
- RequestStatus.WARNING
+ RequestStatus.WARNING,
),
Arguments.of(
"""
- {
- "patient": "4711",
- "issues": [
- { "severity": "info", "message": "Info Message" }
- ]
- }
+ {
+ "patient": "4711",
+ "issues": [
+ { "severity": "info", "message": "Info Message" }
+ ]
+ }
""".trimIndent(),
- RequestStatus.SUCCESS
- )
+ RequestStatus.SUCCESS,
+ ),
)
- }
}
-
-} \ No newline at end of file
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/RequestProcessorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/RequestProcessorTest.kt
index 0a42b9b..4bd3fc1 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/RequestProcessorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/RequestProcessorTest.kt
@@ -35,6 +35,8 @@ import dev.dnpm.etl.processor.output.RestMtbFileSender
import dev.dnpm.etl.processor.pseudonym.PseudonymizeService
import dev.dnpm.etl.processor.randomRequestId
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -47,42 +49,40 @@ import org.mockito.kotlin.anyValueClass
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.whenever
import org.springframework.context.ApplicationEventPublisher
-import java.time.Instant
-import java.util.*
-
@ExtendWith(MockitoExtension::class)
class RequestProcessorTest {
- private lateinit var pseudonymizeService: PseudonymizeService
- private lateinit var transformationService: TransformationService
- private lateinit var sender: MtbFileSender
- private lateinit var requestService: RequestService
- private lateinit var applicationEventPublisher: ApplicationEventPublisher
- private lateinit var appConfigProperties: AppConfigProperties
- private lateinit var consentProcessor: ConsentProcessor
- private lateinit var requestProcessor: RequestProcessor
-
- @BeforeEach
- fun setup(
- @Mock pseudonymizeService: PseudonymizeService,
- @Mock transformationService: TransformationService,
- @Mock sender: RestMtbFileSender,
- @Mock requestService: RequestService,
- @Mock applicationEventPublisher: ApplicationEventPublisher,
- @Mock consentProcessor: ConsentProcessor
- ) {
- this.pseudonymizeService = pseudonymizeService
- this.transformationService = transformationService
- this.sender = sender
- this.requestService = requestService
- this.applicationEventPublisher = applicationEventPublisher
- this.appConfigProperties = AppConfigProperties()
- this.consentProcessor = consentProcessor
-
- val objectMapper = ObjectMapper()
-
- requestProcessor = RequestProcessor(
+ private lateinit var pseudonymizeService: PseudonymizeService
+ private lateinit var transformationService: TransformationService
+ private lateinit var sender: MtbFileSender
+ private lateinit var requestService: RequestService
+ private lateinit var applicationEventPublisher: ApplicationEventPublisher
+ private lateinit var appConfigProperties: AppConfigProperties
+ private lateinit var consentProcessor: ConsentProcessor
+ private lateinit var requestProcessor: RequestProcessor
+
+ @BeforeEach
+ fun setup(
+ @Mock pseudonymizeService: PseudonymizeService,
+ @Mock transformationService: TransformationService,
+ @Mock sender: RestMtbFileSender,
+ @Mock requestService: RequestService,
+ @Mock applicationEventPublisher: ApplicationEventPublisher,
+ @Mock consentProcessor: ConsentProcessor,
+ ) {
+ this.pseudonymizeService = pseudonymizeService
+ this.transformationService = transformationService
+ this.sender = sender
+ this.requestService = requestService
+ this.applicationEventPublisher = applicationEventPublisher
+ this.appConfigProperties = AppConfigProperties()
+ this.consentProcessor = consentProcessor
+
+ val objectMapper = ObjectMapper()
+
+ requestProcessor =
+ RequestProcessor(
pseudonymizeService,
transformationService,
sender,
@@ -90,224 +90,228 @@ class RequestProcessorTest {
objectMapper,
applicationEventPublisher,
appConfigProperties,
- consentProcessor
+ consentProcessor,
)
- }
-
- @Test
- fun testShouldSendMtbFileDuplicationAndSaveUnknownRequestStatusAtFirst() {
- doAnswer {
- Request(
- 1L,
- randomRequestId(),
- PatientPseudonym("TEST_12345678901"),
- PatientId("P1"),
- Fingerprint("6vkiti5bk6ikwifpajpt7cygmd3dvw54d6lwfhzlynb3pqtzferq"),
- RequestType.MTB_FILE,
- RequestStatus.SUCCESS,
- Instant.parse("2023-08-08T02:00:00Z")
- )
- }.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
-
- doAnswer {
- false
- }.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
-
- doAnswer {
- it.arguments[0] as String
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- it.arguments[0]
- }.whenever(transformationService).transform(any<Mtb>())
-
- whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
-
- val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
+ }
+
+ @Test
+ fun testShouldSendMtbFileDuplicationAndSaveUnknownRequestStatusAtFirst() {
+ doAnswer {
+ Request(
+ 1L,
+ randomRequestId(),
+ PatientPseudonym("TEST_12345678901"),
+ PatientId("P1"),
+ Fingerprint("6vkiti5bk6ikwifpajpt7cygmd3dvw54d6lwfhzlynb3pqtzferq"),
+ RequestType.MTB_FILE,
+ RequestStatus.SUCCESS,
+ Instant.parse("2023-08-08T02:00:00Z"),
+ )
+ }
+ .whenever(requestService)
+ .lastMtbFileRequestForPatientPseudonym(anyValueClass())
+
+ doAnswer { false }
+ .whenever(requestService)
+ .isLastRequestWithKnownStatusDeletion(anyValueClass())
+
+ doAnswer { it.arguments[0] as String }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { it.arguments[0] }.whenever(transformationService).transform(any<Mtb>())
+
+ whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
+
+ val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
.episodesOfCare(
listOf(
MtbEpisodeOfCare.builder()
.id("1")
.patient(Reference.builder().id("123").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()
- this.requestProcessor.processMtbFile(mtbFile)
-
- val requestCaptor = argumentCaptor<Request>()
- verify(requestService, times(1)).save(requestCaptor.capture())
- assertThat(requestCaptor.firstValue).isNotNull
- assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.UNKNOWN)
- }
-
- @Test
- fun testShouldDetectMtbFileDuplicationAndSendDuplicationEvent() {
- doAnswer {
- Request(
- 1L,
- randomRequestId(),
- PatientPseudonym("TEST_12345678901"),
- PatientId("P1"),
- Fingerprint("4gcjwtjjtcczybsljxepdfpkaeusvd7g3vogfqpmphyffyzfx7dq"),
- RequestType.MTB_FILE,
- RequestStatus.SUCCESS,
- Instant.parse("2023-08-08T02:00:00Z")
- )
- }.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
-
- doAnswer {
- false
- }.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
-
- doAnswer {
- it.arguments[0] as String
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- it.arguments[0]
- }.whenever(transformationService).transform(any<Mtb>())
-
- whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
-
- val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
+ this.requestProcessor.processMtbFile(mtbFile)
+
+ val requestCaptor = argumentCaptor<Request>()
+ verify(requestService, times(1)).save(requestCaptor.capture())
+ assertThat(requestCaptor.firstValue).isNotNull
+ assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.UNKNOWN)
+ }
+
+ @Test
+ fun testShouldDetectMtbFileDuplicationAndSendDuplicationEvent() {
+ doAnswer {
+ Request(
+ 1L,
+ randomRequestId(),
+ PatientPseudonym("TEST_12345678901"),
+ PatientId("P1"),
+ Fingerprint("4gcjwtjjtcczybsljxepdfpkaeusvd7g3vogfqpmphyffyzfx7dq"),
+ RequestType.MTB_FILE,
+ RequestStatus.SUCCESS,
+ Instant.parse("2023-08-08T02:00:00Z"),
+ )
+ }
+ .whenever(requestService)
+ .lastMtbFileRequestForPatientPseudonym(anyValueClass())
+
+ doAnswer { false }
+ .whenever(requestService)
+ .isLastRequestWithKnownStatusDeletion(anyValueClass())
+
+ doAnswer { it.arguments[0] as String }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { it.arguments[0] }.whenever(transformationService).transform(any<Mtb>())
+
+ whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
+
+ val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
.episodesOfCare(
listOf(
MtbEpisodeOfCare.builder()
.id("1")
.patient(Reference.builder().id("123").build())
- .period(PeriodDate.builder().start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z"))).build())
+ .period(
+ PeriodDate.builder()
+ .start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z")))
+ .build()
+ )
.build()
)
)
.build()
- this.requestProcessor.processMtbFile(mtbFile)
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.DUPLICATION)
- }
-
- @Test
- fun testShouldSendMtbFileAndSendSuccessEvent() {
- doAnswer {
- Request(
- 1L,
- randomRequestId(),
- PatientPseudonym("TEST_12345678901"),
- PatientId("P1"),
- Fingerprint("different"),
- RequestType.MTB_FILE,
- RequestStatus.SUCCESS,
- Instant.parse("2023-08-08T02:00:00Z")
- )
- }.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
-
- doAnswer {
- false
- }.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.SUCCESS)
- }.whenever(sender).send(any<DnpmV2MtbFileRequest>())
-
- doAnswer {
- it.arguments[0] as String
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- it.arguments[0]
- }.whenever(transformationService).transform(any<Mtb>())
-
- whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
-
- val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
+ this.requestProcessor.processMtbFile(mtbFile)
+
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.DUPLICATION)
+ }
+
+ @Test
+ fun testShouldSendMtbFileAndSendSuccessEvent() {
+ doAnswer {
+ Request(
+ 1L,
+ randomRequestId(),
+ PatientPseudonym("TEST_12345678901"),
+ PatientId("P1"),
+ Fingerprint("different"),
+ RequestType.MTB_FILE,
+ RequestStatus.SUCCESS,
+ Instant.parse("2023-08-08T02:00:00Z"),
+ )
+ }
+ .whenever(requestService)
+ .lastMtbFileRequestForPatientPseudonym(anyValueClass())
+
+ doAnswer { false }
+ .whenever(requestService)
+ .isLastRequestWithKnownStatusDeletion(anyValueClass())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.SUCCESS) }
+ .whenever(sender)
+ .send(any<DnpmV2MtbFileRequest>())
+
+ doAnswer { it.arguments[0] as String }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { it.arguments[0] }.whenever(transformationService).transform(any<Mtb>())
+
+ whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
+
+ val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
.episodesOfCare(
listOf(
MtbEpisodeOfCare.builder()
.id("1")
.patient(Reference.builder().id("123").build())
- .period(PeriodDate.builder().start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z"))).build())
+ .period(
+ PeriodDate.builder()
+ .start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z")))
+ .build()
+ )
.build()
)
)
.build()
- this.requestProcessor.processMtbFile(mtbFile)
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
- }
-
- @Test
- fun testShouldSendMtbFileAndSendErrorEvent() {
- doAnswer {
- Request(
- 1L,
- randomRequestId(),
- PatientPseudonym("TEST_12345678901"),
- PatientId("P1"),
- Fingerprint("different"),
- RequestType.MTB_FILE,
- RequestStatus.SUCCESS,
- Instant.parse("2023-08-08T02:00:00Z")
- )
- }.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
-
- doAnswer {
- false
- }.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.ERROR)
- }.whenever(sender).send(any<DnpmV2MtbFileRequest>())
-
- doAnswer {
- it.arguments[0] as String
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- it.arguments[0]
- }.whenever(transformationService).transform(any<Mtb>())
-
- whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
-
- val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
+ this.requestProcessor.processMtbFile(mtbFile)
+
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
+ }
+
+ @Test
+ fun testShouldSendMtbFileAndSendErrorEvent() {
+ doAnswer {
+ Request(
+ 1L,
+ randomRequestId(),
+ PatientPseudonym("TEST_12345678901"),
+ PatientId("P1"),
+ Fingerprint("different"),
+ RequestType.MTB_FILE,
+ RequestStatus.SUCCESS,
+ Instant.parse("2023-08-08T02:00:00Z"),
+ )
+ }
+ .whenever(requestService)
+ .lastMtbFileRequestForPatientPseudonym(anyValueClass())
+
+ doAnswer { false }
+ .whenever(requestService)
+ .isLastRequestWithKnownStatusDeletion(anyValueClass())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.ERROR) }
+ .whenever(sender)
+ .send(any<DnpmV2MtbFileRequest>())
+
+ doAnswer { it.arguments[0] as String }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { it.arguments[0] }.whenever(transformationService).transform(any<Mtb>())
+
+ whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
+
+ val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
.metadata(
- MvhMetadata
- .builder()
+ MvhMetadata.builder()
.modelProjectConsent(
- ModelProjectConsent
- .builder()
+ ModelProjectConsent.builder()
.provisions(
- listOf(Provision.builder().type(ConsentProvision.PERMIT).purpose(ModelProjectConsentPurpose.SEQUENCING).build())
- ).build()
+ listOf(
+ Provision.builder()
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .build()
+ )
+ )
+ .build()
)
.build()
)
@@ -316,143 +320,139 @@ class RequestProcessorTest {
MtbEpisodeOfCare.builder()
.id("1")
.patient(Reference.builder().id("123").build())
- .period(PeriodDate.builder().start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z"))).build())
+ .period(
+ PeriodDate.builder()
+ .start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z")))
+ .build()
+ )
.build()
)
)
.build()
- this.requestProcessor.processMtbFile(mtbFile)
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
- }
-
- @Test
- fun testShouldSendDeleteRequestAndSaveUnknownRequestStatusAtFirst() {
- doAnswer {
- "PSEUDONYM"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.UNKNOWN)
- }.whenever(sender).send(any<DeleteRequest>())
-
- this.requestProcessor.processDeletion(
- TEST_PATIENT_ID,
- isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
-
- val requestCaptor = argumentCaptor<Request>()
- verify(requestService, times(1)).save(requestCaptor.capture())
- assertThat(requestCaptor.firstValue).isNotNull
- assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.UNKNOWN)
- }
-
- @Test
- fun testShouldSendDeleteRequestAndSendSuccessEvent() {
- doAnswer {
- "PSEUDONYM"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.SUCCESS)
- }.whenever(sender).send(any<DeleteRequest>())
-
- this.requestProcessor.processDeletion(
- TEST_PATIENT_ID,
- isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
- }
-
- @Test
- fun testShouldSendDeleteRequestAndSendErrorEvent() {
- doAnswer {
- "PSEUDONYM"
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.ERROR)
- }.whenever(sender).send(any<DeleteRequest>())
-
- this.requestProcessor.processDeletion(
- TEST_PATIENT_ID,
- isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
- }
-
- @Test
- fun testShouldSendDeleteRequestWithPseudonymErrorAndSaveErrorRequestStatus() {
- doThrow(RuntimeException()).whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- this.requestProcessor.processDeletion(
- TEST_PATIENT_ID,
- isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE
- )
-
- val requestCaptor = argumentCaptor<Request>()
- verify(requestService, times(1)).save(requestCaptor.capture())
- assertThat(requestCaptor.firstValue).isNotNull
- assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
- }
-
- @Test
- fun testShouldNotDetectMtbFileDuplicationIfDuplicationNotConfigured() {
- this.appConfigProperties.duplicationDetection = false
-
- doAnswer {
- it.arguments[0] as String
- }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
-
- doAnswer {
- it.arguments[0]
- }.whenever(transformationService).transform(any<Mtb>())
-
- doAnswer {
- MtbFileSender.Response(status = RequestStatus.SUCCESS)
- }.whenever(sender).send(any<DnpmV2MtbFileRequest>())
-
- whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
-
- val mtbFile = Mtb.builder()
- .patient(
- Patient.builder()
- .id("123")
- .build()
- )
+ this.requestProcessor.processMtbFile(mtbFile)
+
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
+ }
+
+ @Test
+ fun testShouldSendDeleteRequestAndSaveUnknownRequestStatusAtFirst() {
+ doAnswer { "PSEUDONYM" }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.UNKNOWN) }
+ .whenever(sender)
+ .send(any<DeleteRequest>())
+
+ this.requestProcessor.processDeletion(
+ TEST_PATIENT_ID,
+ isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ )
+
+ val requestCaptor = argumentCaptor<Request>()
+ verify(requestService, times(1)).save(requestCaptor.capture())
+ assertThat(requestCaptor.firstValue).isNotNull
+ assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.UNKNOWN)
+ }
+
+ @Test
+ fun testShouldSendDeleteRequestAndSendSuccessEvent() {
+ doAnswer { "PSEUDONYM" }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.SUCCESS) }
+ .whenever(sender)
+ .send(any<DeleteRequest>())
+
+ this.requestProcessor.processDeletion(
+ TEST_PATIENT_ID,
+ isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ )
+
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
+ }
+
+ @Test
+ fun testShouldSendDeleteRequestAndSendErrorEvent() {
+ doAnswer { "PSEUDONYM" }.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.ERROR) }
+ .whenever(sender)
+ .send(any<DeleteRequest>())
+
+ this.requestProcessor.processDeletion(
+ TEST_PATIENT_ID,
+ isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ )
+
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
+ }
+
+ @Test
+ fun testShouldSendDeleteRequestWithPseudonymErrorAndSaveErrorRequestStatus() {
+ doThrow(RuntimeException()).whenever(pseudonymizeService).patientPseudonym(anyValueClass())
+
+ this.requestProcessor.processDeletion(
+ TEST_PATIENT_ID,
+ isConsented = TtpConsentStatus.UNKNOWN_CHECK_FILE,
+ )
+
+ val requestCaptor = argumentCaptor<Request>()
+ verify(requestService, times(1)).save(requestCaptor.capture())
+ assertThat(requestCaptor.firstValue).isNotNull
+ assertThat(requestCaptor.firstValue.status).isEqualTo(RequestStatus.ERROR)
+ }
+
+ @Test
+ fun testShouldNotDetectMtbFileDuplicationIfDuplicationNotConfigured() {
+ this.appConfigProperties.duplicationDetection = false
+
+ doAnswer { it.arguments[0] as String }
+ .whenever(pseudonymizeService)
+ .patientPseudonym(anyValueClass())
+
+ doAnswer { it.arguments[0] }.whenever(transformationService).transform(any<Mtb>())
+
+ doAnswer { MtbFileSender.Response(status = RequestStatus.SUCCESS) }
+ .whenever(sender)
+ .send(any<DnpmV2MtbFileRequest>())
+
+ whenever(consentProcessor.consentGatedCheckAndTryEmbedding(any())).thenReturn(true)
+
+ val mtbFile =
+ Mtb.builder()
+ .patient(Patient.builder().id("123").build())
.episodesOfCare(
listOf(
MtbEpisodeOfCare.builder()
.id("1")
.patient(Reference.builder().id("123").build())
- .period(PeriodDate.builder().start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z"))).build())
+ .period(
+ PeriodDate.builder()
+ .start(Date.from(Instant.parse("2021-01-01T00:00:00.00Z")))
+ .build()
+ )
.build()
)
)
.build()
- this.requestProcessor.processMtbFile(mtbFile)
-
- val eventCaptor = argumentCaptor<ResponseEvent>()
- verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
- assertThat(eventCaptor.firstValue).isNotNull
- assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
- }
+ this.requestProcessor.processMtbFile(mtbFile)
- companion object {
- val TEST_PATIENT_ID = PatientId("TEST_12345678901")
- }
+ val eventCaptor = argumentCaptor<ResponseEvent>()
+ verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
+ assertThat(eventCaptor.firstValue).isNotNull
+ assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
+ }
+ companion object {
+ val TEST_PATIENT_ID = PatientId("TEST_12345678901")
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/RequestServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/RequestServiceTest.kt
index c0e4400..bc0286c 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/RequestServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/RequestServiceTest.kt
@@ -24,6 +24,7 @@ import dev.dnpm.etl.processor.monitoring.Request
import dev.dnpm.etl.processor.monitoring.RequestRepository
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.dnpm.etl.processor.monitoring.RequestType
+import java.time.Instant
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -33,37 +34,37 @@ import org.mockito.Mockito.*
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.anyValueClass
import org.mockito.kotlin.whenever
-import java.time.Instant
@ExtendWith(MockitoExtension::class)
class RequestServiceTest {
- private lateinit var requestRepository: RequestRepository
-
- private lateinit var requestService: RequestService
-
- private fun anyRequest() = any(Request::class.java) ?: Request(
- 0L,
- randomRequestId(),
- PatientPseudonym("TEST_dummy"),
- PatientId("PX"),
- Fingerprint("dummy"),
- RequestType.MTB_FILE,
- RequestStatus.SUCCESS,
- Instant.parse("2023-08-08T02:00:00Z")
- )
-
- @BeforeEach
- fun setup(
- @Mock requestRepository: RequestRepository
- ) {
- this.requestRepository = requestRepository
- this.requestService = RequestService(requestRepository)
- }
-
- @Test
- fun shouldIndicateLastRequestIsDeleteRequest() {
- val requests = listOf(
+ private lateinit var requestRepository: RequestRepository
+
+ private lateinit var requestService: RequestService
+
+ private fun anyRequest() =
+ any(Request::class.java)
+ ?: Request(
+ 0L,
+ randomRequestId(),
+ PatientPseudonym("TEST_dummy"),
+ PatientId("PX"),
+ Fingerprint("dummy"),
+ RequestType.MTB_FILE,
+ RequestStatus.SUCCESS,
+ Instant.parse("2023-08-08T02:00:00Z"),
+ )
+
+ @BeforeEach
+ fun setup(@Mock requestRepository: RequestRepository) {
+ this.requestRepository = requestRepository
+ this.requestService = RequestService(requestRepository)
+ }
+
+ @Test
+ fun shouldIndicateLastRequestIsDeleteRequest() {
+ val requests =
+ listOf(
Request(
1L,
randomRequestId(),
@@ -72,7 +73,7 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.MTB_FILE,
RequestStatus.WARNING,
- Instant.parse("2023-07-07T00:00:00Z")
+ Instant.parse("2023-07-07T00:00:00Z"),
),
Request(
2L,
@@ -82,7 +83,7 @@ class RequestServiceTest {
Fingerprint("0123456789abcdefd"),
RequestType.DELETE,
RequestStatus.WARNING,
- Instant.parse("2023-07-07T02:00:00Z")
+ Instant.parse("2023-07-07T02:00:00Z"),
),
Request(
3L,
@@ -92,18 +93,19 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.MTB_FILE,
RequestStatus.UNKNOWN,
- Instant.parse("2023-08-11T00:00:00Z")
- )
+ Instant.parse("2023-08-11T00:00:00Z"),
+ ),
)
- val actual = RequestService.isLastRequestWithKnownStatusDeletion(requests)
+ val actual = RequestService.isLastRequestWithKnownStatusDeletion(requests)
- assertThat(actual).isTrue()
- }
+ assertThat(actual).isTrue()
+ }
- @Test
- fun shouldIndicateLastRequestIsNotDeleteRequest() {
- val requests = listOf(
+ @Test
+ fun shouldIndicateLastRequestIsNotDeleteRequest() {
+ val requests =
+ listOf(
Request(
1L,
randomRequestId(),
@@ -112,7 +114,7 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.MTB_FILE,
RequestStatus.WARNING,
- Instant.parse("2023-07-07T00:00:00Z")
+ Instant.parse("2023-07-07T00:00:00Z"),
),
Request(
2L,
@@ -122,7 +124,7 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.MTB_FILE,
RequestStatus.WARNING,
- Instant.parse("2023-07-07T02:00:00Z")
+ Instant.parse("2023-07-07T02:00:00Z"),
),
Request(
3L,
@@ -132,18 +134,19 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.MTB_FILE,
RequestStatus.UNKNOWN,
- Instant.parse("2023-08-11T00:00:00Z")
- )
+ Instant.parse("2023-08-11T00:00:00Z"),
+ ),
)
- val actual = RequestService.isLastRequestWithKnownStatusDeletion(requests)
+ val actual = RequestService.isLastRequestWithKnownStatusDeletion(requests)
- assertThat(actual).isFalse()
- }
+ assertThat(actual).isFalse()
+ }
- @Test
- fun shouldReturnPatientsLastRequest() {
- val requests = listOf(
+ @Test
+ fun shouldReturnPatientsLastRequest() {
+ val requests =
+ listOf(
Request(
1L,
randomRequestId(),
@@ -152,7 +155,7 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef1"),
RequestType.DELETE,
RequestStatus.SUCCESS,
- Instant.parse("2023-07-07T02:00:00Z")
+ Instant.parse("2023-07-07T02:00:00Z"),
),
Request(
1L,
@@ -162,66 +165,71 @@ class RequestServiceTest {
Fingerprint("0123456789abcdef2"),
RequestType.MTB_FILE,
RequestStatus.WARNING,
- Instant.parse("2023-08-08T00:00:00Z")
- )
+ Instant.parse("2023-08-08T00:00:00Z"),
+ ),
)
- val actual = RequestService.lastMtbFileRequestForPatientPseudonym(requests)
+ val actual = RequestService.lastMtbFileRequestForPatientPseudonym(requests)
- assertThat(actual).isInstanceOf(Request::class.java)
- assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef2"))
- }
+ assertThat(actual).isInstanceOf(Request::class.java)
+ assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef2"))
+ }
- @Test
- fun shouldReturnNullIfNoRequests() {
- val requests = listOf<Request>()
+ @Test
+ fun shouldReturnNullIfNoRequests() {
+ val requests = listOf<Request>()
- val actual = RequestService.lastMtbFileRequestForPatientPseudonym(requests)
+ val actual = RequestService.lastMtbFileRequestForPatientPseudonym(requests)
- assertThat(actual).isNull()
- }
+ assertThat(actual).isNull()
+ }
- @Test
- fun saveShouldSaveRequestUsingRepository() {
- doAnswer {
- val obj = it.arguments[0] as Request
- obj.copy(id = 1L)
- }.whenever(requestRepository).save(anyRequest())
+ @Test
+ fun saveShouldSaveRequestUsingRepository() {
+ doAnswer {
+ val obj = it.arguments[0] as Request
+ obj.copy(id = 1L)
+ }
+ .whenever(requestRepository)
+ .save(anyRequest())
- val request = Request(
+ val request =
+ Request(
randomRequestId(),
PatientPseudonym("TEST_12345678901"),
PatientId("P1"),
Fingerprint("0123456789abcdef1"),
RequestType.DELETE,
RequestStatus.SUCCESS,
- Instant.parse("2023-07-07T02:00:00Z")
+ Instant.parse("2023-07-07T02:00:00Z"),
)
- requestService.save(request)
-
- verify(requestRepository, times(1)).save(anyRequest())
- }
+ requestService.save(request)
- @Test
- fun allRequestsByPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
- requestService.allRequestsByPatientPseudonym(PatientPseudonym("TEST_12345678901"))
+ verify(requestRepository, times(1)).save(anyRequest())
+ }
- verify(requestRepository, times(1)).findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
- }
+ @Test
+ fun allRequestsByPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
+ requestService.allRequestsByPatientPseudonym(PatientPseudonym("TEST_12345678901"))
- @Test
- fun lastMtbFileRequestForPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
- requestService.lastMtbFileRequestForPatientPseudonym(PatientPseudonym("TEST_12345678901"))
+ verify(requestRepository, times(1))
+ .findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
+ }
- verify(requestRepository, times(1)).findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
- }
+ @Test
+ fun lastMtbFileRequestForPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
+ requestService.lastMtbFileRequestForPatientPseudonym(PatientPseudonym("TEST_12345678901"))
- @Test
- fun isLastRequestDeletionShouldRequestAllRequestsForPatientPseudonym() {
- requestService.isLastRequestWithKnownStatusDeletion(PatientPseudonym("TEST_12345678901"))
+ verify(requestRepository, times(1))
+ .findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
+ }
- verify(requestRepository, times(1)).findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
- }
+ @Test
+ fun isLastRequestDeletionShouldRequestAllRequestsForPatientPseudonym() {
+ requestService.isLastRequestWithKnownStatusDeletion(PatientPseudonym("TEST_12345678901"))
-} \ No newline at end of file
+ verify(requestRepository, times(1))
+ .findAllByPatientPseudonymOrderByProcessedAtDesc(anyValueClass())
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/ResponseProcessorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/ResponseProcessorTest.kt
index 465d8b8..16a5791 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/ResponseProcessorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/ResponseProcessorTest.kt
@@ -23,6 +23,8 @@ import dev.dnpm.etl.processor.*
import dev.dnpm.etl.processor.monitoring.Request
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.dnpm.etl.processor.monitoring.RequestType
+import java.time.Instant
+import java.util.*
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
@@ -33,105 +35,92 @@ import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.*
import reactor.core.publisher.Sinks
-import java.time.Instant
-import java.util.*
@ExtendWith(MockitoExtension::class)
class ResponseProcessorTest {
- private lateinit var requestService: RequestService
- private lateinit var statisticsUpdateProducer: Sinks.Many<Any>
-
- private lateinit var responseProcessor: ResponseProcessor
-
- private val testRequest = Request(
- 1L,
- RequestId("TestID1234"),
- PatientPseudonym("PSEUDONYM-A"),
- PatientId("1"),
- Fingerprint("dummyfingerprint"),
- RequestType.MTB_FILE,
- RequestStatus.UNKNOWN
- )
-
- @BeforeEach
- fun setup(
- @Mock requestService: RequestService,
- @Mock statisticsUpdateProducer: Sinks.Many<Any>
- ) {
- this.requestService = requestService
- this.statisticsUpdateProducer = statisticsUpdateProducer
-
- this.responseProcessor = ResponseProcessor(requestService, statisticsUpdateProducer)
- }
+ private lateinit var requestService: RequestService
+ private lateinit var statisticsUpdateProducer: Sinks.Many<Any>
- @Test
- fun shouldNotSaveStatusForUnknownRequest() {
- doAnswer {
- Optional.empty<Request>()
- }.whenever(requestService).findByUuid(anyValueClass())
+ private lateinit var responseProcessor: ResponseProcessor
- val event = ResponseEvent(
- RequestId("TestID1234"),
- Instant.parse("2023-09-09T00:00:00Z"),
- RequestStatus.SUCCESS
- )
+ private val testRequest =
+ Request(
+ 1L,
+ RequestId("TestID1234"),
+ PatientPseudonym("PSEUDONYM-A"),
+ PatientId("1"),
+ Fingerprint("dummyfingerprint"),
+ RequestType.MTB_FILE,
+ RequestStatus.UNKNOWN,
+ )
- this.responseProcessor.handleResponseEvent(event)
+ @BeforeEach
+ fun setup(@Mock requestService: RequestService, @Mock statisticsUpdateProducer: Sinks.Many<Any>) {
+ this.requestService = requestService
+ this.statisticsUpdateProducer = statisticsUpdateProducer
- verify(requestService, never()).save(any())
- }
+ this.responseProcessor = ResponseProcessor(requestService, statisticsUpdateProducer)
+ }
- @Test
- fun shouldNotSaveStatusWithUnknownState() {
- doAnswer {
- Optional.of(testRequest)
- }.whenever(requestService).findByUuid(anyValueClass())
+ @Test
+ fun shouldNotSaveStatusForUnknownRequest() {
+ doAnswer { Optional.empty<Request>() }.whenever(requestService).findByUuid(anyValueClass())
- val event = ResponseEvent(
+ val event =
+ ResponseEvent(
RequestId("TestID1234"),
Instant.parse("2023-09-09T00:00:00Z"),
- RequestStatus.UNKNOWN
+ RequestStatus.SUCCESS,
)
- this.responseProcessor.handleResponseEvent(event)
+ this.responseProcessor.handleResponseEvent(event)
- verify(requestService, never()).save(any<Request>())
- }
+ verify(requestService, never()).save(any())
+ }
- @ParameterizedTest
- @MethodSource("requestStatusSource")
- fun shouldSaveStatusForKnownRequest(requestStatus: RequestStatus) {
- doAnswer {
- Optional.of(testRequest)
- }.whenever(requestService).findByUuid(anyValueClass())
+ @Test
+ fun shouldNotSaveStatusWithUnknownState() {
+ doAnswer { Optional.of(testRequest) }.whenever(requestService).findByUuid(anyValueClass())
- val event = ResponseEvent(
+ val event =
+ ResponseEvent(
RequestId("TestID1234"),
Instant.parse("2023-09-09T00:00:00Z"),
- requestStatus
+ RequestStatus.UNKNOWN,
)
- this.responseProcessor.handleResponseEvent(event)
+ this.responseProcessor.handleResponseEvent(event)
- val captor = argumentCaptor<Request>()
- verify(requestService, times(1)).save(captor.capture())
- assertThat(captor.firstValue).isNotNull
- assertThat(captor.firstValue.status).isEqualTo(requestStatus)
- }
+ verify(requestService, never()).save(any<Request>())
+ }
- companion object {
+ @ParameterizedTest
+ @MethodSource("requestStatusSource")
+ fun shouldSaveStatusForKnownRequest(requestStatus: RequestStatus) {
+ doAnswer { Optional.of(testRequest) }.whenever(requestService).findByUuid(anyValueClass())
- @JvmStatic
- fun requestStatusSource(): Set<RequestStatus> {
- return setOf(
- RequestStatus.SUCCESS,
- RequestStatus.WARNING,
- RequestStatus.ERROR,
- RequestStatus.DUPLICATION
- )
- }
+ val event =
+ ResponseEvent(RequestId("TestID1234"), Instant.parse("2023-09-09T00:00:00Z"), requestStatus)
- }
+ this.responseProcessor.handleResponseEvent(event)
-} \ No newline at end of file
+ val captor = argumentCaptor<Request>()
+ verify(requestService, times(1)).save(captor.capture())
+ assertThat(captor.firstValue).isNotNull
+ assertThat(captor.firstValue.status).isEqualTo(requestStatus)
+ }
+
+ companion object {
+
+ @JvmStatic
+ fun requestStatusSource(): Set<RequestStatus> {
+ return setOf(
+ RequestStatus.SUCCESS,
+ RequestStatus.WARNING,
+ RequestStatus.ERROR,
+ RequestStatus.DUPLICATION,
+ )
+ }
+ }
+}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/TransformationServiceTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/TransformationServiceTest.kt
index ba9d23f..c6438e8 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/TransformationServiceTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/TransformationServiceTest.kt
@@ -21,106 +21,139 @@ package dev.dnpm.etl.processor.services
import dev.dnpm.etl.processor.config.JacksonConfig
import dev.pcvolkmer.mv64e.mtb.*
+import java.time.Instant
+import java.util.Date
import org.assertj.core.api.Assertions.assertThat
+import org.hl7.fhir.instance.model.api.IBaseResource
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
-import org.hl7.fhir.instance.model.api.IBaseResource
-import java.time.Instant
-import java.util.Date
class TransformationServiceTest {
- private lateinit var service: TransformationService
+ private lateinit var service: TransformationService
- @BeforeEach
- fun setup() {
- this.service = TransformationService(
- JacksonConfig().objectMapper(), listOf(
+ @BeforeEach
+ fun setup() {
+ this.service =
+ TransformationService(
+ JacksonConfig().objectMapper(),
+ listOf(
Transformation.of("diagnoses[*].code.version") from "2013" to "2014",
- )
+ ),
)
- }
-
- @Test
- fun shouldTransformMtbFile() {
- val mtbFile = Mtb.builder().diagnoses(
- listOf(
- MtbDiagnosis.builder().id("1234").code(Coding.builder().code("F79.9").version("2013").build()).build()
+ }
+
+ @Test
+ fun shouldTransformMtbFile() {
+ val mtbFile =
+ Mtb.builder()
+ .diagnoses(
+ listOf(
+ MtbDiagnosis.builder()
+ .id("1234")
+ .code(Coding.builder().code("F79.9").version("2013").build())
+ .build()
+ )
)
- ).build()
-
- val actual = this.service.transform(mtbFile)
-
- assertThat(actual).isNotNull
- assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
- }
-
- @Test
- fun shouldOnlyTransformGivenValues() {
- val mtbFile = Mtb.builder().diagnoses(
- listOf(
- MtbDiagnosis.builder().id("1234").code(Coding.builder().code("F79.9").version("2013").build()).build(),
- MtbDiagnosis.builder().id("1234").code(Coding.builder().code("F79.8").version("2019").build()).build()
+ .build()
+
+ val actual = this.service.transform(mtbFile)
+
+ assertThat(actual).isNotNull
+ assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
+ }
+
+ @Test
+ fun shouldOnlyTransformGivenValues() {
+ val mtbFile =
+ Mtb.builder()
+ .diagnoses(
+ listOf(
+ MtbDiagnosis.builder()
+ .id("1234")
+ .code(Coding.builder().code("F79.9").version("2013").build())
+ .build(),
+ MtbDiagnosis.builder()
+ .id("1234")
+ .code(Coding.builder().code("F79.8").version("2019").build())
+ .build(),
+ )
)
- ).build()
-
- val actual = this.service.transform(mtbFile)
+ .build()
+
+ val actual = this.service.transform(mtbFile)
+
+ assertThat(actual).isNotNull
+ assertThat(actual.diagnoses[0].code.code).isEqualTo("F79.9")
+ assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
+ assertThat(actual.diagnoses[1].code.code).isEqualTo("F79.8")
+ assertThat(actual.diagnoses[1].code.version).isEqualTo("2019")
+ }
+
+ @Test
+ fun shouldTransformConsentValues() {
+ val mtbFile =
+ Mtb.builder()
+ .diagnoses(
+ listOf(
+ MtbDiagnosis.builder()
+ .id("1234")
+ .code(Coding.builder().code("F79.9").version("2013").build())
+ .build(),
+ MtbDiagnosis.builder()
+ .id("1234")
+ .code(Coding.builder().code("F79.8").version("2019").build())
+ .build(),
+ )
+ )
+ .build()
+
+ val actual = this.service.transform(mtbFile)
+
+ assertThat(actual).isNotNull
+ assertThat(actual.diagnoses[0].code.code).isEqualTo("F79.9")
+ assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
+ assertThat(actual.diagnoses[1].code.code).isEqualTo("F79.8")
+ assertThat(actual.diagnoses[1].code.version).isEqualTo("2019")
+ }
+
+ @Test
+ fun shouldTransformConsent() {
+ val mvhMetadata = MvhMetadata.builder().transferTan("transfertan12345").build()
+
+ assertThat(mvhMetadata).isNotNull
+ mvhMetadata.modelProjectConsent =
+ ModelProjectConsent.builder()
+ .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z")))
+ .version("1")
+ .provisions(
+ listOf(
+ Provision.builder()
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.SEQUENCING)
+ .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z")))
+ .build(),
+ Provision.builder()
+ .type(ConsentProvision.PERMIT)
+ .purpose(ModelProjectConsentPurpose.REIDENTIFICATION)
+ .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z")))
+ .build(),
+ Provision.builder()
+ .type(ConsentProvision.DENY)
+ .purpose(ModelProjectConsentPurpose.CASE_IDENTIFICATION)
+ .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z")))
+ .build(),
+ )
+ )
+ .build()
+ val consent = ConsentProcessorTest.getDummyGenomDeConsent()
- assertThat(actual).isNotNull
- assertThat(actual.diagnoses[0].code.code).isEqualTo("F79.9")
- assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
- assertThat(actual.diagnoses[1].code.code).isEqualTo("F79.8")
- assertThat(actual.diagnoses[1].code.version).isEqualTo("2019")
- }
+ mvhMetadata.researchConsents = mutableListOf()
+ mvhMetadata.researchConsents.add(mapOf(consent.id to consent as IBaseResource))
- @Test
- fun shouldTransformConsentValues() {
- val mtbFile = Mtb.builder().diagnoses(
- listOf(
- MtbDiagnosis.builder().id("1234").code(Coding.builder().code("F79.9").version("2013").build()).build(),
- MtbDiagnosis.builder().id("1234").code(Coding.builder().code("F79.8").version("2019").build()).build()
- )
- ).build()
-
- val actual = this.service.transform(mtbFile)
-
- assertThat(actual).isNotNull
- assertThat(actual.diagnoses[0].code.code).isEqualTo("F79.9")
- assertThat(actual.diagnoses[0].code.version).isEqualTo("2014")
- assertThat(actual.diagnoses[1].code.code).isEqualTo("F79.8")
- assertThat(actual.diagnoses[1].code.version).isEqualTo("2019")
- }
-
- @Test
- fun shouldTransformConsent() {
- val mvhMetadata = MvhMetadata.builder().transferTan("transfertan12345").build()
-
- assertThat(mvhMetadata).isNotNull
- mvhMetadata.modelProjectConsent =
- ModelProjectConsent.builder().date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z")))
- .version("1").provisions(
- listOf(
- Provision.builder().type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.SEQUENCING)
- .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))).build(),
- Provision.builder().type(ConsentProvision.PERMIT)
- .purpose(ModelProjectConsentPurpose.REIDENTIFICATION)
- .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))).build(),
- Provision.builder().type(ConsentProvision.DENY)
- .purpose(ModelProjectConsentPurpose.CASE_IDENTIFICATION)
- .date(Date.from(Instant.parse("2025-08-15T00:00:00.00Z"))).build()
- )
- ).build()
- val consent = ConsentProcessorTest.getDummyGenomDeConsent()
-
- mvhMetadata.researchConsents = mutableListOf()
- mvhMetadata.researchConsents.add(mapOf(consent.id to consent as IBaseResource))
-
- val mtbFile = Mtb.builder().metadata(mvhMetadata).build()
-
- val transformed = service.transform(mtbFile)
- assertThat(transformed.metadata.modelProjectConsent.date).isNotNull
-
- }
+ val mtbFile = Mtb.builder().metadata(mvhMetadata).build()
+ val transformed = service.transform(mtbFile)
+ assertThat(transformed.metadata.modelProjectConsent.date).isNotNull
+ }
}
diff --git a/src/test/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessorTest.kt b/src/test/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessorTest.kt
index 95bf41b..8d5024a 100644
--- a/src/test/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessorTest.kt
+++ b/src/test/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessorTest.kt
@@ -39,7 +39,6 @@ import org.springframework.http.HttpStatus
@ExtendWith(MockitoExtension::class)
class KafkaResponseProcessorTest {
-
private lateinit var eventPublisher: ApplicationEventPublisher
private lateinit var objectMapper: ObjectMapper
@@ -48,9 +47,9 @@ class KafkaResponseProcessorTest {
private fun createKafkaRecord(
requestId: String,
statusCode: Int = 200,
- statusBody: Map<String, Any>? = mapOf()
- ): ConsumerRecord<String, String> {
- return ConsumerRecord<String, String>(
+ statusBody: Map<String, Any>? = mapOf(),
+ ): ConsumerRecord<String, String> =
+ ConsumerRecord<String, String>(
"test-topic",
0,
0,
@@ -58,14 +57,15 @@ class KafkaResponseProcessorTest {
if (statusBody == null) {
""
} else {
- this.objectMapper.writeValueAsString(KafkaResponseProcessor.ResponseBody(requestId, statusCode, statusBody))
- }
+ this.objectMapper.writeValueAsString(
+ KafkaResponseProcessor.ResponseBody(requestId, statusCode, statusBody),
+ )
+ },
)
- }
@BeforeEach
fun setup(
- @Mock eventPublisher: ApplicationEventPublisher
+ @Mock eventPublisher: ApplicationEventPublisher,
) {
this.eventPublisher = eventPublisher
this.objectMapper = ObjectMapper().registerModule(KotlinModule.Builder().build())
@@ -75,18 +75,19 @@ class KafkaResponseProcessorTest {
@Test
fun shouldNotProcessRecordsWithoutRequestIdInBody() {
- val record = ConsumerRecord<String, String>(
- "test-topic",
- 0,
- 0,
- null,
- """
+ val record =
+ ConsumerRecord<String, String>(
+ "test-topic",
+ 0,
+ 0,
+ null,
+ """
{
"statusCode": 200,
"statusBody": {}
}
- """.trimIndent()
- )
+ """.trimIndent(),
+ )
this.kafkaResponseProcessor.onMessage(record)
@@ -95,19 +96,20 @@ class KafkaResponseProcessorTest {
@Test
fun shouldProcessRecordsWithAliasNames() {
- val record = ConsumerRecord<String, String>(
- "test-topic",
- 0,
- 0,
- null,
- """
+ val record =
+ ConsumerRecord<String, String>(
+ "test-topic",
+ 0,
+ 0,
+ null,
+ """
{
"request_id": "test0123456789",
"status_code": 200,
"status_body": {}
}
- """.trimIndent()
- )
+ """.trimIndent(),
+ )
this.kafkaResponseProcessor.onMessage(record)
@@ -116,7 +118,9 @@ class KafkaResponseProcessorTest {
@Test
fun shouldNotProcessRecordsWithoutValidStatusBody() {
- this.kafkaResponseProcessor.onMessage(createKafkaRecord(requestId = "TestID1234", statusBody = null))
+ this.kafkaResponseProcessor.onMessage(
+ createKafkaRecord(requestId = "TestID1234", statusBody = null),
+ )
verify(eventPublisher, never()).publishEvent(any<ResponseEvent>())
}
@@ -129,21 +133,16 @@ class KafkaResponseProcessorTest {
}
companion object {
-
@JvmStatic
- fun statusCodeSource(): Set<Int> {
- return setOf(
+ fun statusCodeSource(): Set<Int> =
+ setOf(
HttpStatus.OK,
HttpStatus.CREATED,
HttpStatus.BAD_REQUEST,
HttpStatus.NOT_FOUND,
HttpStatus.UNPROCESSABLE_ENTITY,
- HttpStatus.INTERNAL_SERVER_ERROR
- )
- .map { it.value() }
+ HttpStatus.INTERNAL_SERVER_ERROR,
+ ).map { it.value() }
.toSet()
- }
-
}
-
-} \ No newline at end of file
+}