Skip to content

Commit

Permalink
feature: game sort by rating
Browse files Browse the repository at this point in the history
  • Loading branch information
kuoche1712003 committed Nov 8, 2024
1 parent e89ba7a commit 923b0ae
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package tw.waterballsa.gaas.spring.repositories

import org.springframework.data.domain.Sort
import org.springframework.data.domain.Sort.Order
import org.springframework.data.mongodb.core.query.Update
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.aggregation.Aggregation.*
import org.springframework.stereotype.Component
import tw.waterballsa.gaas.application.repositories.GameRegistrationRepository
import tw.waterballsa.gaas.domain.GameRegistration
Expand All @@ -14,7 +15,8 @@ import tw.waterballsa.gaas.spring.repositories.data.toData

@Component
class SpringGameRegistrationRepository(
private val gameRegistrationDAO: GameRegistrationDAO
private val gameRegistrationDAO: GameRegistrationDAO,
private val mongoTemplate: MongoTemplate,
) : GameRegistrationRepository {
override fun registerGame(gameRegistration: GameRegistration): GameRegistration =
gameRegistrationDAO.save(gameRegistration.toData()).toDomain()
Expand All @@ -31,10 +33,21 @@ class SpringGameRegistrationRepository(
override fun existsByUniqueName(uniqueName: String): Boolean = gameRegistrationDAO.existsByUniqueName(uniqueName)

override fun findGameRegistrations(sortBy: String?): List<GameRegistration> {
return SortBy.from(sortBy)
?.let { Sort.by(it.orders) }
?.run { gameRegistrationDAO.findAll(this).map { it.toDomain() } }
?: gameRegistrationDAO.findAll().map { it.toDomain() }
val agg =
SortBy.from(sortBy)?.let {
newAggregation(
addFields()
.addField("rating").withValueOfExpression("totalRating / numberOfComments")
.build(),
sort(Sort.by(it.orders))
)
} ?: newAggregation(
addFields()
.addField("rating").withValueOfExpression("totalRating / numberOfComments")
.build(),
)
return mongoTemplate.aggregate(agg, "gameRegistrationData", GameRegistrationData::class.java)
.mappedResults.map { it.toDomain() }
}

override fun findById(id: Id): GameRegistration? =
Expand All @@ -45,7 +58,8 @@ class SpringGameRegistrationRepository(

enum class SortBy(val value: String, val orders: List<Order>) {
CREATED_ON("createdOn", listOf(Order.desc("createdOn"), Order.desc("_id"))),
TIMES_PLAYED("timesPlayed", listOf(Order.desc("timesPlayed"), Order.desc("_id")))
TIMES_PLAYED("timesPlayed", listOf(Order.desc("timesPlayed"), Order.desc("_id"))),
RATING("rating", listOf(Order.desc("ratio"), Order.desc("_id")))
;

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import org.springframework.http.MediaType.APPLICATION_JSON
import org.springframework.test.web.servlet.ResultActions
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
import tw.waterballsa.gaas.application.eventbus.EventBus
import tw.waterballsa.gaas.application.repositories.GameRegistrationRepository
import tw.waterballsa.gaas.domain.GameRegistration
import tw.waterballsa.gaas.domain.Room
import tw.waterballsa.gaas.domain.User
import tw.waterballsa.gaas.events.CommentGameEvent
import tw.waterballsa.gaas.events.StartedGameEvent
import tw.waterballsa.gaas.events.enums.EventMessageType
import tw.waterballsa.gaas.spring.controllers.GetGameRegistrationPresenter.*
import tw.waterballsa.gaas.spring.controllers.RegisterGamePresenter.RegisterGameViewModel
import tw.waterballsa.gaas.spring.controllers.viewmodel.UpdateGameRegistrationViewModel
Expand All @@ -22,6 +28,7 @@ import java.util.UUID.randomUUID
@AutoConfigureMockMvc(addFilters = false)
class GameRegistrationControllerTest @Autowired constructor(
val gameRegistrationRepository: GameRegistrationRepository,
val eventBus: EventBus,
) : AbstractSpringBootTest() {

@BeforeEach
Expand Down Expand Up @@ -104,22 +111,63 @@ class GameRegistrationControllerTest @Autowired constructor(
.getBody(object : TypeReference<List<GetGamesViewModel>>() {})
}

@Test
fun givenBig2TimesPlayedIsGreaterThanUnoTimesPlayed_WhenThenUserViewsGameListByTimesPlayed_ThenBig2RankInFront() {
val unoRequest = createGameRegistrationRequest("uno-java", "UNO Java")
val big2Request = createGameRegistrationRequest("big2-Java", "Big2 Java")
registerGameSuccessfully(unoRequest)
val big2 = registerGameSuccessfully(big2Request)
eventBus.broadcast(
StartedGameEvent(
EventMessageType.GAME_STARTED,
StartedGameEvent.Data("", Room.Id(""), big2.id, emptyList())
)
)
mockMvc.perform(get("/games?sort_by=timesPlayed"))
.andExpect(status().isOk)
.andExpect(jsonPath("$").isArray)
.andExpect(jsonPath("$.size()").value(2))
.validateSpecificElement(0, big2Request)
.validateSpecificElement(1, unoRequest)
.getBody(object : TypeReference<List<GetGamesViewModel>>() {})
}

@Test
fun givenBig2RatingIsGreaterThanUnoRating_WhenThenUserViewsGameListByRating_ThenBig2RankInFront() {
val unoRequest = createGameRegistrationRequest("uno-java", "UNO Java")
val big2Request = createGameRegistrationRequest("big2-Java", "Big2 Java")
registerGameSuccessfully(unoRequest)
val big2 = registerGameSuccessfully(big2Request)

eventBus.broadcast(CommentGameEvent(big2.id, User.Id(""), 5, 1))

mockMvc.perform(get("/games?sort_by=rating"))
.andExpect(status().isOk)
.andExpect(jsonPath("$").isArray)
.andExpect(jsonPath("$.size()").value(2))
.validateSpecificElement(0, big2Request)
.validateSpecificElement(1, unoRequest)
.getBody(object : TypeReference<List<GetGamesViewModel>>() {})
}


@Test
fun givenBig2HasRegistered_whenUpdateGameRegistrationWithWrongId_thenShouldReturnGameRegistrationNotFound() {
givenGameHasRegistered("big2", "Big2")
whenUpdateGameRegistration(
"not-exist-game-id",
TestGameRegistrationRequest(
"big2",
"updated big2",
"updated big2 description",
"updated big2 rules",
"updated big2 image url",
3,
8,
"updated big2 frontend url",
"updated big2 backend url",
))
"big2",
"updated big2",
"updated big2 description",
"updated big2 rules",
"updated big2 image url",
3,
8,
"updated big2 frontend url",
"updated big2 backend url",
)
)
.thenShouldReturnGameRegistrationNotFound()
}

Expand All @@ -140,7 +188,8 @@ class GameRegistrationControllerTest @Autowired constructor(
8,
"updated big2 frontend url",
"updated big2 backend url",
))
)
)
.thenShouldReturnGameAlreadyExists()
}

Expand Down Expand Up @@ -284,9 +333,13 @@ class GameRegistrationControllerTest @Autowired constructor(
return registerGameSuccessfully(createGameRegistrationRequest).id
}

private fun whenUpdateGameRegistration(gameId: String, updateGameRegistrationRequest: TestGameRegistrationRequest): ResultActions {
return mockMvc.perform(put("/games/$gameId")
.withJson(updateGameRegistrationRequest)
private fun whenUpdateGameRegistration(
gameId: String,
updateGameRegistrationRequest: TestGameRegistrationRequest
): ResultActions {
return mockMvc.perform(
put("/games/$gameId")
.withJson(updateGameRegistrationRequest)
)
}

Expand Down

0 comments on commit 923b0ae

Please sign in to comment.