round.test.ts 8.28 KB
import { expect } from "chai";
import { prepareGame } from "./util/prepare";

describe("라운드", () => {
  it("첫 라운드가 시작되면 startRound와 wordSet을 받습니다", () => {
    const {
      sockets: [socket1, socket2],
      drawerSocket,
    } = prepareGame(2);

    expect(socket1.socket.received("startRound").round).eq(1);
    expect(socket2.socket.received("startRound").round).eq(1);

    // drawer는 wordSet을 받습니다.
    expect(drawerSocket.socket.received("wordSet").words.length).eq(3);
  });
  it("drawer가 단어를 선택하면 모두가 wordChosen과 timer를 받습니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(2);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    expect(drawerSocket.socket.received("wordChosen").length).eq(word.length);
    expect(guesserSockets[0].socket.received("wordChosen").length).eq(
      word.length
    );

    let timerSettings = drawerSocket.socket.received("timer");
    expect(timerSettings.state).eq(timerSettings.state);
    expect(timerSettings.time).greaterThan(59);
  });
  it("drawer가 단어를 선택하지 않으면 라운드가 진행되지 않습니다", (done) => {
    const { drawerSocket, guesserSockets } = prepareGame(2, 5, 0.1);

    // 0.2초 뒤에도 라운드가 종료되지 않습니다.
    setTimeout(() => {
      drawerSocket.socket.notReceived("finishRound");
      guesserSockets[0].socket.notReceived("finishRound");
      done();
    }, 200);
  });
  it("아무도 단어를 맞추지 못하고 시간이 지나면 라운드가 종료됩니다", (done) => {
    const { drawerSocket, guesserSockets } = prepareGame(2, 5, 0.2);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    // 0.1초 뒤에는 라운드가 종료되지 않습니다.
    setTimeout(() => {
      drawerSocket.socket.notReceived("finishRound");
      guesserSockets[0].socket.notReceived("finishRound");
    }, 100);
    // 0.3초 뒤에는 라운드가 종료됩니다.
    setTimeout(() => {
      expect(drawerSocket.socket.received("finishRound").answer).eq(word);
      expect(guesserSockets[0].socket.received("finishRound").answer).eq(word);
      done();
    }, 300);
  });
  it("모든 guesser가 단어를 맞추면 라운드가 종료됩니다", (done) => {
    const { drawerSocket, guesserSockets } = prepareGame(3, 5, 0.5);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    // 0.1초 뒤에는 라운드가 종료되지 않습니다.
    setTimeout(() => {
      drawerSocket.socket.notReceived("finishRound");

      // 첫번째 guesser가 단어를 맞춥니다.
      guesserSockets[0].testOk("chat", { message: word });
      expect(guesserSockets[0].socket.received("answerAccepted").answer).eq(
        word
      );
    }, 100);
    // 0.2초 뒤에도 라운드가 종료되지 않습니다.
    setTimeout(() => {
      drawerSocket.socket.notReceived("finishRound");

      // 두번째 guesser가 단어를 맞춥니다.
      guesserSockets[1].testOk("chat", { message: word });
      expect(guesserSockets[1].socket.received("answerAccepted").answer).eq(
        word
      );
    }, 200);
    // 0.3초 뒤에는 라운드가 종료됩니다.
    setTimeout(() => {
      drawerSocket.socket.received("finishRound");
      done();
    }, 300);
  });
  it("drawer가 단어를 선택하지 않고 나가면 즉시 라운드가 다시 시작됩니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(3);
    guesserSockets[0].socket.received("startRound");

    guesserSockets[0].socket.notReceived("startRound");
    drawerSocket.disconnect();
    expect(guesserSockets[0].socket.received("startRound").round).eq(1);
  });
  it("drawer가 단어를 선택하지 않고 모든 guesser가 나가면 인원이 부족하므로 게임이 종료됩니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(3);

    drawerSocket.socket.notReceived("finishRound");
    guesserSockets[0].disconnect();
    drawerSocket.socket.notReceived("finishRound");
    guesserSockets[1].disconnect();
    // 단어가 선택되지 않았으므로 finishRound가 수신되지 않습니다.
    drawerSocket.socket.received("finishGame");
  });
  it("drawer가 단어를 선택하고 모든 guesser가 나가면 인원이 부족하므로 게임이 종료됩니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(3);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    drawerSocket.socket.notReceived("finishRound");
    guesserSockets[0].disconnect();
    drawerSocket.socket.notReceived("finishRound");
    guesserSockets[1].disconnect();
    drawerSocket.socket.received("finishRound");
    drawerSocket.socket.received("finishGame");
  });
  it("drawer가 단어를 선택하고 나가면 라운드가 종료됩니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(3);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    guesserSockets[0].socket.notReceived("finishRound");
    drawerSocket.disconnect();
    guesserSockets[0].socket.received("finishRound");
    guesserSockets[0].socket.notReceived("finishGame");
  });
  it("라운드가 종료되고 다음 라운드를 기다리는 동안 drawer가 나가도 다음 라운드가 시작됩니다", (done) => {
    const { drawerSocket, guesserSockets } = prepareGame(3, 5, 5, 0.1);
    guesserSockets[0].socket.received("startRound");

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });
    guesserSockets[0].testOk("chat", { message: word });
    guesserSockets[1].testOk("chat", { message: word });

    guesserSockets[0].socket.received("finishRound");
    guesserSockets[0].socket.notReceived("startRound");

    drawerSocket.disconnect();

    setTimeout(() => {
      expect(guesserSockets[0].socket.received("startRound").round).eq(2);
      done();
    }, 200);
  });
  it("라운드가 종료되고 다음 라운드를 기다리는 동안 인원이 부족해지면 게임이 즉시 종료됩니다", () => {
    const { drawerSocket, guesserSockets } = prepareGame(2, 5, 5, 0.1);
    guesserSockets[0].socket.received("startRound");

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });
    guesserSockets[0].testOk("chat", { message: word });

    drawerSocket.socket.received("finishRound");

    guesserSockets[0].disconnect();

    drawerSocket.socket.received("finishGame");
  });
  it("라운드가 종료되면 다음 라운드가 시작됩니다", (done) => {
    const { drawerSocket, guesserSockets } = prepareGame(2, 5, 0.2, 0.2);

    drawerSocket.socket.received("startRound");
    guesserSockets[0].socket.received("startRound");

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    // 0.1초 뒤에는 라운드가 종료되지 않습니다.
    setTimeout(() => {
      drawerSocket.socket.notReceived("finishRound");
      guesserSockets[0].socket.notReceived("finishRound");
    }, 100);
    // 0.3초 뒤에는 라운드가 종료됩니다.
    setTimeout(() => {
      expect(drawerSocket.socket.received("finishRound").answer).eq(word);
      expect(guesserSockets[0].socket.received("finishRound").answer).eq(word);
      drawerSocket.socket.notReceived("startRound");
    }, 300);
    // 0.5초 뒤에는 다음 라운드가 시작됩니다.
    setTimeout(() => {
      expect(drawerSocket.socket.received("startRound").round).eq(2);
      expect(guesserSockets[0].socket.received("startRound").round).eq(2);
      done();
    }, 500);
  });
  it("마지막 라운드가 종료되면 게임이 종료됩니다", (done) => {
    const { drawerSocket } = prepareGame(2, 1, 0.1, 0.2);

    const word = drawerSocket.socket.received("wordSet").words[0];
    drawerSocket.testOk("chooseWord", { word });

    setTimeout(() => {
      drawerSocket.socket.received("finishRound");
      drawerSocket.socket.notReceived("finishGame");
    }, 200);
    setTimeout(() => {
      drawerSocket.socket.received("finishGame");
      done();
    }, 400);
  });
});