Skip to content

Commit

Permalink
feat: pvp game tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bhoopesh369 committed Jan 24, 2024
1 parent 94877ef commit c870223
Show file tree
Hide file tree
Showing 6 changed files with 404 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class PvPGameService(
}
if(gameStatusUpdateEntity.gameResultPlayer1 == null || gameStatusUpdateEntity.gameResultPlayer2 == null) {
val newPvPGameEntity = oldPvPGameEntity.copy(status = gameStatusUpdateEntity.gameStatus)
println("newPvPGameEntity: $newPvPGameEntity")
return pvPGameRepository.save(newPvPGameEntity)
}

Expand All @@ -87,7 +88,7 @@ class PvPGameService(
status = gameStatus
)

val pvPGame: PvPGameEntity = pvPGameRepository.save(newPvPGameEntity)
val pvPGame = pvPGameRepository.save(newPvPGameEntity)
pvPGameLogService.savePvPGameLog(pvPGame.matchId, gameResultPlayer1.log, gameResultPlayer2.log)
return pvPGame
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package delta.codecharacter.server.pvp_game.pvp_game_log

import delta.codecharacter.server.match.MatchRepository
import delta.codecharacter.server.match.PvPMatchRepository
import delta.codecharacter.server.user.public_user.PublicUserEntity
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.annotation.Id
Expand All @@ -10,12 +11,17 @@ import java.util.UUID
@Service
class PvPGameLogService(
@Autowired private val pvPGameLogRepository: PvPGameLogRepository,
@Autowired private val matchRepository: MatchRepository
@Autowired private val pvPMatchRepository: PvPMatchRepository,
) {

fun getPlayerLog(gameId: UUID, userId: UUID): String {
val match = pvPMatchRepository.findById(gameId)

if (!match.isPresent) {
return ""
}

val pvPGameLog = pvPGameLogRepository.findById(gameId)
val match = matchRepository.findById(gameId)
val player1 : PublicUserEntity = match.get().player1
val player2 : PublicUserEntity = match.get().player2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@ class TestAttributes {
loginType = LoginType.PASSWORD,
isProfileComplete = true,
)

val opponent =
UserEntity(
id = UUID.randomUUID(),
password = "password",
email = "[email protected]",
isEnabled = true,
isAccountNonExpired = true,
isAccountNonLocked = true,
loginType = LoginType.PASSWORD,
isProfileComplete = true,
)

val dailyChallengeCode =
DailyChallengeEntity(
id = UUID.randomUUID(),
Expand Down Expand Up @@ -63,6 +76,24 @@ class TestAttributes {
dailyChallengeHistory = hashMapOf(0 to DailyChallengeHistory(0.0, dailyChallengeCode)),
tutorialLevel = 1
)

val publicOpponent =
PublicUserEntity(
userId = opponent.id,
username = "TestOpponentUser",
name = "Test Opponent User",
country = "Test Country",
college = "Test College",
avatarId = 1,
rating = 1000.0,
wins = 4,
losses = 2,
ties = 1,
tier = TierTypeDto.TIER_PRACTICE,
score = 0.0,
dailyChallengeHistory = hashMapOf(0 to DailyChallengeHistory(0.0, dailyChallengeCode)),
tutorialLevel = 1
)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package delta.codecharacter.server.pvp_game

import com.fasterxml.jackson.databind.ObjectMapper
import delta.codecharacter.server.TestAttributes
import delta.codecharacter.server.WithMockCustomUser
import delta.codecharacter.server.match.MatchModeEnum
import delta.codecharacter.server.match.MatchVerdictEnum
import delta.codecharacter.server.match.PvPMatchEntity
import delta.codecharacter.server.pvp_game.pvp_game_log.PvPGameLogEntity
import delta.codecharacter.server.user.UserEntity
import delta.codecharacter.server.user.public_user.PublicUserEntity
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.dropCollection
import org.springframework.http.MediaType
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.get
import java.time.Instant
import java.util.UUID

@AutoConfigureMockMvc
@SpringBootTest
internal class PvPGameControllerIntegrationTest(@Autowired val mockMvc: MockMvc) {
@Autowired private lateinit var mongoTemplate: MongoTemplate

@Autowired private lateinit var jackson2ObjectMapperBuilder: Jackson2ObjectMapperBuilder
private lateinit var mapper: ObjectMapper

@BeforeEach
fun setUp() {
mapper = jackson2ObjectMapperBuilder.build()
mongoTemplate.save<UserEntity>(TestAttributes.user)
mongoTemplate.save<UserEntity>(TestAttributes.opponent)
mongoTemplate.save<PublicUserEntity>(TestAttributes.publicUser)
mongoTemplate.save<PublicUserEntity>(TestAttributes.publicOpponent)

val context = SecurityContextHolder.createEmptyContext()
val auth: Authentication =
UsernamePasswordAuthenticationToken(
TestAttributes.user, TestAttributes.user.password, TestAttributes.user.authorities
)
context.authentication = auth
SecurityContextHolder.setContext(context)
}

@Test
@WithMockCustomUser
fun `should get pvp game log`() {
val pvPGameEntity =
PvPGameEntity(
matchId = UUID.randomUUID(),
destructionPlayer1 = 100.0,
destructionPlayer2 = 100.0,
coinsUsedPlayer1 = 100,
coinsUsedPlayer2 = 100,
status = PvPGameStatusEnum.EXECUTED,
)
mongoTemplate.save<PvPGameEntity>(pvPGameEntity)

val pvPMatchEntity =
PvPMatchEntity(
id = pvPGameEntity.matchId,
player1 = TestAttributes.publicUser,
player2 = TestAttributes.publicOpponent,
game = pvPGameEntity,
mode = MatchModeEnum.PVP,
verdict = MatchVerdictEnum.PLAYER1,
createdAt = Instant.now(),
totalPoints = 100,
)
mongoTemplate.save<PvPMatchEntity>(pvPMatchEntity)

val pvPGameLogEntity = PvPGameLogEntity(gameId = pvPGameEntity.matchId, player1Log = "game log player 1", player2Log = "game log player 2")
mongoTemplate.save<PvPGameLogEntity>(pvPGameLogEntity)

mockMvc
.get("/pvpgames/${pvPGameEntity.matchId}/logs") {
contentType = MediaType.APPLICATION_JSON
}
.andExpect {
status { isOk() }
content { contentType(MediaType.APPLICATION_JSON) }
content { string(pvPGameLogEntity.player1Log) }
}
}

@Test
@WithMockCustomUser
fun `should return empty string when pvp game or match not found`() {
val randomUUID = UUID.randomUUID()

mockMvc.get("/pvpgames/${randomUUID}/logs") { contentType = MediaType.APPLICATION_JSON }.andExpect {
status { isOk() }
content { contentType(MediaType.APPLICATION_JSON) }
content { string("") }
}
}

@AfterEach
fun tearDown() {
mongoTemplate.dropCollection<UserEntity>()
mongoTemplate.dropCollection<PublicUserEntity>()
mongoTemplate.dropCollection<PvPGameEntity>()
mongoTemplate.dropCollection<PvPMatchEntity>()
mongoTemplate.dropCollection<PvPGameLogEntity>()

SecurityContextHolder.clearContext()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
package delta.codecharacter.server.pvp_game

import com.fasterxml.jackson.databind.ObjectMapper
import delta.codecharacter.server.code.LanguageEnum
import delta.codecharacter.server.config.GameConfiguration
import delta.codecharacter.server.exception.CustomException
import delta.codecharacter.server.params.GameCode
import delta.codecharacter.server.params.GameParameters
import delta.codecharacter.server.pvp_game.pvp_game_log.PvPGameLogService
import delta.codecharacter.server.pvp_game.queue.entities.PvPGameRequestEntity
import delta.codecharacter.server.pvp_game.queue.entities.PvPGameResultEntity
import delta.codecharacter.server.pvp_game.queue.entities.PvPGameStatusUpdateEntity
import io.mockk.mockk
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.amqp.rabbit.core.RabbitTemplate
import java.util.UUID
import java.util.Optional
import io.mockk.confirmVerified
import io.mockk.every
import io.mockk.verify
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertThrows
import org.springframework.http.HttpStatus

internal class PvPGameServiceTest {
private lateinit var pvPGameRepository: PvPGameRepository
private lateinit var pvPGameService: PvPGameService
private lateinit var pvPGameLogService: PvPGameLogService
private lateinit var rabbitTemplate: RabbitTemplate
private lateinit var mapper: ObjectMapper
private lateinit var gameParameters: GameParameters


@BeforeEach
fun setUp() {
pvPGameRepository = mockk(relaxed = true)
pvPGameLogService = mockk(relaxed = true)
rabbitTemplate = mockk(relaxed = true)
mapper = ObjectMapper()
val gameConfiguration = GameConfiguration()
gameParameters = gameConfiguration.gameParameters()

pvPGameService = PvPGameService(pvPGameRepository, pvPGameLogService, rabbitTemplate, gameParameters)
}

@Test
fun `should return pvp game by id`() {
val pvPGameEntity = mockk<PvPGameEntity>()
val gameId = UUID.randomUUID() // gameId and matchId are the same for PvP Game

every { pvPGameRepository.findById(any()) } returns Optional.of(pvPGameEntity)

val result = pvPGameService.getPvPGame(gameId)
assertEquals(pvPGameEntity, result)

verify { pvPGameRepository.findById(gameId) }
confirmVerified(pvPGameRepository)
}

@Test
@Throws(CustomException::class)
fun `should throw exception if pvp game not found`() {
val gameId = UUID.randomUUID()

every { pvPGameRepository.findById(any()) } returns Optional.empty()

val exception = assertThrows(CustomException::class.java) {
pvPGameService.getPvPGame(gameId)
}

assertEquals(exception.status, HttpStatus.NOT_FOUND)

verify { pvPGameRepository.findById(gameId) }
confirmVerified(pvPGameRepository)
}

@Test
fun `should create pvp game request`() {
val pvPGame = mockk<PvPGameEntity>()
val matchId = UUID.randomUUID()

val expectedPvPGameRequest =
PvPGameRequestEntity(
gameId = matchId,
player1 = GameCode("player1 code", LanguageEnum.CPP),
player2 = GameCode("player2 code", LanguageEnum.JAVA),
parameters = gameParameters,
)

every {pvPGame.matchId} returns matchId
every {
rabbitTemplate.convertAndSend(
"gamePvPRequestQueue",
mapper.writeValueAsString(expectedPvPGameRequest)
)
} returns Unit

pvPGameService.sendPvPGameRequest(pvPGame, expectedPvPGameRequest.player1, expectedPvPGameRequest.player2)

verify {
rabbitTemplate.convertAndSend(
"gamePvPRequestQueue",
mapper.writeValueAsString(expectedPvPGameRequest)
)
}
confirmVerified(rabbitTemplate)
}

@Test
fun `should receive pvp game status update with result`() {
val pvPGame =
PvPGameEntity(
matchId = UUID.randomUUID(),
destructionPlayer1 = 100.0,
destructionPlayer2 = 100.0,
coinsUsedPlayer1 = 100,
coinsUsedPlayer2 = 100,
status = PvPGameStatusEnum.IDLE,
)
val pvPGameStatusUpdate =
PvPGameStatusUpdateEntity(
gameId = pvPGame.matchId,
gameStatus = PvPGameStatusEnum.EXECUTED,
gameResultPlayer1 =
PvPGameResultEntity(
coinsUsed = 0,
destructionPercentage = 0.0,
hasErrors = false,
log = "player1 log"
),
gameResultPlayer2 =
PvPGameResultEntity(
coinsUsed = 0,
destructionPercentage = 0.0,
hasErrors = false,
log = "player2 log"
),
)

val updatedPvPGameEntity =
PvPGameEntity(
matchId = pvPGame.matchId,
destructionPlayer1 = pvPGameStatusUpdate.gameResultPlayer1!!.destructionPercentage,
destructionPlayer2 = pvPGameStatusUpdate.gameResultPlayer2!!.destructionPercentage,
coinsUsedPlayer1 = pvPGameStatusUpdate.gameResultPlayer1!!.coinsUsed,
coinsUsedPlayer2 = pvPGameStatusUpdate.gameResultPlayer2!!.coinsUsed,
status = pvPGameStatusUpdate.gameStatus,
)

every { pvPGameRepository.findById(pvPGame.matchId) } returns Optional.of(pvPGame)
every { pvPGameRepository.save(updatedPvPGameEntity) } returns updatedPvPGameEntity

pvPGameService.updateGameStatus(mapper.writeValueAsString(pvPGameStatusUpdate))

verify { pvPGameRepository.findById(pvPGame.matchId) }
verify {
pvPGameRepository.save(
PvPGameEntity (
matchId = pvPGame.matchId,
destructionPlayer1 = pvPGameStatusUpdate.gameResultPlayer1!!.destructionPercentage,
destructionPlayer2 = pvPGameStatusUpdate.gameResultPlayer2!!.destructionPercentage,
coinsUsedPlayer1 = pvPGameStatusUpdate.gameResultPlayer1!!.coinsUsed,
coinsUsedPlayer2 = pvPGameStatusUpdate.gameResultPlayer2!!.coinsUsed,
status = pvPGameStatusUpdate.gameStatus,
)
)
}
confirmVerified(pvPGameRepository)
}
}
Loading

0 comments on commit c870223

Please sign in to comment.