Overnap

Merge branch 'develop' into feature/rooms-buttons

...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
22 22
23 특정한 방에 접속하기 위해서는 서버에 `joinRoom`을 보내면 됩니다. 요청이 성공하면 `RoomInfo`가 반환됩니다. `RoomInfo`에는 본인을 포함한 모든 다른 플레이어들의 정보가 담겨 있습니다. 23 특정한 방에 접속하기 위해서는 서버에 `joinRoom`을 보내면 됩니다. 요청이 성공하면 `RoomInfo`가 반환됩니다. `RoomInfo`에는 본인을 포함한 모든 다른 플레이어들의 정보가 담겨 있습니다.
24 24
25 +새로운 방을 만들고 싶다면 `createRoom`을 보내면 됩니다. 방의 이름을 `name` 속성에 담아 보내야 합니다. 방의 이름은 공백일 수 없고, 최대 30자까지 가능합니다. 방을 만드는데 성공했다면 방에 자동으로 접속되고 방장을 맡게 됩니다. 이때 반환값은 `joinRoom`과 동일한 `RoomInfo`를 받습니다.
26 +
25 ### 방 27 ### 방
26 28
27 방에 접속중인 유저의 목록에 변화가 생기면, `updateRoomUser`가 수신됩니다. `state`는 다음 3가지 값 중 하나의 값을 가집니다. 29 방에 접속중인 유저의 목록에 변화가 생기면, `updateRoomUser`가 수신됩니다. `state`는 다음 3가지 값 중 하나의 값을 가집니다.
......
...@@ -29,6 +29,12 @@ export class ServerInboundMessageRecordMap { ...@@ -29,6 +29,12 @@ export class ServerInboundMessageRecordMap {
29 result: Array(RoomDescriptionRecord), 29 result: Array(RoomDescriptionRecord),
30 }); 30 });
31 31
32 + // 방을 만듭니다.
33 + createRoom = Record({
34 + name: String,
35 + result: RoomInfoRecord,
36 + });
37 +
32 // 방에 접속합니다. 38 // 방에 접속합니다.
33 joinRoom = Record({ 39 joinRoom = Record({
34 uuid: String, 40 uuid: String,
......
1 +import { expect } from "chai";
2 +import { RoomManager } from "../room/RoomManager";
3 +import {
4 + prepareJoinedRoom,
5 + prepareUsers,
6 + prepareUsersEmptyRooms,
7 +} from "./util/prepare";
8 +import { SocketTester } from "./util/SocketTester";
9 +
10 +describe("방 생성", () => {
11 + it("로그인하지 않은 유저는 요청할 수 없습니다", () => {
12 + const roomManager = new RoomManager();
13 + const socket = new SocketTester(roomManager);
14 + socket.testNotOk("createRoom", { name: "테스트" });
15 + });
16 + it("방을 생성합니다", () => {
17 + const {
18 + sockets: [socket],
19 + users: [user],
20 + } = prepareUsers(1);
21 +
22 + const response = socket.test("createRoom", { name: "테스트" });
23 + expect(response.ok).eq(true);
24 + expect(response.result?.name).eq("테스트");
25 + expect(response.result?.users?.length).eq(1);
26 + expect(response.result?.users[0]?.username).eq(user.username);
27 + });
28 + it("방을 생성하면 방장이 됩니다", () => {
29 + const {
30 + sockets: [socket],
31 + } = prepareUsers(1);
32 +
33 + const response = socket.test("createRoom", { name: "테스트" });
34 + expect(response.ok).eq(true);
35 + expect(response.result?.users[0]?.admin).eq(true);
36 + });
37 + it("방의 이름은 공백이 될 수 없습니다", () => {
38 + const {
39 + sockets: [socket],
40 + } = prepareUsers(1);
41 +
42 + socket.testNotOk("createRoom", { name: "" });
43 + socket.testNotOk("createRoom", { name: " " });
44 + });
45 + it("방의 이름은 30자보다 길 수 없습니다", () => {
46 + const {
47 + sockets: [socket],
48 + } = prepareUsers(1);
49 +
50 + socket.testNotOk("createRoom", { name: "a".repeat(31) });
51 + socket.testNotOk("createRoom", { name: "가".repeat(31) });
52 + });
53 + it("방에 이미 접속한 상태에서 방을 만들 수 없습니다", () => {
54 + const {
55 + sockets: [socket],
56 + } = prepareJoinedRoom(1);
57 +
58 + socket.testNotOk("createRoom", { name: "테스트" });
59 + });
60 +});
...@@ -20,6 +20,16 @@ export class User { ...@@ -20,6 +20,16 @@ export class User {
20 roomList: (user, message) => { 20 roomList: (user, message) => {
21 return { ok: true, result: connection.roomManager.list() }; 21 return { ok: true, result: connection.roomManager.list() };
22 }, 22 },
23 + createRoom: (user, message) => {
24 + if (user.room) {
25 + return { ok: false };
26 + }
27 + if (message.name.length >= 30 || message.name.trim().length === 0) {
28 + return { ok: false };
29 + }
30 + const room = connection.roomManager.create(message.name, 8, user);
31 + return { ok: true, result: room.getInfo() };
32 + },
23 joinRoom: (user, message) => { 33 joinRoom: (user, message) => {
24 const room = connection.roomManager.get(message.uuid); 34 const room = connection.roomManager.get(message.uuid);
25 if (user.room || !room) { 35 if (user.room || !room) {
......