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.
93 lines
3.2 KiB
Kotlin
93 lines
3.2 KiB
Kotlin
import com.correx.core.approvals.ApprovalOutcome
|
|
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.SessionId
|
|
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.Assertions.assertNull
|
|
import org.junit.jupiter.api.Test
|
|
|
|
class GrantSemanticsTest {
|
|
|
|
private val engine = DefaultApprovalEngine()
|
|
|
|
@Test
|
|
fun `grant permits exact tier - auto_approved`() {
|
|
val req = request("r1", Tier.T2)
|
|
val grant = ApprovalGrant(
|
|
id = GrantId("g1"),
|
|
scope = GrantScope.SESSION,
|
|
permittedTiers = setOf(Tier.T2),
|
|
reason = "test",
|
|
timestamp = Instant.parse("2026-01-01T00:00:00Z")
|
|
)
|
|
val ctx = ApprovalContext(
|
|
ApprovalScopeIdentity(SessionId("s1"), null, null),
|
|
ApprovalMode.DENY
|
|
)
|
|
val now = Instant.parse("2026-01-01T00:00:01Z")
|
|
|
|
val decision = engine.evaluate(req, ctx, listOf(grant), now)
|
|
assertEquals(ApprovalOutcome.AUTO_APPROVED, decision.outcome)
|
|
assertEquals(ApprovalStatus.COMPLETED, decision.state)
|
|
}
|
|
|
|
@Test
|
|
fun `grant does not permit other tiers`() {
|
|
val req = request("r1", Tier.T3)
|
|
val grant = ApprovalGrant(
|
|
id = GrantId("g1"),
|
|
scope = GrantScope.SESSION,
|
|
permittedTiers = setOf(Tier.T2),
|
|
reason = "test",
|
|
timestamp = Instant.parse("2026-01-01T00:00:00Z")
|
|
)
|
|
val ctx = ApprovalContext(
|
|
ApprovalScopeIdentity(SessionId("s1"), null, null),
|
|
ApprovalMode.DENY
|
|
)
|
|
val now = Instant.parse("2026-01-01T00:00:01Z")
|
|
|
|
val decision = engine.evaluate(req, ctx, listOf(grant), now)
|
|
assertEquals(ApprovalStatus.PENDING, decision.state)
|
|
assertNull(decision.outcome)
|
|
}
|
|
|
|
@Test
|
|
fun `multiple grants - any match is enough`() {
|
|
val req = request("r1", Tier.T4)
|
|
val grants = listOf(
|
|
ApprovalGrant(
|
|
GrantId("g1"),
|
|
GrantScope.SESSION,
|
|
setOf(Tier.T3),
|
|
"",
|
|
Instant.parse("2026-01-01T00:00:00Z")
|
|
),
|
|
ApprovalGrant(
|
|
GrantId("g2"),
|
|
GrantScope.SESSION,
|
|
setOf(Tier.T4),
|
|
"",
|
|
Instant.parse("2026-01-01T00:00:00Z")
|
|
)
|
|
)
|
|
val ctx = ApprovalContext(
|
|
ApprovalScopeIdentity(SessionId("s1"), null, null),
|
|
ApprovalMode.DENY
|
|
)
|
|
val now = Instant.parse("2026-01-01T00:00:01Z")
|
|
|
|
val decision = engine.evaluate(req, ctx, grants, now)
|
|
assertEquals(ApprovalOutcome.AUTO_APPROVED, decision.outcome)
|
|
}
|
|
}
|