-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 依據第二次code review修正 依據第一次code review修正 實作離開房間 * 依據第三次code review修正 * 根據第四次code review修正 --------- Co-authored-by: Ted <[email protected]>
- Loading branch information
Showing
6 changed files
with
126 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
application/src/main/kotlin/tw/waterballsa/gaas/application/usecases/LeaveRoomUsecase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package tw.waterballsa.gaas.application.usecases | ||
|
||
import tw.waterballsa.gaas.application.eventbus.EventBus | ||
import tw.waterballsa.gaas.application.repositories.RoomRepository | ||
import tw.waterballsa.gaas.domain.Room | ||
import tw.waterballsa.gaas.domain.Room.Player | ||
import tw.waterballsa.gaas.exceptions.NotFoundException.Companion.notFound | ||
import javax.inject.Named | ||
|
||
@Named | ||
class LeaveRoomUsecase( | ||
private val roomRepository: RoomRepository, | ||
private val eventBus: EventBus | ||
) { | ||
|
||
fun execute(request: LeaveRoomUsecase.Request) { | ||
with(request) { | ||
val room = findRoomById(Room.Id(roomId)) | ||
room.leaveRoom(Player.Id(playerId)) | ||
roomRepository.leaveRoom(room) | ||
} | ||
} | ||
|
||
private fun findRoomById(roomId: Room.Id) = | ||
roomRepository.findById(roomId) | ||
?: throw notFound(Room::class).id(roomId) | ||
|
||
data class Request( | ||
val roomId: String, | ||
val playerId: String | ||
) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,18 @@ | ||
package tw.waterballsa.gaas.spring.it.controllers | ||
|
||
import org.assertj.core.api.Assertions.* | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.AfterEach | ||
import org.junit.jupiter.api.Assertions.assertFalse | ||
import org.junit.jupiter.api.BeforeEach | ||
import org.junit.jupiter.api.Test | ||
import org.springframework.beans.factory.annotation.Autowired | ||
import org.springframework.security.oauth2.core.oidc.OidcIdToken | ||
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser | ||
import org.springframework.security.oauth2.core.oidc.user.OidcUser | ||
import org.springframework.security.oauth2.jwt.Jwt | ||
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oidcLogin | ||
import org.springframework.test.web.servlet.ResultActions | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete | ||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath | ||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status | ||
import tw.waterballsa.gaas.application.model.Pagination | ||
|
@@ -272,6 +272,18 @@ class RoomControllerTest @Autowired constructor( | |
.thenPlayersShouldBeInTheRoom(roomC.roomId!!, hostA, playerB) | ||
} | ||
|
||
@Test | ||
fun givenHostAndPlayerBAndPlayerCAreInRoomD_WhenHostLeaveRoomD_ThenPreviousHostShouldBeNotInRoomDAndChangedNewHost() { | ||
val userA = testUser | ||
val host = userA.toRoomPlayer() | ||
val playerB = createUser("2", "[email protected]", "winner1122").toRoomPlayer() | ||
val playerC = createUser("3", "[email protected]", "winner0033").toRoomPlayer() | ||
|
||
givenHostAndPlayersAreInTheRoom(host, playerB, playerC) | ||
.whenUserLeaveTheRoom(userA) | ||
.thenPlayerShouldBeNotInRoomAndHostIsChanged(host) | ||
} | ||
|
||
private fun TestGetRoomsRequest.whenUserAVisitLobby(joinUser: User): ResultActions = | ||
mockMvc.perform( | ||
get("/rooms") | ||
|
@@ -325,6 +337,12 @@ class RoomControllerTest @Autowired constructor( | |
.withJwt(user.id!!.value.toJwt()) | ||
) | ||
|
||
private fun leaveRoom(leaveUser: Jwt): ResultActions = | ||
mockMvc.perform( | ||
delete("/rooms/${testRoom.roomId!!.value}/players/me") | ||
.withJwt(leaveUser) | ||
) | ||
|
||
private fun givenTheHostCreatePublicRoom(host: User): Room { | ||
testRoom = createRoom(host) | ||
return testRoom | ||
|
@@ -335,6 +353,12 @@ class RoomControllerTest @Autowired constructor( | |
return testRoom | ||
} | ||
|
||
private fun givenHostAndPlayersAreInTheRoom(host: Player, vararg players: Player): Room { | ||
val combinedPlayers = (listOf(host) + players).toMutableList() | ||
testRoom = createRoom(host, combinedPlayers) | ||
return testRoom | ||
} | ||
|
||
private fun Room.whenUserJoinTheRoom(user: User, password: String? = null): ResultActions { | ||
val request = joinRoomRequest(password) | ||
val joinUser = mockOidcUser(user) | ||
|
@@ -349,6 +373,11 @@ class RoomControllerTest @Autowired constructor( | |
post("/rooms/${roomId.value}/players/me:cancel").withJwt(user.id!!.value.toJwt()) | ||
) | ||
|
||
private fun Room.whenUserLeaveTheRoom(user: User): ResultActions { | ||
val leaveUser = user.id!!.value.toJwt() | ||
return leaveRoom(leaveUser) | ||
} | ||
|
||
private fun ResultActions.thenCreateRoomSuccessfully(request: TestCreateRoomRequest) { | ||
request.let { | ||
andExpect(status().isCreated) | ||
|
@@ -380,6 +409,13 @@ class RoomControllerTest @Autowired constructor( | |
.andExpect(jsonPath("$.message").value("${resourceType.simpleName} not found")) | ||
} | ||
|
||
private fun ResultActions.thenPlayerShouldBeNotInRoomAndHostIsChanged(player: Player) { | ||
andExpect(status().isNoContent) | ||
val room = roomRepository.findById(testRoom.roomId!!)!! | ||
assertFalse(room.hasPlayer(player.id)) | ||
assertFalse(room.isHost(player.id)) | ||
} | ||
|
||
private fun createUser(id: String, email: String, nickname: String): User = | ||
userRepository.createUser(User(User.Id(id), email, nickname)) | ||
|
||
|
@@ -411,6 +447,20 @@ class RoomControllerTest @Autowired constructor( | |
) | ||
) | ||
|
||
private fun createRoom(host: Player, players: MutableList<Player>, password: String? = null): Room = | ||
roomRepository.createRoom( | ||
Room( | ||
game = testGame, | ||
host = host, | ||
players = players, | ||
maxPlayers = testGame.maxPlayers, | ||
minPlayers = testGame.minPlayers, | ||
name = "My Room", | ||
status = Room.Status.WAITING, | ||
password = password | ||
) | ||
) | ||
|
||
private fun createRoomRequest(password: String? = null): TestCreateRoomRequest = | ||
TestCreateRoomRequest( | ||
name = "Rapid Mahjong Room", | ||
|
@@ -466,4 +516,13 @@ class RoomControllerTest @Autowired constructor( | |
findRoomById(roomId)!!.players.map { it.id.value }.let { | ||
assertThat(it).containsAll(users.map { user -> user.id!!.value }) | ||
} | ||
|
||
private fun User.toRoomPlayer(): Player = | ||
Player(Player.Id(id!!.value), nickname) | ||
|
||
private fun Room.hasPlayer(playerId: Player.Id): Boolean = | ||
players.any { it.id == playerId } | ||
|
||
private fun Room.isHost(playerId: Player.Id): Boolean = | ||
host.id == playerId | ||
} |