Fix picks being broadcasted, finish up main test
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Hamcha 2019-06-28 18:19:02 +02:00
parent fcb265c490
commit 21c257a0b1
2 changed files with 93 additions and 61 deletions

View File

@ -4,28 +4,33 @@ import (
"testing"
"time"
"git.fromouter.space/mcg/draft"
"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"
draftbot "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
in chan room.ServerMessage
out chan room.BotMessage
t *testing.T
timeout time.Duration
}
func makeMockServer() *MockServer {
func makeMockServer(t *testing.T, timeout int) *MockServer {
in := make(chan room.ServerMessage, 99)
out := make(chan room.BotMessage, 99)
srv := &MockServer{
in: in,
out: out,
in: in,
out: out,
t: t,
timeout: time.Duration(timeout) * time.Second,
}
return srv
}
@ -41,9 +46,9 @@ func (m *MockServer) Bind(fn bot.MessageHandler) {
}
func TestDraftSession(t *testing.T) {
mock := makeMockServer()
draftbot := draft.NewDraftBot(mock, TestBotName)
go mock.Bind(draftbot.OnMessage)
mock := makeMockServer(t, 5)
drafter := draftbot.NewDraftBot(mock, TestBotName)
go mock.Bind(drafter.OnMessage)
// Create a new room
mock.in <- room.ServerMessage{
@ -60,33 +65,49 @@ func TestDraftSession(t *testing.T) {
}
// Create new session with a fake message from owner
mock.message("test-owner", "create", draft.SessionOptions{
mock.message("test-owner", "create", draftbot.SessionOptions{
Players: 8, // Two players, six bots
Options: draft.DraftOptions{
Type: draft.DraftSet,
Positioning: draft.PosEven,
Options: draftbot.DraftOptions{
Type: draftbot.DraftSet,
Positioning: draftbot.PosEven,
Set: mlp.SetAbsoluteDiscord,
PackCount: 4,
},
})
mock.expect(t, "session-open", 5)
mock.expect("session-open")
// Join session as owner
mock.message("test-owner", "join", nil)
mock.expect(t, "player-joined-session", 5)
mock.expect("player-joined-session")
// .. and as second player
mock.message("test-guest", "join", nil)
mock.expect(t, "player-joined-session", 5)
mock.expect("player-joined-session")
// 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")
mock.multiexpect("session-start", "draft-order")
//TODO make players pick cards etc
// Pick card for each player
for packi := 0; packi < 4; packi++ {
mock.expect("draft-newpack")
for cardi := 0; cardi < 12; cardi++ {
// Get packs
msg1 := mock.expect("draft-newpick")
pack1 := msg1.Data.(draft.Pack)
msg2 := mock.expect("draft-newpick")
pack2 := msg2.Data.(draft.Pack)
// Pick first card in each pack
mock.message(msg1.To, "pick", pack1[0].ID)
mock.message(msg2.To, "pick", pack2[0].ID)
// Intercept picked events
mock.multiexpect("card-picked", "card-picked")
}
}
mock.expect("draft-finish")
// Close the room
mock.in <- room.ServerMessage{
@ -99,9 +120,9 @@ func TestDraftSession(t *testing.T) {
}
func TestDraftSessionButEverythingGoesWrong(t *testing.T) {
mock := makeMockServer()
draftbot := draft.NewDraftBot(mock, TestBotName)
go mock.Bind(draftbot.OnMessage)
mock := makeMockServer(t, 5)
drafter := draftbot.NewDraftBot(mock, TestBotName)
go mock.Bind(drafter.OnMessage)
// Create a new room
mock.in <- room.ServerMessage{
@ -117,80 +138,80 @@ func TestDraftSessionButEverythingGoesWrong(t *testing.T) {
}
// Try creating a new session as NOT the owner
mock.message("test-guest", "create", draft.SessionOptions{
mock.message("test-guest", "create", draftbot.SessionOptions{
Players: 8,
Options: draft.DraftOptions{
Type: draft.DraftSet,
Positioning: draft.PosEven,
Options: draftbot.DraftOptions{
Type: draftbot.DraftSet,
Positioning: draftbot.PosEven,
Set: mlp.SetAbsoluteDiscord,
PackCount: 4,
},
})
mock.expect(t, "must-be-owner", 5)
mock.expect("must-be-owner")
// Try creating a session with an invalid type
mock.message("test-owner", "create", draft.SessionOptions{
mock.message("test-owner", "create", draftbot.SessionOptions{
Players: 8,
Options: draft.DraftOptions{
Options: draftbot.DraftOptions{
Type: "lolwhat",
},
})
mock.expect(t, "session-create-error", 5)
mock.expect("session-create-error")
// Try creating a session with invalid data
mock.message("test-owner", "create", 42)
mock.expect(t, "invalid-data", 5)
mock.expect("invalid-data")
// Try starting a session that doesn't exist
mock.message("test-owner", "start", nil)
mock.expect(t, "command-unavailable", 5)
mock.expect("command-unavailable")
// Try creating the session twice
mock.message("test-owner", "create", draft.SessionOptions{
mock.message("test-owner", "create", draftbot.SessionOptions{
Players: 2,
Options: draft.DraftOptions{
Type: draft.DraftSet,
Positioning: draft.PosEven,
Options: draftbot.DraftOptions{
Type: draftbot.DraftSet,
Positioning: draftbot.PosEven,
Set: mlp.SetAbsoluteDiscord,
PackCount: 4,
},
})
mock.expect(t, "session-open", 5)
mock.expect("session-open")
mock.message("test-owner", "create", draft.SessionOptions{
mock.message("test-owner", "create", draftbot.SessionOptions{
Players: 2,
Options: draft.DraftOptions{
Type: draft.DraftSet,
Positioning: draft.PosEven,
Options: draftbot.DraftOptions{
Type: draftbot.DraftSet,
Positioning: draftbot.PosEven,
Set: mlp.SetAbsoluteDiscord,
PackCount: 4,
},
})
mock.expect(t, "command-unavailable", 5)
mock.expect("command-unavailable")
// Try to start session when no-one has joined
mock.message("test-owner", "start", nil)
mock.expect(t, "session-start-error", 5)
mock.expect("session-start-error")
// Try to make too many players join
mock.message("a", "join", nil)
mock.expect(t, "player-joined-session", 5)
mock.expect("player-joined-session")
mock.message("b", "join", nil)
mock.expect(t, "player-joined-session", 5)
mock.expect("player-joined-session")
mock.message("c", "join", nil)
mock.expect(t, "session-full", 5)
mock.expect("session-full")
// Try to make someone join a session that already started
mock.message("test-owner", "start", nil)
mock.multiexpect(t, 5, "session-start", "draft-order")
mock.multiexpect("session-start", "draft-order", "draft-newpack", "draft-newpick", "draft-newpick")
mock.message("c", "join", nil)
mock.expect(t, "session-already-started", 5)
mock.expect("session-already-started")
//TODO More picking, etc shenanigans
}
func (m *MockServer) expect(t *testing.T, typ string, timeout int) {
func (m *MockServer) expect(typ string) *room.Message {
for {
select {
case msg := <-m.out:
@ -202,27 +223,31 @@ func (m *MockServer) expect(t *testing.T, typ string, timeout int) {
// Check expected type
if msg.Message.Type != typ {
// Oh noes
t.Fatalf("Expected message \"%s\" but got \"%s\"", typ, msg.Message.Type)
m.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)
return msg.Message
case <-time.After(m.timeout):
m.t.Fatalf("Expected message \"%s\" but found nothing (timeout)!", typ)
return nil
}
}
}
func (m *MockServer) multiexpect(t *testing.T, timeout int, types ...string) {
func (m *MockServer) multiexpect(types ...string) {
for {
if len(types) < 1 {
return
}
select {
case msg := <-m.out:
// Skip all actions
if msg.Type != room.MsgMessage {
continue
}
m.t.Logf("-> [%s] %s", msg.Message.Type, msg.Message.Message)
// Check expected type
found := false
for i, typ := range types {
@ -235,15 +260,16 @@ func (m *MockServer) multiexpect(t *testing.T, timeout int, types ...string) {
}
if !found {
// Oh noes
t.Fatalf("Expected one of %s but got \"%s\"", types, msg.Message.Type)
m.t.Fatalf("Expected one of %s but got \"%s\"", types, msg.Message.Type)
}
case <-time.After(time.Duration(timeout) * time.Second):
t.Fatalf("Expected one of %s but found nothing (timeout after %d seconds)!", types, timeout)
case <-time.After(m.timeout):
m.t.Fatalf("Expected one of %s but found nothing (timeout)!", types)
}
}
}
func (m *MockServer) message(from string, typ string, data interface{}) {
m.t.Logf("<- <%s> %s (%v)", from, typ, data)
m.in <- room.ServerMessage{
RoomID: TestRoomName,
Type: room.MsgMessage,

View File

@ -231,15 +231,20 @@ func (s *session) handlePicks() {
bot.PickNext()
}
// Tell every players their new cards
for _, player := range s.Players {
for pname, player := range s.Players {
s.messages <- room.Message{
Channel: "draft",
To: pname,
Type: "draft-newpick",
Data: player.CurrentPack,
Message: fmt.Sprintf("You got these cards: %s", player.CurrentPack),
}
}
nextPack := false
select {
case <-s.Pod.ReadyNextPack:
// Break of pick loop, get next packs
nextPack = true
case <-s.Pod.ReadyNextPick:
// Pass packs around
err := s.Pod.NextPacks()
@ -253,15 +258,16 @@ func (s *session) handlePicks() {
return
}
}
case <-s.Pod.ReadyNextPack:
// Break of pick loop, get next packs
break
case <-s.exit:
// Room closed, exit early
close(s.messages)
close(s.exit)
return
}
if nextPack {
break
}
}
}
}