fix(tui): use takeLast(3) for events, add bridge/TUI tests for snapshot recentEvents

- Change EventHistoryStrip take(3) to takeLast(3) so it shows the 3 most
  recent events instead of the 3 oldest (chronological order is oldest-first)
- Add bridge test confirming replaySnapshot populates recentEvents from the
  event store (with 3 different event types mapped correctly)
- Add TUI SessionsReducer test confirming processSessionSnapshotMessage maps
  EventEntryDto entries from the snapshot into TuiEventEntry on the summary
This commit is contained in:
2026-05-26 13:39:11 +04:00
parent 450b492937
commit d701e3cbf3
3 changed files with 62 additions and 1 deletions
@@ -1,5 +1,6 @@
package com.correx.apps.server.bridge
import com.correx.apps.server.protocol.EventEntryDto
import com.correx.apps.server.protocol.ServerMessage
import com.correx.apps.server.registry.WorkflowRegistry
import com.correx.core.approvals.ApprovalProjector
@@ -10,7 +11,9 @@ import com.correx.core.events.events.EventMetadata
import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.NewEvent
import com.correx.core.events.events.OrchestrationResumedEvent
import com.correx.core.events.events.StageCompletedEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TransitionExecutedEvent
import com.correx.core.events.events.WorkflowCompletedEvent
import com.correx.core.events.events.WorkflowStartedEvent
import com.correx.core.events.orchestration.OrchestrationState
@@ -20,6 +23,7 @@ import com.correx.core.events.types.ArtifactId
import com.correx.core.events.types.EventId
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.kernel.orchestration.OrchestrationRepository
import com.correx.core.sessions.projections.replay.DefaultEventReplayer
import com.correx.core.tools.contract.Tool
@@ -139,6 +143,37 @@ class SessionEventBridgeTest {
assertEquals(ServerMessage.SnapshotComplete, sent[1])
}
@Test
fun `replaySnapshot populates recentEvents from event store`() = runTest {
val events = listOf(
storedEvent(WorkflowStartedEvent(sessionId, workflowId, stageId), seq = 1L),
storedEvent(TransitionExecutedEvent(sessionId, stageId, StageId("stage-2"), TransitionId("t1")), seq = 2L),
storedEvent(StageCompletedEvent(sessionId, stageId, TransitionId("t2")), seq = 3L),
storedEvent(WorkflowCompletedEvent(sessionId, stageId, 1), seq = 4L),
)
val store = fakeEventStore(allEventsList = events)
val orchRepo = activeOrchestrationRepository(status = OrchestrationStatus.COMPLETED)
val sent = mutableListOf<ServerMessage>()
val bridge = SessionEventBridge(
store,
noopArtifactStore,
orchRepo,
approvalRepository,
noopWorkflowRegistry,
noopToolRegistry,
) { sent.add(it) }
bridge.replaySnapshot()
assertEquals(2, sent.size)
val snapshot = sent[0] as ServerMessage.SessionSnapshot
// WorkflowStartedEvent is filtered out by eventToEntry (maps to null)
assertEquals(3, snapshot.recentEvents.size)
assertEquals(EventEntryDto(timestamp.toEpochMilliseconds(), "StageStarted", "stage-2"), snapshot.recentEvents[0])
assertEquals(EventEntryDto(timestamp.toEpochMilliseconds(), "StageCompleted", stageId.value), snapshot.recentEvents[1])
assertEquals(EventEntryDto(timestamp.toEpochMilliseconds(), "SessionCompleted", ""), snapshot.recentEvents[2])
}
@Test
fun `replaySnapshot skips unmapped events`() = runTest {
val events = listOf(