From 1b0bb5d4d9ebfcf0db424a2e308df8f8497eeb6b Mon Sep 17 00:00:00 2001 From: apozdniakov Date: Mon, 20 May 2024 11:05:46 +0200 Subject: [PATCH] change leaderboard behaviour --- backend/api-spec/Makefile | 28 +++++++++++++++++++ backend/api-spec/leaderboard_get.hurl | 6 ++++ backend/api-spec/leaderboard_post.hurl | 12 ++++++++ backend/api-spec/statistic_get.hurl | 11 ++++++++ backend/api-spec/statistic_post.hurl | 14 ++++++++++ .../repository/LeaderboardRepository.kt | 21 ++++++-------- 6 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 backend/api-spec/Makefile create mode 100644 backend/api-spec/leaderboard_get.hurl create mode 100644 backend/api-spec/leaderboard_post.hurl create mode 100644 backend/api-spec/statistic_get.hurl create mode 100644 backend/api-spec/statistic_post.hurl diff --git a/backend/api-spec/Makefile b/backend/api-spec/Makefile new file mode 100644 index 0000000..5023762 --- /dev/null +++ b/backend/api-spec/Makefile @@ -0,0 +1,28 @@ +# Define Hurl scripts +HURL_SCRIPTS = leaderboard_post.hurl leaderboard_get.hurl statistic_post.hurl statistic_get.hurl + +# Default target to run all Hurl scripts +all: run_all + +# Target to run leaderboard POST +leaderboard_post: leaderboard_post.hurl + hurl leaderboard_post.hurl | jq . + +# Target to run leaderboard GET +leaderboard_get: leaderboard_get.hurl + hurl leaderboard_get.hurl | jq . + +# Target to run statistic POST +statistic_post: statistic_post.hurl + hurl statistic_post.hurl | jq . + +# Target to run statistic GET +statistic_get: statistic_get.hurl + hurl statistic_get.hurl | jq . + +# Target to run all Hurl scripts +run_all: leaderboard_post leaderboard_get statistic_post statistic_get + +# Clean target to remove .run files +clean: + rm -f *.run diff --git a/backend/api-spec/leaderboard_get.hurl b/backend/api-spec/leaderboard_get.hurl new file mode 100644 index 0000000..9434177 --- /dev/null +++ b/backend/api-spec/leaderboard_get.hurl @@ -0,0 +1,6 @@ +GET http://localhost:8080/api/statistics/leaderboard?limit=10 + +HTTP/1.1 200 +[Asserts] +jsonpath "$[0].userId" exists +jsonpath "$[0].speed" exists diff --git a/backend/api-spec/leaderboard_post.hurl b/backend/api-spec/leaderboard_post.hurl new file mode 100644 index 0000000..8853b36 --- /dev/null +++ b/backend/api-spec/leaderboard_post.hurl @@ -0,0 +1,12 @@ +POST http://localhost:8080/api/statistics/leaderboard +Content-Type: application/json + +{ + "userId": "user-1", + "speed": 235.5 +} + +HTTP/1.1 201 +GET http://localhost:8080/api/statistics/leaderboard?limit=10 + +HTTP/1.1 200 diff --git a/backend/api-spec/statistic_get.hurl b/backend/api-spec/statistic_get.hurl new file mode 100644 index 0000000..916581f --- /dev/null +++ b/backend/api-spec/statistic_get.hurl @@ -0,0 +1,11 @@ +GET http://localhost:8080/api/statistics/user123 + +HTTP/1.1 200 +[Asserts] +jsonpath "$.userId" equals "user123" +jsonpath "$.completedDuels" greaterThanOrEqual 0 +jsonpath "$.averageSpeed" greaterThanOrEqual 0.0 +jsonpath "$.totalReward" greaterThanOrEqual 0.0 +jsonpath "$.overallWinsInDuels" greaterThanOrEqual 0 +jsonpath "$.maxSpeed" greaterThanOrEqual 0.0 +jsonpath "$.topSpeeds" exists diff --git a/backend/api-spec/statistic_post.hurl b/backend/api-spec/statistic_post.hurl new file mode 100644 index 0000000..c6a7487 --- /dev/null +++ b/backend/api-spec/statistic_post.hurl @@ -0,0 +1,14 @@ +POST http://localhost:8080/api/statistics +Content-Type: application/json + +{ + "userId": "user123", + "completedDuels": 5, + "averageSpeed": 110.2, + "totalReward": 500.0, + "overallWinsInDuels": 3, + "maxSpeed": 120.5, + "topSpeeds": [120.5, 115.3, 110.0, 105.5, 100.0] +} + +HTTP/1.1 201 diff --git a/backend/src/main/kotlin/com/retypeme/project/statistic/repository/LeaderboardRepository.kt b/backend/src/main/kotlin/com/retypeme/project/statistic/repository/LeaderboardRepository.kt index d0d4ebc..9f67236 100644 --- a/backend/src/main/kotlin/com/retypeme/project/statistic/repository/LeaderboardRepository.kt +++ b/backend/src/main/kotlin/com/retypeme/project/statistic/repository/LeaderboardRepository.kt @@ -5,32 +5,29 @@ import org.springframework.data.redis.core.RedisTemplate import org.springframework.data.redis.core.ZSetOperations import org.springframework.stereotype.Repository - interface LeaderboardRepository { fun addUserScore(userId: String, score: Double) fun getTopUsers(limit: Int): List } @Repository -class LeaderboardRepositoryImpl(private val redisTemplate: RedisTemplate) : - LeaderboardRepository { +class LeaderboardRepositoryImpl(private val redisTemplate: RedisTemplate) : LeaderboardRepository { private val leaderboardKey = "leaderboard" + private val zSetOps: ZSetOperations by lazy { + redisTemplate.opsForZSet() + } + override fun addUserScore(userId: String, score: Double) { - val zSetOps: ZSetOperations = redisTemplate.opsForZSet() val existingScore = zSetOps.score(leaderboardKey, userId) - if (existingScore == null || score > existingScore) { - zSetOps.add(leaderboardKey, LeaderboardItemModel(userId, score), score) + zSetOps.add(leaderboardKey, userId, score) } } override fun getTopUsers(limit: Int): List { - val zSetOps: ZSetOperations = redisTemplate.opsForZSet() - val topUsers: MutableSet> = - zSetOps.reverseRangeWithScores(leaderboardKey, 0, (limit - 1).toLong()) ?: return emptyList() - - return topUsers.map { it.value!! } + val topUsers = zSetOps.reverseRangeWithScores(leaderboardKey, 0, (limit - 1).toLong()) + return topUsers?.map { LeaderboardItemModel(it.value ?: "", it.score ?: 0.0) } ?: emptyList() } -} \ No newline at end of file +}