Create GameStateRepository

Use GameState.apply() to build Projection
Create GameEventHandler
Add PlayerWinEvent
This commit is contained in:
2025-03-09 03:43:31 +01:00
parent 3080e515d6
commit 19e425d684
22 changed files with 371 additions and 81 deletions

View File

@@ -1,11 +1,15 @@
package eventDemo.app.query
import eventDemo.app.GameState
import eventDemo.app.entity.Card
import eventDemo.app.entity.GameId
import eventDemo.app.entity.Player
import eventDemo.app.event.GameEventStream
import eventDemo.app.event.GameEventHandler
import eventDemo.app.event.event.CardIsPlayedEvent
import eventDemo.app.event.event.GameStartedEvent
import eventDemo.app.event.event.NewPlayerEvent
import eventDemo.app.event.event.PlayerReadyEvent
import eventDemo.app.event.projection.GameState
import eventDemo.app.event.projection.GameStateRepository
import eventDemo.configuration.configure
import eventDemo.configuration.makeJwt
import io.kotest.core.spec.style.FunSpec
@@ -20,9 +24,13 @@ import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.testApplication
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.koin.core.context.stopKoin
import org.koin.ktor.ext.inject
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertNotNull
class GameStateRouteTest :
FunSpec({
@@ -51,30 +59,56 @@ class GameStateRouteTest :
test("/game/{id}/card/last") {
testApplication {
val id = GameId()
val card: Card = Card.NumericCard(1, Card.Color.Blue)
val player = Player(name = "Nikola")
val gameId = GameId()
val player1 = Player(name = "Nikola")
val player2 = Player(name = "Einstein")
var lastPlayedCard: Card? = null
application {
stopKoin()
configure()
val eventStream by inject<GameEventStream>()
eventStream.publish(
CardIsPlayedEvent(id, Card.NumericCard(2, Card.Color.Yellow), player),
CardIsPlayedEvent(id, card, player),
// Other game
CardIsPlayedEvent(GameId(), Card.NumericCard(2, Card.Color.Yellow), player),
)
val eventHandler by inject<GameEventHandler>()
val stateRepo by inject<GameStateRepository>()
runBlocking {
eventHandler.handle(
NewPlayerEvent(gameId, player1),
NewPlayerEvent(gameId, player2),
PlayerReadyEvent(gameId, player1),
PlayerReadyEvent(gameId, player2),
GameStartedEvent.new(
gameId,
setOf(player1, player2),
shuffleIsDisabled = true,
),
)
delay(100)
lastPlayedCard = stateRepo.get(gameId).playableCards(player1).first()
assertNotNull(lastPlayedCard)
.let { assertIs<Card.NumericCard>(lastPlayedCard) }
.let {
it.number shouldBeEqual 0
it.color shouldBeEqual Card.Color.Red
}
delay(100)
eventHandler.handle(
CardIsPlayedEvent(
gameId,
assertNotNull(lastPlayedCard),
player1,
),
)
delay(100)
}
}
httpClient()
.get("/game/$id/card/last") {
withAuth(player)
.get("/game/$gameId/card/last") {
withAuth(player1)
accept(ContentType.Application.Json)
}.apply {
assertEquals(HttpStatusCode.OK, status, message = bodyAsText())
assertEquals(card, call.body<Card>())
assertEquals(assertNotNull(lastPlayedCard), call.body<Card>())
}
}
}