Files
correx/testing/approvals/src/test/kotlin/ApprovalEngineEdgeCasesTest.kt
T

89 lines
2.9 KiB
Kotlin

import com.correx.core.approvals.ApprovalStatus
import com.correx.core.approvals.GrantScope
import com.correx.core.approvals.Tier
import com.correx.core.approvals.domain.DefaultApprovalEngine
import com.correx.core.approvals.model.ApprovalContext
import com.correx.core.approvals.model.ApprovalGrant
import com.correx.core.approvals.model.ApprovalScopeIdentity
import com.correx.core.events.types.GrantId
import com.correx.core.events.types.ProjectId
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.sessions.ApprovalMode
import com.correx.testing.fixtures.request
import kotlinx.datetime.Instant
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
class ApprovalEngineEdgeCasesTest {
private val engine = DefaultApprovalEngine()
private val now = Instant.parse("2026-01-01T00:00:01Z")
private fun context(mode: ApprovalMode) = ApprovalContext(
ApprovalScopeIdentity(SessionId("s1"), StageId("st1"), ProjectId("p1")),
mode
)
@Test
fun `grants from different scopes apply only to matching identity`() {
val sessionGrant = ApprovalGrant(
id = GrantId("g1"),
scope = GrantScope.SESSION,
permittedTiers = setOf(Tier.T3),
reason = "",
timestamp = Instant.parse("2026-01-01T00:00:00Z")
)
val stageGrant = ApprovalGrant(
id = GrantId("g2"),
scope = GrantScope.STAGE(StageId("st2")),
permittedTiers = setOf(Tier.T4),
reason = "",
timestamp = Instant.parse("2026-01-01T00:00:00Z")
)
val decision = engine.evaluate(
request("r1", Tier.T4),
context(ApprovalMode.DENY),
listOf(sessionGrant, stageGrant),
now
)
assertEquals(
ApprovalStatus.PENDING, decision.state,
"Stage grant for different stage should not apply"
)
}
@Test
fun `expired grant is ignored`() {
val past = Instant.parse("2025-12-31T23:59:59Z")
val expiredGrant = ApprovalGrant(
id = GrantId("g1"),
scope = GrantScope.SESSION,
permittedTiers = setOf(Tier.T2),
reason = "",
timestamp = past,
expiresAt = past // expired before 'now'
)
val decision = engine.evaluate(
request("r1", Tier.T2),
context(ApprovalMode.DENY),
listOf(expiredGrant),
now
)
assertEquals(ApprovalStatus.PENDING, decision.state)
}
@Test
fun `timestamp passed to evaluate is used as resolution timestamp`() {
val myNow = Instant.parse("2026-07-01T12:00:00Z")
val decision = engine.evaluate(
request("r1", Tier.T0),
context(ApprovalMode.YOLO),
emptyList(),
myNow
)
assertEquals(myNow, decision.resolutionTimestamp)
}
}