test.test.ts 4.33 KB
import ioclient, { Socket } from "socket.io-client";
import { expect } from "chai";
import { Server } from "./Server";
import { response } from "express";
import {
  RawMessage,
  ServerInboundMessage,
  ServerInboundMessageKey,
  ServerOutboundMessage,
  ServerOutboundMessageKey,
  ServerResponse,
} from "../common";

describe("server", () => {
  const PORT = 3000;

  var server: Server;
  var client1: Socket;
  var client2: Socket;

  before((done) => {
    let connected = 0;

    client1 = ioclient(`http://localhost:${PORT}`);
    client1.on("connect", () => ++connected == 2 && done());

    client2 = ioclient(`http://localhost:${PORT}`);
    client2.on("connect", () => ++connected == 2 && done());

    server = new Server(3000);
  });

  after(() => {
    server.close();
    client1.close();
    client2.close();
  });

  var roomUserUpdateMessage: ServerOutboundMessage<"updateRoomUser">;
  var roomChatMessage: ServerOutboundMessage<"chat">;

  const send = <T extends ServerInboundMessageKey>(
    socket: Socket,
    type: T,
    message: ServerInboundMessage<T>,
    callback: (response: ServerResponse<T>) => void
  ) => {
    socket.emit(
      "msg",
      {
        type: type as string,
        message: message,
      },
      callback
    );
  };

  step("register listeners", () => {
    client1.on("msg", (raw: RawMessage) => {
      if (raw.type == "updateRoomUser") roomUserUpdateMessage = raw.message;
    });

    client1.on("msg", (raw: RawMessage) => {
      if (raw.type == "chat") roomChatMessage = raw.message;
    });
  });

  step("login 1", (done) => {
    send(
      client1,
      "login",
      {
        username: "guest1",
      },
      (response) => {
        expect(response.ok).to.eq(true);
        done();
      }
    );
  });

  step("login 2", (done) => {
    send(
      client2,
      "login",
      {
        username: "guest2",
      },
      (response) => {
        expect(response.ok).to.eq(true);
        done();
      }
    );
  });

  var roomToJoin: string;

  step("room list", (done) => {
    send(client1, "roomList", {}, (response) => {
      expect(response.ok).to.eq(true);
      expect(response.result !== undefined).to.eq(true);
      if (response.result) {
        expect(response.result[0].name).to.eq("테스트 방 #1");
        roomToJoin = response.result[0].uuid;
      }
      done();
    });
  });

  step("room join 1", (done) => {
    send(client1, "joinRoom", { uuid: roomToJoin }, (response) => {
      expect(response.ok).to.eq(true);
      expect(response.result !== undefined).to.eq(true);
      if (response.result) {
        expect(response.result.uuid).to.eq(roomToJoin);
        expect(response.result.users.length).to.eq(1);
        expect(response.result.users[0].username).to.eq("guest1");
      }
      done();
    });
  });

  step("room join 2", (done) => {
    send(client2, "joinRoom", { uuid: roomToJoin }, (response) => {
      expect(response.ok).to.eq(true);
      expect(response.result !== undefined).to.eq(true);
      if (response.result) {
        expect(response.result.uuid).to.eq(roomToJoin);
        expect(response.result.users.length).to.eq(2);
      }
      done();
    });
  });

  // TODO: RoomUserUpdateMessage가 아직 도착하지 않았는데 실행되는 경우
  step("client 1 received user update", () => {
    expect(roomUserUpdateMessage !== undefined).to.eq(true);
    if (roomUserUpdateMessage) {
      expect(roomUserUpdateMessage.state).to.eq("added");
      expect(roomUserUpdateMessage.user.username).to.eq("guest2");
    }
  });

  step("client 2 send chat", (done) => {
    send(client2, "chat", { message: "Hello World" }, (response) => {
      expect(response.ok).to.eq(true);
      done();
    });
  });

  step("client 1 received chat", () => {
    expect(roomChatMessage !== undefined).to.eq(true);
    if (roomChatMessage) {
      expect(roomChatMessage.sender).to.eq("guest2");
      expect(roomChatMessage.message).to.eq("Hello World");
    }
  });

  step("client 2 leave", (done) => {
    send(client2, "leaveRoom", {}, (response) => {
      expect(response.ok).to.eq(true);
      done();
    });
  });

  step("client 1 received user update", () => {
    expect(roomUserUpdateMessage !== undefined).to.eq(true);
    if (roomUserUpdateMessage) {
      expect(roomUserUpdateMessage.state).to.eq("removed");
      expect(roomUserUpdateMessage.user.username).to.eq("guest2");
    }
  });
});