diff --git a/build.gradle.kts b/build.gradle.kts index 96779d0..aecda71 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -18,6 +18,7 @@ var versions = mapOf( "hapi-fhir" to "6.10.2", "httpclient5" to "5.2.1", "mockito-kotlin" to "5.3.1", + "archunit" to "1.3.0", // Webjars "echarts" to "5.4.3", "htmx.org" to "1.9.11" @@ -85,6 +86,7 @@ dependencies { testImplementation("org.mockito.kotlin:mockito-kotlin:${versions["mockito-kotlin"]}") integrationTestImplementation("org.testcontainers:junit-jupiter") integrationTestImplementation("org.testcontainers:postgresql") + integrationTestImplementation("com.tngtech.archunit:archunit:${versions["archunit"]}") // Override dependency version from org.testcontainers:junit-jupiter - CVE-2024-26308, CVE-2024-25710 integrationTestImplementation("org.apache.commons:commons-compress:1.26.1") } diff --git a/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt new file mode 100644 index 0000000..0467286 --- /dev/null +++ b/src/integrationTest/kotlin/dev/dnpm/etl/processor/EtlProcessorArchTest.kt @@ -0,0 +1,75 @@ +package dev.dnpm.etl.processor + +import com.tngtech.archunit.base.DescribedPredicate.doNot +import com.tngtech.archunit.core.domain.JavaClass.Predicates.simpleNameEndingWith +import com.tngtech.archunit.core.domain.JavaClasses +import com.tngtech.archunit.core.importer.ClassFileImporter +import com.tngtech.archunit.lang.conditions.ArchPredicates.have +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes +import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.data.repository.Repository + +class EtlProcessorArchTest { + + private lateinit var noTestClasses: JavaClasses + + @BeforeEach + fun setUp() { + this.noTestClasses = ClassFileImporter().importPackages("dev.dnpm.etl.processor") + .that(doNot(have(simpleNameEndingWith("Test").or(simpleNameEndingWith("Tests"))))) + } + + @Test + fun noClassesInInputPackageShouldDependOnMonitoringPackage() { + val rule = noClasses() + .that() + .resideInAPackage("..input") + .should().dependOnClassesThat() + .resideInAnyPackage("..monitoring") + + rule.check(noTestClasses) + } + + @Test + fun noClassesInInputPackageShouldDependOnRepositories() { + val rule = noClasses() + .that() + .resideInAPackage("..input") + .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + + rule.check(noTestClasses) + } + + @Test + fun noClassesInOutputPackageShouldDependOnRepositories() { + val rule = noClasses() + .that() + .resideInAPackage("..output") + .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + + rule.check(noTestClasses) + } + + @Test + fun noClassesInWebPackageShouldDependOnRepositories() { + val rule = noClasses() + .that() + .resideInAPackage("..web") + .should().dependOnClassesThat().haveSimpleNameEndingWith("Repository") + + rule.check(noTestClasses) + } + + @Test + fun repositoryClassNamesShouldEndWithRepository() { + val rule = classes() + .that() + .areInterfaces().and().areAssignableTo(Repository::class.java) + .should().haveSimpleNameEndingWith("Repository") + + rule.check(noTestClasses) + } + +} \ No newline at end of file