Ajoute des tests unitaires JUnit 5 (CP9 - plans de tests)

14 tests couvrant VoteConfig (Spigot + Velocity) et YamlPendingVoteStore
(Spigot + Velocity) : valeurs par defaut, portee per-server/global,
merge de config sans ecraser l'existant, incrementation/reset des
votes en attente, colorisation des messages.

Mockito pour VoteConfig/YamlPendingVoteStore cote Spigot (mock de
VoteNetworkSpigot, pas besoin de serveur Bukkit reel). Cote Velocity,
tests directs sans framework (classes deja decouplees de Velocity-API).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
SarTron-NorthBlue
2026-07-13 09:14:12 +04:00
co-authored by Claude Sonnet 5
parent d5f6e0cfb3
commit 5abe49fdd0
8 changed files with 325 additions and 0 deletions
@@ -0,0 +1,104 @@
package fr.votenetwork.velocity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.slf4j.helpers.NOPLogger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class VoteConfigTest {
@Test
void loadCopiesDefaultsWhenFileMissing(@TempDir Path dataDir) {
VoteConfig config = new VoteConfig(dataDir, NOPLogger.NOP_LOGGER);
config.load();
assertTrue(config.isMysqlStorage());
assertEquals("jdbc:mysql://127.0.0.1:3306/votenetwork?useSSL=false&autoReconnect=true&characterEncoding=utf8",
config.getJdbcUrl());
assertTrue(Files.exists(dataDir.resolve("config.properties")));
}
@Test
void perServerScopeFallsBackToGlobalWhenServerListEmpty(@TempDir Path dataDir) throws IOException {
writeConfig(dataDir, """
storage.type=mysql
mysql.host=127.0.0.1
mysql.port=3306
mysql.database=votenetwork
mysql.user=root
mysql.password=changeme
mysql.pool-size=5
direct-vote.servers=
pending-votes.scope=per-server
""");
VoteConfig config = new VoteConfig(dataDir, NOPLogger.NOP_LOGGER);
config.load();
assertFalse(config.isPerServerScope(), "sans direct-vote.servers, per-server doit retomber sur global");
}
@Test
void perServerScopeAppliesWhenServersListed(@TempDir Path dataDir) throws IOException {
writeConfig(dataDir, """
storage.type=mysql
mysql.host=127.0.0.1
mysql.port=3306
mysql.database=votenetwork
mysql.user=root
mysql.password=changeme
mysql.pool-size=5
direct-vote.servers=gen1, GEN2
pending-votes.scope=per-server
""");
VoteConfig config = new VoteConfig(dataDir, NOPLogger.NOP_LOGGER);
config.load();
assertTrue(config.isPerServerScope());
assertTrue(config.isDirectVoteServer("gen1"));
assertTrue(config.isDirectVoteServer("Gen2"), "la comparaison doit ignorer la casse");
assertFalse(config.isDirectVoteServer("lobby"));
}
@Test
void isDirectVoteServerAllowsAllWhenListEmpty(@TempDir Path dataDir) throws IOException {
writeConfig(dataDir, """
storage.type=mysql
direct-vote.servers=
""");
VoteConfig config = new VoteConfig(dataDir, NOPLogger.NOP_LOGGER);
config.load();
assertTrue(config.isDirectVoteServer("n_importe_quoi"));
}
@Test
void mergeAddsMissingKeysWithoutTouchingExistingOnes(@TempDir Path dataDir) throws IOException {
writeConfig(dataDir, """
mysql.password=ne-pas-toucher
""");
VoteConfig config = new VoteConfig(dataDir, NOPLogger.NOP_LOGGER);
config.load();
String fileContent = Files.readString(dataDir.resolve("config.properties"), StandardCharsets.UTF_8);
assertTrue(fileContent.contains("mysql.password=ne-pas-toucher"), "la valeur existante ne doit jamais etre ecrasee");
assertTrue(fileContent.contains("pending-votes.scope="), "les cles manquantes doivent etre ajoutees");
assertEquals("ne-pas-toucher", config.getPassword());
}
private void writeConfig(Path dataDir, String content) throws IOException {
Files.createDirectories(dataDir);
Files.writeString(dataDir.resolve("config.properties"), content, StandardCharsets.UTF_8);
}
}
@@ -0,0 +1,55 @@
package fr.votenetwork.velocity;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.slf4j.helpers.NOPLogger;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static org.junit.jupiter.api.Assertions.assertTrue;
class YamlPendingVoteStoreTest {
@Test
void addPendingVoteCreatesEntryAndIncrements(@TempDir Path dataDir)
throws ExecutionException, InterruptedException, TimeoutException, IOException {
YamlPendingVoteStore store = new YamlPendingVoteStore(dataDir, NOPLogger.NOP_LOGGER);
UUID uuid = UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5");
store.addPendingVote(uuid, "Notch").get(5, TimeUnit.SECONDS);
String content = Files.readString(dataDir.resolve("pending-votes.yml"), StandardCharsets.UTF_8);
assertTrue(content.contains(uuid.toString()));
assertTrue(content.contains("name: Notch"));
assertTrue(content.contains("votes: 1"));
store.addPendingVote(uuid, "Notch").get(5, TimeUnit.SECONDS);
content = Files.readString(dataDir.resolve("pending-votes.yml"), StandardCharsets.UTF_8);
assertTrue(content.contains("votes: 2"), "un deuxieme vote hors ligne doit incrementer le compteur existant");
}
@Test
void addPendingVoteHandlesTwoDifferentPlayersIndependently(@TempDir Path dataDir)
throws ExecutionException, InterruptedException, TimeoutException, IOException {
YamlPendingVoteStore store = new YamlPendingVoteStore(dataDir, NOPLogger.NOP_LOGGER);
UUID uuidA = UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5");
UUID uuidB = UUID.fromString("853c80ef-3c37-49fd-aa49-938b674adae6");
store.addPendingVote(uuidA, "Sar_Tron").get(5, TimeUnit.SECONDS);
store.addPendingVote(uuidB, "Notch").get(5, TimeUnit.SECONDS);
String content = Files.readString(dataDir.resolve("pending-votes.yml"), StandardCharsets.UTF_8);
assertTrue(content.contains(uuidA.toString()));
assertTrue(content.contains(uuidB.toString()));
assertTrue(content.contains("name: Sar_Tron"));
assertTrue(content.contains("name: Notch"));
}
}