diff options
49 files changed, 553 insertions, 503 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index a27e4680..c52d8dcb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - val kotlinVersion = "1.3.40" + val kotlinVersion = "1.3.41" kotlin("jvm") version kotlinVersion apply false kotlin("multiplatform") version kotlinVersion apply false kotlin("plugin.spring") version kotlinVersion apply false diff --git a/settings.gradle b/settings.gradle index ee1cb240..11887e42 100644 --- a/settings.gradle +++ b/settings.gradle @@ -13,4 +13,7 @@ rootProject.name = "seven-wonders" include 'sw-common-model' include 'sw-engine' include 'sw-server' +include 'sw-client' include 'sw-ui' + +enableFeaturePreview("GRADLE_METADATA") diff --git a/sw-client/build.gradle.kts b/sw-client/build.gradle.kts new file mode 100644 index 00000000..35cebd82 --- /dev/null +++ b/sw-client/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + kotlin("multiplatform") + id("org.jlleitschuh.gradle.ktlint") +} + +val krossbowVersion = "0.3.1" + +kotlin { + jvm() + js() + sourceSets { + val commonMain by getting { + dependencies { + api(project(":sw-common-model")) + implementation(kotlin("stdlib-common")) + implementation("org.hildan.krossbow:krossbow-client-metadata:$krossbowVersion") + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("org.hildan.krossbow:krossbow-client-jvm:$krossbowVersion") + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + } + } + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + implementation("org.hildan.krossbow:krossbow-client-js:$krossbowVersion") + } + } + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } + } +} diff --git a/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt new file mode 100644 index 00000000..544c870b --- /dev/null +++ b/sw-client/src/commonMain/kotlin/org/luxons/sevenwonders/client/SevenWondersClient.kt @@ -0,0 +1,118 @@ +package org.luxons.sevenwonders.client + +import kotlinx.coroutines.channels.ReceiveChannel +import kotlinx.coroutines.channels.map +import org.hildan.krossbow.client.KrossbowClient +import org.hildan.krossbow.engines.KrossbowSession +import org.hildan.krossbow.engines.KrossbowSubscription +import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.GameState +import org.luxons.sevenwonders.model.PlayerTurnInfo +import org.luxons.sevenwonders.model.api.LobbyDTO +import org.luxons.sevenwonders.model.api.PlayerDTO +import org.luxons.sevenwonders.model.api.SEVEN_WONDERS_WS_ENDPOINT +import org.luxons.sevenwonders.model.api.actions.ChooseNameAction +import org.luxons.sevenwonders.model.api.actions.CreateGameAction +import org.luxons.sevenwonders.model.api.actions.JoinGameAction +import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction +import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction +import org.luxons.sevenwonders.model.api.errors.ErrorDTO +import org.luxons.sevenwonders.model.cards.PreparedCard + +class SevenWondersClient { + + private val stompClient = KrossbowClient() + + suspend fun connect(serverUrl: String): SevenWondersSession { + val session = stompClient.connect("$serverUrl$SEVEN_WONDERS_WS_ENDPOINT") + return SevenWondersSession(session) + } +} + +suspend inline fun <reified T : Any> KrossbowSession.request( + sendDestination: String, + receiveDestination: String, + payload: Any? = null +): T { + val sub = subscribe<T>(receiveDestination) + send(sendDestination, payload) + val msg = sub.messages.receive() + sub.unsubscribe() + return msg.payload +} + +data class SevenWondersSubscription<T : Any>( + val messages: ReceiveChannel<T>, + val unsubscribe: suspend () -> Unit +) + +private fun <T : Any> KrossbowSubscription<T>.ignoreHeaders() = SevenWondersSubscription( + messages = messages.map { it.payload }, + unsubscribe = { unsubscribe() } +) + +class SevenWondersSession(private val stompSession: KrossbowSession) { + + suspend fun disconnect() = stompSession.disconnect() + + suspend fun watchErrors(): KrossbowSubscription<ErrorDTO> = + stompSession.subscribe("/user/queue/errors") + + suspend fun chooseName(displayName: String): PlayerDTO { + val action = ChooseNameAction(displayName) + return stompSession.request("/app/chooseName", "/user/queue/nameChoice", action) + } + + suspend fun watchGames(): SevenWondersSubscription<Array<LobbyDTO>> = + stompSession.subscribe<Array<LobbyDTO>>("/topic/games").ignoreHeaders() + + suspend fun createGame(gameName: String): LobbyDTO { + val action = CreateGameAction(gameName) + return stompSession.request("/app/lobby/create", "/user/queue/lobby/joined", action) + } + + suspend fun joinGame(gameId: Long): LobbyDTO { + val action = JoinGameAction(gameId) + return stompSession.request("/app/lobby/join", "/user/queue/lobby/joined", action) + } + + suspend fun leaveGame() { + stompSession.send("/app/lobby/leave") + } + + suspend fun reorderPlayers(players: List<String>) { + stompSession.send("/app/lobby/reorderPlayers", ReorderPlayersAction(players)) + } + + suspend fun updateSettings(settings: CustomizableSettings) { + stompSession.send("/app/lobby/reorderPlayers", UpdateSettingsAction(settings)) + } + + suspend fun watchLobbyUpdates(gameId: Long): SevenWondersSubscription<LobbyDTO> = + stompSession.subscribe<LobbyDTO>("/topic/lobby/$gameId/updated").ignoreHeaders() + + suspend fun watchGameStart(gameId: Long): SevenWondersSubscription<Unit> = + stompSession.subscribe<Unit>("/topic/lobby/$gameId/started").ignoreHeaders() + + suspend fun startGame(gameId: Long) { + val sendDestination = "/app/lobby/startGame" + val receiveDestination = "/topic/lobby/$gameId/started" + stompSession.request<Unit>(sendDestination, receiveDestination) + } + + suspend fun watchPlayerReady(gameId: Long): SevenWondersSubscription<String> = + stompSession.subscribe<String>("/topic/game/$gameId/playerReady").ignoreHeaders() + + suspend fun watchTableUpdates(gameId: Long): SevenWondersSubscription<GameState> = + stompSession.subscribe<GameState>("/topic/game/$gameId/tableUpdates").ignoreHeaders() + + suspend fun watchPreparedCards(gameId: Long): SevenWondersSubscription<PreparedCard> = + stompSession.subscribe<PreparedCard>("/topic/game/$gameId/prepared").ignoreHeaders() + + suspend fun watchTurns(): SevenWondersSubscription<PlayerTurnInfo> = + stompSession.subscribe<PlayerTurnInfo>("/user/queue/game/turn").ignoreHeaders() + + suspend fun sayReady() { + stompSession.send("/app/game/sayReady") + } +} diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt new file mode 100644 index 00000000..04c7ef2f --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/Api.kt @@ -0,0 +1,23 @@ +package org.luxons.sevenwonders.model.api + +const val SEVEN_WONDERS_WS_ENDPOINT = "/seven-wonders-websocket" + +enum class State { + LOBBY, PLAYING +} + +data class LobbyDTO( + val id: Long, + val name: String, + val owner: String, + val players: List<PlayerDTO>, + val state: State +) + +data class PlayerDTO( + val username: String, + val displayName: String, + val index: Int, + val isGameOwner: Boolean, + val isUser: Boolean +) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt new file mode 100644 index 00000000..59bc2e5b --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/actions/Actions.kt @@ -0,0 +1,65 @@ +package org.luxons.sevenwonders.model.api.actions + +import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.PlayerMove + +/** + * The action to choose the player's name. This is the first action that should be called. + */ +class ChooseNameAction( + /** + * The display name of the player. May contain spaces and special characters. + */ + val playerName: String +) + +/** + * The action to create a game. + */ +class CreateGameAction( + /** + * The name of the game to create. + */ + val gameName: String +) + +/** + * The action to join a game. + */ +class JoinGameAction( + /** + * The ID of the game to join. + */ + val gameId: Long +) + +/** + * The action to prepare the next move during a game. + */ +class PrepareMoveAction( + /** + * The move to prepare. + */ + val move: PlayerMove +) + +/** + * The action to update the order of the players around the table. Can only be called in the lobby by the owner of the + * game. + */ +class ReorderPlayersAction( + /** + * The list of usernames of the players, in the new order. + */ + val orderedPlayers: List<String> +) + +/** + * The action to update the settings of the game. Can only be called in the lobby by the owner of the game. + */ +class UpdateSettingsAction( + /** + * The new values for the settings. + */ + val settings: CustomizableSettings +) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/errors/Errors.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/errors/Errors.kt new file mode 100644 index 00000000..f668f020 --- /dev/null +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/api/errors/Errors.kt @@ -0,0 +1,18 @@ +package org.luxons.sevenwonders.model.api.errors + +enum class ErrorType { + VALIDATION, CLIENT, SERVER +} + +data class ErrorDTO( + val code: String, + val message: String, + val type: ErrorType, + val details: List<ValidationErrorDTO> = emptyList() +) + +data class ValidationErrorDTO( + val path: String, + val message: String, + val rejectedValue: Any? = null +) diff --git a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt index 57cf3a00..11a3e8d8 100644 --- a/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt +++ b/sw-common-model/src/commonMain/kotlin/org/luxons/sevenwonders/model/cards/Cards.kt @@ -1,5 +1,6 @@ package org.luxons.sevenwonders.model.cards +import org.luxons.sevenwonders.model.api.PlayerDTO import org.luxons.sevenwonders.model.boards.Requirements import org.luxons.sevenwonders.model.resources.ResourceTransactions @@ -29,6 +30,11 @@ data class HandCard( val playability: CardPlayability ) +class PreparedCard( + val player: PlayerDTO, + val cardBack: CardBack +) + data class CardBack(val image: String) enum class PlayabilityLevel { diff --git a/sw-server/build.gradle.kts b/sw-server/build.gradle.kts index ecfb5380..59a533df 100644 --- a/sw-server/build.gradle.kts +++ b/sw-server/build.gradle.kts @@ -28,9 +28,11 @@ dependencies { testImplementation(kotlin("test")) testImplementation(kotlin("test-junit")) + testImplementation(project(":sw-client")) testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.hildan.jackstomp:jackstomp:2.0.0") testImplementation("com.fasterxml.jackson.module:jackson-module-kotlin") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0-M1") } // packages the frontend app within the jar diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ChooseNameAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ChooseNameAction.kt deleted file mode 100644 index ab444780..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ChooseNameAction.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation -import javax.validation.constraints.Size - -/** - * The action to choose the player's name. This is the first action that should be called. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class ChooseNameAction( - /** - * The display name of the player. May contain spaces and special characters. - */ - @Size(min = 2, max = 20) - @ApiTypeProperty(required = true) - val playerName: String -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/CreateGameAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/CreateGameAction.kt deleted file mode 100644 index c10f9c34..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/CreateGameAction.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation -import javax.validation.constraints.Size - -/** - * The action to create a game. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class CreateGameAction( - /** - * The name of the game to create. - */ - @Size(min = 2, max = 30) - @ApiTypeProperty(required = true) - val gameName: String -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/JoinGameAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/JoinGameAction.kt deleted file mode 100644 index 002309b3..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/JoinGameAction.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation - -/** - * The action to join a game. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class JoinGameAction( - /** - * The ID of the game to join. - */ - @ApiTypeProperty(required = true) - val gameId: Long -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/PrepareMoveAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/PrepareMoveAction.kt deleted file mode 100644 index ed420cfc..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/PrepareMoveAction.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation -import org.luxons.sevenwonders.model.PlayerMove - -/** - * The action to prepare the next move during a game. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class PrepareMoveAction( - /** - * The move to prepare. - */ - @ApiTypeProperty(required = true) - val move: PlayerMove -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ReorderPlayersAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ReorderPlayersAction.kt deleted file mode 100644 index 79a32137..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/ReorderPlayersAction.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation - -/** - * The action to update the order of the players around the table. Can only be called in the lobby by the owner of the - * game. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class ReorderPlayersAction( - /** - * The list of usernames of the players, in the new order. - */ - @ApiTypeProperty(required = true) - val orderedPlayers: List<String> -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/UpdateSettingsAction.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/UpdateSettingsAction.kt deleted file mode 100644 index 33303044..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/actions/UpdateSettingsAction.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.luxons.sevenwonders.actions - -import org.hildan.livedoc.core.annotations.types.ApiType -import org.hildan.livedoc.core.annotations.types.ApiTypeProperty -import org.luxons.sevenwonders.doc.Documentation -import org.luxons.sevenwonders.model.CustomizableSettings - -/** - * The action to update the settings of the game. Can only be called in the lobby by the owner of the game. - */ -@ApiType(group = Documentation.GROUP_ACTIONS) -class UpdateSettingsAction( - /** - * The new values for the settings. - */ - @ApiTypeProperty(required = true) - val settings: CustomizableSettings -) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/LobbyDTO.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/LobbyDTO.kt deleted file mode 100644 index b4445f32..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/LobbyDTO.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.luxons.sevenwonders.api - -import org.luxons.sevenwonders.lobby.Lobby -import org.luxons.sevenwonders.lobby.State - -data class LobbyDTO( - val id: Long, - val name: String, - val owner: String, - val players: List<PlayerDTO>, - val state: State -) - -fun Lobby.toDTO(currentUser: String): LobbyDTO { - val players = getPlayers().map { it.toDTO(currentUser) } - return LobbyDTO(id, name, owner.username, players, state) -} diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/PlayerDTO.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/PlayerDTO.kt deleted file mode 100644 index 54c69122..00000000 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/api/PlayerDTO.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.luxons.sevenwonders.api - -import org.luxons.sevenwonders.lobby.Player - -data class PlayerDTO( - val username: String, - val displayName: String, - val index: Int, - val isGameOwner: Boolean, - val isUser: Boolean -) - -fun Player.toDTO(currentUser: String) = - PlayerDTO(username, displayName, index, isGameOwner, username === currentUser) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/errors/ErrorDTO.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/Converters.kt index c3eae0b5..7e1a6fdf 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/errors/ErrorDTO.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/Converters.kt @@ -1,25 +1,9 @@ -package org.luxons.sevenwonders.errors +package org.luxons.sevenwonders.server +import org.luxons.sevenwonders.model.api.errors.ValidationErrorDTO import org.springframework.validation.FieldError import org.springframework.validation.ObjectError -enum class ErrorType { - VALIDATION, CLIENT, SERVER -} - -data class ErrorDTO( - val code: String, - val message: String, - val type: ErrorType, - val details: List<ValidationErrorDTO> = emptyList() -) - -data class ValidationErrorDTO( - val path: String, - val message: String, - val rejectedValue: Any? = null -) - fun ObjectError.toDTO() = (this as? FieldError)?.fieldError() ?: objectError() fun FieldError.fieldError(): ValidationErrorDTO = diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/errors/ExceptionHandler.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/ExceptionHandler.kt index 76d01f5f..f006505b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/errors/ExceptionHandler.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/ExceptionHandler.kt @@ -1,5 +1,7 @@ -package org.luxons.sevenwonders.errors +package org.luxons.sevenwonders.server +import org.luxons.sevenwonders.model.api.errors.ErrorDTO +import org.luxons.sevenwonders.model.api.errors.ErrorType import org.slf4j.LoggerFactory import org.springframework.messaging.converter.MessageConversionException import org.springframework.messaging.handler.annotation.MessageExceptionHandler diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/SevenWonders.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/SevenWonders.kt index 04f03956..51710115 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/SevenWonders.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/SevenWonders.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders +package org.luxons.sevenwonders.server import org.hildan.livedoc.spring.boot.starter.EnableJSONDoc import org.springframework.boot.autoconfigure.SpringBootApplication diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt new file mode 100644 index 00000000..6f0fc180 --- /dev/null +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/api/Converters.kt @@ -0,0 +1,14 @@ +package org.luxons.sevenwonders.server.api + +import org.luxons.sevenwonders.model.api.LobbyDTO +import org.luxons.sevenwonders.model.api.PlayerDTO +import org.luxons.sevenwonders.server.lobby.Lobby +import org.luxons.sevenwonders.server.lobby.Player + +fun Lobby.toDTO(currentUser: String): LobbyDTO { + val players = getPlayers().map { it.toDTO(currentUser) } + return LobbyDTO(id, name, owner.username, players, state) +} + +fun Player.toDTO(currentUser: String) = + PlayerDTO(username, displayName, index, isGameOwner, username === currentUser) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/AnonymousUsersHandshakeHandler.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/AnonymousUsersHandshakeHandler.kt index db707d1b..56b3400f 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/AnonymousUsersHandshakeHandler.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/AnonymousUsersHandshakeHandler.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.config +package org.luxons.sevenwonders.server.config import org.springframework.http.server.ServerHttpRequest import org.springframework.security.authentication.UsernamePasswordAuthenticationToken diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/TopicSubscriptionInterceptor.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/TopicSubscriptionInterceptor.kt index f4c55c2c..5342503b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/TopicSubscriptionInterceptor.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/TopicSubscriptionInterceptor.kt @@ -1,6 +1,6 @@ -package org.luxons.sevenwonders.config +package org.luxons.sevenwonders.server.config -import org.luxons.sevenwonders.validation.DestinationAccessValidator +import org.luxons.sevenwonders.server.validation.DestinationAccessValidator import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.Message diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/WebSecurityConfig.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt index 06b2bc90..9557ba1a 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/WebSecurityConfig.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSecurityConfig.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.config +package org.luxons.sevenwonders.server.config import org.springframework.context.annotation.Configuration import org.springframework.security.config.annotation.web.builders.HttpSecurity diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/WebSocketConfig.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt index b49d39cc..72312b70 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/config/WebSocketConfig.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/config/WebSocketConfig.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.config +package org.luxons.sevenwonders.server.config import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/GameBrowserController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt index f856365f..e2f0458e 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/GameBrowserController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserController.kt @@ -1,14 +1,14 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.hildan.livedoc.core.annotations.Api -import org.luxons.sevenwonders.actions.CreateGameAction -import org.luxons.sevenwonders.actions.JoinGameAction -import org.luxons.sevenwonders.api.LobbyDTO -import org.luxons.sevenwonders.api.toDTO -import org.luxons.sevenwonders.errors.ApiMisuseException -import org.luxons.sevenwonders.lobby.Lobby -import org.luxons.sevenwonders.repositories.LobbyRepository -import org.luxons.sevenwonders.repositories.PlayerRepository +import org.luxons.sevenwonders.model.api.LobbyDTO +import org.luxons.sevenwonders.model.api.actions.CreateGameAction +import org.luxons.sevenwonders.model.api.actions.JoinGameAction +import org.luxons.sevenwonders.server.ApiMisuseException +import org.luxons.sevenwonders.server.api.toDTO +import org.luxons.sevenwonders.server.lobby.Lobby +import org.luxons.sevenwonders.server.repositories.LobbyRepository +import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.handler.annotation.MessageMapping diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/GameController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt index a923f845..e1fae39b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/GameController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/GameController.kt @@ -1,14 +1,13 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.hildan.livedoc.core.annotations.Api -import org.luxons.sevenwonders.actions.PrepareMoveAction -import org.luxons.sevenwonders.api.PlayerDTO -import org.luxons.sevenwonders.api.toDTO import org.luxons.sevenwonders.engine.Game import org.luxons.sevenwonders.model.GameState -import org.luxons.sevenwonders.model.cards.CardBack -import org.luxons.sevenwonders.lobby.Player -import org.luxons.sevenwonders.repositories.PlayerRepository +import org.luxons.sevenwonders.model.api.actions.PrepareMoveAction +import org.luxons.sevenwonders.model.cards.PreparedCard +import org.luxons.sevenwonders.server.api.toDTO +import org.luxons.sevenwonders.server.lobby.Player +import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.handler.annotation.MessageMapping @@ -98,5 +97,3 @@ class GameController @Autowired constructor( private val logger = LoggerFactory.getLogger(GameController::class.java) } } - -class PreparedCard(val player: PlayerDTO, val cardBack: CardBack) diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/HomeController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt index bd672000..a0d53f8b 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/HomeController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/HomeController.kt @@ -1,10 +1,10 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.hildan.livedoc.core.annotations.Api -import org.luxons.sevenwonders.actions.ChooseNameAction -import org.luxons.sevenwonders.api.PlayerDTO -import org.luxons.sevenwonders.api.toDTO -import org.luxons.sevenwonders.repositories.PlayerRepository +import org.luxons.sevenwonders.model.api.PlayerDTO +import org.luxons.sevenwonders.model.api.actions.ChooseNameAction +import org.luxons.sevenwonders.server.api.toDTO +import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.handler.annotation.MessageMapping diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/LobbyController.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt index 4e4120a9..19834ef1 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/controllers/LobbyController.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/controllers/LobbyController.kt @@ -1,13 +1,13 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.hildan.livedoc.core.annotations.Api -import org.luxons.sevenwonders.actions.ReorderPlayersAction -import org.luxons.sevenwonders.actions.UpdateSettingsAction -import org.luxons.sevenwonders.api.LobbyDTO -import org.luxons.sevenwonders.api.toDTO -import org.luxons.sevenwonders.lobby.Player -import org.luxons.sevenwonders.repositories.LobbyRepository -import org.luxons.sevenwonders.repositories.PlayerRepository +import org.luxons.sevenwonders.model.api.LobbyDTO +import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction +import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction +import org.luxons.sevenwonders.server.api.toDTO +import org.luxons.sevenwonders.server.lobby.Player +import org.luxons.sevenwonders.server.repositories.LobbyRepository +import org.luxons.sevenwonders.server.repositories.PlayerRepository import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.messaging.handler.annotation.MessageMapping @@ -98,7 +98,7 @@ class LobbyController @Autowired constructor( val game = lobby.startGame() logger.info("Game {} successfully started", game.id) - template.convertAndSend("/topic/lobby/" + lobby.id + "/started", "") + template.convertAndSend("/topic/lobby/" + lobby.id + "/started", Unit) } companion object { diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/doc/Documentation.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/doc/Documentation.kt index 3b04356a..f033ddd0 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/doc/Documentation.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/doc/Documentation.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.doc +package org.luxons.sevenwonders.server.doc object Documentation { diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/lobby/Lobby.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt index 4b9f5bc3..7158a417 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/lobby/Lobby.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Lobby.kt @@ -1,12 +1,9 @@ -package org.luxons.sevenwonders.lobby +package org.luxons.sevenwonders.server.lobby import org.luxons.sevenwonders.engine.Game -import org.luxons.sevenwonders.model.CustomizableSettings import org.luxons.sevenwonders.engine.data.GameDefinition - -enum class State { - LOBBY, PLAYING -} +import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.api.State class Lobby( val id: Long, diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/lobby/Player.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Player.kt index d057fcb2..8ed7d048 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/lobby/Player.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/lobby/Player.kt @@ -1,7 +1,7 @@ -package org.luxons.sevenwonders.lobby +package org.luxons.sevenwonders.server.lobby -import org.luxons.sevenwonders.errors.ApiMisuseException import org.luxons.sevenwonders.engine.Game +import org.luxons.sevenwonders.server.ApiMisuseException class Player( val username: String, diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/repositories/LobbyRepository.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt index 02866ffc..ff06f549 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/repositories/LobbyRepository.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepository.kt @@ -1,8 +1,8 @@ -package org.luxons.sevenwonders.repositories +package org.luxons.sevenwonders.server.repositories import org.luxons.sevenwonders.engine.data.GameDefinition -import org.luxons.sevenwonders.lobby.Lobby -import org.luxons.sevenwonders.lobby.Player +import org.luxons.sevenwonders.server.lobby.Lobby +import org.luxons.sevenwonders.server.lobby.Player import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Repository import java.util.HashMap diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/repositories/PlayerRepository.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt index 4d552eaa..00badf75 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/repositories/PlayerRepository.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepository.kt @@ -1,7 +1,7 @@ -package org.luxons.sevenwonders.repositories +package org.luxons.sevenwonders.server.repositories -import org.luxons.sevenwonders.errors.ApiMisuseException -import org.luxons.sevenwonders.lobby.Player +import org.luxons.sevenwonders.server.ApiMisuseException +import org.luxons.sevenwonders.server.lobby.Player import org.springframework.stereotype.Repository import java.util.HashMap diff --git a/sw-server/src/main/kotlin/org/luxons/sevenwonders/validation/DestinationAccessValidator.kt b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/validation/DestinationAccessValidator.kt index 5f704357..04daf311 100644 --- a/sw-server/src/main/kotlin/org/luxons/sevenwonders/validation/DestinationAccessValidator.kt +++ b/sw-server/src/main/kotlin/org/luxons/sevenwonders/server/validation/DestinationAccessValidator.kt @@ -1,6 +1,6 @@ -package org.luxons.sevenwonders.validation +package org.luxons.sevenwonders.server.validation -import org.luxons.sevenwonders.repositories.LobbyRepository +import org.luxons.sevenwonders.server.repositories.LobbyRepository import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component import java.util.regex.Pattern diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/SevenWondersTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/SevenWondersTest.kt deleted file mode 100644 index 01de366a..00000000 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/SevenWondersTest.kt +++ /dev/null @@ -1,145 +0,0 @@ -package org.luxons.sevenwonders - -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.luxons.sevenwonders.test.api.SevenWondersClient -import org.luxons.sevenwonders.test.api.SevenWondersSession -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 java.util.concurrent.TimeUnit -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull - -@RunWith(SpringRunner::class) -@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) -class SevenWondersTest { - - @LocalServerPort - private val randomServerPort: Int = 0 - - private lateinit var client: SevenWondersClient - - private lateinit var serverUrl: String - - @Before - fun setUpClientAndUrl() { - client = SevenWondersClient() - serverUrl = "ws://localhost:$randomServerPort" - } - - private fun disconnect(vararg sessions: SevenWondersSession) { - for (session in sessions) { - session.disconnect() - } - } - - @Test - fun chooseName() { - val session = client.connect(serverUrl) - val playerName = "Test User" - val player = session.chooseName(playerName) - assertNotNull(player) - assertEquals(playerName, player.displayName) - session.disconnect() - } - - private fun newPlayer(name: String): SevenWondersSession { - val otherSession = client.connect(serverUrl) - otherSession.chooseName(name) - return otherSession - } - - @Test - fun lobbySubscription_ignoredForOutsiders() { - val ownerSession = newPlayer("GameOwner") - val session1 = newPlayer("Player1") - val session2 = newPlayer("Player2") - val gameName = "Test Game" - val lobby = ownerSession.createGame(gameName) - session1.joinGame(lobby.id) - session2.joinGame(lobby.id) - - val outsiderSession = newPlayer("Outsider") - val session = outsiderSession.jackstompSession - val started = session.subscribeEmptyMsgs("/topic/lobby/" + lobby.id + "/started") - - ownerSession.startGame(lobby.id) - val nothing = started.next(1, TimeUnit.SECONDS) - assertNull(nothing) - disconnect(ownerSession, session1, session2, outsiderSession) - } - - @Test - fun createGame_success() { - val ownerSession = newPlayer("GameOwner") - - val gameName = "Test Game" - val lobby = ownerSession.createGame(gameName) - assertNotNull(lobby) - assertEquals(gameName, lobby.name) - - disconnect(ownerSession) - } - - @Test - fun createGame_seenByConnectedPlayers() { - val otherSession = newPlayer("OtherPlayer") - val games = otherSession.watchGames() - - var receivedLobbies = games.next() - assertNotNull(receivedLobbies) - assertEquals(0, receivedLobbies.size) - - val ownerSession = newPlayer("GameOwner") - val gameName = "Test Game" - val createdLobby = ownerSession.createGame(gameName) - - receivedLobbies = games.next() - assertNotNull(receivedLobbies) - assertEquals(1, receivedLobbies.size) - val receivedLobby = receivedLobbies[0] - assertEquals(createdLobby.id, receivedLobby.id) - assertEquals(createdLobby.name, receivedLobby.name) - - disconnect(ownerSession, otherSession) - } - - @Test - fun startGame_3players() { - val session1 = newPlayer("Player1") - val session2 = newPlayer("Player2") - - val lobby = session1.createGame("Test Game") - session2.joinGame(lobby.id) - - val session3 = newPlayer("Player3") - session3.joinGame(lobby.id) - - session1.startGame(lobby.id) - - val turns1 = session1.watchTurns() - val turns2 = session2.watchTurns() - val turns3 = session3.watchTurns() - session1.sayReady() - session2.sayReady() - session3.sayReady() - val turn1 = turns1.next() - val turn2 = turns2.next() - val turn3 = turns3.next() - assertNotNull(turn1) - assertNotNull(turn2) - assertNotNull(turn3) - - disconnect(session1, session2, session3) - } - - @After - fun tearDown() { - client.stop() - } -} 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 new file mode 100644 index 00000000..4771076d --- /dev/null +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/SevenWondersTest.kt @@ -0,0 +1,146 @@ +package org.luxons.sevenwonders.server + +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withTimeout +import kotlinx.coroutines.withTimeoutOrNull +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.luxons.sevenwonders.client.SevenWondersClient +import org.luxons.sevenwonders.client.SevenWondersSession +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.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +@RunWith(SpringRunner::class) +@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) +class SevenWondersTest { + + @LocalServerPort + private val randomServerPort: Int = 0 + + private lateinit var client: SevenWondersClient + + private lateinit var serverUrl: String + + @Before + fun setUpClientAndUrl() { + client = SevenWondersClient() + serverUrl = "ws://localhost:$randomServerPort" + } + + private suspend fun disconnect(vararg sessions: SevenWondersSession) { + for (session in sessions) { + session.disconnect() + } + } + + @Test + fun chooseName() { + runBlocking { + val session = client.connect(serverUrl) + val playerName = "Test User" + val player = session.chooseName(playerName) + assertNotNull(player) + assertEquals(playerName, player.displayName) + session.disconnect() + } + } + + private suspend fun newPlayer(name: String): SevenWondersSession = client.connect(serverUrl).apply { + chooseName(name) + } + + @Test + fun lobbySubscription_ignoredForOutsiders() { + runBlocking { + val ownerSession = newPlayer("GameOwner") + val session1 = newPlayer("Player1") + val session2 = newPlayer("Player2") + val gameName = "Test Game" + val lobby = ownerSession.createGame(gameName) + session1.joinGame(lobby.id) + session2.joinGame(lobby.id) + + val outsiderSession = newPlayer("Outsider") + val (started) = outsiderSession.watchGameStart(lobby.id) + + ownerSession.startGame(lobby.id) + val nothing = withTimeoutOrNull(30) { started.receive() } + assertNull(nothing) + disconnect(ownerSession, session1, session2, outsiderSession) + } + } + + @Test + fun createGame_success() { + runBlocking { + val ownerSession = newPlayer("GameOwner") + + val gameName = "Test Game" + val lobby = ownerSession.createGame(gameName) + assertNotNull(lobby) + assertEquals(gameName, lobby.name) + + disconnect(ownerSession) + } + } + + @Test + fun createGame_seenByConnectedPlayers() { + runBlocking { + val otherSession = newPlayer("OtherPlayer") + val (games) = otherSession.watchGames() + + var receivedLobbies = withTimeout(500) { games.receive() } + assertNotNull(receivedLobbies) + assertEquals(0, receivedLobbies.size) + + val ownerSession = newPlayer("GameOwner") + val gameName = "Test Game" + val createdLobby = ownerSession.createGame(gameName) + + receivedLobbies = withTimeout(500) { games.receive() } + assertNotNull(receivedLobbies) + assertEquals(1, receivedLobbies.size) + val receivedLobby = receivedLobbies[0] + assertEquals(createdLobby.id, receivedLobby.id) + assertEquals(createdLobby.name, receivedLobby.name) + + disconnect(ownerSession, otherSession) + } + } + + @Test + fun startGame_3players() = runBlocking { + val session1 = newPlayer("Player1") + val session2 = newPlayer("Player2") + + val lobby = session1.createGame("Test Game") + session2.joinGame(lobby.id) + + val session3 = newPlayer("Player3") + session3.joinGame(lobby.id) + + session1.startGame(lobby.id) + + val (turns1) = session1.watchTurns() + val (turns2) = session2.watchTurns() + val (turns3) = session3.watchTurns() + session1.sayReady() + session2.sayReady() + session3.sayReady() + val turn1 = turns1.receive() + val turn2 = turns2.receive() + val turn3 = turns3.receive() + assertNotNull(turn1) + assertNotNull(turn2) + assertNotNull(turn3) + + disconnect(session1, session2, session3) + } +} diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/GameBrowserControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt index 343b7f34..804b5f6e 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/GameBrowserControllerTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/GameBrowserControllerTest.kt @@ -1,15 +1,15 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.junit.Before import org.junit.Test -import org.luxons.sevenwonders.actions.CreateGameAction -import org.luxons.sevenwonders.actions.JoinGameAction -import org.luxons.sevenwonders.api.toDTO -import org.luxons.sevenwonders.controllers.GameBrowserController.UserAlreadyInGameException -import org.luxons.sevenwonders.repositories.LobbyRepository -import org.luxons.sevenwonders.repositories.PlayerNotFoundException -import org.luxons.sevenwonders.repositories.PlayerRepository -import org.luxons.sevenwonders.test.mockSimpMessagingTemplate +import org.luxons.sevenwonders.model.api.actions.CreateGameAction +import org.luxons.sevenwonders.model.api.actions.JoinGameAction +import org.luxons.sevenwonders.server.api.toDTO +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 kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/HomeControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt index 3374a025..c2c3c05d 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/HomeControllerTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/HomeControllerTest.kt @@ -1,8 +1,8 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.junit.Test -import org.luxons.sevenwonders.actions.ChooseNameAction -import org.luxons.sevenwonders.repositories.PlayerRepository +import org.luxons.sevenwonders.model.api.actions.ChooseNameAction +import org.luxons.sevenwonders.server.repositories.PlayerRepository import kotlin.test.assertEquals class HomeControllerTest { diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/LobbyControllerTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt index 90db48f5..e8b2a9c0 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/LobbyControllerTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/LobbyControllerTest.kt @@ -1,20 +1,20 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import org.junit.Before import org.junit.Test -import org.luxons.sevenwonders.actions.ReorderPlayersAction -import org.luxons.sevenwonders.actions.UpdateSettingsAction +import org.luxons.sevenwonders.model.api.actions.ReorderPlayersAction +import org.luxons.sevenwonders.model.api.actions.UpdateSettingsAction import org.luxons.sevenwonders.model.CustomizableSettings import org.luxons.sevenwonders.model.WonderSidePickMethod.ALL_A -import org.luxons.sevenwonders.lobby.Lobby -import org.luxons.sevenwonders.lobby.Player -import org.luxons.sevenwonders.lobby.PlayerIsNotOwnerException -import org.luxons.sevenwonders.lobby.PlayerNotInLobbyException -import org.luxons.sevenwonders.lobby.State -import org.luxons.sevenwonders.repositories.LobbyRepository -import org.luxons.sevenwonders.repositories.PlayerNotFoundException -import org.luxons.sevenwonders.repositories.PlayerRepository -import org.luxons.sevenwonders.test.mockSimpMessagingTemplate +import org.luxons.sevenwonders.server.lobby.Lobby +import org.luxons.sevenwonders.server.lobby.Player +import org.luxons.sevenwonders.server.lobby.PlayerIsNotOwnerException +import org.luxons.sevenwonders.server.lobby.PlayerNotInLobbyException +import org.luxons.sevenwonders.model.api.State +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 java.util.HashMap import kotlin.test.assertEquals import kotlin.test.assertFailsWith diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/TestPrincipal.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/TestPrincipal.kt index 76b0f8fa..6a57c570 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/controllers/TestPrincipal.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/controllers/TestPrincipal.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.controllers +package org.luxons.sevenwonders.server.controllers import java.security.Principal diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/lobby/LobbyTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt index bf1ea4bf..80f5e866 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/lobby/LobbyTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/lobby/LobbyTest.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.lobby +package org.luxons.sevenwonders.server.lobby import org.junit.Assume.assumeTrue import org.junit.Before @@ -8,14 +8,15 @@ import org.junit.experimental.theories.DataPoints import org.junit.experimental.theories.Theories import org.junit.experimental.theories.Theory import org.junit.runner.RunWith -import org.luxons.sevenwonders.model.CustomizableSettings import org.luxons.sevenwonders.engine.data.GameDefinition -import org.luxons.sevenwonders.lobby.Lobby.GameAlreadyStartedException -import org.luxons.sevenwonders.lobby.Lobby.PlayerListMismatchException -import org.luxons.sevenwonders.lobby.Lobby.PlayerNameAlreadyUsedException -import org.luxons.sevenwonders.lobby.Lobby.PlayerOverflowException -import org.luxons.sevenwonders.lobby.Lobby.PlayerUnderflowException -import org.luxons.sevenwonders.lobby.Lobby.UnknownPlayerException +import org.luxons.sevenwonders.model.CustomizableSettings +import org.luxons.sevenwonders.model.api.State +import org.luxons.sevenwonders.server.lobby.Lobby.GameAlreadyStartedException +import org.luxons.sevenwonders.server.lobby.Lobby.PlayerListMismatchException +import org.luxons.sevenwonders.server.lobby.Lobby.PlayerNameAlreadyUsedException +import org.luxons.sevenwonders.server.lobby.Lobby.PlayerOverflowException +import org.luxons.sevenwonders.server.lobby.Lobby.PlayerUnderflowException +import org.luxons.sevenwonders.server.lobby.Lobby.UnknownPlayerException import kotlin.test.assertEquals import kotlin.test.assertFailsWith import kotlin.test.assertFalse diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepositoryTest.kt index 446feee6..c59dc49f 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/repositories/LobbyRepositoryTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/repositories/LobbyRepositoryTest.kt @@ -1,8 +1,8 @@ -package org.luxons.sevenwonders.repositories +package org.luxons.sevenwonders.server.repositories import org.junit.Before import org.junit.Test -import org.luxons.sevenwonders.lobby.Player +import org.luxons.sevenwonders.server.lobby.Player import kotlin.test.assertFailsWith import kotlin.test.assertNotNull import kotlin.test.assertSame diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepositoryTest.kt index aeedc54c..fc016903 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/repositories/PlayerRepositoryTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/repositories/PlayerRepositoryTest.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.repositories +package org.luxons.sevenwonders.server.repositories import org.junit.Before import org.junit.Test diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/TestUtils.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt index 9f328c5f..6eaa7e49 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/TestUtils.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/test/TestUtils.kt @@ -1,4 +1,4 @@ -package org.luxons.sevenwonders.test +package org.luxons.sevenwonders.server.test import org.springframework.messaging.Message import org.springframework.messaging.MessageChannel diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/validation/DestinationAccessValidatorTest.kt index 85d03e99..c5ef3f44 100644 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/validation/DestinationAccessValidatorTest.kt +++ b/sw-server/src/test/kotlin/org/luxons/sevenwonders/server/validation/DestinationAccessValidatorTest.kt @@ -1,11 +1,11 @@ -package org.luxons.sevenwonders.validation +package org.luxons.sevenwonders.server.validation import org.junit.Before import org.junit.Test -import org.luxons.sevenwonders.lobby.Lobby -import org.luxons.sevenwonders.lobby.Player -import org.luxons.sevenwonders.repositories.LobbyNotFoundException -import org.luxons.sevenwonders.repositories.LobbyRepository +import org.luxons.sevenwonders.server.lobby.Lobby +import org.luxons.sevenwonders.server.lobby.Player +import org.luxons.sevenwonders.server.repositories.LobbyNotFoundException +import org.luxons.sevenwonders.server.repositories.LobbyRepository import kotlin.test.assertFailsWith import kotlin.test.assertFalse import kotlin.test.assertTrue diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersClient.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersClient.kt deleted file mode 100644 index 95384e06..00000000 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersClient.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.luxons.sevenwonders.test.api - -import com.fasterxml.jackson.module.kotlin.KotlinModule -import org.hildan.jackstomp.JackstompClient -import org.luxons.sevenwonders.config.SEVEN_WONDERS_WS_ENDPOINT -import org.springframework.messaging.converter.MappingJackson2MessageConverter -import java.util.concurrent.ExecutionException -import java.util.concurrent.TimeoutException - -class SevenWondersClient { - - private val client: JackstompClient - - init { - val mappingJackson2MessageConverter = MappingJackson2MessageConverter() - mappingJackson2MessageConverter.objectMapper.registerModule(KotlinModule()) - - client = JackstompClient() - client.webSocketClient.messageConverter = mappingJackson2MessageConverter - } - - @Throws(InterruptedException::class, ExecutionException::class, TimeoutException::class) - fun connect(serverUrl: String): SevenWondersSession { - val session = client.syncConnect(serverUrl + SEVEN_WONDERS_WS_ENDPOINT) - return SevenWondersSession(session) - } - - fun stop() { - client.stop() - } -} diff --git a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersSession.kt b/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersSession.kt deleted file mode 100644 index f02a5c3b..00000000 --- a/sw-server/src/test/kotlin/org/luxons/sevenwonders/test/api/SevenWondersSession.kt +++ /dev/null @@ -1,70 +0,0 @@ -package org.luxons.sevenwonders.test.api - -import org.hildan.jackstomp.Channel -import org.hildan.jackstomp.JackstompSession -import org.luxons.sevenwonders.actions.ChooseNameAction -import org.luxons.sevenwonders.actions.CreateGameAction -import org.luxons.sevenwonders.actions.JoinGameAction -import org.luxons.sevenwonders.api.LobbyDTO -import org.luxons.sevenwonders.api.PlayerDTO -import org.luxons.sevenwonders.errors.ErrorDTO -import org.luxons.sevenwonders.model.PlayerTurnInfo -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertTrue - -class SevenWondersSession(val jackstompSession: JackstompSession) { - - fun disconnect() { - jackstompSession.disconnect() - } - - fun watchErrors(): Channel<ErrorDTO> = jackstompSession.subscribe("/user/queue/errors", ErrorDTO::class.java) - - @Throws(InterruptedException::class) - fun chooseName(displayName: String): PlayerDTO { - val action = ChooseNameAction(displayName) - return jackstompSession.request(action, PlayerDTO::class.java, "/app/chooseName", "/user/queue/nameChoice") - } - - fun watchGames(): Channel<Array<LobbyDTO>> { - return jackstompSession.subscribe("/topic/games", Array<LobbyDTO>::class.java) - } - - @Throws(InterruptedException::class) - fun createGame(gameName: String): LobbyDTO { - val action = CreateGameAction(gameName) - return jackstompSession.request(action, LobbyDTO::class.java, "/app/lobby/create", "/user/queue/lobby/joined") - } - - @Throws(InterruptedException::class) - fun joinGame(gameId: Long): LobbyDTO { - val action = JoinGameAction(gameId) - val lobby = - jackstompSession.request(action, LobbyDTO::class.java, "/app/lobby/join", "/user/queue/lobby/joined") - assertNotNull(lobby) - assertEquals(gameId, lobby.id) - return lobby - } - - fun watchLobbyUpdates(gameId: Long): Channel<LobbyDTO> = - jackstompSession.subscribe("/topic/lobby/$gameId/updated", LobbyDTO::class.java) - - fun watchLobbyStart(gameId: Long): Channel<LobbyDTO> = - jackstompSession.subscribe("/topic/lobby/$gameId/started", LobbyDTO::class.java) - - @Throws(InterruptedException::class) - fun startGame(gameId: Long) { - val sendDestination = "/app/lobby/startGame" - val receiveDestination = "/topic/lobby/$gameId/started" - val received = jackstompSession.request(null, sendDestination, receiveDestination) - assertTrue(received) - } - - fun sayReady() { - jackstompSession.send("/app/game/sayReady", "") - } - - fun watchTurns(): Channel<PlayerTurnInfo> = - jackstompSession.subscribe("/user/queue/game/turn", PlayerTurnInfo::class.java) -} diff --git a/sw-ui/build.gradle b/sw-ui/build.gradle index 61f01053..201cd6a1 100644 --- a/sw-ui/build.gradle +++ b/sw-ui/build.gradle @@ -4,6 +4,17 @@ plugins { apply plugin: 'base' +// Fix for "Could not find org.nodejs:node:10.15.3" +// Gradle node plugin + Gradle metadata seems to need this fix +// https://github.com/JetBrains/kotlin-native/issues/1612 +repositories.whenObjectAdded { + if (it instanceof IvyArtifactRepository) { + metadataSources { + artifact() + } + } +} + buildDir = 'build' node { |