This commit is contained in:
Gu://em_ 2026-04-03 21:51:46 +02:00
parent e6dfbfbe03
commit c552442029
33 changed files with 2455 additions and 132 deletions

View file

@ -16,7 +16,6 @@ public final class DtoToEntityConverter {
if (dto == null) return null;
YakamonEntity entity = new YakamonEntity();
// may be null / invalid
if (dto.uuid != null) {
try {
entity.uuid = UUID.fromString(dto.uuid);
@ -44,15 +43,12 @@ public final class DtoToEntityConverter {
e.evolutionId = dto.evolutionId;
e.caught = dto.caught;
// map element type strings to enum
if (dto.firstType != null) {
try {
e.firstType = ElementType.valueOf(dto.firstType);
} catch (IllegalArgumentException ex) {
e.firstType = null;
}
} else {
e.firstType = null;
}
if (dto.secondType != null) {
@ -61,8 +57,6 @@ public final class DtoToEntityConverter {
} catch (IllegalArgumentException ex) {
e.secondType = null;
}
} else {
e.secondType = null;
}
return e;

View file

@ -8,7 +8,6 @@ import fr.epita.assistants.yakamon.domain.entity.GameEntity;
import fr.epita.assistants.yakamon.domain.entity.PlayerEntity;
import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity;
import fr.epita.assistants.yakamon.domain.entity.YakamonEntity;
import java.time.LocalDateTime;
public final class EntityToModelConverter {
@ -38,16 +37,10 @@ public final class EntityToModelConverter {
if (e == null) return null;
YakamonModel m = new YakamonModel();
m.nickname = e.nickname;
m.energyPoints = e.energyPoints;
m.energy_points = e.energyPoints;
if (e.yakadexId != null) {
YakadexEntryModel yakadex = new YakadexEntryModel();
yakadex.name = null;
yakadex.caught = null;
yakadex.firstType = null;
yakadex.secondType = null;
yakadex.description = null;
yakadex.evolveThreshold = null;
m.yakadexEntryId = yakadex;
m.yakadex_entry_id = yakadex;
}
return m;
}
@ -57,11 +50,11 @@ public final class EntityToModelConverter {
YakadexEntryModel m = new YakadexEntryModel();
m.name = e.name;
m.caught = e.caught;
m.firstType = e.firstType;
m.secondType = e.secondType;
m.first_type = e.firstType != null ? e.firstType.name() : null;
m.second_type = e.secondType != null ? e.secondType.name() : null;
m.description = e.description;
m.evolveThreshold = e.evolveThreshold;
m.evolutionId = null; // don't know yet
m.evolve_threshold = e.evolveThreshold;
m.evolution_id = null;
return m;
}
}

View file

@ -4,11 +4,15 @@ import fr.epita.assistants.yakamon.utils.tile.ItemType;
import jakarta.persistence.*;
@Entity
@Table(name="item")
@Table(name = "item")
public class ItemModel {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) protected Integer id;
public ItemType type;
public Integer quantity;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;
@Enumerated
public ItemType type;
public Integer quantity;
}

View file

@ -13,13 +13,16 @@ public class YakadexEntryModel {
public String name;
public Boolean caught;
public ElementType firstType;
public ElementType secondType;
// Changed to string otherwise it doesn't work
public String first_type;
public String second_type;
public String description;
@OneToOne
@JoinColumn(name = "evolution_id")
public YakadexEntryModel evolutionId;
public YakadexEntryModel evolution_id;
public Integer evolveThreshold;
public Integer evolve_threshold;
}

View file

@ -1,15 +1,20 @@
package fr.epita.assistants.yakamon.data.model;
import jakarta.persistence.*;
import java.util.UUID;
@Entity
@Table(name="yakamon")
@Table(name = "yakamon")
public class YakamonModel {
@Id
@GeneratedValue(strategy = GenerationType.UUID) protected UUID id;
@GeneratedValue(strategy = GenerationType.UUID)
public UUID id;
public String nickname;
public Integer energyPoints;
@ManyToOne @JoinColumn(name="yakadex_id") public YakadexEntryModel yakadexEntryId;
public Integer energy_points;
@ManyToOne
@JoinColumn(name = "yakadex_id")
public YakadexEntryModel yakadex_entry_id;
}

View file

@ -1,3 +1,8 @@
package fr.epita.assistants.yakamon.data.repository;
public class GameRepository {}
import fr.epita.assistants.yakamon.data.model.GameModel;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class GameRepository implements PanacheRepository<GameModel> {}

View file

@ -0,0 +1,8 @@
package fr.epita.assistants.yakamon.data.repository;
import fr.epita.assistants.yakamon.data.model.ItemModel;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class ItemRepository implements PanacheRepository<ItemModel> {}

View file

@ -1,3 +1,8 @@
package fr.epita.assistants.yakamon.data.repository;
public class PlayerRepository {}
import fr.epita.assistants.yakamon.data.model.PlayerModel;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class PlayerRepository implements PanacheRepository<PlayerModel> {}

View file

@ -1,3 +0,0 @@
package fr.epita.assistants.yakamon.data.repository;
public class TeamRepository {}

View file

@ -1,3 +1,9 @@
package fr.epita.assistants.yakamon.data.repository;
public class YakadexRepository {}
import fr.epita.assistants.yakamon.data.model.YakadexEntryModel;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class YakadexRepository
implements PanacheRepository<YakadexEntryModel> {}

View file

@ -0,0 +1,8 @@
package fr.epita.assistants.yakamon.data.repository;
import fr.epita.assistants.yakamon.data.model.YakamonModel;
import io.quarkus.hibernate.orm.panache.PanacheRepository;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class YakamonRepository implements PanacheRepository<YakamonModel> {}

View file

@ -4,35 +4,37 @@ import java.time.LocalDateTime;
public class GameEntity {
public Long id;
public static GameEntity INSTANCE = null;
public String mapPath;
public boolean started;
public LocalDateTime startTime;
public TileEntity[][] map;
public GameEntity() {}
public GameEntity() {
this.start(null);
}
public GameEntity(
Long id,
String mapPath,
boolean started,
LocalDateTime startTime
) {
this.id = id;
public GameEntity(String mapPath) {
this.start(null);
this.mapPath = mapPath;
this.started = started;
this.startTime = startTime;
GameEntity.INSTANCE = this;
}
public GameEntity start(LocalDateTime startTime) {
// TODO
if (started || INSTANCE != null) {
this.stop();
}
startTime = startTime == null ? LocalDateTime.now() : startTime;
started = true;
this.startTime = startTime;
this.started = true;
return this;
}
public GameEntity stop() {
GameEntity.INSTANCE = null;
this.started = false;
this.startTime = null;
this.map = null;
return this;
}
}

View file

@ -2,26 +2,19 @@ package fr.epita.assistants.yakamon.domain.entity;
import fr.epita.assistants.yakamon.utils.tile.ItemType;
import java.util.Objects;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
public class ItemEntity {
public Integer id;
public ItemType type;
public Integer quantity;
public ItemEntity(Integer id, ItemType type, Integer quantity) {
this.id = id;
if (type == null) {
System.err.println(
"Warning: attempted to pass null item type, using default 'NONE'"
);
type = ItemType.NONE;
}
this.type = Objects.requireNonNull(type, "type must not be null");
this.quantity = quantity != null ? quantity : 0;
}
// public ItemEntity(Integer id, ItemType type, Integer quantity) {
// }
// public ItemEntity addQuantity(int amount) {
// int current = this.quantity != null ? this.quantity : 0;

View file

@ -0,0 +1,14 @@
package fr.epita.assistants.yakamon.domain.entity;
import java.time.LocalDateTime;
public class PlayerEntity {
public String name;
public Integer posX;
public Integer posY;
public LocalDateTime lastMove;
public LocalDateTime lastCatch;
public LocalDateTime lastCollect;
public LocalDateTime lastFeed;
}

View file

@ -0,0 +1,16 @@
package fr.epita.assistants.yakamon.domain.entity;
public class TileEntity {
public Character terrain;
public Character collectible;
public TileEntity(Character terrain, Character collectible) {
this.terrain = terrain;
this.collectible = collectible;
}
public boolean isWalkable() {
return terrain == 'G' || terrain == 'R' || terrain == 'S';
}
}

View file

@ -1,26 +1,72 @@
package fr.epita.assistants.yakamon.domain.service;
import fr.epita.assistants.yakamon.converter.EntityToModelConverter;
import fr.epita.assistants.yakamon.data.model.GameModel;
import fr.epita.assistants.yakamon.data.model.ItemModel;
import fr.epita.assistants.yakamon.data.model.PlayerModel;
import fr.epita.assistants.yakamon.data.repository.GameRepository;
import fr.epita.assistants.yakamon.data.repository.ItemRepository;
import fr.epita.assistants.yakamon.data.repository.PlayerRepository;
import fr.epita.assistants.yakamon.domain.entity.GameEntity;
import fr.epita.assistants.yakamon.domain.entity.TileEntity;
import fr.epita.assistants.yakamon.utils.ErrorCode;
import fr.epita.assistants.yakamon.utils.tile.ItemType;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.List;
@NoArgsConstructor
@ApplicationScoped
public class GameService {
public static GameEntity game = new GameEntity();
public static final GameService INSTANCE = new GameService(); // TODO ?
@Inject
GameRepository gameRepository;
public GameEntity startGame(String mapPath) {
@Inject
PlayerRepository playerRepository;
@Inject
ItemRepository itemRepository;
public static GameEntity game;
public GameEntity startGame(String mapPath, String playerName) {
if (mapPath == null) {
throw new RuntimeException(
"Could not start game with null mapPath"
);
}
if (game == null) {
game = new GameEntity();
ErrorCode.INVALID_MAP.throwException("Map is null");
}
game.start(LocalDateTime.now());
// Initialize Game with mapPath
game = new GameEntity(mapPath);
GameModel gameModel = EntityToModelConverter.toGameModel(game);
// Parse map and store in GameEntity
TileEntity[][] parsedMap = parseMapFile(mapPath);
game.map = parsedMap;
// Initialize player
LocalDateTime now = LocalDateTime.now();
PlayerModel player = new PlayerModel();
player.name = playerName;
player.posX = 0;
player.posY = 0;
player.lastCatch = now;
player.lastCollect = now;
player.lastFeed = now;
player.lastMove = now;
// Initialize player inventory
ItemModel yakaballs = new ItemModel();
yakaballs.type = ItemType.YAKABALL;
yakaballs.quantity = 5;
// Store
playerRepository.persist(player);
itemRepository.persist(yakaballs);
gameRepository.persist(gameModel);
return game;
}
@ -30,8 +76,78 @@ public class GameService {
public void stopGame() {
if (game == null) {
game = new GameEntity();
ErrorCode.GAME_NOT_STARTED.throwException();
}
game.stop();
gameRepository.deleteAll();
playerRepository.deleteAll();
}
private TileEntity[][] parseMapFile(String mapPath) {
try {
String resourcePath = "maps/" + mapPath + ".epimap";
BufferedReader reader = new BufferedReader(
new InputStreamReader(
GameService.class.getClassLoader().getResourceAsStream(
resourcePath
)
)
);
List<List<TileEntity>> mapList = new ArrayList<>();
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
List<TileEntity> row = parseLine(line);
mapList.add(row);
}
}
reader.close();
if (mapList.isEmpty()) {
ErrorCode.INVALID_MAP.throwException("Map file is empty");
}
TileEntity[][] map = new TileEntity[mapList.size()][];
for (int i = 0; i < mapList.size(); i++) {
List<TileEntity> row = mapList.get(i);
map[i] = row.toArray(new TileEntity[0]);
}
return map;
} catch (Exception e) {
ErrorCode.INVALID_MAP.throwException("Failed to load map");
}
return null;
}
private List<TileEntity> parseLine(String line) {
List<TileEntity> row = new ArrayList<>();
int i = 0;
while (i < line.length()) {
// Parse count
int count = Character.getNumericValue(line.charAt(i));
i++;
// Parse terrain character
if (i >= line.length()) break;
char terrain = line.charAt(i);
i++;
// Parse collectible character
if (i >= line.length()) break;
char collectible = line.charAt(i);
i++;
// Add tiles
for (int j = 0; j < count; j++) {
row.add(new TileEntity(terrain, collectible));
}
}
return row;
}
}

View file

@ -1,3 +1,240 @@
package fr.epita.assistants.yakamon.domain.service;
public class PlayerService {}
import fr.epita.assistants.yakamon.data.model.ItemModel;
import fr.epita.assistants.yakamon.data.model.PlayerModel;
import fr.epita.assistants.yakamon.data.model.YakadexEntryModel;
import fr.epita.assistants.yakamon.data.model.YakamonModel;
import fr.epita.assistants.yakamon.data.repository.ItemRepository;
import fr.epita.assistants.yakamon.data.repository.PlayerRepository;
import fr.epita.assistants.yakamon.data.repository.YakadexRepository;
import fr.epita.assistants.yakamon.data.repository.YakamonRepository;
import fr.epita.assistants.yakamon.domain.entity.GameEntity;
import fr.epita.assistants.yakamon.domain.entity.TileEntity;
import fr.epita.assistants.yakamon.utils.Direction;
import fr.epita.assistants.yakamon.utils.ErrorCode;
import fr.epita.assistants.yakamon.utils.Point;
import fr.epita.assistants.yakamon.utils.tile.Collectible;
import fr.epita.assistants.yakamon.utils.tile.CollectibleUtils;
import fr.epita.assistants.yakamon.utils.tile.ItemType;
import fr.epita.assistants.yakamon.utils.tile.YakamonInfo;
import fr.epita.assistants.yakamon.utils.tile.YakamonType;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.UUID;
@ApplicationScoped
public class PlayerService {
@Inject
PlayerRepository playerRepository;
@Inject
YakamonRepository yakamonRepository;
@Inject
YakadexRepository yakadexRepository;
@Inject
ItemRepository itemRepository;
@Transactional
public Point move(Direction direction) {
if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) {
ErrorCode.GAME_NOT_STARTED.throwException();
}
PlayerModel player = playerRepository.findAll().firstResult();
if (player == null) {
ErrorCode.BAD_REQUEST.throwException("Player not found");
}
checkMovementDelay(player);
if (direction == null) {
ErrorCode.BAD_REQUEST.throwException("Invalid direction");
}
TileEntity[][] map = GameEntity.INSTANCE.map;
if (map == null) {
ErrorCode.INVALID_MAP.throwException("Map not loaded");
}
Point directionOffset = direction.getPoint();
int newX = player.posX + directionOffset.getPosX();
int newY = player.posY + directionOffset.getPosY();
if (
newY < 0 ||
newY >= map.length ||
newX < 0 ||
newX >= map[newY].length
) {
ErrorCode.BAD_REQUEST.throwException(
"Cannot move outside map boundaries"
);
}
TileEntity tile = map[newY][newX];
if (tile == null || !tile.isWalkable()) {
ErrorCode.BAD_REQUEST.throwException("Tile is not walkable");
}
player.posX = newX;
player.posY = newY;
player.lastMove = LocalDateTime.now();
return new Point(newX, newY);
}
@Transactional
public YakamonModel catchYakamon() {
if (GameEntity.INSTANCE == null || !GameEntity.INSTANCE.started) {
ErrorCode.GAME_NOT_STARTED.throwException();
}
PlayerModel player = playerRepository.findAll().firstResult();
if (player == null) {
ErrorCode.BAD_REQUEST.throwException("Player not found");
}
checkCatchDelay(player);
TileEntity[][] map = GameEntity.INSTANCE.map;
if (map == null) {
ErrorCode.INVALID_MAP.throwException("Map not loaded");
}
int x = player.posX;
int y = player.posY;
if (y < 0 || y >= map.length || x < 0 || x >= map[y].length) {
ErrorCode.BAD_REQUEST.throwException("Invalid position");
}
TileEntity tile = map[y][x];
if (
tile == null || tile.collectible == null || tile.collectible == 'N'
) {
throw new WebApplicationException(
Response.status(400)
.entity("No yakamon at this position")
.build()
);
}
Collectible collectible = CollectibleUtils.getCollectible(
tile.collectible
);
if (!(collectible instanceof YakamonType)) {
throw new WebApplicationException(
Response.status(400)
.entity("No yakamon at this position")
.build()
);
}
ItemModel yakaballItem = itemRepository
.find("type", ItemType.YAKABALL)
.firstResult();
if (yakaballItem == null || yakaballItem.quantity < 1) {
throw new WebApplicationException(
Response.status(400).entity("Not enough Yakaballs").build()
);
}
long teamSize = yakamonRepository.count();
if (teamSize >= 3) {
throw new WebApplicationException(
Response.status(400).entity("Team is full").build()
);
}
YakamonType yakamonType = (YakamonType) collectible;
YakamonInfo yakamonInfo =
(YakamonInfo) yakamonType.getCollectibleInfo();
Integer yakadexId = yakamonInfo.getYakadexId();
YakadexEntryModel yakadex = yakadexRepository
.find("id", yakadexId)
.firstResult();
if (yakadex == null) {
ErrorCode.BAD_REQUEST.throwException("Yakamon species not found");
}
yakaballItem.quantity -= 1;
itemRepository.persist(yakaballItem);
YakamonModel newYakamon = new YakamonModel();
newYakamon.nickname = yakamonType.name();
newYakamon.energy_points = 0;
newYakamon.yakadex_entry_id = yakadex;
yakamonRepository.persist(newYakamon);
yakadex.caught = true;
yakadexRepository.persist(yakadex);
tile.collectible = 'N';
player.lastCatch = LocalDateTime.now();
playerRepository.persist(player);
return newYakamon;
}
private void checkMovementDelay(PlayerModel player) {
String tickDurationStr = System.getenv("JWS_TICK_DURATION");
String movementDelayStr = System.getenv("JWS_MOVEMENT_DELAY");
if (tickDurationStr == null || movementDelayStr == null) {
return;
}
try {
long tickDuration = Long.parseLong(tickDurationStr);
long movementDelay = Long.parseLong(movementDelayStr);
long requiredDelay = tickDuration * movementDelay;
LocalDateTime now = LocalDateTime.now();
long elapsed = ChronoUnit.MILLIS.between(player.lastMove, now);
if (elapsed < requiredDelay) {
throw new WebApplicationException(Response.status(429).build());
}
} catch (NumberFormatException e) {
ErrorCode.BAD_REQUEST.throwException(
"Invalid environment variables"
);
}
}
private void checkCatchDelay(PlayerModel player) {
String tickDurationStr = System.getenv("JWS_TICK_DURATION");
String catchDelayStr = System.getenv("JWS_CATCH_DELAY");
if (tickDurationStr == null || catchDelayStr == null) {
return;
}
try {
long tickDuration = Long.parseLong(tickDurationStr);
long catchDelay = Long.parseLong(catchDelayStr);
long requiredDelay = tickDuration * catchDelay;
LocalDateTime now = LocalDateTime.now();
long elapsed = ChronoUnit.MILLIS.between(player.lastCatch, now);
if (elapsed < requiredDelay) {
throw new WebApplicationException(Response.status(429).build());
}
} catch (NumberFormatException e) {
ErrorCode.BAD_REQUEST.throwException(
"Invalid environment variables"
);
}
}
}

View file

@ -1,3 +1,66 @@
package fr.epita.assistants.yakamon.domain.service;
public class YakadexService {}
import fr.epita.assistants.yakamon.data.model.YakadexEntryModel;
import fr.epita.assistants.yakamon.data.repository.YakadexRepository;
import fr.epita.assistants.yakamon.presentation.api.YakadexEntry;
import fr.epita.assistants.yakamon.presentation.api.response.YakadexAllInfosResponse;
import fr.epita.assistants.yakamon.presentation.api.response.YakadexInfosResponse;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.ArrayList;
import java.util.List;
@ApplicationScoped
public class YakadexService {
@Inject
YakadexRepository yakadexRepository;
public YakadexAllInfosResponse getAllEntries(Boolean onlyMissing) {
List<YakadexEntryModel> entries;
if (onlyMissing != null && onlyMissing) {
entries = yakadexRepository.find("caught = false").list();
} else {
entries = yakadexRepository.listAll();
}
List<YakadexEntry> dtos = new ArrayList<>();
for (YakadexEntryModel entry : entries) {
YakadexEntry dto = new YakadexInfosResponse(
entry.id,
entry.name,
entry.first_type,
entry.second_type,
entry.evolve_threshold,
null,
entry.caught,
entry.description
);
dtos.add(dto);
}
return new YakadexAllInfosResponse(dtos.toArray(new YakadexEntry[0]));
}
public YakadexInfosResponse getEntryById(Integer id) {
YakadexEntryModel entry = yakadexRepository
.find("id = ?1", id)
.firstResult();
if (entry == null) {
return null;
}
return new YakadexInfosResponse(
entry.id,
entry.name,
entry.first_type,
entry.second_type,
entry.evolve_threshold,
null,
entry.caught,
entry.description
);
}
}

View file

@ -2,9 +2,13 @@ package fr.epita.assistants.yakamon.presentation.api.request;
import fr.epita.assistants.yakamon.utils.Direction;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PlayerMoveRequest {
Direction direction;
public Direction direction;
}

View file

@ -40,23 +40,32 @@ public class GameResource {
}
LOGGER.info(
"Starting game for player='" +
"Starting game for player '" +
request.playerName +
"' with map='" +
"' with map '" +
request.mapPath +
"'"
);
GameService gameService = new GameService();
GameEntity startedGame = gameService.startGame(request.mapPath);
try {
GameService gameService = new GameService();
GameEntity startedGame = gameService.startGame(
request.mapPath,
request.playerName
);
LOGGER.info(
"Game started at: " +
(startedGame != null ? startedGame.startTime : "unknown")
);
LOGGER.info(
"Game started at: " +
(startedGame != null ? startedGame.startTime : "unknown")
);
// StartGameResponse response = new StartGameResponse();
// return Response.ok(response).build();
return Response.ok().build();
// StartGameResponse response = new StartGameResponse();
// return Response.ok(response).build();
return Response.ok().build();
} catch (Exception e) {
return Response.status(
400,
"Invalid path or invalid name provided."
).build();
}
}
}

View file

@ -1,5 +1,6 @@
package fr.epita.assistants.yakamon.presentation.rest;
import fr.epita.assistants.yakamon.domain.service.GameService;
import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
@ -13,10 +14,18 @@ import jakarta.ws.rs.core.Response;
@Consumes(MediaType.APPLICATION_JSON)
public class InventoryResource {
private final GameService gameService = new GameService();
@GET
public Response getInventory() {
// GetInventoryResponse response = new GetInventoryResponse();
if (!gameService.isStarted()) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Game not started")
.build();
}
// TODO service
// GetInventoryResponse response = inventoryService.getInventory();
// return Response.ok(response).build();
return Response.ok().build();
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
}
}

View file

@ -1,12 +1,14 @@
package fr.epita.assistants.yakamon.presentation.rest;
import fr.epita.assistants.yakamon.domain.service.GameService;
import fr.epita.assistants.yakamon.domain.service.PlayerService;
import fr.epita.assistants.yakamon.presentation.api.request.PlayerMoveRequest;
import fr.epita.assistants.yakamon.presentation.api.response.GetInventoryResponse;
import fr.epita.assistants.yakamon.presentation.api.response.PlayerCatchResponse;
import fr.epita.assistants.yakamon.presentation.api.response.PlayerCollectResponse;
import fr.epita.assistants.yakamon.presentation.api.response.PlayerInfosResponse;
import fr.epita.assistants.yakamon.presentation.api.response.PlayerMoveResponse;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@ -16,7 +18,11 @@ import jakarta.ws.rs.core.Response;
@Produces(MediaType.APPLICATION_JSON)
public class PlayerResource {
private final GameService gameService = new GameService();
@Inject
private GameService gameService;
@Inject
private PlayerService playerService;
@POST
@Path("/catch")
@ -26,8 +32,23 @@ public class PlayerResource {
.entity("Game not started")
.build();
}
// TODO service
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
try {
var yakamon = playerService.catchYakamon();
var response = new PlayerCatchResponse(
yakamon.id.toString(),
yakamon.nickname,
yakamon.yakadex_entry_id.id,
yakamon.energy_points
);
return Response.ok(response).build();
} catch (jakarta.ws.rs.WebApplicationException e) {
return e.getResponse();
} catch (Exception e) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(e.getMessage())
.build();
}
}
@POST
@ -42,20 +63,6 @@ public class PlayerResource {
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
}
@GET
@Path("/inventory")
public Response getInventory() {
if (!gameService.isStarted()) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Game not started")
.build();
}
// TODO service
// GetInventoryResponse response = inventoryService.getInventory();
// return Response.ok(response).build();
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
}
@POST
@Path("/move")
public Response move(PlayerMoveRequest request) {
@ -64,19 +71,27 @@ public class PlayerResource {
.entity("Game not started")
.build();
}
if (request == null) {
if (request == null || request.direction == null) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("Request body is required")
.entity("Invalid direction")
.build();
}
// if (request.direction == null) {
// return Response.status(Response.Status.BAD_REQUEST)
// .entity("Direction is required")
// .build();
// }
// TODO service
return Response.status(Response.Status.NOT_IMPLEMENTED).build();
try {
fr.epita.assistants.yakamon.utils.Point newPos = playerService.move(
request.direction
);
return Response.ok(
new PlayerMoveResponse(newPos.getPosX(), newPos.getPosY())
).build();
} catch (jakarta.ws.rs.WebApplicationException e) {
return e.getResponse();
} catch (Exception e) {
return Response.status(Response.Status.BAD_REQUEST)
.entity(e.getMessage())
.build();
}
}
@GET

View file

@ -1,8 +1,10 @@
package fr.epita.assistants.yakamon.presentation.rest;
import fr.epita.assistants.yakamon.domain.service.GameService;
import fr.epita.assistants.yakamon.domain.service.YakadexService;
import fr.epita.assistants.yakamon.presentation.api.response.YakadexAllInfosResponse;
import fr.epita.assistants.yakamon.presentation.api.response.YakadexInfosResponse;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
@ -12,7 +14,11 @@ import jakarta.ws.rs.core.Response;
@Consumes(MediaType.APPLICATION_JSON)
public class YakadexResource {
private final GameService gameService = new GameService();
@Inject
private GameService gameService;
@Inject
private YakadexService yakadexService;
@GET
public Response getYakadex(
@ -24,9 +30,10 @@ public class YakadexResource {
.build();
}
// YakadexAllInfosResponse response = new YakadexAllInfosResponse();
// return Response.ok(response).build();
return Response.ok().build();
YakadexAllInfosResponse response = yakadexService.getAllEntries(
onlyMissing
);
return Response.ok(response).build();
}
@GET
@ -38,12 +45,12 @@ public class YakadexResource {
.build();
}
if (id == null || id < 0) {
YakadexInfosResponse response = yakadexService.getEntryById(id);
if (response == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
// YakadexInfosResponse response = new YakadexInfosResponse();
// return Response.ok(response).build();
return Response.ok().build();
return Response.ok(response).build();
}
}

View file

@ -1,23 +1,31 @@
package fr.epita.assistants.yakamon.utils;
import static jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import static jakarta.ws.rs.core.Response.Status;
@Getter
@RequiredArgsConstructor
public enum ErrorCode {
EXAMPLE_ERROR(Status.INTERNAL_SERVER_ERROR, "This is an error example");
EXAMPLE_ERROR(Status.INTERNAL_SERVER_ERROR, "This is an error example"),
BAD_REQUEST(Status.BAD_REQUEST, "Bad request"),
INVALID_MAP(Status.BAD_REQUEST, "Given map is invalid"),
GAME_NOT_STARTED(Status.CONFLICT, "Game has not been started"),
GAME_ALREADY_STARTED(Status.FORBIDDEN, "Game is already started");
private final Response.Status errorCode;
private final String errorMessage;
public WebApplicationException getException() {
return new WebApplicationException(Response.status(errorCode).entity(new ErrorInfo(errorMessage)).build());
return new WebApplicationException(
Response.status(errorCode)
.entity(new ErrorInfo(errorMessage))
.build()
);
}
public void throwException() {
@ -25,6 +33,10 @@ public enum ErrorCode {
}
public void throwException(String prefix) {
throw new WebApplicationException(Response.status(errorCode).entity(new ErrorInfo(prefix + ": " + errorMessage)).build());
throw new WebApplicationException(
Response.status(errorCode)
.entity(new ErrorInfo(prefix + ": " + errorMessage))
.build()
);
}
}

View file

@ -0,0 +1,239 @@
package fr.epita.assistants.yakamon_testsuite;
import static org.junit.jupiter.api.Assertions.*;
import fr.epita.assistants.yakamon.converter.DtoToEntityConverter;
import fr.epita.assistants.yakamon.converter.EntityToDtoConverter;
import fr.epita.assistants.yakamon.converter.EntityToModelConverter;
import fr.epita.assistants.yakamon.domain.entity.GameEntity;
import fr.epita.assistants.yakamon.domain.entity.YakadexEntryEntity;
import fr.epita.assistants.yakamon.domain.entity.YakamonEntity;
import fr.epita.assistants.yakamon.presentation.api.YakadexEntry;
import fr.epita.assistants.yakamon.presentation.api.YakamonAction;
import fr.epita.assistants.yakamon.presentation.api.request.StartGameRequest;
import fr.epita.assistants.yakamon.utils.ElementType;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("ConverterTests")
public class ConverterTests {
@Test
@DisplayName("ModelToYakamon: null returns null")
public void testNullYakamonToModel() {
assertNull(EntityToModelConverter.toYakamonModel(null));
}
@Test
@DisplayName("ModelToYakamon: valid conversion")
public void testYakamonToModel() {
YakamonEntity yakamon = new YakamonEntity();
yakamon.uuid = UUID.randomUUID();
yakamon.nickname = "Bastiedon";
yakamon.yakadexId = 6;
yakamon.energyPoints = 50;
var model = EntityToModelConverter.toYakamonModel(yakamon);
assertNotNull(model);
assertEquals("Bastiedon", model.nickname);
assertEquals(50, model.energy_points);
}
@Test
@DisplayName("ModelToYakadex: null returns null")
public void testNullYakadexToModel() {
assertNull(EntityToModelConverter.toYakadexEntryModel(null));
}
@Test
@DisplayName("ModelToYakadex: single type")
public void testYakadexSingleType() {
YakadexEntryEntity yakadex = new YakadexEntryEntity();
yakadex.id = 1;
yakadex.name = "Yakimon";
yakadex.firstType = ElementType.NORMAL;
yakadex.secondType = null;
yakadex.caught = true;
var model = EntityToModelConverter.toYakadexEntryModel(yakadex);
assertNotNull(model);
assertEquals("NORMAL", model.first_type);
assertNull(model.second_type);
}
@Test
@DisplayName("ModelToYakadex: dual types")
public void testYakadexDualTypes() {
YakadexEntryEntity yakadex = new YakadexEntryEntity();
yakadex.id = 25;
yakadex.name = "Pikachu";
yakadex.firstType = ElementType.ELECTRIC;
yakadex.secondType = ElementType.FLYING;
yakadex.caught = false;
var model = EntityToModelConverter.toYakadexEntryModel(yakadex);
assertNotNull(model);
assertEquals("ELECTRIC", model.first_type);
assertEquals("FLYING", model.second_type);
}
@Test
@DisplayName("DtoToYakamon: null returns null")
public void testNullYakamonAction() {
assertNull(DtoToEntityConverter.toYakamonEntity(null));
}
@Test
@DisplayName("DtoToYakamon: valid conversion")
public void testYakamonActionValid() {
UUID uuid = UUID.randomUUID();
YakamonAction action = new YakamonAction(
uuid.toString(),
"Bastiedon",
6,
100
);
YakamonEntity entity = DtoToEntityConverter.toYakamonEntity(action);
assertNotNull(entity);
assertEquals(uuid, entity.uuid);
assertEquals("Bastiedon", entity.nickname);
}
@Test
@DisplayName("DtoToYakamon: invalid uuid handled")
public void testYakamonInvalidUuid() {
YakamonAction action = new YakamonAction("not-a-uuid", "Test", 1, 0);
YakamonEntity entity = DtoToEntityConverter.toYakamonEntity(action);
assertNotNull(entity);
assertNull(entity.uuid);
}
@Test
@DisplayName("DtoToYakadex: null returns null")
public void testNullYakadexEntry() {
assertNull(DtoToEntityConverter.toYakadexEntryEntity(null));
}
@Test
@DisplayName("DtoToYakadex: valid types")
public void testYakadexTypesConvert() {
YakadexEntry dto = new YakadexEntry(
1,
"Yakimon",
"NORMAL",
"FLYING",
10,
2,
true,
"A creature"
);
YakadexEntryEntity entity = DtoToEntityConverter.toYakadexEntryEntity(
dto
);
assertNotNull(entity);
assertEquals(ElementType.NORMAL, entity.firstType);
assertEquals(ElementType.FLYING, entity.secondType);
}
@Test
@DisplayName("DtoToYakadex: invalid enum handled")
public void testYakadexInvalidEnum() {
YakadexEntry dto = new YakadexEntry(
1,
"Test",
"INVALID",
null,
10,
null,
false,
"Test"
);
YakadexEntryEntity entity = DtoToEntityConverter.toYakadexEntryEntity(
dto
);
assertNotNull(entity);
assertNull(entity.firstType);
}
@Test
@DisplayName("DtoToGame: converts correctly")
public void testGameDtoConvert() {
StartGameRequest request = new StartGameRequest("test_map", "Player");
GameEntity entity = DtoToEntityConverter.toGameEntity(request);
assertNotNull(entity);
assertEquals("test_map", entity.mapPath);
assertTrue(entity.started);
}
@Test
@DisplayName("EntityToYakamon: null returns null")
public void testNullYakamonDto() {
assertNull(EntityToDtoConverter.toYakamonAction(null));
}
@Test
@DisplayName("EntityToYakamon: valid conversion")
public void testYakamonDto() {
YakamonEntity yakamon = new YakamonEntity();
yakamon.uuid = UUID.randomUUID();
yakamon.nickname = "Bastiedon";
yakamon.yakadexId = 6;
yakamon.energyPoints = 75;
YakamonAction action = EntityToDtoConverter.toYakamonAction(yakamon);
assertNotNull(action);
assertEquals("Bastiedon", action.nickname);
assertEquals(6, action.yakadexId);
}
@Test
@DisplayName("EntityToYakadex: null returns null")
public void testNullYakadexDto() {
assertNull(EntityToDtoConverter.toYakadexEntry(null));
}
@Test
@DisplayName("EntityToYakadex: conversion")
public void testYakadexDto() {
YakadexEntryEntity yakadex = new YakadexEntryEntity();
yakadex.id = 1;
yakadex.name = "Yakimon";
yakadex.firstType = ElementType.NORMAL;
yakadex.secondType = null;
yakadex.caught = true;
YakadexEntry entry = EntityToDtoConverter.toYakadexEntry(yakadex);
assertNotNull(entry);
assertEquals("NORMAL", entry.firstType);
assertNull(entry.secondType);
}
@Test
@DisplayName("EntityToYakamon: list conversion")
public void testYakamonListDto() {
YakamonEntity y1 = new YakamonEntity();
y1.uuid = UUID.randomUUID();
y1.nickname = "Yak1";
y1.yakadexId = 1;
y1.energyPoints = 0;
var result = EntityToDtoConverter.toYakamonActions(
java.util.List.of(y1)
);
assertEquals(1, result.size());
assertEquals("Yak1", result.get(0).nickname);
}
}

View file

@ -0,0 +1,189 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("GameResourceTest")
public class GameResourceTest {
@Test
@DisplayName("POST /start/ with valid request")
public void testStartGameWithValidRequest() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /start without trailing slash")
public void testStartGameWithoutTrailingSlash() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /start/ missing mapPath returns 400")
public void testStartGameWithoutMapPath() {
String requestBody = "{\"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ missing playerName returns 400")
public void testStartGameWithoutPlayerName() {
String requestBody = "{\"mapPath\": \"map1.txt\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ blank mapPath returns 400")
public void testStartGameWithBlankMapPath() {
String requestBody = "{\"mapPath\": \"\", \"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ blank playerName returns 400")
public void testStartGameWithBlankPlayerName() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ both fields blank returns 400")
public void testStartGameWithBothBlank() {
String requestBody = "{\"mapPath\": \"\", \"playerName\": \"\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ whitespace mapPath returns 400")
public void testStartGameWithWhitespaceMapPath() {
String requestBody =
"{\"mapPath\": \" \", \"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ whitespace playerName returns 400")
public void testStartGameWithWhitespacePlayerName() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \" \"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /start/ with special characters in name")
public void testStartGameWithSpecialCharacterName() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice-Smith_123\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /start/ with complex map path")
public void testStartGameWithComplexMapPath() {
String requestBody =
"{\"mapPath\": \"maps/world/level1/forest.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /start/ returns JSON")
public void testStartGameContentType() {
String requestBody =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"Alice\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/start/")
.then()
.contentType(ContentType.JSON);
}
}

View file

@ -0,0 +1,79 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("HelloWorldResourceTest")
public class HelloWorldResourceTest {
@Test
@DisplayName("GET /hello/")
public void testHelloWorldWithoutName() {
given()
.when()
.get("/hello/")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
@Test
@DisplayName("GET /hello without trailing slash")
public void testHelloWorldWithoutTrailingSlash() {
given()
.when()
.get("/hello")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
@Test
@DisplayName("GET /hello/{name}")
public void testHelloWorldWithName() {
given()
.when()
.get("/hello/Alice")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
@Test
@DisplayName("GET /hello/{name} with different name")
public void testHelloWorldWithDifferentName() {
given()
.when()
.get("/hello/Bob")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
@Test
@DisplayName("GET /hello/{name} with special characters")
public void testHelloWorldWithSpecialCharacters() {
given()
.when()
.get("/hello/John-Doe")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
@Test
@DisplayName("GET /hello/{name} with numeric name")
public void testHelloWorldWithNumericName() {
given()
.when()
.get("/hello/123")
.then()
.statusCode(200)
.contentType(ContentType.TEXT);
}
}

View file

@ -0,0 +1,116 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("InventoryResourceTest")
public class InventoryResourceTest {
@Test
@DisplayName("GET /inventory returns 200")
public void testGetInventorySuccess() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /inventory returns JSON")
public void testGetInventoryContentType() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /inventory without trailing slash")
public void testGetInventoryWithoutTrailingSlash() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /inventory multiple requests")
public void testGetInventoryMultipleCalls() {
for (int i = 0; i < 5; i++) {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
}
@Test
@DisplayName("GET /inventory with accept header")
public void testGetInventoryWithAcceptHeader() {
given()
.accept(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200)
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /inventory without body")
public void testGetInventoryNoBody() {
given().when().get("/inventory").then().statusCode(200);
}
@Test
@DisplayName("GET /inventory with query params")
public void testGetInventoryWithQueryParams() {
given()
.contentType(ContentType.JSON)
.queryParam("filter", "all")
.when()
.get("/inventory")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /inventory rapid consecutive requests")
public void testGetInventoryRapidRequests() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200);
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200);
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(200);
}
}

View file

@ -0,0 +1,7 @@
package fr.epita.assistants.yakamon_testsuite;
// import static org.junit.jupiter.api.Assertions.*;
// import org.junit.jupiter.api.Test;
public class MainTests {}

View file

@ -0,0 +1,210 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("PlayerResourceTest")
public class PlayerResourceTest {
@Test
@DisplayName("POST /catch without game returns 400")
public void testCatchYakamonWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.post("/catch")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /collect without game returns 400")
public void testCollectWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.post("/collect")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /inventory without game returns 400")
public void testGetInventoryWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move without game returns 400")
public void testMoveWithoutGameStarted() {
String requestBody = "{\"direction\": \"UP\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move without body returns 400")
public void testMoveWithoutRequestBody() {
given()
.contentType(ContentType.JSON)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /player without game returns 400")
public void testGetPlayerInfosWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.get("/player")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /inventory returns JSON")
public void testGetInventoryContentType() {
given()
.contentType(ContentType.JSON)
.when()
.get("/inventory")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /move returns JSON")
public void testMoveContentType() {
String requestBody = "{\"direction\": \"UP\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /player returns JSON")
public void testGetPlayerContentType() {
given()
.contentType(ContentType.JSON)
.when()
.get("/player")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /catch returns JSON")
public void testCatchContentType() {
given()
.contentType(ContentType.JSON)
.when()
.post("/catch")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /collect returns JSON")
public void testCollectContentType() {
given()
.contentType(ContentType.JSON)
.when()
.post("/collect")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /move with UP direction")
public void testMoveWithUpDirection() {
String requestBody = "{\"direction\": \"UP\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move with DOWN direction")
public void testMoveWithDownDirection() {
String requestBody = "{\"direction\": \"DOWN\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move with LEFT direction")
public void testMoveWithLeftDirection() {
String requestBody = "{\"direction\": \"LEFT\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move with RIGHT direction")
public void testMoveWithRightDirection() {
String requestBody = "{\"direction\": \"RIGHT\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /move with invalid direction")
public void testMoveWithInvalidDirection() {
String requestBody = "{\"direction\": \"INVALID\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/move")
.then()
.statusCode(400);
}
}

View file

@ -0,0 +1,173 @@
package fr.epita.assistants.yakamon_testsuite;
import static org.junit.jupiter.api.Assertions.*;
import fr.epita.assistants.yakamon.domain.entity.GameEntity;
import fr.epita.assistants.yakamon.domain.entity.TileEntity;
import fr.epita.assistants.yakamon.utils.Direction;
import fr.epita.assistants.yakamon.utils.Point;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("ServiceLayerTests")
public class ServiceLayerTests {
@BeforeEach
public void setup() {
GameEntity.INSTANCE = null;
}
@Test
@DisplayName("GameStart")
public void testGameStart() {
GameEntity game = new GameEntity("test_map");
assertTrue(game.started);
assertEquals("test_map", game.mapPath);
}
@Test
@DisplayName("GameStop")
public void testGameStop() {
GameEntity game = new GameEntity("map");
game.stop();
assertFalse(game.started);
assertNull(GameEntity.INSTANCE);
}
@Test
@DisplayName("GameSetMap")
public void testGameSetMap() {
GameEntity game = new GameEntity("map");
TileEntity[][] map = new TileEntity[2][2];
game.map = map;
assertNotNull(game.map);
assertEquals(2, game.map.length);
}
@Test
@DisplayName("TileGrassWalkable")
public void testGrassWalkable() {
TileEntity tile = new TileEntity('G', 'N');
assertTrue(tile.isWalkable());
}
@Test
@DisplayName("TileSandWalkable")
public void testSandWalkable() {
TileEntity tile = new TileEntity('S', 'N');
assertTrue(tile.isWalkable());
}
@Test
@DisplayName("TileRockWalkable")
public void testRockWalkable() {
TileEntity tile = new TileEntity('R', 'N');
assertTrue(tile.isWalkable());
}
@Test
@DisplayName("TileWaterNotWalkable")
public void testWaterNotWalkable() {
TileEntity tile = new TileEntity('W', 'N');
assertFalse(tile.isWalkable());
}
@Test
@DisplayName("TileMountainNotWalkable")
public void testMountainNotWalkable() {
TileEntity tile = new TileEntity('M', 'N');
assertFalse(tile.isWalkable());
}
@Test
@DisplayName("TileLavaNotWalkable")
public void testLavaNotWalkable() {
TileEntity tile = new TileEntity('L', 'N');
assertFalse(tile.isWalkable());
}
@Test
@DisplayName("TileCollectible")
public void testTileCollectible() {
TileEntity tile = new TileEntity('G', 'Y');
assertEquals('Y', tile.collectible);
assertEquals('G', tile.terrain);
}
@Test
@DisplayName("DirectionUp")
public void testDirectionUp() {
Point p = Direction.UP.getPoint();
assertEquals(0, p.getPosX());
assertEquals(-1, p.getPosY());
}
@Test
@DisplayName("DirectionDown")
public void testDirectionDown() {
Point p = Direction.DOWN.getPoint();
assertEquals(0, p.getPosX());
assertEquals(1, p.getPosY());
}
@Test
@DisplayName("DirectionLeft")
public void testDirectionLeft() {
Point p = Direction.LEFT.getPoint();
assertEquals(-1, p.getPosX());
assertEquals(0, p.getPosY());
}
@Test
@DisplayName("DirectionRight")
public void testDirectionRight() {
Point p = Direction.RIGHT.getPoint();
assertEquals(1, p.getPosX());
assertEquals(0, p.getPosY());
}
@Test
@DisplayName("PointCreation")
public void testPointCreation() {
Point p = new Point(5, 10);
assertEquals(5, p.getPosX());
assertEquals(10, p.getPosY());
}
@Test
@DisplayName("GameInstance")
public void testGameInstance() {
GameEntity g1 = new GameEntity("map1");
assertSame(GameEntity.INSTANCE, g1);
}
@Test
@DisplayName("MapGrid")
public void testMapGrid() {
TileEntity[][] map = new TileEntity[3][3];
map[0][0] = new TileEntity('G', 'N');
map[1][1] = new TileEntity('W', 'N');
map[2][2] = new TileEntity('R', 'Y');
assertTrue(map[0][0].isWalkable());
assertFalse(map[1][1].isWalkable());
assertTrue(map[2][2].isWalkable());
}
@Test
@DisplayName("YakamonTile")
public void testYakamonTile() {
TileEntity tile = new TileEntity('G', 'b');
assertEquals('b', tile.collectible);
assertTrue(tile.isWalkable());
}
@Test
@DisplayName("ItemTile")
public void testItemTile() {
TileEntity tile = new TileEntity('S', 'S');
assertEquals('S', tile.collectible);
assertTrue(tile.isWalkable());
}
}

View file

@ -0,0 +1,457 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("TeamResourceTest")
public class TeamResourceTest {
private static final String VALID_UUID =
"550e8400-e29b-41d4-a716-446655440000";
private static final String ANOTHER_UUID =
"6ba7b810-9dad-11d1-80b4-00c04fd430c8";
@Test
@DisplayName("GET /team without game returns 400")
public void testGetTeamWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.get("/team")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /team returns JSON")
public void testGetTeamContentType() {
given()
.contentType(ContentType.JSON)
.when()
.get("/team")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /team/{uuid}/evolve without game returns 400")
public void testEvolveWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.post("/team/" + VALID_UUID + "/evolve")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/evolve with blank uuid returns 400")
public void testEvolveWithBlankUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.post("/team//evolve")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/evolve with valid uuid returns 200")
public void testEvolveWithValidUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.post("/team/" + VALID_UUID + "/evolve")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /team/{uuid}/evolve returns JSON")
public void testEvolveContentType() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.post("/team/" + VALID_UUID + "/evolve")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("POST /team/{uuid}/feed without game returns 400")
public void testFeedWithoutGameStarted() {
String requestBody = "{\"quantity\": 10}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed with blank uuid returns 400")
public void testFeedWithBlankUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": 10}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team//feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed with null quantity returns 400")
public void testFeedWithNullQuantity() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": null}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed with zero quantity returns 400")
public void testFeedWithZeroQuantity() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": 0}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed with negative quantity returns 400")
public void testFeedWithNegativeQuantity() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": -5}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed with valid quantity returns 200")
public void testFeedWithValidQuantity() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": 10}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(200);
}
@Test
@DisplayName("POST /team/{uuid}/feed without body returns 400")
public void testFeedWithMissingRequestBody() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.statusCode(400);
}
@Test
@DisplayName("POST /team/{uuid}/feed returns JSON")
public void testFeedContentType() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"quantity\": 10}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.post("/team/" + VALID_UUID + "/feed")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("DELETE /team/{uuid}/release without game returns 400")
public void testReleaseWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.delete("/team/" + VALID_UUID + "/release")
.then()
.statusCode(400);
}
@Test
@DisplayName("DELETE /team/{uuid}/release with blank uuid returns 400")
public void testReleaseWithBlankUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.delete("/team//release")
.then()
.statusCode(400);
}
@Test
@DisplayName("DELETE /team/{uuid}/release with valid uuid returns 204")
public void testReleaseWithValidUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.delete("/team/" + VALID_UUID + "/release")
.then()
.statusCode(204);
}
@Test
@DisplayName("DELETE /team/{uuid}/release multiple times")
public void testReleaseWithMultipleUuids() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.delete("/team/" + VALID_UUID + "/release")
.then()
.statusCode(204);
given()
.contentType(ContentType.JSON)
.when()
.delete("/team/" + ANOTHER_UUID + "/release")
.then()
.statusCode(204);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename without game returns 400")
public void testRenameWithoutGameStarted() {
String requestBody = "{\"newNickname\": \"NewName\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.patch("/team/" + VALID_UUID + "/rename")
.then()
.statusCode(400);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename with blank uuid returns 400")
public void testRenameWithBlankUuid() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"newNickname\": \"NewName\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.patch("/team//rename")
.then()
.statusCode(400);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename without body returns 400")
public void testRenameWithMissingRequestBody() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.patch("/team/" + VALID_UUID + "/rename")
.then()
.statusCode(400);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename with valid request returns 200")
public void testRenameWithValidRequest() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"newNickname\": \"NewName\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.patch("/team/" + VALID_UUID + "/rename")
.then()
.statusCode(200);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename returns JSON")
public void testRenameContentType() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"newNickname\": \"NewName\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.patch("/team/" + VALID_UUID + "/rename")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("PATCH /team/{uuid}/rename with special characters")
public void testRenameWithSpecialCharacters() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
String requestBody = "{\"newNickname\": \"New-Name_123\"}";
given()
.contentType(ContentType.JSON)
.body(requestBody)
.when()
.patch("/team/" + VALID_UUID + "/rename")
.then()
.statusCode(200);
}
}

View file

@ -0,0 +1,328 @@
package fr.epita.assistants.yakamon_testsuite;
import static io.restassured.RestAssured.given;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@QuarkusTest
@DisplayName("YakadexResourceTest")
public class YakadexResourceTest {
@Test
@DisplayName("GET /yakadex without game returns 400")
public void testGetYakadexWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /yakadex returns 200 when game started")
public void testGetYakadexWithGameStarted() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex with only_missing=true")
public void testGetYakadexWithOnlyMissingTrue() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.queryParam("only_missing", true)
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex with only_missing=false")
public void testGetYakadexWithOnlyMissingFalse() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.queryParam("only_missing", false)
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex with only_missing=TRUE uppercase")
public void testGetYakadexWithOnlyMissingUppercase() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.queryParam("only_missing", "TRUE")
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex returns JSON")
public void testGetYakadexContentType() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /yakadex/{id} without game returns 400")
public void testGetYakadexByIdWithoutGameStarted() {
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/1")
.then()
.statusCode(400);
}
@Test
@DisplayName("GET /yakadex/{id} with valid id")
public void testGetYakadexByIdWithGameStarted() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/1")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex/{id} with id=0")
public void testGetYakadexByIdWithZero() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/0")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex/{id} with negative id returns 404")
public void testGetYakadexByIdWithNegativeId() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/-1")
.then()
.statusCode(404);
}
@Test
@DisplayName("GET /yakadex/{id} with large id")
public void testGetYakadexByIdWithLargeId() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/999999")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex/{id} returns JSON")
public void testGetYakadexByIdContentType() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/1")
.then()
.contentType(ContentType.JSON);
}
@Test
@DisplayName("GET /yakadex/{id} multiple different ids")
public void testGetYakadexByIdMultipleIds() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
int[] ids = { 1, 2, 5, 10, 42, 100 };
for (int id : ids) {
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/" + id)
.then()
.statusCode(200);
}
}
@Test
@DisplayName("GET /yakadex/{id} with id=-2 returns 404")
public void testGetYakadexByIdWithAnotherNegativeId() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/-2")
.then()
.statusCode(404);
}
@Test
@DisplayName("GET /yakadex/{id} with id=-100 returns 404")
public void testGetYakadexByIdWithLargeNegativeId() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex/-100")
.then()
.statusCode(404);
}
@Test
@DisplayName("GET /yakadex without query params")
public void testGetYakadexWithoutQueryParams() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
@Test
@DisplayName("GET /yakadex multiple calls")
public void testGetYakadexMultipleCalls() {
String startRequest =
"{\"mapPath\": \"map1.txt\", \"playerName\": \"TestPlayer\"}";
given()
.contentType(ContentType.JSON)
.body(startRequest)
.when()
.post("/start/");
for (int i = 0; i < 3; i++) {
given()
.contentType(ContentType.JSON)
.when()
.get("/yakadex")
.then()
.statusCode(200);
}
}
}