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.
245 lines
6.7 KiB
Kotlin
245 lines
6.7 KiB
Kotlin
import com.correx.core.events.events.SessionCompletedEvent
|
|
import com.correx.core.events.events.SessionFailedEvent
|
|
import com.correx.core.events.events.SessionPausedEvent
|
|
import com.correx.core.events.events.SessionResumedEvent
|
|
import com.correx.core.events.events.SessionStartedEvent
|
|
import com.correx.core.events.events.StageCompletedEvent
|
|
import com.correx.core.events.events.StageFailedEvent
|
|
import com.correx.core.events.events.StageStartedEvent
|
|
import com.correx.core.events.events.TransitionExecutedEvent
|
|
import com.correx.core.events.types.SessionId
|
|
import com.correx.core.events.types.StageId
|
|
import com.correx.core.events.types.TransitionId
|
|
import com.correx.core.sessions.DefaultSessionReducer
|
|
import com.correx.core.sessions.SessionState
|
|
import com.correx.core.sessions.SessionStatus
|
|
import com.correx.testing.fixtures.EventFixtures.stored
|
|
import kotlinx.datetime.Instant
|
|
import org.junit.jupiter.api.Assertions.assertEquals
|
|
import org.junit.jupiter.api.Test
|
|
|
|
class DefaultSessionReducerTest {
|
|
|
|
private val reducer = DefaultSessionReducer()
|
|
|
|
private val sessionId = SessionId("session-1")
|
|
|
|
@Test
|
|
fun `SessionStartedEvent sets ACTIVE status`() {
|
|
val state = initialState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = SessionStartedEvent(sessionId)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.ACTIVE, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `SessionPausedEvent sets PAUSED status`() {
|
|
val state = activeState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = SessionPausedEvent(sessionId)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.PAUSED, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `SessionResumedEvent sets ACTIVE status`() {
|
|
val state = pausedState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = SessionResumedEvent(sessionId)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.ACTIVE, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `SessionCompletedEvent sets COMPLETED status`() {
|
|
val state = activeState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = SessionCompletedEvent(sessionId)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.COMPLETED, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `SessionFailedEvent sets FAILED status`() {
|
|
val state = activeState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = SessionFailedEvent(sessionId)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.FAILED, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `StageStartedEvent sets ACTIVE status`() {
|
|
val state = pausedState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = StageStartedEvent(
|
|
sessionId,
|
|
stageId = StageId("stage-a"),
|
|
transitionId = TransitionId("transition-a")
|
|
)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.ACTIVE, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `StageCompletedEvent sets ACTIVE status`() {
|
|
val state = pausedState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = StageCompletedEvent(
|
|
sessionId,
|
|
stageId = StageId("stage-a"),
|
|
transitionId = TransitionId("transition-a")
|
|
)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.ACTIVE, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `StageFailedEvent sets FAILED status`() {
|
|
val state = activeState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = StageFailedEvent(
|
|
sessionId,
|
|
stageId = StageId("stage-a"),
|
|
transitionId = TransitionId("transition-a"),
|
|
reason = "boom"
|
|
)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.FAILED, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `TransitionExecutedEvent sets ACTIVE status`() {
|
|
val state = pausedState()
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
sessionId = sessionId,
|
|
payload = TransitionExecutedEvent(
|
|
sessionId,
|
|
from = StageId("stage-a"),
|
|
to = StageId("stage-b"),
|
|
transitionId = TransitionId("transition-a"),
|
|
)
|
|
)
|
|
)
|
|
|
|
assertEquals(SessionStatus.ACTIVE, result.status)
|
|
}
|
|
|
|
@Test
|
|
fun `createdAt is initialized once`() {
|
|
val timestamp = Instant.parse("2026-01-01T00:00:00Z")
|
|
|
|
val result = reducer.reduce(
|
|
state = initialState(),
|
|
event = stored(
|
|
payload = SessionStartedEvent(sessionId),
|
|
timestamp = timestamp
|
|
)
|
|
)
|
|
|
|
assertEquals(timestamp, result.createdAt)
|
|
}
|
|
|
|
@Test
|
|
fun `createdAt is preserved after initialization`() {
|
|
val createdAt = Instant.parse("2026-01-01T00:00:00Z")
|
|
val updatedAt = Instant.parse("2026-01-02T00:00:00Z")
|
|
|
|
val state = activeState().copy(
|
|
createdAt = createdAt
|
|
)
|
|
|
|
val result = reducer.reduce(
|
|
state = state,
|
|
event = stored(
|
|
payload = SessionPausedEvent(sessionId),
|
|
timestamp = updatedAt
|
|
)
|
|
)
|
|
|
|
assertEquals(createdAt, result.createdAt)
|
|
}
|
|
|
|
@Test
|
|
fun `updatedAt always reflects latest event timestamp`() {
|
|
val timestamp = Instant.parse("2026-01-02T00:00:00Z")
|
|
|
|
val result = reducer.reduce(
|
|
state = activeState(),
|
|
event = stored(
|
|
payload = SessionPausedEvent(sessionId),
|
|
timestamp = timestamp
|
|
)
|
|
)
|
|
|
|
assertEquals(timestamp, result.updatedAt)
|
|
}
|
|
|
|
private fun initialState() =
|
|
SessionState(
|
|
status = SessionStatus.CREATED
|
|
)
|
|
|
|
private fun activeState() =
|
|
SessionState(
|
|
status = SessionStatus.ACTIVE
|
|
)
|
|
|
|
private fun pausedState() =
|
|
SessionState(
|
|
status = SessionStatus.PAUSED
|
|
)
|
|
}
|