diff --git a/backend/pom.xml b/backend/pom.xml
index 17c6151..5a0b791 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -68,6 +68,11 @@
expo-server-sdk
0.6.0
+
+ org.springframework.security
+ spring-security-test
+ 4.0.4.RELEASE
+
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/AssignmentList.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/AssignmentList.java
new file mode 100644
index 0000000..624d3d3
--- /dev/null
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/AssignmentList.java
@@ -0,0 +1,58 @@
+package de.marvinbrieger.toothbrushgame.domain;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import de.marvinbrieger.toothbrushgame.exceptions.MurderAssignmentNotFoundException;
+import de.marvinbrieger.toothbrushgame.webservice.mapping.FilteredMurderAssignmentsSerializer;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import net.bytebuddy.implementation.bind.annotation.IgnoreForBinding;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embeddable;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.Transient;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Embeddable
+public class AssignmentList {
+
+ @Transient
+ private Game game;
+
+ @OneToMany(
+ cascade = CascadeType.ALL,
+ mappedBy = "game"
+ )
+ @JsonSerialize(using = FilteredMurderAssignmentsSerializer.class)
+ private List murderAssignments;
+
+ public MurderAssignment findAssignment(Long assignmentId) {
+ return this.murderAssignments.parallelStream()
+ .filter(assignment -> assignment.getId().equals(assignmentId))
+ .findAny()
+ .orElseThrow(() -> new MurderAssignmentNotFoundException(assignmentId));
+ }
+
+ private MurderAssignment findSuccessor(MurderAssignment source) {
+ return murderAssignments.parallelStream()
+ .filter(source::hasSuccessor)
+ .findAny()
+ .orElseThrow(IllegalArgumentException::new);
+ }
+
+ public void newAssignemntForSuccessfullKiller(MurderAssignment currentAssignment) {
+ Player killer = currentAssignment.getKiller();
+ MurderAssignment victimsAssignment = findSuccessor(currentAssignment);
+
+ MurderAssignment killersNewMission = new MurderAssignment(null, game, killer, victimsAssignment.getTarget(),
+ MurderAssignmentStatus.PENDING, null);
+
+ getMurderAssignments().add(killersNewMission);
+ }
+
+}
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Game.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Game.java
index 128385b..67ea95f 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Game.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Game.java
@@ -1,11 +1,9 @@
package de.marvinbrieger.toothbrushgame.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import de.marvinbrieger.toothbrushgame.exceptions.GameInWrongStateException;
import de.marvinbrieger.toothbrushgame.exceptions.MurderAssignmentNotFoundException;
import de.marvinbrieger.toothbrushgame.exceptions.PlayerAlreadyExistsException;
-import de.marvinbrieger.toothbrushgame.webservice.mapping.FilteredMurderAssignmentsSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -43,12 +41,8 @@ public class Game {
@OneToMany(mappedBy = "game")
private List players;
- @OneToMany(
- cascade = CascadeType.ALL,
- mappedBy = "game"
- )
- @JsonSerialize(using = FilteredMurderAssignmentsSerializer.class)
- private List murderAssignments;
+ @Embedded
+ private AssignmentList murderAssignments;
/**
* Creates a new game with the given game code, the title and preferences as the given game, the status {@link GameStatus#PREPARATION},
@@ -66,42 +60,25 @@ public Game(Game game, String gameCode, ApplicationUser creator) {
this.gameCode = gameCode;
this.gameStatus = GameStatus.PREPARATION;
this.players = new ArrayList<>();
- this.murderAssignments = new ArrayList<>();
this.owner = new Player(game.getOwner(), this, creator);
+ this.murderAssignments = game.getMurderAssignments();
// owner is also a player
this.players.add(this.owner);
}
- public boolean inPreparation() {
- return gameStatus == GameStatus.PREPARATION;
+ public boolean notInPreparation() {
+ return gameStatus != GameStatus.PREPARATION;
}
@JsonIgnore
- public boolean isRunning() {
- return gameStatus == GameStatus.RUNNING;
- }
-
- private MurderAssignment findSuccessor(MurderAssignment source) {
- for (MurderAssignment potentialSuccessor : murderAssignments)
- if (source.hasSuccessor(potentialSuccessor))
- return potentialSuccessor;
-
- throw new IllegalArgumentException();
- }
-
- private void addSucceedingAssignment(MurderAssignment currentAssignment) {
- Player killer = currentAssignment.getKiller();
- MurderAssignment targetsAssignment = findSuccessor(currentAssignment);
-
- MurderAssignment killersNewMission = new MurderAssignment(null, this, killer, targetsAssignment.getTarget(),
- MurderAssignmentStatus.PENDING, null);
-
- getMurderAssignments().add(killersNewMission);
+ public boolean notRunning() {
+ return gameStatus != GameStatus.RUNNING;
}
/**
* Fulfills the assignment with given ID.
+ *
* @param assignmentId ID of the assignment that is fulfilled
* @throws GameInWrongStateException if the game is not running
* @throws MurderAssignmentNotFoundException if there is no assignment with that ID that is part of the game
@@ -109,30 +86,28 @@ private void addSucceedingAssignment(MurderAssignment currentAssignment) {
*/
public void commitMurder(Long assignmentId) {
// ensure game is running
- if (!this.isRunning())
+ if (this.notRunning())
throw new GameInWrongStateException(GameStatus.RUNNING, getGameStatus());
// get the assignment
- MurderAssignment assignment = this.murderAssignments.parallelStream()
- .filter(assig -> assig.getId().equals(assignmentId))
- .findAny()
- .orElseThrow(() -> new MurderAssignmentNotFoundException(assignmentId));
+ MurderAssignment currentAssignment = murderAssignments.findAssignment(assignmentId);
// commit murder and add new assignment for the killer
- assignment.commitMurder();
- assignment.getTarget().getCurrentAssignment().setAssignmentStatus(MurderAssignmentStatus.FAILED);
- addSucceedingAssignment(assignment);
+ currentAssignment.commitMurder();
+ currentAssignment.getTarget().setFailed();
+ murderAssignments.newAssignemntForSuccessfullKiller(currentAssignment);
}
/**
* Lets the given player join the game.
+ *
* @param player the joining player
* @throws GameInWrongStateException if the game is not in preparation
* @throws PlayerAlreadyExistsException if there is already a player with the same name or user in the game
*/
public void addPlayer(Player player) {
// check game state
- if (!inPreparation())
+ if (notInPreparation())
throw new GameInWrongStateException(GameStatus.PREPARATION, getGameStatus());
// check neither player with same name nor with same user has already joined
@@ -157,21 +132,22 @@ public void addPlayer(Player player) {
* @throws GameInWrongStateException if the game is not in preparation
*/
public void start(List assignments) {
- // check and update state
- if (!inPreparation())
+ if (notInPreparation())
throw new GameInWrongStateException(GameStatus.PREPARATION, getGameStatus());
- setGameStatus(GameStatus.RUNNING);
- setMurderAssignments(assignments);
+ setGameStatus(GameStatus.RUNNING);
+ setMurderAssignments(new AssignmentList(this, assignments));
}
/**
* Ends the game.
+ *
* @throws GameInWrongStateException if the game is not running
*/
public void end() {
- if (isRunning())
+ if (notRunning())
throw new GameInWrongStateException(GameStatus.RUNNING, getGameStatus());
+
setGameStatus(GameStatus.FINISHED);
}
}
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/MurderAssignment.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/MurderAssignment.java
index 11178a3..bd073ee 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/MurderAssignment.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/MurderAssignment.java
@@ -42,13 +42,12 @@ public boolean isPending() {
return assignmentStatus == MurderAssignmentStatus.PENDING;
}
-
public boolean hasSuccessor(MurderAssignment assignment) {
return target.equals(assignment.killer) && assignment.isPending();
}
public void commitMurder() {
- if (this.getAssignmentStatus() != MurderAssignmentStatus.PENDING)
+ if (!isPending())
throw new MurderAssignmentNotFoundException(this.getId(), MurderAssignmentStatus.PENDING);
Murder murder = new Murder(null, Instant.now(), this);
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Player.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Player.java
index a9e20cf..ce29191 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Player.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/domain/Player.java
@@ -48,8 +48,12 @@ public Player(Player player, Game game, ApplicationUser user) {
this(null, game, player.getPlayerName(), user, new LinkedList<>());
}
+ public void setFailed() {
+ getCurrentAssignment().setAssignmentStatus(MurderAssignmentStatus.FAILED);
+ }
+
@JsonIgnore
- public MurderAssignment getCurrentAssignment() {
+ private MurderAssignment getCurrentAssignment() {
return assignments.parallelStream()
.filter(assignment -> assignment.getAssignmentStatus() == MurderAssignmentStatus.PENDING)
.findFirst()
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/GameServiceImpl.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/GameServiceImpl.java
index 9ac92f1..35b7e18 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/GameServiceImpl.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/GameServiceImpl.java
@@ -11,6 +11,7 @@
import de.marvinbrieger.toothbrushgame.push.messagebuilders.MurderAssignmentNotificationService;
import de.marvinbrieger.toothbrushgame.services.interfaces.CurrentUserService;
import de.marvinbrieger.toothbrushgame.services.interfaces.EnsureGameOwnerService;
+import de.marvinbrieger.toothbrushgame.services.interfaces.GameService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
@@ -18,7 +19,7 @@
@Service
@AllArgsConstructor
-public class GameServiceImpl implements de.marvinbrieger.toothbrushgame.services.interfaces.GameService {
+public class GameServiceImpl implements GameService {
private final GameRepository gameRepository;
private final GameCodeService gameCodeService;
private final AssignmentGeneratorService assignmentHelperService;
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImpl.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImpl.java
index d98391d..0b65ca8 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImpl.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImpl.java
@@ -19,13 +19,13 @@ public class PlayerServiceImpl implements PlayerService {
@Override
public Player joinGame(Long gameId, Player player) {
- Game gameToJoin = gameRepository.findById(gameId)
+ return gameRepository.findById(gameId)
+ .map(game -> {
+ Player newPlayer = new Player(player, game, currentUserService.getCurrentUser());
+ game.addPlayer(newPlayer);
+ return playerRepository.save(newPlayer);
+ })
.orElseThrow(() -> new GameNotFoundException(gameId));
-
- Player newPlayer = new Player(player, gameToJoin, currentUserService.getCurrentUser());
- gameToJoin.addPlayer(newPlayer);
-
- return playerRepository.save(player);
}
}
diff --git a/backend/src/main/java/de/marvinbrieger/toothbrushgame/webservice/UserController.java b/backend/src/main/java/de/marvinbrieger/toothbrushgame/webservice/UserController.java
index 9b95cc7..3e93c01 100644
--- a/backend/src/main/java/de/marvinbrieger/toothbrushgame/webservice/UserController.java
+++ b/backend/src/main/java/de/marvinbrieger/toothbrushgame/webservice/UserController.java
@@ -1,10 +1,12 @@
package de.marvinbrieger.toothbrushgame.webservice;
+import java.io.File;
import de.marvinbrieger.toothbrushgame.domain.ApplicationUser;
import de.marvinbrieger.toothbrushgame.services.interfaces.UserService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
+import java.io.IOException;
import java.util.Locale;
@RestController
@@ -14,7 +16,7 @@ public class UserController {
private final UserService userService;
@PostMapping("/sign-up")
- public void signUp(@RequestBody ApplicationUser user) {
+ public void signUp(@RequestBody ApplicationUser user) throws IOException {
userService.signUp(user);
}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/ApplicationUserMocks.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/ApplicationUserMocks.java
new file mode 100644
index 0000000..923ccdc
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/ApplicationUserMocks.java
@@ -0,0 +1,26 @@
+package de.marvinbrieger.toothbrushgame.mocks;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+public class ApplicationUserMocks {
+
+ public static JSONObject MARVINS_DEVICE;
+
+ public static JSONObject ELIAS_DEVICE;
+
+ static {
+ try {
+ MARVINS_DEVICE = new JSONObject()
+ .put("deviceId", "marvins device")
+ .put("password", "marvins password");
+
+ ELIAS_DEVICE = new JSONObject()
+ .put("deviceId", "elias device")
+ .put("password", "elias password");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GameMocks.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GameMocks.java
index f847006..51c98dd 100644
--- a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GameMocks.java
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GameMocks.java
@@ -1,66 +1,26 @@
package de.marvinbrieger.toothbrushgame.mocks;
-import de.marvinbrieger.toothbrushgame.domain.Game;
-import de.marvinbrieger.toothbrushgame.domain.GameStatus;
-import de.marvinbrieger.toothbrushgame.domain.MurderAssignment;
-import de.marvinbrieger.toothbrushgame.domain.Player;
-import de.marvinbrieger.toothbrushgame.services.AssignmentGeneratorService;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static de.marvinbrieger.toothbrushgame.mocks.GamePreferencesMocks.STANDARD_PREFERENCES;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.ELIAS;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_ALEX;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_ELIAS;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_KIPF;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_MARVIN;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_NEUMANN;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.STORED_WINTER;
+import org.json.JSONException;
+import org.json.JSONObject;
public class GameMocks {
- public static final Game SOFTSKILL_GAME;
-
- public static final Game STORED_SOFTSKILL_GAME;
-
- public static final Game SOFTSKILL_GAME_MARVIN_JOINED;
-
- public static final Game SOFTSKILL_GAME_STARTED;
+ public static JSONObject SOFTSKILL_GAME;
static {
- SOFTSKILL_GAME = new Game(null, "Softskillkurs SE 14", STANDARD_PREFERENCES,
- null, ELIAS, null, null, null);
-
- List storedPlayers = new ArrayList();
- storedPlayers.add(STORED_ELIAS);
- STORED_SOFTSKILL_GAME = new Game(1L, "Softskillkurs SE 14", STANDARD_PREFERENCES,
- "ANTZUF", STORED_ELIAS, GameStatus.PREPARATION, storedPlayers, null);
-
- List playersMarvinJoined = new ArrayList();
- playersMarvinJoined.add(STORED_ELIAS);
- playersMarvinJoined.add(STORED_MARVIN);
- SOFTSKILL_GAME_MARVIN_JOINED = new Game(1L, "Softskillkurs SE 14", STANDARD_PREFERENCES,
- "ANTZUF", STORED_ELIAS, GameStatus.PREPARATION, playersMarvinJoined, null);
-
- List playersStartedGame = getPlayersList();
- Game startedGame = new Game(1L, "Softskillkurs SE 14", STANDARD_PREFERENCES,
- "ANTZUF", STORED_ELIAS, GameStatus.RUNNING, playersStartedGame, null);
- AssignmentGeneratorService assignmentHelperService = new AssignmentGeneratorService();
- List murderAssignments = assignmentHelperService.generateKillAssignments(startedGame);
- startedGame.setMurderAssignments(murderAssignments);
- SOFTSKILL_GAME_STARTED = startedGame;
+ try {
+ SOFTSKILL_GAME = new JSONObject()
+ .put("title", "SE 14")
+ .put("preferences", new JSONObject()
+ .put("dailyReassignment", false)
+ .put("noAttestors", true)
+ .put("furtherRules", "nicht beim Essen töten"))
+ .put("owner", new JSONObject()
+ .put("playerName", "Marvin"));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
}
- private static List getPlayersList() {
- List players = new ArrayList();
- players.add(STORED_ELIAS);
- players.add(STORED_MARVIN);
- players.add(STORED_ALEX);
- players.add(STORED_KIPF);
- players.add(STORED_WINTER);
- players.add(STORED_NEUMANN);
- return players;
- }
}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GamePreferencesMocks.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GamePreferencesMocks.java
deleted file mode 100644
index ccd720a..0000000
--- a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/GamePreferencesMocks.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package de.marvinbrieger.toothbrushgame.mocks;
-
-import de.marvinbrieger.toothbrushgame.domain.GamePreferences;
-import java.util.HashSet;
-
-public class GamePreferencesMocks {
-
- public static final GamePreferences STANDARD_PREFERENCES
- = new GamePreferences(1L, false, true, "", new HashSet<>());
-
-}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/PlayerMocks.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/PlayerMocks.java
index 8228dbf..814f2c3 100644
--- a/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/PlayerMocks.java
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/mocks/PlayerMocks.java
@@ -2,40 +2,22 @@
import de.marvinbrieger.toothbrushgame.domain.ApplicationUser;
import de.marvinbrieger.toothbrushgame.domain.Player;
+import org.json.JSONException;
+import org.json.JSONObject;
import java.util.HashSet;
public class PlayerMocks {
- public static final ApplicationUser USER_MARVIN = new ApplicationUser(1L, "marvins device", "marvins password", null, new HashSet<>(),
- null);
- public static final ApplicationUser USER_ELIAS = new ApplicationUser(2L, "elias device", "elias password", null, new HashSet<>(), null);
- public static final Player ELIAS = new Player(null, null, "Elias", USER_ELIAS, null);
+ public static JSONObject ELIAS_PLAYER;
- public static final Player STORED_ELIAS = new Player(1L, null, "Elias", USER_ELIAS, null);
-
- public static final Player MARVIN = new Player(null, null, "Marvin", USER_MARVIN, null);
-
- public static final Player STORED_MARVIN = new Player(2L, null, "Marvin", USER_MARVIN, null);
-
- public static final Player ALEX = new Player(null, null, "Alex", null, null);
-
- public static final Player STORED_ALEX = new Player(3L, null, "Alex", null, null);
-
- public static final Player KIPF = new Player(null, null, "Kipf", null, null);
-
- public static final Player STORED_KIPF = new Player(4L, null, "Kipf", null, null);
-
- public static final Player WINTER = new Player(null, null, "Winter", null, null);
-
- public static final Player STORED_WINTER = new Player(5L, null, "Winter", null, null);
-
- public static final Player NEUMANN = new Player(null, null, "Neumann", null, null);
-
- public static final Player STORED_NEUMANN = new Player(6L, null, "Neumann", null, null);
-
- public static final Player SCHELLY = new Player(null, null, "Schelly", null, null);
-
- public static final Player STORED_SCHELLY = new Player(7L, null, "Schelly", null, null);
+ static {
+ try {
+ ELIAS_PLAYER = new JSONObject()
+ .put("playerName", "Elias");
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImplTest.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImplTest.java
deleted file mode 100644
index 723471a..0000000
--- a/backend/src/test/java/de/marvinbrieger/toothbrushgame/services/PlayerServiceImplTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package de.marvinbrieger.toothbrushgame.services;
-
-import de.marvinbrieger.toothbrushgame.domain.Game;
-import de.marvinbrieger.toothbrushgame.exceptions.GameNotFoundException;
-import de.marvinbrieger.toothbrushgame.exceptions.PlayerAlreadyExistsException;
-import de.marvinbrieger.toothbrushgame.persistence.GameRepository;
-import de.marvinbrieger.toothbrushgame.persistence.PlayerRepository;
-import de.marvinbrieger.toothbrushgame.services.interfaces.CurrentUserService;
-import de.marvinbrieger.toothbrushgame.services.interfaces.PlayerService;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.Optional;
-
-import static de.marvinbrieger.toothbrushgame.mocks.GameMocks.STORED_SOFTSKILL_GAME;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.ELIAS;
-import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.MARVIN;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-@RunWith(SpringRunner.class)
-public class PlayerServiceImplTest {
-
- private PlayerService playerService;
-
- private final Long EXISTING_ID = 1L;
-
- private final Long MISSING_ID = 2L;
-
- @Before
- public void setup() {
- PlayerRepository playerRepository = mock(PlayerRepository.class);
- when(playerRepository.existsByGame_IdAndPlayerName(EXISTING_ID, "Elias")).thenReturn(true);
- when(playerRepository.existsByGame_IdAndPlayerName(EXISTING_ID, "Marvin")).thenReturn(false);
-
- GameRepository gameRepository = mock(GameRepository.class);
- Optional standardGame = Optional.of(STORED_SOFTSKILL_GAME);
- when(gameRepository.findById(EXISTING_ID)).thenReturn(standardGame);
- when(gameRepository.findById(MISSING_ID)).thenReturn(Optional.empty());
-
- CurrentUserService currentUserService = mock(CurrentUserService.class);
-
- this.playerService = new PlayerServiceImpl(playerRepository, gameRepository, currentUserService);
- }
-
- @Test(expected = PlayerAlreadyExistsException.class)
- public void ownerShouldJoin_ThrowsException() {
- playerService.joinGame(EXISTING_ID, ELIAS);
- }
-
- @Test(expected = GameNotFoundException.class)
- public void joinToMissingGame_ThrowsException() {
- playerService.joinGame(MISSING_ID, MARVIN);
- }
-
- @Test
- public void joinToGame_Succeeds() {
- playerService.joinGame(EXISTING_ID, MARVIN);
- }
-
-}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/DbCleaningHelper.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/DbCleaningHelper.java
new file mode 100644
index 0000000..01b9d87
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/DbCleaningHelper.java
@@ -0,0 +1,21 @@
+package de.marvinbrieger.toothbrushgame.utils;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class DbCleaningHelper {
+
+ public static void truncateAllTables(Connection conn) throws SQLException {
+ conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=0");
+ ResultSet rs = conn.createStatement().
+ executeQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = SCHEMA()");
+
+ while (rs.next()) {
+ String tableName = rs.getString(1);
+ conn.createStatement().executeUpdate("TRUNCATE TABLE " + tableName);
+ }
+ conn.createStatement().executeUpdate("SET FOREIGN_KEY_CHECKS=1");
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MockMvcHelper.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MockMvcHelper.java
new file mode 100644
index 0000000..358c7e9
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MockMvcHelper.java
@@ -0,0 +1,16 @@
+package de.marvinbrieger.toothbrushgame.utils;
+
+import org.json.JSONObject;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+
+abstract public class MockMvcHelper {
+
+ public static MockHttpServletRequestBuilder withJsonHeaders(MockHttpServletRequestBuilder builder) {
+ return builder.contentType(MediaType.APPLICATION_JSON)
+ .characterEncoding("utf-8");
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiContext.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiContext.java
new file mode 100644
index 0000000..e6baf75
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiContext.java
@@ -0,0 +1,54 @@
+package de.marvinbrieger.toothbrushgame.utils;
+
+import org.json.JSONObject;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+import static de.marvinbrieger.toothbrushgame.utils.MockMvcHelper.withJsonHeaders;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+public class MurderApiContext {
+
+ private String bearerToken;
+
+ private MockMvc mockMvc;
+
+ private boolean print;
+
+ public MurderApiContext(MockMvc mockMvc, JSONObject applicationUser) throws Exception {
+ this(mockMvc, applicationUser, false);
+ }
+
+ public MurderApiContext(MockMvc mockMvc, JSONObject applicationUser, boolean print) throws Exception {
+ this.mockMvc = mockMvc;
+ this.print = print;
+
+ ResultActions signUp = mockMvc.perform(
+ withJsonHeaders(post("/user/sign-up"))
+ .content(applicationUser.toString()));
+ ResultActions login = mockMvc.perform(
+ withJsonHeaders(post("/user/login"))
+ .content(applicationUser.toString()));
+
+ if (print) {
+ signUp.andDo(print());
+ login.andDo(print());
+ }
+
+ this.bearerToken = login.andReturn()
+ .getResponse()
+ .getHeader("Authorization");
+ }
+
+ public MurderApiRequest createGet(String route) throws Exception {
+ return new MurderApiRequest(mockMvc, withJsonHeaders(get(route))
+ .header("Authorization", bearerToken), print);
+ }
+
+ public MurderApiRequest createPost(String route) throws Exception {
+ return new MurderApiRequest(mockMvc, withJsonHeaders(post(route))
+ .header("Authorization", bearerToken), print);
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiRequest.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiRequest.java
new file mode 100644
index 0000000..81729a9
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiRequest.java
@@ -0,0 +1,38 @@
+package de.marvinbrieger.toothbrushgame.utils;
+
+import org.json.JSONObject;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.ResultActions;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+public class MurderApiRequest {
+
+ private MockMvc mockMvc;
+
+ private MockHttpServletRequestBuilder requestBuilder;
+
+ private boolean print;
+
+ public MurderApiRequest(MockMvc mockMvc, MockHttpServletRequestBuilder requestBuilder, boolean print) throws Exception {
+ this.mockMvc = mockMvc;
+ this.requestBuilder = requestBuilder;
+ this.print = print;
+ }
+
+ public MurderApiRequest content(JSONObject payload) {
+ requestBuilder.content(payload.toString());
+ return this;
+ }
+
+ public MurderApiResponse send() throws Exception {
+ ResultActions result = mockMvc.perform(requestBuilder);
+ if (print)
+ result.andDo(print());
+
+ return new MurderApiResponse(result.andReturn().getResponse());
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiResponse.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiResponse.java
new file mode 100644
index 0000000..a26eeb9
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/utils/MurderApiResponse.java
@@ -0,0 +1,24 @@
+package de.marvinbrieger.toothbrushgame.utils;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.test.web.servlet.ResultActions;
+
+import java.io.UnsupportedEncodingException;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+public class MurderApiResponse {
+
+ private MockHttpServletResponse response;
+
+ public MurderApiResponse(MockHttpServletResponse response) {
+ this.response = response;
+ }
+
+ public JSONObject getJsonAnswer() throws UnsupportedEncodingException, JSONException {
+ return new JSONObject(response.getContentAsString());
+ }
+
+}
diff --git a/backend/src/test/java/de/marvinbrieger/toothbrushgame/webservice/GameControllerTest.java b/backend/src/test/java/de/marvinbrieger/toothbrushgame/webservice/GameControllerTest.java
new file mode 100644
index 0000000..153d495
--- /dev/null
+++ b/backend/src/test/java/de/marvinbrieger/toothbrushgame/webservice/GameControllerTest.java
@@ -0,0 +1,114 @@
+package de.marvinbrieger.toothbrushgame.webservice;
+
+import de.marvinbrieger.toothbrushgame.services.interfaces.UserService;
+import de.marvinbrieger.toothbrushgame.utils.DbCleaningHelper;
+import de.marvinbrieger.toothbrushgame.utils.MurderApiContext;
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers;
+import org.springframework.test.annotation.Commit;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import javax.sql.DataSource;
+
+import static de.marvinbrieger.toothbrushgame.mocks.ApplicationUserMocks.ELIAS_DEVICE;
+import static de.marvinbrieger.toothbrushgame.mocks.ApplicationUserMocks.MARVINS_DEVICE;
+import static de.marvinbrieger.toothbrushgame.mocks.GameMocks.SOFTSKILL_GAME;
+import static de.marvinbrieger.toothbrushgame.mocks.PlayerMocks.ELIAS_PLAYER;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@Commit
+@TestPropertySource("classpath:test.properties")
+@AutoConfigureMockMvc
+public class GameControllerTest {
+
+ @Autowired
+ private UserService userService;
+
+ @Autowired
+ private WebApplicationContext webApplicationContext;
+
+ @Autowired
+ DataSource dataSource;
+
+ private MockMvc mockMvc;
+
+ private MurderApiContext marvinContext;
+
+ private MurderApiContext eliasContext;
+
+ @Before
+ public void init() throws Exception {
+ DbCleaningHelper.truncateAllTables(dataSource.getConnection());
+
+ mockMvc = MockMvcBuilders
+ .webAppContextSetup(webApplicationContext)
+ .apply(SecurityMockMvcConfigurers.springSecurity())
+ .build();
+
+ marvinContext = new MurderApiContext(mockMvc, MARVINS_DEVICE);
+ eliasContext = new MurderApiContext(mockMvc, ELIAS_DEVICE);
+ }
+
+ @Test
+ public void testCreateGame() throws Exception {
+ JSONObject game = marvinContext.createPost("/games")
+ .content(SOFTSKILL_GAME)
+ .send()
+ .getJsonAnswer();
+
+ game = marvinContext.createGet("/games/" + game.getString("id"))
+ .send()
+ .getJsonAnswer();
+
+ assertEquals("SE 14", game.getString("title"));
+ }
+
+ @Test
+ public void testJoinGame() throws Exception {
+ // Arrange
+ JSONObject game = marvinContext.createPost("/games")
+ .content(SOFTSKILL_GAME)
+ .send()
+ .getJsonAnswer();
+
+ // Act
+ JSONObject player = eliasContext.createPost("/games/" + game.getString("id") + "/players")
+ .content(ELIAS_PLAYER)
+ .send()
+ .getJsonAnswer();
+
+ game = eliasContext.createGet("/games/" + game.getString("id"))
+ .send()
+ .getJsonAnswer();
+
+ // Assert
+ JSONArray playersArray = game.getJSONArray("players");
+ boolean found = false;
+ for (int k = 0; k < playersArray.length(); k++) {
+ JSONObject joinedPlayer = playersArray.getJSONObject(k);
+ if (joinedPlayer.getString("playerName").equals(ELIAS_PLAYER.getString("playerName")))
+ found = true;
+ }
+
+ if (!found)
+ fail("player should be contained after joining");
+ }
+
+}
diff --git a/backend/src/test/resources/test.properties b/backend/src/test/resources/test.properties
new file mode 100644
index 0000000..c8defcf
--- /dev/null
+++ b/backend/src/test/resources/test.properties
@@ -0,0 +1,10 @@
+# Data-Source-Settings
+spring.datasource.url=jdbc:h2:mem:mydb;DB_CLOSE_ON_EXIT=FALSE
+spring.datasource.username=root
+spring.datasource.password=dbpass
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.platform=h2
+
+# The SQL dialect makes Hibernate generate better SQL for the chosen database
+spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
+spring.jpa.hibernate.ddl-auto=create