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:
co-authored by
Claude Sonnet 5
parent
d5f6e0cfb3
commit
5abe49fdd0
@@ -36,6 +36,12 @@
|
||||
<version>2.10.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user