diff --git a/CHANGELOG.md b/CHANGELOG.md index f4c9af9..00677bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # 📈 LIST OF CHANGES FOR WEREWOLVES ASSISTANT API +## 0.5.3 (2020-08-17) + +### 🐛 Bug fixes + +* Correct order for actions when game's phase is `day`. + +--- + ## 0.5.2 (2020-08-17) ### 🐛 Bug fixes diff --git a/config/apidoc/apidoc.json b/config/apidoc/apidoc.json index 7a6bdc1..72f338a 100755 --- a/config/apidoc/apidoc.json +++ b/config/apidoc/apidoc.json @@ -1,6 +1,6 @@ { "name": "\uD83D\uDC3A Werewolves Assistant API", - "version": "0.5.2", + "version": "0.5.3", "description": "Werewolves Assistant API provides over HTTP requests a way of manage Werewolves games in order to help the game master in his task.", "header": { "title": "Classes", diff --git a/package.json b/package.json index 3c3373c..9d0dc95 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "werewolwes-assistant-api", - "version": "0.5.2", + "version": "0.5.3", "description": "Back end for the werewolves assistant", "main": "app.js", "scripts": { diff --git a/src/controllers/Player.js b/src/controllers/Player.js index 9ece483..ef58909 100644 --- a/src/controllers/Player.js +++ b/src/controllers/Player.js @@ -94,6 +94,15 @@ exports.checkAndFillTargets = async(targets, game, options) => { await this.checkAllTargetsDependingOnAction(targets, game, options.action); }; +exports.insertActionBeforeAllVote = (game, waiting) => { + const waitingForAllToVoteIdx = game.waiting.findIndex(({ to }) => to === "vote"); + if (waitingForAllToVoteIdx !== -1 && waitingForAllToVoteIdx !== 0) { + game.waiting.splice(waitingForAllToVoteIdx, 0, waiting); + } else { + game.waiting.push(waiting); + } +}; + exports.killPlayer = (playerId, { action }, game) => { const player = game.players.find(({ _id, isAlive }) => _id.toString() === playerId.toString() && isAlive); if (player && (action === "eat" && canBeEaten(player) || action !== "eat" && !hasAttribute(player, "protected"))) { @@ -102,10 +111,10 @@ exports.killPlayer = (playerId, { action }, game) => { if (murdered) { player.murdered = murdered; if (player.role.current === "hunter") { - game.waiting.push({ for: "hunter", to: "shoot" }); + this.insertActionBeforeAllVote(game, { for: "hunter", to: "shoot" }); } if (hasAttribute(player, "sheriff")) { - game.waiting.push({ for: "sheriff", to: "delegate" }); + this.insertActionBeforeAllVote(game, { for: "sheriff", to: "delegate" }); } } } diff --git a/src/routes/index.js b/src/routes/index.js index 224130d..7345818 100755 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -12,7 +12,7 @@ module.exports = app => { * @apiSuccess {String} version API's version */ app.route("/").get((req, res) => { - res.status(200).json({ name: "🐺 Werewolves Assistant API", version: "0.5.2" }); + res.status(200).json({ name: "🐺 Werewolves Assistant API", version: "0.5.3" }); }); return; } diff --git a/tests/e2e/game/hunter-kills-mayor-on-day-time.test.js b/tests/e2e/game/hunter-kills-mayor-on-day-time.test.js new file mode 100644 index 0000000..ac3bff0 --- /dev/null +++ b/tests/e2e/game/hunter-kills-mayor-on-day-time.test.js @@ -0,0 +1,111 @@ +const { describe, it, before, after } = require("mocha"); +const chai = require("chai"); +const chaiHttp = require("chai-http"); +const app = require("../../../app"); +const Config = require("../../../config"); +const { resetDatabase } = require("../../../src/helpers/functions/Test"); + +chai.use(chaiHttp); +const { expect } = chai; + +const credentials = { email: "test@test.fr", password: "secret" }; +const players = [ + { name: "Dug", role: "hunter" }, // O + { name: "Dig", role: "villager" }, // 1 + { name: "Deg", role: "werewolf" }, // 2 + { name: "Dog", role: "werewolf" }, // 3 +]; +let token, game; + +// eslint-disable-next-line max-lines-per-function +describe("H - Game where hunter kills mayor when day rises", () => { + before(done => resetDatabase(done)); + after(done => resetDatabase(done)); + it("👤 Creates new user (POST /users)", done => { + chai.request(app) + .post("/users") + .auth(Config.app.basicAuth.username, Config.app.basicAuth.password) + .send(credentials) + .end((err, res) => { + expect(res).to.have.status(200); + done(); + }); + }); + it("🔑 Logs in successfully (POST /users/login)", done => { + chai.request(app) + .post(`/users/login`) + .auth(Config.app.basicAuth.username, Config.app.basicAuth.password) + .send(credentials) + .end((err, res) => { + expect(res).to.have.status(200); + token = res.body.token; + done(); + }); + }); + it("🎲 Creates game with JWT auth (POST /games)", done => { + chai.request(app) + .post("/games") + .set({ "Authorization": `Bearer ${token}` }) + .send({ players }) + .end((err, res) => { + expect(res).to.have.status(200); + game = res.body; + done(); + }); + }); + it("👪 All elect a werewolf as the sheriff (POST /games/:id/play)", done => { + const { players } = game; + chai.request(app) + .post(`/games/${game._id}/play`) + .set({ "Authorization": `Bearer ${token}` }) + .send({ source: "all", action: "elect-sheriff", votes: [ + { from: players[0]._id, for: players[2]._id }, + { from: players[1]._id, for: players[2]._id }, + ] }) + .end((err, res) => { + expect(res).to.have.status(200); + game = res.body; + expect(game.players[2].attributes).to.deep.include({ attribute: "sheriff", source: "all" }); + expect(game.history[0].play.votes).to.exist; + done(); + }); + }); + it("🐺 Werewolves eat the hunter (POST /games/:id/play)", done => { + const { players } = game; + chai.request(app) + .post(`/games/${game._id}/play`) + .set({ "Authorization": `Bearer ${token}` }) + .send({ source: "werewolves", action: "eat", targets: [ + { player: players[0]._id }, + ] }) + .end((err, res) => { + expect(res).to.have.status(200); + game = res.body; + done(); + }); + }); + it("☀️ Sun is rising and hunter is dead", done => { + expect(game.phase).to.equals("day"); + expect(game.players[0].isAlive).to.equals(false); + done(); + }); + it("🔫 Hunter shoots at the sheriff werewolf (POST /games/:id/play)", done => { + const { players } = game; + chai.request(app) + .post(`/games/${game._id}/play`) + .set({ "Authorization": `Bearer ${token}` }) + .send({ source: "hunter", action: "shoot", targets: [ + { player: players[2]._id }, + ] }) + .end((err, res) => { + expect(res).to.have.status(200); + game = res.body; + expect(game.players[2].isAlive).to.equals(false); + done(); + }); + }); + it("🎲 Game is waiting for 'sheriff' to 'delegate'", done => { + expect(game.waiting[0]).to.deep.equals({ for: "sheriff", to: "delegate" }); + done(); + }); +}); \ No newline at end of file diff --git a/tests/e2e/game/index.js b/tests/e2e/game/index.js index c9e6d4b..15b9187 100644 --- a/tests/e2e/game/index.js +++ b/tests/e2e/game/index.js @@ -8,4 +8,5 @@ describe("E2E - 🎲 Game tests", () => { require("./game-repartition.test"); require("./raven-marked-dead-player-game.test"); require("./kill-player-twice-game.test"); + require("./hunter-kills-mayor-on-day-time.test"); }); \ No newline at end of file