summaryrefslogtreecommitdiff
path: root/sw-server/src/test/kotlin/org/luxons
diff options
context:
space:
mode:
authorJoffrey Bion <joffrey.bion@gmail.com>2021-03-09 00:06:23 +0100
committerJoffrey Bion <joffrey.bion@gmail.com>2021-03-09 00:06:23 +0100
commit10366ca0240bc6bb5d66cd06a0c18373c2c8e875 (patch)
tree4b491912b1e28d76a41f40d8d46bb3f328596abf /sw-server/src/test/kotlin/org/luxons
parentUpgrade ktlint (diff)
downloadseven-wonders-10366ca0240bc6bb5d66cd06a0c18373c2c8e875.tar.gz
seven-wonders-10366ca0240bc6bb5d66cd06a0c18373c2c8e875.tar.bz2
seven-wonders-10366ca0240bc6bb5d66cd06a0c18373c2c8e875.zip
Unify game events
Diffstat (limited to 'sw-server/src/test/kotlin/org/luxons')
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt107
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt55
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt14
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt7
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/ClientEventsAsserts.kt48
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/MockMessageChannel.kt53
-rw-r--r--sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt10
7 files changed, 218 insertions, 76 deletions
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
index 7f05688b..549ef267 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt
@@ -1,23 +1,18 @@
package org.luxons.sevenwonders.server
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.produceIn
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withTimeout
-import kotlinx.coroutines.withTimeoutOrNull
+import kotlinx.coroutines.*
import org.junit.runner.RunWith
import org.luxons.sevenwonders.client.*
import org.luxons.sevenwonders.model.TurnAction
-import org.luxons.sevenwonders.model.api.GameListEvent
-import org.luxons.sevenwonders.model.api.LobbyDTO
-import org.luxons.sevenwonders.server.test.runAsyncTest
+import org.luxons.sevenwonders.model.api.events.GameEvent
+import org.luxons.sevenwonders.model.api.events.GameListEvent
+import org.luxons.sevenwonders.server.test.*
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment
import org.springframework.boot.web.server.LocalServerPort
import org.springframework.test.context.junit4.SpringRunner
import kotlin.test.Test
import kotlin.test.assertEquals
-import kotlin.test.assertNull
import kotlin.test.assertTrue
@RunWith(SpringRunner::class)
@@ -43,13 +38,13 @@ class SevenWondersTest {
fun chooseName_succeedsWithCorrectDisplayName() = runAsyncTest {
val session = connectNewClient()
val playerName = "Test User"
- val player = session.chooseName(playerName)
+ val player = session.chooseNameAndAwait(playerName)
assertEquals(playerName, player.displayName)
session.disconnect()
}
private suspend fun newPlayer(name: String): SevenWondersSession = connectNewClient().apply {
- chooseName(name)
+ chooseNameAndAwait(name)
}
@Test
@@ -59,17 +54,18 @@ class SevenWondersTest {
val session2 = newPlayer("Player2")
val gameName = "Test Game"
- val lobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
+ val lobby = ownerSession.createGameAndAwaitLobby(gameName)
session1.joinGameAndAwaitLobby(lobby.id)
session2.joinGameAndAwaitLobby(lobby.id)
val outsiderSession = newPlayer("Outsider")
- val gameStartedEvents = outsiderSession.watchGameStarted()
- ownerSession.startGameAndAwaitFirstTurn()
+ val outsiderAsserter = outsiderSession.eventAsserter(scope = this)
- val nullForTimeout = withTimeoutOrNull(50) { gameStartedEvents.first() }
- assertNull(nullForTimeout, "outsider should not receive the game start event of this game")
+ val ownerAsserter = ownerSession.eventAsserter(scope = this)
+ ownerSession.startGame()
+ ownerAsserter.expectGameEvent<GameEvent.GameStarted>()
+ outsiderAsserter.expectNoGameEvent("outsider should not receive the game start event of this game")
disconnect(ownerSession, session1, session2, outsiderSession)
}
@@ -79,7 +75,7 @@ class SevenWondersTest {
val ownerSession = newPlayer("GameOwner")
val gameName = "Test Game"
- val lobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
+ val lobby = ownerSession.createGameAndAwaitLobby(gameName)
assertEquals(gameName, lobby.name)
disconnect(ownerSession)
@@ -88,18 +84,16 @@ class SevenWondersTest {
@Test
fun createGame_seenByConnectedPlayers() = runAsyncTest {
val otherSession = newPlayer("OtherPlayer")
- val games = otherSession.watchGames().produceIn(this)
+ val asserter = otherSession.eventAsserter(scope = this)
- val initialListEvent = withTimeout(500) { games.receive() }
- assertTrue(initialListEvent is GameListEvent.ReplaceList)
+ val initialListEvent = asserter.expectGameListEvent<GameListEvent.ReplaceList>()
assertEquals(0, initialListEvent.lobbies.size)
val ownerSession = newPlayer("GameOwner")
val gameName = "Test Game"
- val createdLobby = ownerSession.createGameWithLegacySettingsAndWaitLobby(gameName)
+ val createdLobby = ownerSession.createGameAndAwaitLobby(gameName)
- val afterGameListEvent = withTimeout(500) { games.receive() }
- assertTrue(afterGameListEvent is GameListEvent.CreateOrUpdate)
+ val afterGameListEvent = asserter.expectGameListEvent<GameListEvent.CreateOrUpdate>()
val receivedLobby = afterGameListEvent.lobby
assertEquals(createdLobby.id, receivedLobby.id)
assertEquals(createdLobby.name, receivedLobby.name)
@@ -107,46 +101,57 @@ class SevenWondersTest {
disconnect(ownerSession, otherSession)
}
+ @OptIn(ExperimentalCoroutinesApi::class, FlowPreview::class)
@Test
fun startGame_3players() = runAsyncTest {
val session1 = newPlayer("Player1")
val session2 = newPlayer("Player2")
- val startEvents1 = session1.watchGameStarted()
- val lobby = session1.createGameWithLegacySettingsAndWaitLobby("Test Game")
+ val asserter1 = session1.eventAsserter(scope = this)
+ val lobby = session1.createGameAndAwaitLobby("Test Game")
+ asserter1.expectGameEvent<GameEvent.LobbyJoined>()
- val startEvents2 = session2.watchGameStarted()
- session2.joinGameAndAwaitLobby(lobby.id)
+ val asserter2 = session2.eventAsserter(scope = this)
+ session2.joinGame(lobby.id)
+ asserter1.expectGameEvent<GameEvent.LobbyUpdated>()
+ asserter2.expectGameEvent<GameEvent.LobbyUpdated>()
+ asserter2.expectGameEvent<GameEvent.LobbyJoined>()
// player 3 connects after game creation (on purpose)
val session3 = newPlayer("Player3")
- val startEvents3 = session3.watchGameStarted()
- session3.joinGameAndAwaitLobby(lobby.id)
+ val asserter3 = session3.eventAsserter(scope = this)
+ session3.joinGame(lobby.id)
+ asserter1.expectGameEvent<GameEvent.LobbyUpdated>()
+ asserter2.expectGameEvent<GameEvent.LobbyUpdated>()
+ asserter3.expectGameEvent<GameEvent.LobbyUpdated>()
+ asserter3.expectGameEvent<GameEvent.LobbyJoined>()
session1.startGame()
-
- listOf(
- session1 to startEvents1,
- session2 to startEvents2,
- session3 to startEvents3,
- ).forEach { (session, startEvents) ->
- launch {
- val initialReadyTurn = startEvents.first()
- assertTrue(initialReadyTurn.action is TurnAction.SayReady)
- val turns = session.watchTurns()
- session.sayReady()
-
- val firstActualTurn = turns.first()
- val action = firstActualTurn.action
- assertTrue(action is TurnAction.PlayFromHand)
- session.disconnect()
- }
- }
+ asserter1.expectGameEvent<GameEvent.GameStarted>()
+ asserter2.expectGameEvent<GameEvent.GameStarted>()
+ asserter3.expectGameEvent<GameEvent.GameStarted>()
+
+ session2.sayReady()
+ asserter2.expectNoGameEvent("nothing should happen while other players are not ready for game start")
+ asserter1.expectNoGameEvent("nothing should happen while other players are not ready for game start")
+ asserter3.expectNoGameEvent("nothing should happen while other players are not ready for game start")
+
+ session1.sayReady()
+ asserter1.expectNoGameEvent("nothing should happen while other players are not ready for game start")
+ session3.sayReady()
+
+ asserter1.expectPlayFromHandTurn()
+ asserter2.expectPlayFromHandTurn()
+ asserter3.expectPlayFromHandTurn()
+
+ session1.disconnect()
+ session2.disconnect()
+ session3.disconnect()
}
}
-private suspend fun SevenWondersSession.createGameWithLegacySettingsAndWaitLobby(gameName: String): LobbyDTO {
- val lobby = createGameAndAwaitLobby(gameName)
- updateSettings(lobby.settings.copy(askForReadiness = true))
- return lobby
+private suspend fun EventAsserter.expectPlayFromHandTurn() {
+ val firstTurn = expectGameEvent<GameEvent.NewTurnStarted>()
+ val action = firstTurn.turnInfo.action
+ assertTrue(action is TurnAction.PlayFromHand)
}
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt
index 0f6e031b..70369a59 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt
@@ -3,14 +3,18 @@ package org.luxons.sevenwonders.server.controllers
import io.micrometer.core.instrument.simple.SimpleMeterRegistry
import org.junit.Before
import org.junit.Test
-import org.luxons.sevenwonders.model.api.GameListEvent
import org.luxons.sevenwonders.model.api.actions.CreateGameAction
import org.luxons.sevenwonders.model.api.actions.JoinGameAction
+import org.luxons.sevenwonders.model.api.events.GameEvent
+import org.luxons.sevenwonders.model.api.events.GameListEvent
import org.luxons.sevenwonders.server.controllers.GameBrowserController.UserAlreadyInGameException
import org.luxons.sevenwonders.server.repositories.LobbyRepository
import org.luxons.sevenwonders.server.repositories.PlayerNotFoundException
import org.luxons.sevenwonders.server.repositories.PlayerRepository
-import org.luxons.sevenwonders.server.test.mockSimpMessagingTemplate
+import org.luxons.sevenwonders.server.test.MockMessageChannel
+import org.luxons.sevenwonders.server.test.expectSentGameEventTo
+import org.luxons.sevenwonders.server.test.expectSentGameListEvent
+import org.springframework.messaging.simp.SimpMessagingTemplate
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertFalse
@@ -18,18 +22,21 @@ import kotlin.test.assertTrue
class GameBrowserControllerTest {
+ private lateinit var messageChannel: MockMessageChannel
+
private lateinit var playerRepository: PlayerRepository
private lateinit var gameBrowserController: GameBrowserController
@Before
fun setUp() {
+ messageChannel = MockMessageChannel()
+ val messenger = SimpMessagingTemplate(messageChannel)
val meterRegistry = SimpleMeterRegistry()
- playerRepository = PlayerRepository(meterRegistry)
val lobbyRepository = LobbyRepository(meterRegistry)
- val template = mockSimpMessagingTemplate()
- val lobbyController = LobbyController(lobbyRepository, playerRepository, template, "UNUSED", meterRegistry)
- gameBrowserController = GameBrowserController(lobbyController, lobbyRepository, playerRepository, template)
+ playerRepository = PlayerRepository(meterRegistry)
+ val lobbyController = LobbyController(messenger, lobbyRepository, playerRepository, "UNUSED", meterRegistry)
+ gameBrowserController = GameBrowserController(messenger, lobbyController, lobbyRepository, playerRepository)
}
@Test
@@ -46,9 +53,16 @@ class GameBrowserControllerTest {
val action = CreateGameAction("Test Game")
- val createdLobby = gameBrowserController.createGame(action, principal)
+ gameBrowserController.createGame(action, principal)
+
+ val createdEvent = messageChannel.expectSentGameListEvent<GameListEvent.CreateOrUpdate>()
+ val lobbyJoinedEvent = messageChannel.expectSentGameEventTo<GameEvent.LobbyJoined>("testuser")
+ val createdLobby = createdEvent.lobby
assertEquals("Test Game", createdLobby.name)
+ assertEquals(createdLobby, lobbyJoinedEvent.lobby)
+
+ messageChannel.expectNoMoreMessages()
val gameListEvent = gameBrowserController.listGames(principal).event as GameListEvent.ReplaceList
assertFalse(gameListEvent.lobbies.isEmpty())
@@ -91,17 +105,34 @@ class GameBrowserControllerTest {
val ownerPrincipal = TestPrincipal("testowner")
val createGameAction = CreateGameAction("Test Game")
- val createdLobby = gameBrowserController.createGame(createGameAction, ownerPrincipal)
+ gameBrowserController.createGame(createGameAction, ownerPrincipal)
+
+ val createdEvent = messageChannel.expectSentGameListEvent<GameListEvent.CreateOrUpdate>()
+ messageChannel.expectSentGameEventTo<GameEvent.LobbyJoined>("testowner")
+ val createdLobby = createdEvent.lobby
assertEquals(owner.username, createdLobby.players[0].username)
+ messageChannel.expectNoMoreMessages()
+
val joiner = playerRepository.createOrUpdate("testjoiner", "Test User Joiner")
val joinerPrincipal = TestPrincipal("testjoiner")
val joinGameAction = JoinGameAction(createdLobby.id)
- val joinedLobby = gameBrowserController.joinGame(joinGameAction, joinerPrincipal)
+ gameBrowserController.joinGame(joinGameAction, joinerPrincipal)
+
+ // lobby update for existing players
+ messageChannel.expectSentGameEventTo<GameEvent.LobbyUpdated>("testowner")
+ messageChannel.expectSentGameEventTo<GameEvent.LobbyUpdated>("testjoiner")
+ // lobby update for people on game browser page
+ messageChannel.expectSentGameListEvent<GameListEvent.CreateOrUpdate>()
+ // lobby joined for the player who joined
+ val joinedLobbyEvent = messageChannel.expectSentGameEventTo<GameEvent.LobbyJoined>("testjoiner")
+ val joinedLobby = joinedLobbyEvent.lobby
assertEquals(owner.username, joinedLobby.players[0].username)
assertEquals(joiner.username, joinedLobby.players[1].username)
+
+ messageChannel.expectNoMoreMessages()
}
@Test
@@ -110,7 +141,11 @@ class GameBrowserControllerTest {
val ownerPrincipal = TestPrincipal("testowner")
val createGameAction = CreateGameAction("Test Game")
- val createdLobby = gameBrowserController.createGame(createGameAction, ownerPrincipal)
+ gameBrowserController.createGame(createGameAction, ownerPrincipal)
+
+ val createdEvent = messageChannel.expectSentGameListEvent<GameListEvent.CreateOrUpdate>()
+ messageChannel.expectSentGameEventTo<GameEvent.LobbyJoined>("testowner")
+ val createdLobby = createdEvent.lobby
playerRepository.createOrUpdate("testjoiner", "Test User Joiner")
val joinerPrincipal = TestPrincipal("testjoiner")
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt
index c73fba10..4976e2de 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt
@@ -4,7 +4,11 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry
import org.junit.Test
import org.luxons.sevenwonders.model.api.actions.ChooseNameAction
import org.luxons.sevenwonders.model.api.actions.Icon
+import org.luxons.sevenwonders.model.api.events.GameEvent
import org.luxons.sevenwonders.server.repositories.PlayerRepository
+import org.luxons.sevenwonders.server.test.MockMessageChannel
+import org.luxons.sevenwonders.server.test.expectSentGameEventTo
+import org.springframework.messaging.simp.SimpMessagingTemplate
import kotlin.test.assertEquals
class HomeControllerTest {
@@ -13,15 +17,21 @@ class HomeControllerTest {
fun chooseName() {
val meterRegistry = SimpleMeterRegistry()
val playerRepository = PlayerRepository(meterRegistry)
- val homeController = HomeController(playerRepository, meterRegistry)
+ val messageChannel = MockMessageChannel()
+ val messenger = SimpMessagingTemplate(messageChannel)
+ val homeController = HomeController(messenger, playerRepository, meterRegistry)
val action = ChooseNameAction("Test User", Icon("person"), isHuman = true)
val principal = TestPrincipal("testuser")
- val player = homeController.chooseName(action, principal)
+ homeController.chooseName(action, principal)
+ val payload = messageChannel.expectSentGameEventTo<GameEvent.NameChosen>("testuser")
+ val player = payload.player
assertEquals("testuser", player.username)
assertEquals("Test User", player.displayName)
assertEquals("person", player.icon?.name)
+
+ messageChannel.expectNoMoreMessages()
}
}
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt
index 7d9db01d..38f6ffb3 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt
@@ -14,7 +14,8 @@ import org.luxons.sevenwonders.server.lobby.PlayerNotInLobbyException
import org.luxons.sevenwonders.server.repositories.LobbyRepository
import org.luxons.sevenwonders.server.repositories.PlayerNotFoundException
import org.luxons.sevenwonders.server.repositories.PlayerRepository
-import org.luxons.sevenwonders.server.test.mockSimpMessagingTemplate
+import org.luxons.sevenwonders.server.test.MockMessageChannel
+import org.springframework.messaging.simp.SimpMessagingTemplate
import java.util.*
import kotlin.test.*
@@ -29,10 +30,10 @@ class LobbyControllerTest {
@Before
fun setUp() {
val meterRegistry = SimpleMeterRegistry()
- val template = mockSimpMessagingTemplate()
+ val template = SimpMessagingTemplate(MockMessageChannel())
playerRepository = PlayerRepository(meterRegistry)
lobbyRepository = LobbyRepository(meterRegistry)
- lobbyController = LobbyController(lobbyRepository, playerRepository, template, "UNUSED", meterRegistry)
+ lobbyController = LobbyController(template, lobbyRepository, playerRepository, "UNUSED", meterRegistry)
}
@Test
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/ClientEventsAsserts.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/ClientEventsAsserts.kt
new file mode 100644
index 00000000..d87c2122
--- /dev/null
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/ClientEventsAsserts.kt
@@ -0,0 +1,48 @@
+package org.luxons.sevenwonders.server.test
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.FlowPreview
+import kotlinx.coroutines.channels.ReceiveChannel
+import kotlinx.coroutines.flow.produceIn
+import kotlinx.coroutines.withTimeoutOrNull
+import org.luxons.sevenwonders.client.SevenWondersSession
+import org.luxons.sevenwonders.model.api.events.GameEvent
+import org.luxons.sevenwonders.model.api.events.GameListEvent
+import kotlin.test.assertNotNull
+import kotlin.test.assertNull
+import kotlin.test.assertTrue
+import kotlin.time.Duration
+import kotlin.time.milliseconds
+import kotlin.time.seconds
+
+class EventAsserter(
+ val gameListEvents: ReceiveChannel<GameListEvent>,
+ val gameEvents: ReceiveChannel<GameEvent>,
+)
+
+@OptIn(FlowPreview::class)
+suspend fun SevenWondersSession.eventAsserter(scope: CoroutineScope): EventAsserter {
+ val gameListEvents = watchGames().produceIn(scope)
+ val gameEvents = watchGameEvents().produceIn(scope)
+ return EventAsserter(gameListEvents, gameEvents)
+}
+
+suspend inline fun EventAsserter.expectNoGameEvent(message: String? = null, timeout: Duration = 50.milliseconds) {
+ val event = withTimeoutOrNull(timeout) { gameEvents.receive() }
+ val extraMessage = message?.let { " ($it)" } ?: ""
+ assertNull(event, "Expected no game event$extraMessage, but received $event")
+}
+
+suspend inline fun <reified T : GameEvent> EventAsserter.expectGameEvent(timeout: Duration = 1.seconds): T {
+ val event = withTimeoutOrNull(timeout) { gameEvents.receive() }
+ assertNotNull(event, "Expected event of type ${T::class.simpleName}, received nothing in $timeout")
+ assertTrue(event is T, "Expected event of type ${T::class.simpleName}, received $event")
+ return event
+}
+
+suspend inline fun <reified T : GameListEvent> EventAsserter.expectGameListEvent(timeout: Duration = 1.seconds): T {
+ val event = withTimeoutOrNull(timeout) { gameListEvents.receive() }
+ assertNotNull(event, "Expected event of type ${T::class.simpleName}, received nothing in $timeout")
+ assertTrue(event is T, "Expected event of type ${T::class.simpleName}, received $event")
+ return event
+}
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/MockMessageChannel.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/MockMessageChannel.kt
new file mode 100644
index 00000000..e27a2550
--- /dev/null
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/MockMessageChannel.kt
@@ -0,0 +1,53 @@
+package org.luxons.sevenwonders.server.test
+
+import org.luxons.sevenwonders.model.api.events.GameEvent
+import org.luxons.sevenwonders.model.api.events.GameEventWrapper
+import org.luxons.sevenwonders.model.api.events.GameListEvent
+import org.luxons.sevenwonders.model.api.events.GameListEventWrapper
+import org.springframework.messaging.Message
+import org.springframework.messaging.MessageChannel
+import kotlin.test.assertEquals
+import kotlin.test.assertNotNull
+import kotlin.test.assertTrue
+
+class MockMessageChannel : MessageChannel {
+ private val _messages: MutableList<Message<*>> = mutableListOf()
+ val messages: List<Message<*>> get() = _messages
+
+ override fun send(message: Message<*>, timeout: Long): Boolean = _messages.add(message)
+
+ fun expectSentMessageTo(expectedDestination: String): Message<*> {
+ val m = _messages.removeFirstOrNull()
+ assertNotNull(m, "Expected sent message, but no messages found")
+ assertEquals(expectedDestination, m.headers["simpDestination"], "Incorrect message destination")
+ return m
+ }
+
+ fun expectNoMoreMessages() {
+ assertTrue(
+ actual = messages.isEmpty(),
+ message = "No more messages should have been sent, but ${messages.size} were found: $messages",
+ )
+ }
+}
+
+inline fun <reified T> MockMessageChannel.expectSentMessageWithPayload(expectedDestination: String): T {
+ val m = expectSentMessageTo(expectedDestination)
+ val payload = m.payload
+ assertTrue(payload is T, "Message payload should be of type ${T::class.simpleName}")
+ return payload
+}
+
+inline fun <reified T : GameListEvent> MockMessageChannel.expectSentGameListEvent(): T {
+ val wrappedEvent = expectSentMessageWithPayload<GameListEventWrapper>("/topic/games")
+ val event = wrappedEvent.event
+ assertTrue(event is T, "Expected game list event of type ${T::class.simpleName}, got $event")
+ return event
+}
+
+inline fun <reified T : GameEvent> MockMessageChannel.expectSentGameEventTo(username: String): T {
+ val wrappedEvent = expectSentMessageWithPayload<GameEventWrapper>("/user/$username/queue/game/events")
+ val event = wrappedEvent.event
+ assertTrue(event is T, "Expected game event of type ${T::class.simpleName}, got $event")
+ return event
+}
diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt
index efd40a6d..6e64e9da 100644
--- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt
+++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt
@@ -3,18 +3,8 @@ package org.luxons.sevenwonders.server.test
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeoutOrNull
-import org.springframework.messaging.Message
-import org.springframework.messaging.MessageChannel
-import org.springframework.messaging.simp.SimpMessagingTemplate
import kotlin.test.assertNotNull
-fun mockSimpMessagingTemplate(): SimpMessagingTemplate = SimpMessagingTemplate(
- object : MessageChannel {
- override fun send(message: Message<*>): Boolean = true
- override fun send(message: Message<*>, timeout: Long): Boolean = true
- },
-)
-
fun runAsyncTest(timeoutMillis: Long = 10000, block: suspend CoroutineScope.() -> Unit) = runBlocking {
val result = withTimeoutOrNull(timeoutMillis, block)
assertNotNull(result, "Test timed out, exceeded ${timeoutMillis}ms")
bgstack15