Compare commits
No commits in common. "7d7cf8148a106e9f034d87bee2689a4309011df8" and "fae88aa2623cae5fdb476d0bf4ebfa19de27ccf1" have entirely different histories.
7d7cf8148a
...
fae88aa262
9 changed files with 45 additions and 284 deletions
10
pom.xml
10
pom.xml
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
@ -49,12 +49,6 @@
|
||||||
<version>4.7.0</version>
|
<version>4.7.0</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-junit-jupiter</artifactId>
|
|
||||||
<version>4.7.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- to test my json implementation -->
|
<!-- to test my json implementation -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
|
|
@ -13,7 +13,6 @@ import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
|
|
||||||
private final File saveDirectory;
|
private final File saveDirectory;
|
||||||
private final SerializationFactory serializationFactory;
|
private final SerializationFactory serializationFactory;
|
||||||
|
|
||||||
|
@ -23,32 +22,29 @@ public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush(final Player player) throws WritePlayerException {
|
public void flush(final Player player) throws PersistException {
|
||||||
final var playerFile = new File(saveDirectory, player.uuid().toString());
|
final var playerFile = new File(saveDirectory, player.uuid().toString());
|
||||||
final String serializedPlayer = serializationFactory.createSerializer(player).serialize();
|
|
||||||
try (final var writer = new FileWriter(playerFile)) {
|
try (final var writer = new FileWriter(playerFile)) {
|
||||||
writer.write(serializedPlayer);
|
final String jsonPlayer = serializationFactory.createSerializer(player).serialize();
|
||||||
// ensure everything is written
|
writer.write(jsonPlayer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new WritePlayerException("Could not persist player data from player: " + player.uuid(), e);
|
throw new PersistException("Could not persist player data with id: " + player.uuid(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Player> findById(final UUID uuid) throws ReadPlayerException {
|
public Optional<Player> findById(final UUID uuid) throws FindPlayerException {
|
||||||
final File[] files = getFiles();
|
final File[] files = getFiles();
|
||||||
for (final var file : files) {
|
for (final var file : files) {
|
||||||
if (!file.getName().equals(uuid.toString())) {
|
if (file.getName().equals(uuid.toString())) {
|
||||||
continue;
|
try {
|
||||||
}
|
final String fileContent = Files.readString(file.toPath());
|
||||||
|
final Player player = serializationFactory.createDeserializer(fileContent);
|
||||||
try {
|
return Optional.of(player);
|
||||||
final String fileContent = Files.readString(file.toPath());
|
} catch (IOException e) {
|
||||||
final Player player = serializationFactory.createDeserializer(fileContent);
|
throw new FindPlayerException("Player not found with the uuid: " + uuid, e);
|
||||||
return Optional.of(player);
|
}
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ReadPlayerException("Player not found with the uuid: " + uuid, e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +52,7 @@ public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Player> findByName(final String name) throws ReadPlayerException {
|
public Optional<Player> findByName(final String name) throws FindPlayerException {
|
||||||
final File[] files = getFiles();
|
final File[] files = getFiles();
|
||||||
for (final var file : files) {
|
for (final var file : files) {
|
||||||
try {
|
try {
|
||||||
|
@ -66,7 +62,7 @@ public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
return Optional.of(player);
|
return Optional.of(player);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ReadPlayerException("Player not found with the name: " + name, e);
|
throw new FindPlayerException("Player not found with the name: " + name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +70,7 @@ public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Player> findAll() throws ReadPlayerException {
|
public List<Player> findAll() throws FindPlayerException {
|
||||||
final File[] files = getFiles();
|
final File[] files = getFiles();
|
||||||
final var playerList = new ArrayList<Player>();
|
final var playerList = new ArrayList<Player>();
|
||||||
for (final var file : files) {
|
for (final var file : files) {
|
||||||
|
@ -83,7 +79,7 @@ public final class FileSystemDB implements PersistPlayer, FindPlayer {
|
||||||
final Player player = serializationFactory.createDeserializer(fileContent);
|
final Player player = serializationFactory.createDeserializer(fileContent);
|
||||||
playerList.add(player);
|
playerList.add(player);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ReadPlayerException("Player not found with the path: " + file.getAbsolutePath(), e);
|
throw new FindPlayerException("Player not found with the path: " + file.getAbsolutePath(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface FindPlayer {
|
public interface FindPlayer {
|
||||||
Optional<Player> findById(UUID uuid) throws ReadPlayerException;
|
Optional<Player> findById(UUID uuid) throws FindPlayerException;
|
||||||
|
|
||||||
Optional<Player> findByName(String name) throws ReadPlayerException;
|
Optional<Player> findByName(String name) throws FindPlayerException;
|
||||||
|
|
||||||
List<Player> findAll() throws ReadPlayerException;
|
List<Player> findAll() throws FindPlayerException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package de.hhhammer.playtime.ng.persistence;
|
||||||
|
|
||||||
|
public final class FindPlayerException extends Exception {
|
||||||
|
public FindPlayerException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FindPlayerException(final String message, final Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package de.hhhammer.playtime.ng.persistence;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public final class PersistException extends Exception {
|
||||||
|
|
||||||
|
public PersistException(final String message, final IOException cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,5 +3,5 @@ package de.hhhammer.playtime.ng.persistence;
|
||||||
import de.hhhammer.playtime.ng.player.Player;
|
import de.hhhammer.playtime.ng.player.Player;
|
||||||
|
|
||||||
public interface PersistPlayer {
|
public interface PersistPlayer {
|
||||||
void flush(Player player) throws WritePlayerException;
|
void flush(Player player) throws PersistException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package de.hhhammer.playtime.ng.persistence;
|
|
||||||
|
|
||||||
public final class ReadPlayerException extends Exception {
|
|
||||||
public ReadPlayerException(String msg) {
|
|
||||||
super(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ReadPlayerException(final String message, final Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package de.hhhammer.playtime.ng.persistence;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public final class WritePlayerException extends Exception {
|
|
||||||
|
|
||||||
public WritePlayerException(final String message, final IOException cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,229 +0,0 @@
|
||||||
package de.hhhammer.playtime.ng.persistence;
|
|
||||||
|
|
||||||
import de.hhhammer.playtime.ng.player.Player;
|
|
||||||
import de.hhhammer.playtime.ng.serialization.SerializationFactory;
|
|
||||||
import de.hhhammer.playtime.ng.serialization.serializer.Serializer;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Nested;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
|
||||||
class FileSystemDBTest {
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private SerializationFactory mockSerializationFactory;
|
|
||||||
@Mock
|
|
||||||
private Player mockPlayer;
|
|
||||||
@Mock
|
|
||||||
private Serializer mockSerializer;
|
|
||||||
private File testDirectory;
|
|
||||||
private FileSystemDB fileSystemDB;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() throws IOException {
|
|
||||||
final Path path = Files.createTempDirectory("playtime").toAbsolutePath();
|
|
||||||
this.testDirectory = path.toFile();
|
|
||||||
this.fileSystemDB = new FileSystemDB(testDirectory, mockSerializationFactory);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
void cleanup() {
|
|
||||||
testDirectory.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class FlushTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldWriteFile() throws WritePlayerException {
|
|
||||||
when(mockSerializationFactory.createSerializer(any())).thenReturn(mockSerializer);
|
|
||||||
when(mockPlayer.uuid()).thenReturn(UUID.randomUUID());
|
|
||||||
when(mockSerializer.serialize()).thenReturn("");
|
|
||||||
|
|
||||||
assertEquals(0, testDirectory.listFiles().length);
|
|
||||||
|
|
||||||
fileSystemDB.flush(mockPlayer);
|
|
||||||
|
|
||||||
assertEquals(1, testDirectory.listFiles().length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldNameFileWithPlayerUUID() throws WritePlayerException {
|
|
||||||
final var uuid = UUID.randomUUID();
|
|
||||||
when(mockSerializationFactory.createSerializer(any())).thenReturn(mockSerializer);
|
|
||||||
when(mockPlayer.uuid()).thenReturn(uuid);
|
|
||||||
when(mockSerializer.serialize()).thenReturn("");
|
|
||||||
|
|
||||||
fileSystemDB.flush(mockPlayer);
|
|
||||||
|
|
||||||
final File[] foundFiles = testDirectory.listFiles();
|
|
||||||
assertEquals(1, foundFiles.length);
|
|
||||||
assertEquals(uuid.toString(), foundFiles[0].getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldWriteContentFromSerializer() throws WritePlayerException, IOException {
|
|
||||||
when(mockSerializationFactory.createSerializer(any())).thenReturn(mockSerializer);
|
|
||||||
when(mockPlayer.uuid()).thenReturn(UUID.randomUUID());
|
|
||||||
final String content = "test content from serializer";
|
|
||||||
when(mockSerializer.serialize()).thenReturn(content);
|
|
||||||
|
|
||||||
fileSystemDB.flush(mockPlayer);
|
|
||||||
|
|
||||||
final File[] foundFiles = testDirectory.listFiles();
|
|
||||||
assertEquals(1, foundFiles.length);
|
|
||||||
final String foundContent = Files.readString(foundFiles[0].toPath());
|
|
||||||
assertEquals(content, foundContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class FindById {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldThrowIfDirectoryIsAFile() {
|
|
||||||
final var notADir = new File(testDirectory, "not_a_dir");
|
|
||||||
final var fileSystemDB = new FileSystemDB(notADir, mockSerializationFactory);
|
|
||||||
final Exception exception = assertThrows(RuntimeException.class, () -> fileSystemDB.findById(UUID.randomUUID()));
|
|
||||||
assertEquals("Could not find files in: " + notADir.getAbsolutePath(), exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldBeEmptyIfNoFileIsPresent() throws IOException, ReadPlayerException {
|
|
||||||
assertEquals(0, testDirectory.listFiles().length);
|
|
||||||
|
|
||||||
final Optional<Player> foundPlayer = fileSystemDB.findById(UUID.randomUUID());
|
|
||||||
|
|
||||||
assertTrue(foundPlayer.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldBeEmptyIfUuidNotFound() throws IOException, ReadPlayerException {
|
|
||||||
new File(testDirectory, "not_a_uuid").createNewFile();
|
|
||||||
|
|
||||||
final Optional<Player> foundPlayer = fileSystemDB.findById(UUID.randomUUID());
|
|
||||||
|
|
||||||
assertTrue(foundPlayer.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldDeserializeFileContent() throws IOException, ReadPlayerException {
|
|
||||||
final var playerUUID = UUID.randomUUID();
|
|
||||||
final var fakePlayerFile = new File(testDirectory, playerUUID.toString());
|
|
||||||
final String fileContent = "test content";
|
|
||||||
Files.write(fakePlayerFile.toPath(), fileContent.getBytes());
|
|
||||||
|
|
||||||
when(mockSerializationFactory.createDeserializer(any())).thenReturn(mockPlayer);
|
|
||||||
|
|
||||||
fileSystemDB.findById(playerUUID);
|
|
||||||
|
|
||||||
verify(mockSerializationFactory).createDeserializer(fileContent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class FindByName {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldBeEmptyIfNoFilesExist() throws ReadPlayerException {
|
|
||||||
final Optional<Player> result = fileSystemDB.findByName("username");
|
|
||||||
assertTrue(result.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindThroughDeserializePlayerWithOnlyOneFile() throws IOException, ReadPlayerException {
|
|
||||||
final var username = "username";
|
|
||||||
when(mockPlayer.name()).thenReturn(username);
|
|
||||||
final var fakePlayerFile = new File(testDirectory, "fake_player_file");
|
|
||||||
Files.write(fakePlayerFile.toPath(), "".getBytes());
|
|
||||||
when(mockSerializationFactory.createDeserializer(anyString())).thenReturn(mockPlayer);
|
|
||||||
|
|
||||||
final Optional<Player> result = fileSystemDB.findByName(username);
|
|
||||||
assertTrue(result.isPresent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldNotFindThroughDeserializePlayerWithOnlyOneFile() throws IOException, ReadPlayerException {
|
|
||||||
final var username = "username";
|
|
||||||
when(mockPlayer.name()).thenReturn(username);
|
|
||||||
final var fakePlayerFile = new File(testDirectory, "fake_player_file");
|
|
||||||
Files.write(fakePlayerFile.toPath(), "".getBytes());
|
|
||||||
when(mockSerializationFactory.createDeserializer(anyString())).thenReturn(mockPlayer);
|
|
||||||
|
|
||||||
final Optional<Player> result = fileSystemDB.findByName("not_a_username");
|
|
||||||
assertTrue(result.isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindThroughDeserializePlayerOnMultipleFiles() throws IOException, ReadPlayerException {
|
|
||||||
final var wantedUsername = "username";
|
|
||||||
final var notWantedUsername = "not_wanted_username";
|
|
||||||
final var rightPlayer = mock(Player.class);
|
|
||||||
final var wrongPlayer = mock(Player.class);
|
|
||||||
when(rightPlayer.name()).thenReturn(wantedUsername);
|
|
||||||
when(wrongPlayer.name()).thenReturn(notWantedUsername);
|
|
||||||
final var rightPlayerFileContent = "right";
|
|
||||||
final var wrongPlayerFileContent = "wrong";
|
|
||||||
final var rightPlayerFile = new File(testDirectory, "right_player_file");
|
|
||||||
final var wrongPlayerFile = new File(testDirectory, "wrong_player_file");
|
|
||||||
Files.write(rightPlayerFile.toPath(), rightPlayerFileContent.getBytes());
|
|
||||||
Files.write(wrongPlayerFile.toPath(), wrongPlayerFileContent.getBytes());
|
|
||||||
when(mockSerializationFactory.createDeserializer(rightPlayerFileContent)).thenReturn(rightPlayer);
|
|
||||||
when(mockSerializationFactory.createDeserializer(wrongPlayerFileContent)).thenReturn(wrongPlayer);
|
|
||||||
|
|
||||||
final Optional<Player> result = fileSystemDB.findByName(wantedUsername);
|
|
||||||
assertTrue(result.isPresent());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nested
|
|
||||||
class FindAllTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldBeEmptyIfNoFilesExist() throws ReadPlayerException {
|
|
||||||
final List<Player> result = fileSystemDB.findAll();
|
|
||||||
assertEquals(0, result.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindOneFile() throws IOException, ReadPlayerException {
|
|
||||||
final var fakePlayerFile = new File(testDirectory, "fake_player_file");
|
|
||||||
Files.write(fakePlayerFile.toPath(), "test content".getBytes());
|
|
||||||
when(mockSerializationFactory.createDeserializer(anyString())).thenReturn(mockPlayer);
|
|
||||||
|
|
||||||
final List<Player> result = fileSystemDB.findAll();
|
|
||||||
assertEquals(1, result.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void shouldFindTwoFile() throws IOException, ReadPlayerException {
|
|
||||||
final var fakePlayerFile = new File(testDirectory, "fake_player_file");
|
|
||||||
Files.write(fakePlayerFile.toPath(), "test content".getBytes());
|
|
||||||
final var fakePlayerFile2 = new File(testDirectory, "fake_player_file_2");
|
|
||||||
Files.write(fakePlayerFile2.toPath(), "test content".getBytes());
|
|
||||||
|
|
||||||
when(mockSerializationFactory.createDeserializer(anyString())).thenReturn(mockPlayer);
|
|
||||||
|
|
||||||
final List<Player> result = fileSystemDB.findAll();
|
|
||||||
assertEquals(2, result.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue