package no.asgari.civilization.server.action; import no.asgari.civilization.server.SheetName; import no.asgari.civilization.server.model.Civ; import no.asgari.civilization.server.model.GameLog; import no.asgari.civilization.server.model.Item; import no.asgari.civilization.server.model.PBF; import no.asgari.civilization.server.model.Player; import no.asgari.civilization.server.model.Playerhand; import no.asgari.civilization.server.model.Spreadsheet; import no.asgari.civilization.server.model.Undo; import no.asgari.civilization.server.mongodb.AbstractCivilizationTest; import org.junit.Before; import org.junit.Test; import org.mongojack.DBQuery; import java.util.List; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @SuppressWarnings("unchecked") public class UndoActionTest extends AbstractCivilizationTest { private UndoAction undoAction = new UndoAction(getApp().db); @Before public void before() { if (getApp().gameLogCollection.findOne() == null || getApp().gameLogCollection.findOne().getDraw() == null) { createADrawAndInitiateAVoteForUndo(); } } private String createADrawAndInitiateAVoteForUndo() { //First create one UndoAction //Pick one item PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId); assertThat(pbf).isNotNull(); assertThat(pbf.getItems()).isNotEmpty(); DrawAction drawAction = new DrawAction(getApp().db); Optional<GameLog> gameLogOptional = drawAction.draw(getApp().pbfId, getApp().playerId, SheetName.CIV); assertTrue(gameLogOptional.isPresent()); undoAction.initiateUndo(gameLogOptional.get(), getApp().playerId); assertThat(getApp().gameLogCollection.findOneById(gameLogOptional.get().getId()).getDraw().getUndo().getVotes().size()).isEqualTo(1); return gameLogOptional.get().getId(); } @Test public void performAVoteAndCheckIt() throws Exception { String gamelogId = getApp().gameLogCollection.findOne().getId(); if (getApp().gameLogCollection.findOne().getDraw().getUndo() == null || getApp().gameLogCollection.findOne().getDraw().getUndo().isDone()) { gamelogId = createADrawAndInitiateAVoteForUndo(); } final GameLog gameLog = getApp().gameLogCollection.findOneById(gamelogId); assertThat(gameLog.getDraw().getUndo()).isNotNull(); int votes = gameLog.getDraw().getUndo().getVotes().size(); assertThat(gameLog.getDraw().getUndo().isDone()).isFalse(); List<Playerhand> players = getApp().pbfCollection.findOneById(gameLog.getDraw().getPbfId()).getPlayers(); Optional<Playerhand> anotherPlayer = players.stream() .filter(p -> !gameLog.getDraw().getUndo().getVotes().keySet().contains(p.getPlayerId())) .limit(1) .findFirst(); assertThat(gameLog.getDraw().getUndo().getVotes().size()).isEqualTo(votes); votes = votes + 1; assertThat(anotherPlayer.isPresent()).isTrue(); GameLog vote = undoAction.vote(gameLog, anotherPlayer.get().getPlayerId(), Boolean.TRUE); assertThat(vote.getDraw().getUndo().getVotes().size()).isEqualTo(votes); assertThat(getApp().gameLogCollection.findOneById(gameLog.getId()).getDraw().getUndo().getVotes().size()).isEqualTo(votes); } @Test public void allPlayersVoteYesThenPerformUndo() throws Exception { GameLog gameLog = getApp().gameLogCollection.findOne(); if (gameLog.getDraw().getUndo() == null || gameLog.getDraw().getUndo().isDone()) { String gamelogId = createADrawAndInitiateAVoteForUndo(); gameLog = getApp().gameLogCollection.findOneById(gamelogId); } PBF pbf = getApp().pbfCollection.findOneById(gameLog.getPbfId()); assertFalse(pbf.getItems().contains(gameLog.getDraw().getItem())); pbf = getApp().pbfCollection.findOneById(gameLog.getPbfId()); List<Item> items = pbf.getPlayers().stream().filter(p -> p.getPlayerId().equals(getApp().playerId)).findFirst().get().getItems(); assertTrue(items.contains(gameLog.getDraw().getItem())); final GameLog finalGameLog = gameLog; pbf.getPlayers().stream() .filter(p -> !finalGameLog.getDraw().getUndo().getVotes().keySet().contains(p.getUsername())) .forEach(p -> undoAction.vote(finalGameLog, p.getPlayerId(), Boolean.TRUE)); Undo undo = getApp().gameLogCollection.findOneById(gameLog.getId()).getDraw().getUndo(); assertThat(undo.getVotes()).doesNotContainValue(Boolean.FALSE); assertThat(undo.getResultOfVotes().get()).isTrue(); //Check that item is back final Spreadsheet item = gameLog.getDraw().getItem(); assertThat(item).isInstanceOf(Civ.class); //check that its in the pbf assertTrue(getApp().pbfCollection.findOneById(gameLog.getPbfId()).getItems().contains(item)); } @Test public void checkThatYouCanUndoTech() throws Exception { //Pick one item PBF pbf = getApp().pbfCollection.findOneById(getApp().pbfId); assertThat(pbf).isNotNull(); assertThat(pbf.getItems()).isNotEmpty(); PlayerAction playerAction = new PlayerAction(getApp().db); GameLog gameLog = playerAction.chooseTech(getApp().pbfId, "Navy", getApp().playerId); assertThat(gameLog.getDraw().getUndo()).isNull(); undoAction.initiateUndo(gameLog, getApp().playerId); gameLog = getApp().gameLogCollection.findOneById(gameLog.getId()); assertThat(gameLog.getDraw().getUndo()).isNotNull(); } @Test public void voteAndCountRemaingVotes() throws Exception { GameLog gameLog = getApp().gameLogCollection.findOne(); //make another vote assertThat(gameLog.getDraw().getUndo()).isNotNull(); gameLog = undoAction.vote(gameLog, getAnotherPlayerId(), Boolean.TRUE); assertThat(gameLog.getDraw().getUndo().votesRemaining()).isEqualTo(2); } @Test public void getAllActiveUndos() throws Exception { createADrawAndInitiateAVoteForUndo(); List<GameLog> allActiveUndos = undoAction.getAllActiveUndos(getApp().pbfId); assertThat(allActiveUndos).isNotEmpty(); } @Test public void getAllFinishedUndos() throws Exception { allPlayersVoteYesThenPerformUndo(); List<GameLog> allFinishedUndos = undoAction.getAllFinishedUndos(getApp().pbfId); assertThat(allFinishedUndos).isNotEmpty(); } private String getAnotherPlayerId() { //Player anotherPlayer = getApp().playerCollection.findOne(DBQuery.notEquals("_id", getApp().playerId)); Player anotherPlayer = getApp().playerCollection.findOne(DBQuery.is("username", "Itchi")); assertThat(anotherPlayer).isNotNull(); assertThat(anotherPlayer.getId()).isNotEqualTo(getApp().playerId); return anotherPlayer.getId(); } }