package no.asgari.civilization.server.resource;
import no.asgari.civilization.server.SheetName;
import no.asgari.civilization.server.action.DrawAction;
import no.asgari.civilization.server.action.PlayerAction;
import no.asgari.civilization.server.dto.ItemDTO;
import no.asgari.civilization.server.model.Civ;
import no.asgari.civilization.server.model.GameLog;
import no.asgari.civilization.server.model.Infantry;
import no.asgari.civilization.server.model.Item;
import no.asgari.civilization.server.model.PBF;
import no.asgari.civilization.server.model.Playerhand;
import no.asgari.civilization.server.model.Tech;
import no.asgari.civilization.server.mongodb.AbstractCivilizationTest;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.Before;
import org.junit.Test;
import org.mongojack.DBCursor;
import org.mongojack.DBQuery;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.Optional;
import java.util.Set;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
public class PlayerResourceTest extends AbstractCivilizationTest {
protected static String BASE_URL = String.format("http://localhost:%d/api", RULE.getLocalPort());
@Before
public void ensureCurrentPlayer() {
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
Playerhand playerhand = pbf.getPlayers().stream()
.filter(p -> p.getPlayerId().equals(getApp().playerId))
.findFirst().get();
playerhand.setYourTurn(true);
getApp().pbfCollection.updateById(getApp().pbfId, pbf);
}
@Test
public void chooseTechThenRevealThenDelete() throws Exception {
final String techToResearch = "Pottery";
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/tech/choose", getApp().pbfId)).build();
Response response = client().target(uri)
.queryParam("name", techToResearch)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertThat(response.getStatus()).isEqualTo(HttpStatus.NO_CONTENT_204);
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
Optional<Playerhand> cash1981 = pbf.getPlayers().stream()
.filter(p -> p.getUsername().equals("cash1981"))
.findFirst();
assertTrue(cash1981.isPresent());
assertThat(cash1981.get().getTechsChosen()).isNotEmpty();
assertThat(cash1981.get().getTechsChosen()).contains(new Tech("Pottery", Tech.LEVEL_1, 0));
//reveal it
DBCursor<GameLog> gameLogs = getApp().gameLogCollection.find(DBQuery.is("pbfId", getApp().pbfId));
if (!gameLogs.hasNext()) {
fail("Should have gamelog");
}
while (gameLogs.hasNext()) {
GameLog gameLog = gameLogs.next();
if (gameLog.getPrivateLog() != null && gameLog.getPrivateLog().matches(".*researched Pottery.*")) {
uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/tech/reveal/%s", getApp().pbfId, gameLog.getId())).build();
response = client().target(uri).request()
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
}
}
//Now remove it
uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/tech/remove", getApp().pbfId)).build();
response = client().target(uri)
.queryParam("name", techToResearch)
.request()
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.delete(Response.class);
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK_200);
}
@Test
public void endTurnAndChooseNextPlayer() throws Exception {
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
int i = -1;
Playerhand nextPlayer = null;
boolean found = false;
for (Playerhand p : pbf.getPlayers()) {
i++;
if (p.getUsername().equals("cash1981")) {
nextPlayer = pbf.getPlayers().get(++i);
assertFalse(nextPlayer.isYourTurn());
found = true;
break;
}
}
assertTrue(found);
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/endturn", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertThat(response.getStatus()).isEqualTo(HttpStatus.NO_CONTENT_204);
pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
found = false;
for (Playerhand p : pbf.getPlayers()) {
if (p.equals(nextPlayer)) {
assertTrue(p.isYourTurn());
found = true;
break;
}
}
assertTrue(found);
}
@Test
public void testThatYouCanTradeItems() throws Exception {
//Find another player
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
String anotherPlayerId = getAnotherplayerId(pbf);
assertNotNull(anotherPlayerId);
Optional<Item> item = getItemFromPlayerhand(pbf, SheetName.VILLAGES);
if (!item.isPresent()) {
testDrawVillage();
item = getItemFromPlayerhand(pbf, SheetName.VILLAGES);
}
assertTrue(item.isPresent());
ItemDTO itemDTO = createItemDTO(SheetName.VILLAGES, item.get().getName());
itemDTO.setOwnerId(anotherPlayerId);
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/trade", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.OK_200, response.getStatus());
//Check
pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
Playerhand cash1981 = pbf.getPlayers().stream()
.filter(p -> p.getUsername().equals("cash1981"))
.findFirst().get();
Playerhand anotherPlayer = pbf.getPlayers().stream()
.filter(p -> p.getPlayerId().equals(anotherPlayerId))
.findFirst().get();
assertThat(cash1981.getItems()).doesNotContain(item.get());
assertThat(anotherPlayer.getItems()).contains(item.get());
}
private String getAnotherplayerId(PBF pbf) {
return pbf.getPlayers().stream()
.filter(p -> !p.getUsername().equals("cash1981"))
.findFirst().get().getPlayerId();
}
@Test
public void checkThatYouGetExceptionWhenTradingStuffWhichIsNotAllowed() throws Exception {
testDrawArtilleryCard();
//Find another player
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
String anotherPlayerId = getAnotherplayerId(pbf);
assertNotNull(anotherPlayerId);
Item artillery = pbf.getPlayers().stream()
.filter(p -> p.getUsername().equals("cash1981"))
.findFirst().get()
.getItems().stream()
.filter(fil -> fil.getSheetName() == SheetName.ARTILLERY)
.findFirst().get();
assertNotNull(artillery);
ItemDTO itemDTO = new ItemDTO();
itemDTO.setSheetName(SheetName.ARTILLERY.name());
itemDTO.setName(artillery.getName());
itemDTO.setOwnerId(anotherPlayerId);
itemDTO.setPbfId(getApp().pbfId);
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/trade", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.NOT_FOUND_404, response.getStatus());
}
@Test
public void testDrawCultureCard() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, SheetName.CULTURE_1)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testRevealItem() throws Exception {
DrawAction drawAction = new DrawAction(getApp().db);
//Before draw
Optional<GameLog> gameLogOptional = drawAction.draw(getApp().pbfId, getApp().playerId, SheetName.INFANTRY);
assertTrue(gameLogOptional.isPresent());
assertThat(gameLogOptional.get().getDraw().getItem()).isExactlyInstanceOf(Infantry.class);
assertTrue(gameLogOptional.get().getDraw().getItem().isHidden());
GameLog gameLog = getApp().gameLogCollection.findOneById(gameLogOptional.get().getId());
if (gameLog.getDraw() != null && gameLog.getDraw().getItem() != null && gameLog.getPbfId().equals(getApp().pbfId)) {
ItemDTO itemDTO = new ItemDTO();
itemDTO.setSheetName(SheetName.INFANTRY.name());
itemDTO.setName(gameLog.getDraw().getItem().getName());
itemDTO.setPbfId(getApp().pbfId);
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/item/reveal", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.put(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.OK_200, response.getStatus());
} else {
fail("Should have gamelog");
}
}
@Test
public void chooseCiv() throws Exception {
DrawAction drawAction = new DrawAction(getApp().db);
SheetName CIV = SheetName.find("CIV").get();
Optional<GameLog> gameLogOptional = drawAction.draw(getApp().pbfId, getApp().playerId, CIV);
ItemDTO itemDTO = new ItemDTO();
itemDTO.setSheetName(SheetName.CIV.name());
itemDTO.setName(gameLogOptional.get().getDraw().getItem().getName());
itemDTO.setPbfId(getApp().pbfId);
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/item/reveal", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.put(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.OK_200, response.getStatus());
//Make sure tech is gotten
PlayerAction playerAction = new PlayerAction(getApp().db);
Set<Tech> playersTechs = playerAction.getPlayersTechs(getApp().pbfId, getApp().playerId);
assertThat(playersTechs).contains(((Civ)gameLogOptional.get().getDraw().getItem()).getStartingTech());
}
@Test
public void testDrawInfantryCard() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, SheetName.INFANTRY)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testDrawArtilleryCard() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, SheetName.ARTILLERY)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testDrawGreatPersonCard() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, SheetName.GREAT_PERSON)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testDrawVillage() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, SheetName.VILLAGES)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void testTech() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/tech/%s", getApp().pbfId, SheetName.LEVEL_1_TECH)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(response.getStatus(), HttpStatus.METHOD_NOT_ALLOWED_405);
}
@Test
public void testDrawingInvalid() throws Exception {
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/draw/%s/%s", getApp().pbfId, "foobar")).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(response.getStatus(), HttpStatus.NOT_FOUND_404);
}
@Test
public void discardItem() throws Exception {
testDrawVillage();
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
assertThat(pbf.getDiscardedItems()).isEmpty();
Item village = getItemFromPlayerhand(pbf, SheetName.VILLAGES).get();
assertNotNull(village);
ItemDTO itemDTO = createItemDTO(SheetName.VILLAGES, village.getName());
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/item/discard", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.OK_200, response.getStatus());
pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
assertThat(pbf.getDiscardedItems()).isNotEmpty();
}
@Test
public void discardUnit() throws Exception {
testDrawInfantryCard();
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
Item infantry = getItemFromPlayerhand(pbf, SheetName.INFANTRY).get();
assertNotNull(infantry);
ItemDTO itemDTO = createItemDTO(SheetName.INFANTRY, infantry.getName());
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/item/discard", getApp().pbfId)).build();
Response response = client().target(uri)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(Entity.json(itemDTO), Response.class);
assertEquals(HttpStatus.OK_200, response.getStatus());
}
@Test
public void chooseSocialPolicyThenFlipside() throws Exception {
PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
long socialPolicies = pbf.getPlayers()
.stream()
.flatMap(p -> p.getSocialPolicies().stream())
.count();
assertEquals(0, socialPolicies);
String spToChoose = "Rationalism";
URI uri = UriBuilder.fromPath(String.format(BASE_URL + "/player/%s/socialpolicy/choose", getApp().pbfId)).build();
Response response = client().target(uri)
.queryParam("name", spToChoose)
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.NO_CONTENT_204, response.getStatus());
pbf = getApp().pbfCollection.findOneById(getApp().pbfId);
socialPolicies = pbf.getPlayers()
.stream()
.flatMap(p -> p.getSocialPolicies().stream())
.count();
assertEquals(1, socialPolicies);
response = client().target(uri)
.queryParam("name", "Patronage")
.request(MediaType.APPLICATION_JSON)
.header(HttpHeaders.AUTHORIZATION, getUsernameAndPassEncoded())
.post(null);
assertEquals(HttpStatus.BAD_REQUEST_400, response.getStatus());
}
private ItemDTO createItemDTO(SheetName sheetName, String itemName) {
ItemDTO itemDTO = new ItemDTO();
itemDTO.setSheetName(sheetName.name());
itemDTO.setName(itemName);
itemDTO.setOwnerId(getApp().playerId);
itemDTO.setPbfId(getApp().pbfId);
return itemDTO;
}
private Optional<Item> getItemFromPlayerhand(PBF pbf, SheetName sheetName) {
return pbf.getPlayers().stream()
.filter(p -> p.getUsername().equals("cash1981"))
.findFirst().get()
.getItems().stream()
.filter(fil -> fil.getSheetName() == sheetName)
.findFirst();
}
}