mlpcardgame/src/tests/unit/network.spec.ts

151 lines
5.8 KiB
TypeScript

import { MockHelper, EventHook } from "@/testing";
import { NetworkMessage, LocalClient, ChatMessage } from "@/network";
const sampleRoom = () => ({
max_players: 3,
password: ""
});
function messageKind(kind: string): (msg: NetworkMessage) => void {
return msg => {
expect(msg.kind).toEqual(kind);
};
}
describe("network/PeerServer", () => {
test("A server can be created", () => {
const mox = new MockHelper();
mox.createServer(sampleRoom());
});
test("Clients can join servers and receive data", async () => {
const mox = new MockHelper();
const hook = new EventHook();
mox.createServer(sampleRoom());
const client = mox.createClient();
hook.hookEmitter(client, "data", "client-data");
client.connect("test-server");
await hook.expect("client-data", 1000, messageKind("room-info"));
await hook.expect("client-data", 1000, messageKind("player-joined"));
});
test("Servers handle multiple clients and resolve name collisions", async () => {
const mox = new MockHelper();
const hook = new EventHook();
mox.createServer(sampleRoom());
const client1 = mox.createClient();
const client2 = mox.createClient();
hook.hookEmitter(client1, "data", "client1-data");
hook.hookEmitter(client2, "data", "client2-data");
client1.connect("test-server");
await hook.expect("client1-data", 1000, messageKind("room-info"));
await hook.expect("client1-data", 1000, messageKind("player-joined"));
client2.connect("test-server");
await hook.expect("client2-data", 1000, messageKind("rename"));
await hook.expect("client2-data", 1000, messageKind("room-info"));
await hook.expect("client2-data", 1000, messageKind("player-joined"));
await hook.expect("client1-data", 1000, messageKind("player-joined"));
});
test("Local server clients receives client events", async () => {
const mox = new MockHelper();
const hook = new EventHook();
const local = new LocalClient({ name: "server-player" });
const server = mox.createServer(sampleRoom(), "test-server", local);
const client = mox.createClient();
hook.hookEmitter(local, "player-joined", "local-joined");
client.connect("test-server");
await hook.expect("local-joined", 1000);
});
test("Server enforces password protection", async () => {
const mox = new MockHelper();
const hook = new EventHook();
const room = sampleRoom();
const roomPassword = "test-pwd";
room.password = roomPassword;
const server = mox.createServer(room, "test-server");
// This client will try the right password
const client1 = mox.createClient();
hook.hookEmitter(client1, "data", "client1-data");
client1.connect("test-server");
await hook.expect("client1-data", 1000, messageKind("password-req"));
client1.password(roomPassword);
await hook.expect("client1-data", 1000, messageKind("room-info"));
await hook.expect("client1-data", 1000, messageKind("player-joined"));
// This client will try an incorrect password
const client2 = mox.createClient("test-client2", "another-client");
hook.hookEmitter(client2, "data", "client2-data");
client2.connect("test-server");
await hook.expect("client2-data", 1000, messageKind("password-req"));
client2.password("not the right password");
await hook.expect("client2-data", 1000, messageKind("error"));
});
});
describe("network/PeerClient", () => {
test("Client handles forced name change", async () => {
const mox = new MockHelper();
const hook = new EventHook();
mox.createServer(sampleRoom());
const client1 = mox.createClient();
const client2 = mox.createClient();
hook.hookEmitter(client2, "rename", "client-rename");
client1.connect("test-server");
client2.connect("test-server");
await hook.expect("client-rename", 1000);
// Client must have changed its internal data to match the new name
expect(client1.name).not.toEqual(client2.name);
});
test("Client can leave the room", async () => {
const mox = new MockHelper();
const hook = new EventHook();
const local = new LocalClient({ name: "server-player" });
const server = mox.createServer(sampleRoom(), "test-server", local);
const client = mox.createClient();
hook.hookEmitter(local, "player-joined", "client-joined");
hook.hookEmitter(local, "player-left", "client-left");
client.connect("test-server");
await hook.expect("client-joined", 1000);
client.leave();
await hook.expect("client-left", 1000);
});
test("Clients can chat", async () => {
const mox = new MockHelper();
const hook = new EventHook();
const local = new LocalClient({ name: "server-player" });
const server = mox.createServer(sampleRoom(), "test-server", local);
const client = mox.createClient();
hook.hookEmitter(local, "player-joined", "client-joined");
hook.hookEmitter(local, "chat", "client-chat");
client.connect("test-server");
await hook.expect("client-joined", 1000);
const hellomsg = "Hello everyone";
client.say("", hellomsg);
await hook.expect("client-chat", 1000, (msg: ChatMessage) => {
expect(msg.from).toEqual("client-peer");
expect(msg.message).toEqual(hellomsg);
});
});
test("Client internal player list gets correctly updated", async () => {
const mox = new MockHelper();
const hook = new EventHook();
const local = new LocalClient({ name: "server-player" });
const server = mox.createServer(sampleRoom(), "test-server", local);
const client = mox.createClient();
hook.hookEmitter(local, "player-joined", "client-joined");
hook.hookEmitter(local, "player-left", "client-left");
client.connect("test-server");
await hook.expect("client-joined", 1000);
expect(local.players).toHaveLength(2);
client.leave();
await hook.expect("client-left", 1000);
expect(local.players).toHaveLength(1);
});
});