204 lines
4.6 KiB
Go
204 lines
4.6 KiB
Go
package main_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"git.fromouter.space/mcg/draft/mlp"
|
|
|
|
"git.fromouter.space/mcg/cardgage/client/bot"
|
|
lobby "git.fromouter.space/mcg/cardgage/lobby/proto"
|
|
room "git.fromouter.space/mcg/cardgage/room/api"
|
|
draft "git.fromouter.space/mcg/mlp-server-tools/draftbot"
|
|
)
|
|
|
|
const TestBotName = "test-bot"
|
|
const TestRoomName = "test-room"
|
|
|
|
type MockServer struct {
|
|
in chan room.ServerMessage
|
|
out chan room.BotMessage
|
|
}
|
|
|
|
func makeMockServer() *MockServer {
|
|
in := make(chan room.ServerMessage, 99)
|
|
out := make(chan room.BotMessage, 99)
|
|
srv := &MockServer{
|
|
in: in,
|
|
out: out,
|
|
}
|
|
return srv
|
|
}
|
|
|
|
func (m *MockServer) Send(msg room.BotMessage) {
|
|
m.out <- msg
|
|
}
|
|
|
|
func (m *MockServer) Bind(fn bot.MessageHandler) {
|
|
for msg := range m.in {
|
|
fn(msg)
|
|
}
|
|
}
|
|
|
|
func TestDraftSession(t *testing.T) {
|
|
mock := makeMockServer()
|
|
draftbot := draft.NewDraftBot(mock, TestBotName)
|
|
go mock.Bind(draftbot.OnMessage)
|
|
|
|
// Create a new room
|
|
mock.in <- room.ServerMessage{
|
|
RoomID: TestRoomName,
|
|
Type: room.MsgEvent,
|
|
Event: &room.Event{
|
|
Type: room.EvtNewRoom,
|
|
Room: &lobby.Room{
|
|
Id: TestRoomName,
|
|
Name: "Test draft room",
|
|
Creator: "test-owner",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Create new session with a fake message from owner
|
|
mock.message("test-owner", "create", draft.SessionOptions{
|
|
Players: 8, // Two players, six bots
|
|
Options: draft.DraftOptions{
|
|
Type: draft.DraftSet,
|
|
Positioning: draft.PosEven,
|
|
Set: mlp.SetAbsoluteDiscord,
|
|
PackCount: 4,
|
|
},
|
|
})
|
|
|
|
mock.expect(t, "session-open", 5)
|
|
|
|
// Join session as owner
|
|
mock.message("test-owner", "join", nil)
|
|
mock.expect(t, "player-joined-session", 5)
|
|
|
|
// .. and as second player
|
|
mock.message("test-guest", "join", nil)
|
|
mock.expect(t, "player-joined-session", 5)
|
|
|
|
// Try to start the session
|
|
mock.message("test-owner", "start", nil)
|
|
|
|
// These two can happen in any order, so they get their own special check
|
|
mock.multiexpect(t, 5, "session-start", "draft-order")
|
|
|
|
//TODO make players pick cards etc
|
|
|
|
// Close the room
|
|
mock.in <- room.ServerMessage{
|
|
RoomID: TestRoomName,
|
|
Type: room.MsgEvent,
|
|
Event: &room.Event{
|
|
Type: room.EvtRoomClosed,
|
|
},
|
|
}
|
|
}
|
|
|
|
func TestDraftSessionButEverythingGoesWrong(t *testing.T) {
|
|
mock := makeMockServer()
|
|
draftbot := draft.NewDraftBot(mock, TestBotName)
|
|
go mock.Bind(draftbot.OnMessage)
|
|
|
|
// Create a new room
|
|
mock.in <- room.ServerMessage{
|
|
Type: room.MsgEvent,
|
|
Event: &room.Event{
|
|
Type: room.EvtNewRoom,
|
|
Room: &lobby.Room{
|
|
Id: TestRoomName,
|
|
Name: "Test draft room",
|
|
Creator: "test-owner",
|
|
},
|
|
},
|
|
}
|
|
|
|
// Try creating a new session as NOT the owner
|
|
mock.message("test-guest", "create", draft.SessionOptions{
|
|
Players: 8, // Two players, six bots
|
|
Options: draft.DraftOptions{
|
|
Type: draft.DraftSet,
|
|
Positioning: draft.PosEven,
|
|
Set: mlp.SetAbsoluteDiscord,
|
|
PackCount: 4,
|
|
},
|
|
})
|
|
mock.expect(t, "must-be-owner", 5)
|
|
|
|
//TODO:
|
|
// Try to start session when session doesn't exist
|
|
// Try to create session twice
|
|
// Try to start session with no players
|
|
// Try to start session as not the owner
|
|
// Try to make too many players join a session
|
|
}
|
|
|
|
func (m *MockServer) expect(t *testing.T, typ string, timeout int) {
|
|
for {
|
|
select {
|
|
case msg := <-m.out:
|
|
// Skip all actions
|
|
if msg.Type != room.MsgMessage {
|
|
continue
|
|
}
|
|
|
|
// Check expected type
|
|
if msg.Message.Type != typ {
|
|
// Oh noes
|
|
t.Fatalf("Expected message \"%s\" but got \"%s\"", typ, msg.Message.Type)
|
|
}
|
|
return
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
t.Fatalf("Expected message \"%s\" but found nothing (timeout after %d seconds)!", typ, timeout)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *MockServer) multiexpect(t *testing.T, timeout int, types ...string) {
|
|
for {
|
|
if len(types) < 1 {
|
|
return
|
|
}
|
|
select {
|
|
case msg := <-m.out:
|
|
// Skip all actions
|
|
if msg.Type != room.MsgMessage {
|
|
continue
|
|
}
|
|
|
|
// Check expected type
|
|
found := false
|
|
for i, typ := range types {
|
|
if typ == msg.Message.Type {
|
|
found = true
|
|
types[i] = types[len(types)-1]
|
|
types = types[:len(types)-1]
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
// Oh noes
|
|
t.Fatalf("Expected one of %s but got \"%s\"", types, msg.Message.Type)
|
|
}
|
|
return
|
|
case <-time.After(time.Duration(timeout) * time.Second):
|
|
t.Fatalf("Expected one of %s but found nothing (timeout after %d seconds)!", types, timeout)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *MockServer) message(from string, typ string, data interface{}) {
|
|
m.in <- room.ServerMessage{
|
|
RoomID: TestRoomName,
|
|
Type: room.MsgMessage,
|
|
Message: &room.Message{
|
|
From: from,
|
|
To: TestBotName,
|
|
Type: typ,
|
|
Data: data,
|
|
},
|
|
}
|
|
}
|