mirror of
https://gitlab.com/hamburghammer/playtime.git
synced 2024-05-28 13:30:39 +02:00
Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
dfcd3cd35a | |||
ad2afd85d5 | |||
e8fff7b200 | |||
0895514469 | |||
f73fcb8bba | |||
789f4981b6 | |||
b65b48a6f2 | |||
28781c2bc1 |
|
@ -32,10 +32,16 @@ unit-test:
|
|||
artifacts:
|
||||
expire_in: 3 days
|
||||
paths:
|
||||
- build/reports/tests/test/index.html
|
||||
- build/reports/tests/test/
|
||||
reports:
|
||||
junit: build/test-results/test/TEST-*.xml
|
||||
|
||||
coverage:
|
||||
stage: analyse
|
||||
script:
|
||||
- "./gradlew $GRADLE_OPTS clean jacocoTestReport"
|
||||
- "cat build/reports/jacoco/test/html/index.html"
|
||||
|
||||
lint:
|
||||
stage: analyse
|
||||
script:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# PlayTime
|
||||
[![pipeline status](https://gitlab.com/hamburghammer/playtime/badges/dev/pipeline.svg)](https://gitlab.com/hamburghammer/playtime/-/commits/dev)
|
||||
[![coverage report](https://gitlab.com/hamburghammer/playtime/badges/dev/coverage.svg)](https://gitlab.com/hamburghammer/playtime/-/commits/dev)
|
||||
|
||||
It's a plugin for a [Spigot](https://www.spigotmc.org) Minecraft server to log the time players spend on the server and returns it to them.
|
||||
|
||||
|
@ -17,9 +19,14 @@ It's a plugin for a [Spigot](https://www.spigotmc.org) Minecraft server to log t
|
|||
|
||||
`playtime` shows the total play time on the server (Format DD:HH:MM)
|
||||
|
||||
`playtimeof <player>` shows the total play time of the player (Format DD:HH:MM)
|
||||
|
||||
`toptime` shows the top 5 player with the highest total playtime
|
||||
|
||||
## Development
|
||||
|
||||
The plugin gets build with gradle. It is important to run the shadowJar task to include all dependencies.
|
||||
|
||||
It's entirely written in Kotlin and for testing it uses [Mockk](https://mockk.io/) and [Junit5](https://junit.org/junit5/).
|
||||
|
||||
This plugin uses the [linter from Pinterest for Kotlin](https://www.kotlinresources.com/library/ktlint/)
|
||||
|
|
|
@ -3,10 +3,11 @@ plugins {
|
|||
id("org.jlleitschuh.gradle.ktlint") version "9.0.0"
|
||||
id("com.github.johnrengelman.shadow") version "5.2.0"
|
||||
id("org.jetbrains.dokka") version "0.10.0"
|
||||
jacoco
|
||||
}
|
||||
|
||||
group = "de.augustodwenger"
|
||||
version = "0.1.0-SNAPSHOT"
|
||||
version = "0.2.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
@ -45,11 +46,23 @@ tasks {
|
|||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events("passed", "skipped", "failed")
|
||||
events("skipped", "failed")
|
||||
// events("passed", "skipped", "failed")
|
||||
}
|
||||
extensions.configure(JacocoTaskExtension::class) {
|
||||
classDumpDir = file("$buildDir/jacoco/classpathdumps")
|
||||
}
|
||||
}
|
||||
dokka {
|
||||
outputFormat = "html"
|
||||
outputDirectory = "$buildDir/dokka"
|
||||
}
|
||||
jacocoTestReport {
|
||||
reports {
|
||||
xml.isEnabled = false
|
||||
csv.isEnabled = false
|
||||
html.isEnabled = true
|
||||
}
|
||||
dependsOn("test")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import commands.PlayTime
|
||||
import commands.PlayTimeOfCommand
|
||||
import commands.TestCommand
|
||||
import commands.TopTime
|
||||
import commands.UpTime
|
||||
import db.FilePlayerTimeDB
|
||||
import listener.JoinListener
|
||||
import listener.QuitListener
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
@ -11,12 +12,12 @@ import tasks.PersistState
|
|||
/**
|
||||
* Entrypoint of the plugin
|
||||
*
|
||||
* @property playerService A singleton of the playerService with FilePlayerTimeDB
|
||||
* @property playerTime A singleton of the playerService with FilePlayerTimeDB
|
||||
* @property scheduler the scheduler to manage schedules
|
||||
*/
|
||||
class Main : JavaPlugin() {
|
||||
|
||||
private val playerService = PlayerService(FilePlayerTimeDB())
|
||||
private val playerTime: PlayerTime = PlayerTimeService
|
||||
private val scheduler: BukkitScheduler = server.scheduler
|
||||
|
||||
/**
|
||||
|
@ -28,13 +29,15 @@ class Main : JavaPlugin() {
|
|||
super.onEnable()
|
||||
|
||||
this.getCommand("test")?.setExecutor(TestCommand())
|
||||
this.getCommand("playtime")?.setExecutor(PlayTime(playerService))
|
||||
this.getCommand("playtime")?.setExecutor(PlayTime())
|
||||
this.getCommand("uptime")?.setExecutor(UpTime())
|
||||
this.getCommand("playtimeof")?.setExecutor(PlayTimeOfCommand())
|
||||
this.getCommand("toptime")?.setExecutor(TopTime())
|
||||
|
||||
server.pluginManager.registerEvents(JoinListener(playerService), this)
|
||||
server.pluginManager.registerEvents(QuitListener(playerService), this)
|
||||
server.pluginManager.registerEvents(JoinListener(), this)
|
||||
server.pluginManager.registerEvents(QuitListener(), this)
|
||||
|
||||
scheduler.scheduleSyncRepeatingTask(this, PersistState(playerService), 0, minutesToTicks(10))
|
||||
scheduler.scheduleSyncRepeatingTask(this, PersistState(), 0, minutesToTicks(10))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,7 +46,7 @@ class Main : JavaPlugin() {
|
|||
*/
|
||||
override fun onDisable() {
|
||||
super.onDisable()
|
||||
playerService.persistAllPlayer()
|
||||
PersistState().run()
|
||||
}
|
||||
|
||||
private fun secondsToTicks(seconds: Int): Long {
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
import db.PlayerTimeDB
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
import models.Player
|
||||
|
||||
/**
|
||||
* A service to hold the all player that are currently playing
|
||||
* It should only be used as Singleton @see Kotlin objects
|
||||
*
|
||||
* @property db the DB implementation which should be used to persist the state
|
||||
* @property playerMap Holds all online players
|
||||
*/
|
||||
open class PlayerService(private val db: PlayerTimeDB) {
|
||||
|
||||
private val playerMap: ConcurrentMap<UUID, Player> = ConcurrentHashMap()
|
||||
|
||||
/**
|
||||
* Adds the player to the playerMap.
|
||||
* It creates an new player if it's no persisted and adds/refreshes the join time
|
||||
*
|
||||
* @param uuid the actual uuid of a player
|
||||
* @param playerName for debugging because with the new api playerNames are not longer unique
|
||||
*/
|
||||
fun addPlayer(uuid: UUID, playerName: String) {
|
||||
val player: Player = if (db.findByID(uuid)) {
|
||||
val player = db.readPlayer(uuid)
|
||||
player.joinTime = LocalDateTime.now()
|
||||
player
|
||||
} else {
|
||||
val player = Player(uuid, playerName)
|
||||
db.createPlayer(player)
|
||||
player
|
||||
}
|
||||
playerMap[uuid] = player
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a player from the map and persists its status
|
||||
*
|
||||
*@param uuid players uuid
|
||||
*/
|
||||
fun removePlayer(uuid: UUID) {
|
||||
persistPlayer(uuid)
|
||||
playerMap.remove(uuid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the map to prevent directly exposition
|
||||
*
|
||||
* @return status of the inner map
|
||||
*/
|
||||
fun containsPlayer(uuid: UUID): Boolean {
|
||||
return playerMap.containsKey(uuid)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the map to prevent directly exposition
|
||||
*
|
||||
* @return status of the inner map
|
||||
*/
|
||||
fun isEmpty(): Boolean {
|
||||
return playerMap.isEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates and writes the current status to the db
|
||||
*
|
||||
* @param uuid player uuid
|
||||
*/
|
||||
fun persistPlayer(uuid: UUID) {
|
||||
val duration = timePlayed(uuid)
|
||||
val player = getPlayer(uuid)
|
||||
player.playTime = Duration.from(duration)
|
||||
db.writePlayer(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Persists all player
|
||||
*/
|
||||
fun persistAllPlayer() {
|
||||
for ((uuid, _) in playerMap) {
|
||||
persistPlayer(uuid)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player with that uuid
|
||||
*
|
||||
* @param uuid player uuid
|
||||
*/
|
||||
fun getPlayer(uuid: UUID): Player {
|
||||
return playerMap[uuid]!!
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the playtime including the old time
|
||||
* if the stats got save it should use the save time instead of the join time
|
||||
*
|
||||
* @param uuid player uuid
|
||||
*
|
||||
* @return the total playtime
|
||||
*/
|
||||
fun timePlayed(uuid: UUID): Duration {
|
||||
val player = getPlayer(uuid)
|
||||
val playTime: Duration = if (player.lastSave != null) {
|
||||
Duration.between(player.lastSave, LocalDateTime.now())
|
||||
} else {
|
||||
Duration.between(player.joinTime, LocalDateTime.now())
|
||||
}
|
||||
return Duration.from(player.playTime).plus(playTime)
|
||||
}
|
||||
}
|
54
src/main/kotlin/PlayerTime.kt
Normal file
54
src/main/kotlin/PlayerTime.kt
Normal file
|
@ -0,0 +1,54 @@
|
|||
import java.time.Duration
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
|
||||
interface PlayerTime {
|
||||
/**
|
||||
* Adds the player to the playerMap.
|
||||
* It creates an new player if it's no persisted and adds/refreshes the join time
|
||||
*
|
||||
* @param uuid the actual uuid of a player
|
||||
* @param playerName for updating or to create a new player
|
||||
*/
|
||||
fun playerJoin(uuid: UUID, playerName: String)
|
||||
|
||||
/**
|
||||
* Updates the playtime and saves it
|
||||
*
|
||||
* @param uuid UUID
|
||||
*/
|
||||
fun updatePlayTime(uuid: UUID)
|
||||
|
||||
/**
|
||||
* Returns the playtime including the old time
|
||||
* if the stats got save it should use the save time instead of the join time
|
||||
*
|
||||
* @param uuid player uuid
|
||||
*
|
||||
* @return the total playtime
|
||||
*/
|
||||
fun timePlayed(uuid: UUID): Duration
|
||||
|
||||
/**
|
||||
* Search for the players with the highest playtime
|
||||
*
|
||||
* @return List<Player>
|
||||
*/
|
||||
fun getTopPlayers(): List<Player>
|
||||
|
||||
/**
|
||||
* Formats the duration to a simple String
|
||||
*
|
||||
* @param duration Duration
|
||||
* @return String (DD:HH:MM)
|
||||
*/
|
||||
fun timeToString(duration: Duration): String {
|
||||
val days: String =
|
||||
if (duration.toDaysPart() < 10) """0${duration.toDaysPart()}""" else """${duration.toDaysPart()}"""
|
||||
val hours: String =
|
||||
if (duration.toHoursPart() < 10) """0${duration.toHoursPart()}""" else """${duration.toHoursPart()}"""
|
||||
val minutes: String =
|
||||
if (duration.toMinutesPart() < 10) """0${duration.toMinutesPart()}""" else """${duration.toMinutesPart()}"""
|
||||
return """$days:$hours:$minutes"""
|
||||
}
|
||||
}
|
3
src/main/kotlin/PlayerTimeService.kt
Normal file
3
src/main/kotlin/PlayerTimeService.kt
Normal file
|
@ -0,0 +1,3 @@
|
|||
import db.FilePlayerTimeDB
|
||||
|
||||
object PlayerTimeService : PlayerTime by SimplePlayerTime(FilePlayerTimeDB())
|
85
src/main/kotlin/SimplePlayerTime.kt
Normal file
85
src/main/kotlin/SimplePlayerTime.kt
Normal file
|
@ -0,0 +1,85 @@
|
|||
import db.PlayerTimeDB
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
|
||||
/**
|
||||
* A service to hold the all player that are currently playing
|
||||
* It should only be used as Singleton @see Kotlin objects
|
||||
*
|
||||
* @property db the DB implementation which should be used to persist the state
|
||||
*/
|
||||
class SimplePlayerTime(private val db: PlayerTimeDB) : PlayerTime {
|
||||
|
||||
/**
|
||||
* Adds the player to the [db].
|
||||
* It creates an new player if it's no persisted and adds/refreshes the join time
|
||||
*
|
||||
* @param uuid the actual uuid of a player
|
||||
* @param playerName for updating or to create a new player
|
||||
*/
|
||||
override fun playerJoin(uuid: UUID, playerName: String) {
|
||||
val player: Player = if (db.existsById(uuid)) {
|
||||
val dbPlayer = db.findById(uuid)
|
||||
dbPlayer.joinTime = LocalDateTime.now()
|
||||
dbPlayer.playerName = playerName
|
||||
dbPlayer
|
||||
} else {
|
||||
val player = Player(uuid, playerName)
|
||||
db.create(player)
|
||||
player
|
||||
}
|
||||
db.save(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the playtime and saves it from the player with the [uuid]
|
||||
*
|
||||
* @param uuid UUID
|
||||
*/
|
||||
override fun updatePlayTime(uuid: UUID) {
|
||||
val player = db.findById(uuid)
|
||||
player.playTime = calculatePlaytime(player)
|
||||
db.save(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the playtime of the player with the the [uuid]
|
||||
*
|
||||
* @param uuid player uuid
|
||||
*
|
||||
* @return the total playtime
|
||||
*/
|
||||
override fun timePlayed(uuid: UUID): Duration {
|
||||
val player = db.findById(uuid)
|
||||
return calculatePlaytime(player)
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the players with the highest playtime
|
||||
*
|
||||
* @return List<Player> in a descending order by playtime
|
||||
*/
|
||||
override fun getTopPlayers(): List<Player> {
|
||||
val playerList: List<Player> = db.findAll().onEach { player -> player.playTime = calculatePlaytime(player) }
|
||||
return playerList.sortedByDescending { player -> player.playTime }
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the time based on the join and on the last save time of the player
|
||||
* if the playtime got saved it should use the saved time instead of the join time
|
||||
*
|
||||
* @param player Player
|
||||
* @return Duration the playtime of the [player]
|
||||
*/
|
||||
private fun calculatePlaytime(player: Player): Duration {
|
||||
val playTime: Duration =
|
||||
if ((player.lastSave != null) && Duration.between(player.lastSave, player.joinTime).isNegative) {
|
||||
Duration.between(player.lastSave, LocalDateTime.now())
|
||||
} else {
|
||||
Duration.between(player.joinTime, LocalDateTime.now())
|
||||
}
|
||||
return Duration.from(player.playTime).plus(playTime)
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package commands
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandExecutor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
@ -9,9 +10,9 @@ import org.bukkit.entity.Player
|
|||
/**
|
||||
* The command executor for the playtime
|
||||
*
|
||||
* @property playerService the service which holds the current status
|
||||
* @property playerTime the service which holds the current status
|
||||
*/
|
||||
class PlayTime(private val playerService: PlayerService) : CommandExecutor {
|
||||
class PlayTime(private val playerTime: PlayerTime = PlayerTimeService) : CommandExecutor {
|
||||
|
||||
/**
|
||||
* It sends the playtime of and to the CommandSender
|
||||
|
@ -26,16 +27,11 @@ class PlayTime(private val playerService: PlayerService) : CommandExecutor {
|
|||
sender.sendMessage("This command can only be executed as a player")
|
||||
false
|
||||
} else {
|
||||
val duration = playerService.timePlayed(sender.uniqueId)
|
||||
val duration = playerTime.timePlayed(sender.uniqueId)
|
||||
|
||||
val days: String =
|
||||
if (duration.toDaysPart() < 10) """0${duration.toDaysPart()}""" else """${duration.toDaysPart()}"""
|
||||
val hours: String =
|
||||
if (duration.toHoursPart() < 10) """0${duration.toHoursPart()}""" else """${duration.toHoursPart()}"""
|
||||
val minutes: String =
|
||||
if (duration.toMinutesPart() < 10) """0${duration.toMinutesPart()}""" else """${duration.toMinutesPart()}"""
|
||||
val playTime = playerTime.timeToString(duration)
|
||||
|
||||
sender.sendMessage("""Your play time: $days:$hours:$minutes""")
|
||||
sender.sendMessage("""Your play time: $playTime""")
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
39
src/main/kotlin/commands/PlayTimeOfCommand.kt
Normal file
39
src/main/kotlin/commands/PlayTimeOfCommand.kt
Normal file
|
@ -0,0 +1,39 @@
|
|||
package commands
|
||||
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import db.FilePlayerTimeDB
|
||||
import db.PlayerFinder
|
||||
import db.PlayerNotFoundException
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandExecutor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
class PlayTimeOfCommand(private val playerTime: PlayerTime = PlayerTimeService, private val playerTimeDB: PlayerFinder = FilePlayerTimeDB()) :
|
||||
CommandExecutor {
|
||||
|
||||
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<String>): Boolean {
|
||||
if (args.size != 1) {
|
||||
return false
|
||||
} else {
|
||||
val playerName = args.first()
|
||||
val player = try {
|
||||
playerTimeDB.findByName(playerName)
|
||||
} catch (e: PlayerNotFoundException) {
|
||||
sender.sendMessage("""There is no player with the name $playerName""")
|
||||
return false
|
||||
}
|
||||
|
||||
val playerIsOnline = Bukkit.getPlayer(player.uuid)?.isOnline ?: false
|
||||
val time = if (playerIsOnline) {
|
||||
playerTime.timeToString(playerTime.timePlayed(player.uuid))
|
||||
} else {
|
||||
playerTime.timeToString(player.playTime)
|
||||
}
|
||||
|
||||
sender.sendMessage("""The play time from ${player.playerName} is $time""")
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
28
src/main/kotlin/commands/TopTime.kt
Normal file
28
src/main/kotlin/commands/TopTime.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
package commands
|
||||
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import java.util.stream.Collectors
|
||||
import org.bukkit.command.Command
|
||||
import org.bukkit.command.CommandExecutor
|
||||
import org.bukkit.command.CommandSender
|
||||
|
||||
/**
|
||||
* Command to get the top players with the most playtime
|
||||
*
|
||||
* @property playerTime PlayerTime
|
||||
* @property playerListSize Long default = 5
|
||||
* @constructor
|
||||
*/
|
||||
class TopTime(private val playerTime: PlayerTime = PlayerTimeService, private val playerListSize: Long = 5) : CommandExecutor {
|
||||
|
||||
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
||||
val playerTopList = playerTime.getTopPlayers().stream().limit(playerListSize).collect(Collectors.toList()).toList()
|
||||
|
||||
val sb = StringBuilder().appendln("Top list")
|
||||
playerTopList.forEach { sb.appendln("${it.playerName}: ${playerTime.timeToString(it.playTime)}") }
|
||||
sender.sendMessage(sb.toString())
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -1,9 +1,12 @@
|
|||
package db
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import java.io.File
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
import mu.KotlinLogging
|
||||
|
||||
/**
|
||||
* FileDB manages the file based PlayerTime DB and provides basic functionality to interact with it
|
||||
|
@ -13,6 +16,8 @@ import models.Player
|
|||
*/
|
||||
class FilePlayerTimeDB(private val path: File = File("./plugins/PlayTime/")) : PlayerTimeDB {
|
||||
|
||||
val logger = KotlinLogging.logger {}
|
||||
|
||||
private val gson = Gson()
|
||||
|
||||
/**
|
||||
|
@ -29,20 +34,39 @@ class FilePlayerTimeDB(private val path: File = File("./plugins/PlayTime/")) : P
|
|||
*
|
||||
* @return if the file is present
|
||||
*/
|
||||
override fun findByID(uuid: UUID): Boolean {
|
||||
override fun existsById(uuid: UUID): Boolean {
|
||||
return File(path, uuid.toString()).exists()
|
||||
}
|
||||
|
||||
/**
|
||||
* It should look if a player exists by iterating over all saved players
|
||||
*
|
||||
* @param name the id of the player
|
||||
*
|
||||
* @return if the player is present
|
||||
*/
|
||||
override fun existsByName(name: String): Boolean {
|
||||
val fileList = path.listFiles() ?: return false
|
||||
if (fileList.isEmpty()) return false
|
||||
for (file in fileList) {
|
||||
val player = gson.fromJson<Player>(file.readText(), Player::class.java)
|
||||
if (player.playerName == name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a player file
|
||||
*
|
||||
* @param player the player that should be saved to the new file
|
||||
*
|
||||
*/
|
||||
override fun createPlayer(player: Player) {
|
||||
override fun create(player: Player) {
|
||||
val file = File(path, player.uuid.toString())
|
||||
if (!file.exists()) file.createNewFile()
|
||||
writePlayer(player)
|
||||
save(player)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,20 +75,62 @@ class FilePlayerTimeDB(private val path: File = File("./plugins/PlayTime/")) : P
|
|||
* @param uuid the id of the player that should be read
|
||||
*
|
||||
* @return Player
|
||||
*
|
||||
* @throws PlayerNotFoundException
|
||||
*/
|
||||
override fun readPlayer(uuid: UUID): Player {
|
||||
override fun findById(uuid: UUID): Player {
|
||||
val file = File(path, uuid.toString())
|
||||
if (!file.exists()) throw PlayerNotFoundException("""The player with the id $uuid was not found""")
|
||||
return gson.fromJson(file.readText(), Player::class.java)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the player out of a file by finding the right one
|
||||
*
|
||||
* @param name the name of the player that should be read
|
||||
*
|
||||
* @return Player? if present
|
||||
*/
|
||||
override fun findByName(name: String): Player {
|
||||
val fileList =
|
||||
path.listFiles() ?: throw PlayerNotFoundException("""The player with the name $name was not found""")
|
||||
if (fileList.isEmpty()) throw PlayerNotFoundException("""The player with the name $name was not found""")
|
||||
for (file in fileList) {
|
||||
val player = gson.fromJson<Player>(file.readText(), Player::class.java)
|
||||
if (player.playerName == name) {
|
||||
return player
|
||||
}
|
||||
}
|
||||
throw PlayerNotFoundException("""The player with the name $name was not found""")
|
||||
}
|
||||
|
||||
/**
|
||||
* Should read all player and return theme
|
||||
*
|
||||
* @return List<Player>
|
||||
*/
|
||||
override fun findAll(): List<Player> {
|
||||
val playerList = mutableListOf<Player>()
|
||||
val fileList = path.listFiles() ?: return emptyList()
|
||||
fileList.forEach { file: File ->
|
||||
try {
|
||||
playerList.add(gson.fromJson(file.readText(), Player::class.java))
|
||||
} catch (e: JsonSyntaxException) {
|
||||
logger.error { "The player with the ID ${{ file.name }} could not be read out of the files!" }
|
||||
}
|
||||
}
|
||||
return playerList.toList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Writs a player into an existing file
|
||||
* To create a new player file @see createPlayer(player: Player)
|
||||
*
|
||||
* @param player that should be written
|
||||
*/
|
||||
override fun writePlayer(player: Player) {
|
||||
override fun save(player: Player) {
|
||||
val file = File(path, player.uuid.toString())
|
||||
player.lastSave = LocalDateTime.now()
|
||||
file.writeText(gson.toJson(player))
|
||||
}
|
||||
}
|
||||
|
|
55
src/main/kotlin/db/PlayerFinder.kt
Normal file
55
src/main/kotlin/db/PlayerFinder.kt
Normal file
|
@ -0,0 +1,55 @@
|
|||
package db
|
||||
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
|
||||
interface PlayerFinder {
|
||||
|
||||
/**
|
||||
* It should look if a player exists
|
||||
*
|
||||
* @param uuid the id of the player
|
||||
*
|
||||
* @return if the player is present
|
||||
*/
|
||||
fun existsById(uuid: UUID): Boolean
|
||||
|
||||
/**
|
||||
* It should look if a player exists
|
||||
* If uuid of the player available use @see db.PlayerTimeDB.findByID due to the option to change the username
|
||||
*
|
||||
* @param name the name of the player
|
||||
*
|
||||
* @return if the player is present
|
||||
*/
|
||||
fun existsByName(name: String): Boolean
|
||||
|
||||
/**
|
||||
* Should read the player
|
||||
*
|
||||
* @param uuid the uuid of the player that should be read
|
||||
*
|
||||
* @return the actual player
|
||||
*
|
||||
* @throws PlayerNotFoundException
|
||||
*/
|
||||
fun findById(uuid: UUID): Player
|
||||
|
||||
/**
|
||||
* Should read the player
|
||||
*
|
||||
* @param name the name of the player that should be read
|
||||
*
|
||||
* @return the actual player
|
||||
*
|
||||
* @throws PlayerNotFoundException
|
||||
*/
|
||||
fun findByName(name: String): Player
|
||||
|
||||
/**
|
||||
* Should read all player and return theme
|
||||
*
|
||||
* @return List<Player>
|
||||
*/
|
||||
fun findAll(): List<Player>
|
||||
}
|
5
src/main/kotlin/db/PlayerNotFoundException.kt
Normal file
5
src/main/kotlin/db/PlayerNotFoundException.kt
Normal file
|
@ -0,0 +1,5 @@
|
|||
package db
|
||||
|
||||
import java.lang.Exception
|
||||
|
||||
class PlayerNotFoundException(message: String) : Exception(message)
|
|
@ -1,40 +1,21 @@
|
|||
package db
|
||||
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
|
||||
interface PlayerTimeDB {
|
||||
|
||||
/**
|
||||
* It should look if a player exists
|
||||
*
|
||||
* @param uuid the id of the player
|
||||
*
|
||||
* @return if the file is present
|
||||
*/
|
||||
fun findByID(uuid: UUID): Boolean
|
||||
interface PlayerTimeDB : PlayerFinder {
|
||||
|
||||
/**
|
||||
* Should create a player record for persisting
|
||||
*
|
||||
* @param player the player that should be save
|
||||
*/
|
||||
fun createPlayer(player: Player)
|
||||
|
||||
/**
|
||||
* Should read the player
|
||||
*
|
||||
* @param uuid the uuid of the player that should be read
|
||||
*
|
||||
* @return the actual player
|
||||
*/
|
||||
fun readPlayer(uuid: UUID): Player
|
||||
fun create(player: Player)
|
||||
|
||||
/**
|
||||
* Should write a player into persistence
|
||||
* To create a new player file @see createPlayer(player: Player)
|
||||
* To create a new player file @see db.PlayerTimeDB.createPlayer
|
||||
*
|
||||
* @param player that should be written
|
||||
*/
|
||||
fun writePlayer(player: Player)
|
||||
fun save(player: Player)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package listener
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerJoinEvent
|
||||
|
@ -8,9 +9,9 @@ import org.bukkit.event.player.PlayerJoinEvent
|
|||
/**
|
||||
* The listener for the PlayerJoinEvent
|
||||
*
|
||||
* @property playerService the playService to add player to it
|
||||
* @property playerTimeService the playService to add player to it
|
||||
*/
|
||||
class JoinListener(private val playerService: PlayerService) : Listener {
|
||||
class JoinListener(private val playerTimeService: PlayerTime = PlayerTimeService) : Listener {
|
||||
|
||||
/**
|
||||
* Registers as handler for the PlayerJoinEvent
|
||||
|
@ -21,6 +22,6 @@ class JoinListener(private val playerService: PlayerService) : Listener {
|
|||
@EventHandler
|
||||
fun onPlayerJoin(event: PlayerJoinEvent) {
|
||||
val player = event.player
|
||||
playerService.addPlayer(player.uniqueId, player.name)
|
||||
playerTimeService.playerJoin(player.uniqueId, player.name)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package listener
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.player.PlayerQuitEvent
|
||||
|
@ -8,9 +9,9 @@ import org.bukkit.event.player.PlayerQuitEvent
|
|||
/**
|
||||
* The listener for the PlayerQuitEvent
|
||||
*
|
||||
* @property playerService the playService to remove player from it
|
||||
* @property playerTimeService the playService to remove player from it
|
||||
*/
|
||||
class QuitListener(private val playerService: PlayerService) : Listener {
|
||||
class QuitListener(private val playerTimeService: PlayerTime = PlayerTimeService) : Listener {
|
||||
|
||||
/**
|
||||
* Registers as handler for the PlayerQuitEvent
|
||||
|
@ -21,6 +22,6 @@ class QuitListener(private val playerService: PlayerService) : Listener {
|
|||
@EventHandler
|
||||
fun onPlayerQuit(event: PlayerQuitEvent) {
|
||||
val player = event.player
|
||||
playerService.removePlayer(player.uniqueId)
|
||||
playerTimeService.updatePlayTime(player.uniqueId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import java.util.UUID
|
|||
*/
|
||||
data class Player(
|
||||
val uuid: UUID,
|
||||
val playerName: String,
|
||||
var playerName: String,
|
||||
var playTime: Duration = Duration.ZERO,
|
||||
var joinTime: LocalDateTime = LocalDateTime.now(),
|
||||
var lastSave: LocalDateTime? = null
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package tasks
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import PlayerTimeService
|
||||
import org.bukkit.Bukkit
|
||||
|
||||
class PersistState(private val playerService: PlayerService) : Runnable {
|
||||
class PersistState(private val playerTime: PlayerTime = PlayerTimeService) : Runnable {
|
||||
|
||||
override fun run() {
|
||||
playerService.persistAllPlayer()
|
||||
Bukkit.getOnlinePlayers().forEach { player -> playerTime.updatePlayTime(player.uniqueId) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: "PlayTime"
|
||||
author: "hamburghammer"
|
||||
version: "0.1.0"
|
||||
version: "0.2.0"
|
||||
description: "allows player to see how much they have played for."
|
||||
main: Main
|
||||
|
||||
|
@ -10,8 +10,13 @@ commands:
|
|||
description: "Test command for foo"
|
||||
playtime:
|
||||
usage: /<command>
|
||||
# aliases: [timeplayed, pt]
|
||||
description: "Shows the playtime of a player!"
|
||||
uptime:
|
||||
usage: /<command>
|
||||
description: "Shows the up time of the server"
|
||||
description: "Shows the up time of the server"
|
||||
playtimeof:
|
||||
usage: /<command> <player>
|
||||
description: "Shows the playtime of the player"
|
||||
toptime:
|
||||
usage: /<command>
|
||||
description: "Shows top players with the highest playtime"
|
23
src/test/kotlin/FakePlayerTime.kt
Normal file
23
src/test/kotlin/FakePlayerTime.kt
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
import java.time.Duration
|
||||
import java.util.UUID
|
||||
import models.Player
|
||||
|
||||
class FakePlayerTime : PlayerTime {
|
||||
|
||||
override fun playerJoin(uuid: UUID, playerName: String) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun updatePlayTime(uuid: UUID) {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun timePlayed(uuid: UUID): Duration {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun getTopPlayers(): List<Player> {
|
||||
TODO("not implemented") // To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
24
src/test/kotlin/PlayTimeTest.kt
Normal file
24
src/test/kotlin/PlayTimeTest.kt
Normal file
|
@ -0,0 +1,24 @@
|
|||
import java.time.Duration
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class PlayTimeTest {
|
||||
|
||||
@Test
|
||||
fun `right day formatting`() {
|
||||
assertEquals("02:00:00", FakePlayerTime().timeToString(Duration.ofDays(2)))
|
||||
assertEquals("20:00:00", FakePlayerTime().timeToString(Duration.ofDays(20)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `right hour formatting`() {
|
||||
assertEquals("00:02:00", FakePlayerTime().timeToString(Duration.ofHours(2)))
|
||||
assertEquals("00:20:00", FakePlayerTime().timeToString(Duration.ofHours(20)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `right minutes formatting`() {
|
||||
assertEquals("00:00:02", FakePlayerTime().timeToString(Duration.ofMinutes(2)))
|
||||
assertEquals("00:00:20", FakePlayerTime().timeToString(Duration.ofMinutes(20)))
|
||||
}
|
||||
}
|
|
@ -1,245 +0,0 @@
|
|||
import db.PlayerTimeDB
|
||||
import io.mockk.Runs
|
||||
import io.mockk.confirmVerified
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
import models.Player
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class PlayerServiceTest {
|
||||
|
||||
@Nested
|
||||
inner class AddPlayerTest {
|
||||
@Test
|
||||
fun `should add new player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(uuid) } returns false
|
||||
every { mockDB.createPlayer(any()) } just Runs
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
assertTrue(playerService.isEmpty())
|
||||
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
assertTrue(playerService.containsPlayer(uuid))
|
||||
|
||||
verify(exactly = 1) { mockDB.findByID(uuid) }
|
||||
verify(exactly = 1) { mockDB.createPlayer(any()) }
|
||||
confirmVerified(mockDB)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should add existing player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
|
||||
assertTrue(playerService.isEmpty())
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
assertTrue(playerService.containsPlayer(uuid))
|
||||
|
||||
verify(exactly = 1) { mockDB.findByID(any()) }
|
||||
verify(exactly = 1) { mockDB.readPlayer(any()) }
|
||||
confirmVerified(mockDB)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change join time by existing player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
player.joinTime = LocalDateTime.now().minusDays(1)
|
||||
val originalPlayer = player.copy()
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
val extract = playerService.getPlayer(uuid)
|
||||
|
||||
assertNotEquals(originalPlayer.joinTime, extract.joinTime)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `remove a player from the map`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
every { mockDB.writePlayer(any()) } just Runs
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
|
||||
playerService.removePlayer(uuid)
|
||||
|
||||
assertTrue(playerService.isEmpty())
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class PersistPlayerTest {
|
||||
|
||||
@Test
|
||||
fun `persist a player from the map to the db`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
every { mockDB.writePlayer(any()) } just Runs
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
playerService.persistPlayer(uuid)
|
||||
|
||||
verify(exactly = 1) { mockDB.writePlayer(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `persist a player from the map to the db with updated playtime`() {
|
||||
val captureList = mutableListOf<Player>()
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
every { mockDB.writePlayer(capture(captureList)) } just Runs
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
playerService.persistPlayer(uuid)
|
||||
|
||||
assertEquals(1, captureList.size)
|
||||
assertNotEquals(Duration.ZERO, captureList.first().playTime)
|
||||
|
||||
verify(exactly = 1) { mockDB.writePlayer(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `persist all player from the map`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val uuid2 = UUID.randomUUID()
|
||||
|
||||
val player = Player(uuid, "playerName")
|
||||
val player2 = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(uuid) } returns player
|
||||
every { mockDB.readPlayer(uuid2) } returns player2
|
||||
every { mockDB.writePlayer(any()) } just Runs
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
playerService.addPlayer(uuid2, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
|
||||
playerService.persistAllPlayer()
|
||||
|
||||
verify(exactly = 2) { mockDB.writePlayer(any()) }
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class GetPlayerTest {
|
||||
|
||||
@Test
|
||||
fun `get player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
|
||||
val extractedPlayer = playerService.getPlayer(uuid)
|
||||
|
||||
assertEquals(player.uuid, extractedPlayer.uuid)
|
||||
assertEquals(player.playerName, extractedPlayer.playerName)
|
||||
assertEquals(player.playTime, extractedPlayer.playTime)
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class TimePlayedTest {
|
||||
|
||||
@Test
|
||||
fun `get played time and update the field`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns player
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
|
||||
assertNotEquals(Duration.ZERO, playerService.timePlayed(uuid))
|
||||
assertEquals(Duration.ZERO, playerService.getPlayer(uuid).playTime)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get played time after the time was saved`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val mockPlayer = Player(uuid, "playerName" ,lastSave = LocalDateTime.now().minusMinutes(10))
|
||||
|
||||
val mockDB = mockk<PlayerTimeDB>()
|
||||
every { mockDB.findByID(any()) } returns true
|
||||
every { mockDB.readPlayer(any()) } returns mockPlayer
|
||||
|
||||
val playerService = PlayerService(mockDB)
|
||||
|
||||
playerService.addPlayer(uuid, "playerName")
|
||||
|
||||
assertFalse(playerService.isEmpty())
|
||||
|
||||
val playTime = playerService.timePlayed(uuid)
|
||||
|
||||
assertEquals(10, playTime.toMinutes())
|
||||
println(playTime.toMinutes())
|
||||
}
|
||||
}
|
||||
}
|
115
src/test/kotlin/commands/PlayTimeOfCommandTest.kt
Normal file
115
src/test/kotlin/commands/PlayTimeOfCommandTest.kt
Normal file
|
@ -0,0 +1,115 @@
|
|||
package commands
|
||||
|
||||
import FakePlayerTime
|
||||
import SimplePlayerTime
|
||||
import db.PlayerNotFoundException
|
||||
import db.PlayerTimeDB
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkAll
|
||||
import java.time.Duration
|
||||
import java.util.UUID
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import models.Player
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
|
||||
internal class PlayTimeOfCommandTest {
|
||||
|
||||
@AfterTest
|
||||
fun cleanUp() {
|
||||
unmockkAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the there is no arg`() {
|
||||
val mockPlayerService = mockk<SimplePlayerTime>()
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
|
||||
val playTimeOfCommand = PlayTimeOfCommand(mockPlayerService, mockPlayerTimeDB)
|
||||
|
||||
assertFalse(playTimeOfCommand.onCommand(mockk(), mockk(), "", arrayOf()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the player can not be read`() {
|
||||
val nonExistingPlayerName = "foo"
|
||||
val captureList = mutableListOf<String>()
|
||||
val mockPlayerService = mockk<SimplePlayerTime>()
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.findByName(nonExistingPlayerName) } throws (PlayerNotFoundException(""))
|
||||
|
||||
val playTimeOfCommand = PlayTimeOfCommand(mockPlayerService, mockPlayerTimeDB)
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
assertFalse(playTimeOfCommand.onCommand(mockCommandSender, mockk(), "", arrayOf(nonExistingPlayerName)))
|
||||
assertEquals(1, captureList.size)
|
||||
assertEquals("""There is no player with the name $nonExistingPlayerName""", captureList.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `player found online`() {
|
||||
val captureList = mutableListOf<String>()
|
||||
val playerName = "foo"
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
val duration = Duration.ZERO
|
||||
val timeToString = FakePlayerTime().timeToString(duration)
|
||||
|
||||
val mockPlayerService = mockk<SimplePlayerTime>()
|
||||
every { mockPlayerService.timePlayed(uuid) } returns duration
|
||||
every { mockPlayerService.timeToString(duration) } returns timeToString
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.findByName(playerName) } returns player
|
||||
|
||||
val playTimeOfCommand = PlayTimeOfCommand(mockPlayerService, mockPlayerTimeDB)
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
mockkStatic(Bukkit::class)
|
||||
every { Bukkit.getPlayer(uuid)!!.isOnline } returns true
|
||||
|
||||
assertTrue(playTimeOfCommand.onCommand(mockCommandSender, mockk(), "", arrayOf(playerName)))
|
||||
assertEquals(1, captureList.size)
|
||||
assertEquals("""The play time from $playerName is $timeToString""", captureList.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `player found not online`() {
|
||||
val captureList = mutableListOf<String>()
|
||||
val playerName = "foo"
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
val duration = Duration.ZERO
|
||||
val timeToString = FakePlayerTime().timeToString(duration)
|
||||
|
||||
val mockPlayerService = mockk<SimplePlayerTime>()
|
||||
every { mockPlayerService.timeToString(duration) } returns timeToString
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.findByName(playerName) } returns player
|
||||
|
||||
val playTimeOfCommand = PlayTimeOfCommand(mockPlayerService, mockPlayerTimeDB)
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
mockkStatic(Bukkit::class)
|
||||
every { Bukkit.getPlayer(uuid)!!.isOnline } returns false
|
||||
|
||||
assertTrue(playTimeOfCommand.onCommand(mockCommandSender, mockk(), "", arrayOf(playerName)))
|
||||
assertEquals(1, captureList.size)
|
||||
assertEquals("""The play time from $playerName is $timeToString""", captureList.first())
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package commands
|
||||
|
||||
import PlayerService
|
||||
import FakePlayerTime
|
||||
import SimplePlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
|
@ -20,8 +21,10 @@ internal class PlayTimeTest {
|
|||
fun `get the current play time`() {
|
||||
val list = mutableListOf<String>()
|
||||
|
||||
val mockedPlayerService = mockk<PlayerService>()
|
||||
every { mockedPlayerService.timePlayed(any()) } returns Duration.ofMinutes(10)
|
||||
val mockedPlayerService = mockk<SimplePlayerTime>()
|
||||
val duration = Duration.ofMinutes(10)
|
||||
every { mockedPlayerService.timePlayed(any()) } returns duration
|
||||
every { mockedPlayerService.timeToString(any()) } returns FakePlayerTime().timeToString(duration)
|
||||
|
||||
val playTime = PlayTime(mockedPlayerService)
|
||||
|
||||
|
@ -39,7 +42,7 @@ internal class PlayTimeTest {
|
|||
fun `error if not send by player`() {
|
||||
val list = mutableListOf<String>()
|
||||
|
||||
val mockedPlayerService = mockk<PlayerService>()
|
||||
val mockedPlayerService = mockk<SimplePlayerTime>()
|
||||
every { mockedPlayerService.timePlayed(any()) } returns Duration.ofMinutes(10)
|
||||
|
||||
val playTime = PlayTime(mockedPlayerService)
|
||||
|
|
105
src/test/kotlin/commands/TopTimeTest.kt
Normal file
105
src/test/kotlin/commands/TopTimeTest.kt
Normal file
|
@ -0,0 +1,105 @@
|
|||
package commands
|
||||
|
||||
import SimplePlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.unmockkAll
|
||||
import java.time.Duration
|
||||
import java.util.UUID
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import models.Player
|
||||
import org.bukkit.command.CommandSender
|
||||
import org.junit.jupiter.api.Assertions.assertNotEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
|
||||
class TopTimeTest {
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
unmockkAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `send string`() {
|
||||
val captureList = mutableListOf<String>()
|
||||
|
||||
val uuid1 = UUID.randomUUID()
|
||||
val uuid2 = UUID.randomUUID()
|
||||
val uuid3 = UUID.randomUUID()
|
||||
val player1 = Player(uuid1, "player1", playTime = Duration.ZERO)
|
||||
val player2 = Player(uuid2, "player2", playTime = Duration.ofMinutes(10))
|
||||
val player3 = Player(uuid3, "player3", playTime = Duration.ofHours(2))
|
||||
|
||||
val mockPlayTime = mockk<SimplePlayerTime>()
|
||||
every { mockPlayTime.getTopPlayers() } returns listOf(player3, player2, player1)
|
||||
every { mockPlayTime.timeToString(any()) } returns "00:00:00"
|
||||
|
||||
val topTime = TopTime(mockPlayTime)
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
assertTrue(topTime.onCommand(mockCommandSender, mockk(), "", arrayOf()))
|
||||
|
||||
assertTrue(captureList.isNotEmpty())
|
||||
assertNotEquals("", captureList.first())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `correct formatted string output`() {
|
||||
val captureList = mutableListOf<String>()
|
||||
|
||||
val uuid1 = UUID.randomUUID()
|
||||
val uuid2 = UUID.randomUUID()
|
||||
val uuid3 = UUID.randomUUID()
|
||||
val player1 = Player(uuid1, "player1", playTime = Duration.ZERO)
|
||||
val player2 = Player(uuid2, "player2", playTime = Duration.ofMinutes(10))
|
||||
val player3 = Player(uuid3, "player3", playTime = Duration.ofHours(2))
|
||||
|
||||
val mockPlayTime = mockk<SimplePlayerTime>()
|
||||
every { mockPlayTime.getTopPlayers() } returns listOf(player3, player2, player1)
|
||||
every { mockPlayTime.timeToString(any()) } returns "00:00:00"
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
val topTime = TopTime(mockPlayTime)
|
||||
assertTrue(topTime.onCommand(mockCommandSender, mockk(), "", arrayOf()))
|
||||
|
||||
assertEquals(
|
||||
"""Top list
|
||||
player3: 00:00:00
|
||||
player2: 00:00:00
|
||||
player1: 00:00:00
|
||||
""", captureList.first().toString()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `show only top 6 player`() {
|
||||
val playerListSize = 6
|
||||
val defaultNewLines = 2
|
||||
val captureList = mutableListOf<String>()
|
||||
|
||||
val playerList = mutableListOf<Player>()
|
||||
for (i in 1..7) {
|
||||
playerList.add(Player(UUID.randomUUID(), "$i", playTime = Duration.ZERO))
|
||||
}
|
||||
|
||||
val mockPlayTime = mockk<SimplePlayerTime>()
|
||||
every { mockPlayTime.getTopPlayers() } returns playerList.toList()
|
||||
every { mockPlayTime.timeToString(any()) } returns "00:00:00"
|
||||
|
||||
val mockCommandSender = mockk<CommandSender>()
|
||||
every { mockCommandSender.sendMessage(capture(captureList)) } just Runs
|
||||
|
||||
val topTime = TopTime(mockPlayTime, playerListSize.toLong())
|
||||
assertTrue(topTime.onCommand(mockCommandSender, mockk(), "", arrayOf()))
|
||||
|
||||
assertEquals(playerListSize + defaultNewLines, captureList.first().split("\n").count())
|
||||
}
|
||||
}
|
|
@ -7,11 +7,14 @@ import kotlin.test.AfterTest
|
|||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertNotNull
|
||||
import models.Player
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Nested
|
||||
|
||||
internal class FilePlayerTimeDBTest {
|
||||
class FilePlayerTimeDBTest {
|
||||
|
||||
private var dbDir = createTempDir()
|
||||
|
||||
|
@ -30,10 +33,10 @@ internal class FilePlayerTimeDBTest {
|
|||
val uuid = UUID.randomUUID()
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
|
||||
assertFalse(fileDB.findByID(uuid))
|
||||
assertFalse(fileDB.existsById(uuid))
|
||||
|
||||
File(dbDir, uuid.toString()).createNewFile()
|
||||
assertTrue(fileDB.findByID(uuid))
|
||||
assertTrue(fileDB.existsById(uuid))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -42,25 +45,64 @@ internal class FilePlayerTimeDBTest {
|
|||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val player = Player(uuid, "username")
|
||||
|
||||
assertFalse(fileDB.findByID(uuid))
|
||||
assertFalse(fileDB.existsById(uuid))
|
||||
|
||||
fileDB.createPlayer(player)
|
||||
fileDB.create(player)
|
||||
|
||||
assertTrue(fileDB.findByID(uuid))
|
||||
assertTrue(fileDB.existsById(uuid))
|
||||
|
||||
val writtenFile = File(dbDir, uuid.toString())
|
||||
assertEquals(player, Gson().fromJson(writtenFile.readText(), Player::class.java))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `read player from file`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val player = Player(uuid, "username")
|
||||
@Nested
|
||||
inner class ReadPlayer {
|
||||
|
||||
File(dbDir, uuid.toString()).writeText(Gson().toJson(player))
|
||||
@Test
|
||||
fun `read player from file`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val player = Player(uuid, "username")
|
||||
|
||||
assertEquals(player, fileDB.readPlayer(uuid))
|
||||
File(dbDir, uuid.toString()).writeText(Gson().toJson(player))
|
||||
|
||||
assertEquals(player, fileDB.findById(uuid))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `read player from file through player name`() {
|
||||
val playerName = "playerName"
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
|
||||
val file = File(dbDir, uuid.toString())
|
||||
assertTrue(file.createNewFile())
|
||||
|
||||
file.writeText(Gson().toJson(player))
|
||||
|
||||
val readPlayer = fileDB.findByName(playerName)
|
||||
assertNotNull(readPlayer)
|
||||
assertEquals(player, readPlayer)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `read not existing player from file through player name`() {
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
|
||||
val playerName = "foo"
|
||||
val exception = assertFailsWith<PlayerNotFoundException> { fileDB.findByName(playerName) }
|
||||
assertEquals("""The player with the name $playerName was not found""", exception.message)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `read not existing player from file through player id`() {
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
|
||||
val uuid = UUID.randomUUID()
|
||||
val exception = assertFailsWith<PlayerNotFoundException> { fileDB.findById(uuid) }
|
||||
assertEquals("""The player with the id $uuid was not found""", exception.message)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -71,7 +113,83 @@ internal class FilePlayerTimeDBTest {
|
|||
|
||||
val file = File(dbDir, uuid.toString())
|
||||
assertTrue(file.createNewFile())
|
||||
fileDB.writePlayer(player)
|
||||
fileDB.save(player)
|
||||
assertEquals(player, Gson().fromJson(file.readText(), Player::class.java))
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class FindPlayerByName {
|
||||
|
||||
@Test
|
||||
fun `find player over playerName`() {
|
||||
val playerName = "playerName"
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
|
||||
val file = File(dbDir, uuid.toString())
|
||||
assertTrue(file.createNewFile())
|
||||
|
||||
file.writeText(Gson().toJson(player))
|
||||
assertTrue(fileDB.existsByName(playerName))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return false if there is no file`() {
|
||||
val playerName = "playerName"
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
|
||||
assertFalse(fileDB.existsByName(playerName))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `return false if there is no file matching the name`() {
|
||||
val playerName = "playerName"
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
|
||||
val file = File(dbDir, uuid.toString())
|
||||
assertTrue(file.createNewFile())
|
||||
|
||||
file.writeText(Gson().toJson(player))
|
||||
assertFalse(fileDB.existsByName("foo"))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `find all players`() {
|
||||
val playerName = "playerName"
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val uuid = UUID.randomUUID()
|
||||
val uuid2 = UUID.randomUUID()
|
||||
val player = Player(uuid, playerName)
|
||||
val player2 = Player(uuid2, playerName)
|
||||
|
||||
File(dbDir, uuid.toString()).writeText(Gson().toJson(player))
|
||||
File(dbDir, uuid2.toString()).writeText(Gson().toJson(player2))
|
||||
|
||||
val playerList = fileDB.findAll()
|
||||
assertFalse(playerList.isEmpty())
|
||||
assertEquals(2, playerList.size)
|
||||
assertTrue(playerList.contains(player))
|
||||
assertTrue(playerList.contains(player2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `find all players if there is no one`() {
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
|
||||
assertTrue(fileDB.findAll().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `error by deserialization`() {
|
||||
val fileDB = FilePlayerTimeDB(dbDir)
|
||||
val uuid = UUID.randomUUID()
|
||||
|
||||
File(dbDir, uuid.toString()).writeText("Foo")
|
||||
|
||||
assertTrue(fileDB.findAll().isEmpty())
|
||||
}
|
||||
}
|
||||
|
|
243
src/test/kotlin/db/SimplePlayerTimeTest.kt
Normal file
243
src/test/kotlin/db/SimplePlayerTimeTest.kt
Normal file
|
@ -0,0 +1,243 @@
|
|||
package db
|
||||
|
||||
import SimplePlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import java.time.Duration
|
||||
import java.time.LocalDateTime
|
||||
import java.util.UUID
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import models.Player
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertFalse
|
||||
import org.junit.jupiter.api.Assertions.assertNotEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Nested
|
||||
|
||||
class SimplePlayerTimeTest {
|
||||
|
||||
private var dbDir = createTempDir()
|
||||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
dbDir = createTempDir()
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
fun cleanUp() {
|
||||
dbDir.delete()
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class AddPlayerTest {
|
||||
@Test
|
||||
fun `should add new player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(uuid) } returns false
|
||||
every { mockPlayerTimeDB.create(any()) } just Runs
|
||||
every { mockPlayerTimeDB.save(any()) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
verify { mockPlayerTimeDB.save(any()) }
|
||||
verify { mockPlayerTimeDB.create(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should add existing player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(uuid) } returns true
|
||||
every { mockPlayerTimeDB.findById(uuid) } returns player
|
||||
every { mockPlayerTimeDB.save(any()) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
verify { mockPlayerTimeDB.save(any()) }
|
||||
verify { mockPlayerTimeDB.findById(uuid) }
|
||||
verify { mockPlayerTimeDB.existsById(uuid) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should add existing player and update the username`() {
|
||||
val capturedPlayer = mutableListOf<Player>()
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
val updateName = "updateName"
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(uuid) } returns true
|
||||
every { mockPlayerTimeDB.findById(any()) } returns player
|
||||
every { mockPlayerTimeDB.save(capture(capturedPlayer)) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, updateName)
|
||||
|
||||
assertEquals(1, capturedPlayer.size)
|
||||
assertEquals(updateName, capturedPlayer.first().playerName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change join time by existing player`() {
|
||||
val capturedPlayer = mutableListOf<Player>()
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
player.joinTime = LocalDateTime.now().minusDays(1)
|
||||
val originalPlayer = player.copy()
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(uuid) } returns true
|
||||
every { mockPlayerTimeDB.findById(uuid = any()) } returns player
|
||||
every { mockPlayerTimeDB.save(capture(capturedPlayer)) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
assertEquals(1, capturedPlayer.size)
|
||||
assertNotEquals(originalPlayer.joinTime, capturedPlayer.first().joinTime)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `update the play time and save`() {
|
||||
val capturedPlayers = mutableListOf<Player>()
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "", playTime = Duration.ZERO)
|
||||
|
||||
val mockDBPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockDBPlayerTimeDB.findById(uuid) } returns player
|
||||
every { mockDBPlayerTimeDB.save(capture(capturedPlayers)) } just Runs
|
||||
|
||||
val simplePlayerTime = SimplePlayerTime(mockDBPlayerTimeDB)
|
||||
|
||||
simplePlayerTime.updatePlayTime(uuid)
|
||||
|
||||
assertEquals(1, capturedPlayers.size)
|
||||
assertNotEquals(Duration.ZERO, capturedPlayers.first().playTime)
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class TimePlayedTest {
|
||||
|
||||
@Test
|
||||
fun `get played time and update the field`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName")
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(any()) } returns true
|
||||
every { mockPlayerTimeDB.findById(uuid) } returns player
|
||||
every { mockPlayerTimeDB.save(any()) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
// assertFalse(playerService.isEmpty())
|
||||
|
||||
val playTime = playerService.timePlayed(uuid)
|
||||
|
||||
assertNotEquals(Duration.ZERO, playTime)
|
||||
assertFalse(playTime.isNegative)
|
||||
// assertEquals(Duration.ZERO, playerService.getPlayer(uuid).playTime)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get played time after the time was saved`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val player = Player(uuid, "playerName", lastSave = LocalDateTime.now().plusMinutes(10))
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(any()) } returns true
|
||||
every { mockPlayerTimeDB.findById(uuid) } returns player
|
||||
every { mockPlayerTimeDB.save(any()) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
val playTime = playerService.timePlayed(uuid)
|
||||
|
||||
assertTrue(
|
||||
playTime.toMinutes() <= -9,
|
||||
"the result is negative because it is a synthetic test. The playtime is " + playTime.toMinutes()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get played time from the join when the save time earlier than the join time`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val mockPlayer = Player(uuid, "playerName", lastSave = LocalDateTime.now().minusMinutes(10))
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.existsById(any()) } returns true
|
||||
every { mockPlayerTimeDB.findById(uuid) } returns mockPlayer
|
||||
every { mockPlayerTimeDB.save(any()) } just Runs
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
playerService.playerJoin(uuid, "playerName")
|
||||
|
||||
// assertFalse(playerService.isEmpty())
|
||||
|
||||
val playTime = playerService.timePlayed(uuid)
|
||||
|
||||
assertNotEquals(Duration.ZERO, playTime)
|
||||
assertFalse(playTime.isNegative)
|
||||
println(playTime.toMinutes())
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class TopPlayer {
|
||||
|
||||
@Test
|
||||
fun `get list with players`() {
|
||||
val player1 = Player(UUID.randomUUID(), "player1", playTime = Duration.ZERO)
|
||||
val player2 = Player(UUID.randomUUID(), "player2", playTime = Duration.ofMinutes(10))
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.findAll() } returns listOf(player1, player2)
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
val topPlayer = playerService.getTopPlayers()
|
||||
|
||||
assertFalse(topPlayer.isEmpty())
|
||||
assertEquals(2, topPlayer.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `get list with players sorted by most time`() {
|
||||
val player1 = Player(UUID.randomUUID(), "player1", playTime = Duration.ZERO)
|
||||
val player2 = Player(UUID.randomUUID(), "player2", playTime = Duration.ofMinutes(10))
|
||||
val player3 = Player(UUID.randomUUID(), "player3", playTime = Duration.ofHours(2))
|
||||
|
||||
val mockPlayerTimeDB = mockk<PlayerTimeDB>()
|
||||
every { mockPlayerTimeDB.findAll() } returns listOf(player1, player2, player3)
|
||||
|
||||
val playerService = SimplePlayerTime(mockPlayerTimeDB)
|
||||
|
||||
val topPlayer = playerService.getTopPlayers()
|
||||
|
||||
assertEquals(player3, topPlayer[0])
|
||||
assertEquals(player2, topPlayer[1])
|
||||
assertEquals(player1, topPlayer[2])
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
package listener
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.confirmVerified
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
|
@ -16,20 +15,21 @@ class JoinListenerTest {
|
|||
|
||||
@Test
|
||||
fun `should call to add a player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
|
||||
val mockPlayer = mockk<Player>()
|
||||
every { mockPlayer.uniqueId } returns UUID.randomUUID()
|
||||
every { mockPlayer.uniqueId } returns uuid
|
||||
every { mockPlayer.name } returns ""
|
||||
|
||||
val mockPlayerJoinEvent = mockk<PlayerJoinEvent>()
|
||||
every { mockPlayerJoinEvent.player } returns mockPlayer
|
||||
|
||||
val mockPlayerService = mockk<PlayerService>()
|
||||
every { mockPlayerService.addPlayer(any(), any()) } just Runs
|
||||
val mockPlayerDB = mockk<PlayerTime>()
|
||||
every { mockPlayerDB.playerJoin(any(), any()) } just Runs
|
||||
|
||||
val joinListener = JoinListener(mockPlayerService)
|
||||
val joinListener = JoinListener(mockPlayerDB)
|
||||
joinListener.onPlayerJoin(mockPlayerJoinEvent)
|
||||
|
||||
verify(exactly = 1) { mockPlayerService.addPlayer(any(), any()) }
|
||||
confirmVerified(mockPlayerService)
|
||||
verify { mockPlayerDB.playerJoin(any(), any()) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package listener
|
||||
|
||||
import PlayerService
|
||||
import PlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.confirmVerified
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
|
@ -16,20 +15,20 @@ class QuitListenerTest {
|
|||
|
||||
@Test
|
||||
fun `should call to add a player`() {
|
||||
val uuid = UUID.randomUUID()
|
||||
val mockPlayer = mockk<Player>()
|
||||
every { mockPlayer.uniqueId } returns UUID.randomUUID()
|
||||
every { mockPlayer.uniqueId } returns uuid
|
||||
every { mockPlayer.name } returns ""
|
||||
|
||||
val mockPlayerQuitEvent = mockk<PlayerQuitEvent>()
|
||||
every { mockPlayerQuitEvent.player } returns mockPlayer
|
||||
|
||||
val mockPlayerService = mockk<PlayerService>()
|
||||
every { mockPlayerService.removePlayer(any()) } just Runs
|
||||
val mockPlayerDB = mockk<PlayerTime>()
|
||||
every { mockPlayerDB.updatePlayTime(any()) } just Runs
|
||||
|
||||
val quitListener = QuitListener(mockPlayerService)
|
||||
val quitListener = QuitListener(mockPlayerDB)
|
||||
quitListener.onPlayerQuit(mockPlayerQuitEvent)
|
||||
|
||||
verify(exactly = 1) { mockPlayerService.removePlayer(any()) }
|
||||
confirmVerified(mockPlayerService)
|
||||
verify { mockPlayerDB.updatePlayTime(any()) }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,50 @@
|
|||
package tasks
|
||||
|
||||
import PlayerService
|
||||
import SimplePlayerTime
|
||||
import io.mockk.Runs
|
||||
import io.mockk.confirmVerified
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkAll
|
||||
import io.mockk.verify
|
||||
import java.util.UUID
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class PersistStateTest {
|
||||
|
||||
@AfterTest
|
||||
fun cleanUp() {
|
||||
unmockkAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should persist all players`() {
|
||||
val mockPlayerService = mockk<PlayerService>()
|
||||
every { mockPlayerService.persistAllPlayer() } just Runs
|
||||
val captureList = mutableListOf<UUID>()
|
||||
val uuids = listOf<UUID>(UUID.randomUUID(), UUID.randomUUID())
|
||||
|
||||
val player1 = mockk<Player>()
|
||||
val player2 = mockk<Player>()
|
||||
every { player1.uniqueId } returns uuids[0]
|
||||
every { player2.uniqueId } returns uuids[1]
|
||||
|
||||
mockkStatic(Bukkit::class)
|
||||
every { Bukkit.getOnlinePlayers() } returns listOf(player1, player2)
|
||||
|
||||
val mockPlayerService = mockk<SimplePlayerTime>()
|
||||
every { mockPlayerService.updatePlayTime(capture(captureList)) } just Runs
|
||||
|
||||
val persistState = PersistState(mockPlayerService)
|
||||
persistState.run()
|
||||
|
||||
verify(exactly = 1) { mockPlayerService.persistAllPlayer() }
|
||||
assertEquals(2, captureList.size)
|
||||
|
||||
verify(exactly = 2) { mockPlayerService.updatePlayTime(any()) }
|
||||
confirmVerified(mockPlayerService)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
VERSION=0.1.0
|
||||
VERSION=0.2.0
|
||||
|
||||
sh ./gradlew shadowJar
|
||||
|
||||
|
|
Loading…
Reference in a new issue