f827685ed0
fixed detekt issues where possible. fixed disttar failing build because tools is added twice in the server module. added workflowId where required. fixed some tests not being recognized because of runBlocking without explicit return type. formatting + imports.
74 lines
3.0 KiB
Kotlin
74 lines
3.0 KiB
Kotlin
import com.correx.core.events.types.StageId
|
|
import com.correx.core.events.types.TransitionId
|
|
import com.correx.core.transitions.graph.StageConfig
|
|
import com.correx.core.transitions.graph.TransitionEdge
|
|
import com.correx.core.transitions.graph.WorkflowGraph
|
|
import com.correx.core.transitions.resolution.TransitionOrdering
|
|
import com.correx.core.validation.approval.ApprovalTrigger
|
|
import com.correx.core.validation.graph.GraphValidator
|
|
import com.correx.core.validation.model.ValidationContext
|
|
import com.correx.core.validation.pipeline.ValidationOutcome
|
|
import com.correx.core.validation.pipeline.ValidationPipeline
|
|
import com.correx.core.validation.semantic.SemanticValidator
|
|
import com.correx.core.validation.semantic.rules.CyclePolicyBindingRule
|
|
import com.correx.core.validation.transition.TransitionValidator
|
|
import com.correx.testing.fixtures.CycleFixtures
|
|
import com.correx.testing.fixtures.WorkflowFixtures
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.junit.jupiter.api.Assertions.assertFalse
|
|
import org.junit.jupiter.api.Assertions.assertInstanceOf
|
|
import org.junit.jupiter.api.Test
|
|
|
|
class ValidationPipelineIntegrationTest {
|
|
|
|
private val pipeline = ValidationPipeline(
|
|
validators = listOf(
|
|
GraphValidator(),
|
|
TransitionValidator(TransitionOrdering.comparator),
|
|
SemanticValidator(
|
|
rules = listOf(
|
|
CyclePolicyBindingRule(requirePolicyForCycles = true),
|
|
),
|
|
),
|
|
),
|
|
approvalTrigger = ApprovalTrigger()
|
|
)
|
|
|
|
@Test
|
|
fun `full validation pipeline returns NeedsApproval when cycles are unbound`(): Unit = runBlocking {
|
|
|
|
val graph = WorkflowFixtures.simpleGraph()
|
|
|
|
val cycles = listOf(CycleFixtures.simpleCycle())
|
|
|
|
val context = ValidationContext(
|
|
graph = graph,
|
|
detectedCycles = cycles,
|
|
cyclePolicies = emptySet(),
|
|
)
|
|
|
|
val outcome = pipeline.validate(context)
|
|
|
|
assertInstanceOf(ValidationOutcome.NeedsApproval::class.java, outcome)
|
|
}
|
|
|
|
@Test
|
|
fun `rejected outcome retryable is false - set by validator, not orchestrator`(): Unit = runBlocking {
|
|
// A dangling transition triggers GraphValidator ERROR → Rejected(retryable=false).
|
|
// Ownership rule: the validator sets retryable; the orchestrator must only read it.
|
|
val a = StageId("A")
|
|
val ghost = StageId("GHOST")
|
|
val graphWithDanglingTransition = WorkflowGraph(
|
|
id = "workflow-test",
|
|
stages = mapOf(a to StageConfig()),
|
|
transitions = setOf(TransitionEdge(TransitionId("t1"), from = a, to = ghost) { true }),
|
|
start = a,
|
|
)
|
|
val pipeline = ValidationPipeline(validators = listOf(GraphValidator()), approvalTrigger = null)
|
|
val outcome = pipeline.validate(ValidationContext(graph = graphWithDanglingTransition))
|
|
|
|
assertInstanceOf(ValidationOutcome.Rejected::class.java, outcome)
|
|
assertFalse((outcome as ValidationOutcome.Rejected).retryable)
|
|
}
|
|
}
|