Skip to content

Commit

Permalink
feat: game initialized (#72)
Browse files Browse the repository at this point in the history
* chore: logs cleanup

* feat(testcommon): SetupConfigLogger
  • Loading branch information
igor-sirotin authored Jul 9, 2024
1 parent 652b9fc commit 190b6b1
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 42 deletions.
17 changes: 17 additions & 0 deletions internal/testcommon/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package testcommon

import (
"testing"

"github.com/stretchr/testify/require"
"go.uber.org/zap"

"github.com/six78/2-story-points-cli/internal/config"
)

func SetupConfigLogger(t *testing.T) *zap.Logger {
logger, err := zap.NewDevelopment()
require.NoError(t, err)
config.Logger = logger
return logger
}
5 changes: 0 additions & 5 deletions internal/testcommon/matchers/online_matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import (
"encoding/json"
"testing"

"github.com/six78/2-story-points-cli/internal/config"
"github.com/six78/2-story-points-cli/pkg/protocol"
"go.uber.org/zap"
)

type OnlineMatcher struct {
Expand Down Expand Up @@ -40,9 +38,6 @@ func (m *OnlineMatcher) Matches(x interface{}) bool {
return false
}

config.Logger.Debug("<<< OnlineMatcher.Matches",
zap.Any("onlineMessage", onlineMessage),
)
m.triggered <- onlineMessage
return true
}
Expand Down
8 changes: 3 additions & 5 deletions internal/testcommon/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import (

"github.com/brianvoe/gofakeit/v6"
tea "github.com/charmbracelet/bubbletea"
"github.com/six78/2-story-points-cli/internal/config"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"

"github.com/six78/2-story-points-cli/internal/config"
)

type Suite struct {
Expand All @@ -17,10 +18,7 @@ type Suite struct {
}

func (s *Suite) SetupSuite() {
logger, err := zap.NewDevelopment()
s.Require().NoError(err)
s.Logger = logger
config.Logger = logger
s.Logger = SetupConfigLogger(s.T())
}

func (s *Suite) TearDownSuite() {
Expand Down
18 changes: 17 additions & 1 deletion pkg/game/game.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import (
)

var (
ErrNoRoom = errors.New("no room")
ErrNoRoom = errors.New("no room")
ErrGameNotInitialized = errors.New("game is not initialized")

playerOnlineTimeout = 20 * time.Second
)
Expand All @@ -35,6 +36,7 @@ type Game struct {
messages chan []byte
features FeatureFlags
codeControls codeControlFlags
initialized bool

isDealer bool
player *protocol.Player
Expand All @@ -54,6 +56,7 @@ func NewGame(opts []Option) *Game {
messages: make(chan []byte, 42),
features: defaultFeatureFlags(),
codeControls: defaultCodeControlFlags(),
initialized: false,
isDealer: false,
player: nil,
myVote: protocol.VoteResult{
Expand Down Expand Up @@ -109,6 +112,7 @@ func (g *Game) Initialize() error {
Online: true,
}

g.initialized = true
return nil
}

Expand Down Expand Up @@ -457,6 +461,10 @@ func (g *Game) Deal(input string) (protocol.IssueID, error) {
}

func (g *Game) CreateNewRoom() (*protocol.Room, *protocol.State, error) {
if !g.initialized {
return nil, nil, ErrGameNotInitialized
}

room, err := protocol.NewRoom()
if err != nil {
return nil, nil, errors.Wrap(err, "failed to create a new room")
Expand All @@ -480,6 +488,10 @@ func (g *Game) CreateNewRoom() (*protocol.Room, *protocol.State, error) {
}

func (g *Game) JoinRoom(roomID protocol.RoomID, state *protocol.State) error {
if !g.initialized {
return ErrGameNotInitialized
}

if g.RoomID() == roomID {
return errors.New("already in this room")
}
Expand Down Expand Up @@ -568,6 +580,10 @@ func (g *Game) RoomID() protocol.RoomID {
return g.roomID
}

func (g *Game) Initialized() bool {
return g.initialized
}

func (g *Game) Player() protocol.Player {
return *g.player
}
Expand Down
88 changes: 57 additions & 31 deletions pkg/game/game_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import (

"github.com/brianvoe/gofakeit/v6"
"github.com/jonboulle/clockwork"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
"go.uber.org/zap"

"github.com/six78/2-story-points-cli/internal/testcommon"
"github.com/six78/2-story-points-cli/internal/testcommon/matchers"
"github.com/six78/2-story-points-cli/internal/transport"
mocktransport "github.com/six78/2-story-points-cli/internal/transport/mock"
"github.com/six78/2-story-points-cli/pkg/protocol"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"
"go.uber.org/zap"
)

func TestGame(t *testing.T) {
Expand All @@ -29,7 +30,6 @@ type Suite struct {
cancel context.CancelFunc
transport *mocktransport.MockService
clock clockwork.FakeClock
dealer *Game
}

func (s *Suite) newGame(extraOptions []Option) *Game {
Expand All @@ -45,9 +45,11 @@ func (s *Suite) newGame(extraOptions []Option) *Game {

g := NewGame(options)
s.Require().NotNil(g)
s.Require().False(g.Initialized())

err := g.Initialize()
s.Require().NoError(err)
s.Require().True(g.Initialized())

return g
}
Expand All @@ -58,13 +60,6 @@ func (s *Suite) SetupTest() {
ctrl := gomock.NewController(s.T())
s.transport = mocktransport.NewMockService(ctrl)
s.clock = clockwork.NewFakeClock()

s.dealer = s.newGame([]Option{
WithEnableSymmetricEncryption(true),
})

err := s.dealer.Initialize()
s.Require().NoError(err)
}

func (s *Suite) TearDownTest() {
Expand Down Expand Up @@ -140,13 +135,17 @@ func (s *Suite) TestStateSize() {
}

func (s *Suite) TestSimpleGame() {
room, initialState, err := s.dealer.CreateNewRoom()
dealer := s.newGame([]Option{
WithEnableSymmetricEncryption(true),
})

room, initialState, err := dealer.CreateNewRoom()
s.Require().NoError(err)
s.Require().NotNil(room)

roomID := room.ToRoomID()
roomMatcher := matchers.NewRoomMatcher(room)
onlineMatcher := matchers.NewOnlineMatcher(s.T(), s.dealer.Player().ID)
onlineMatcher := matchers.NewOnlineMatcher(s.T(), dealer.Player().ID)

// Online state is sent periodically
s.transport.EXPECT().PublishPublicMessage(roomMatcher, onlineMatcher).AnyTimes()
Expand All @@ -158,7 +157,7 @@ func (s *Suite) TestSimpleGame() {
s.transport.EXPECT().PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

err = s.dealer.JoinRoom(roomID, initialState)
err = dealer.JoinRoom(roomID, initialState)
s.Require().NoError(err)

state := stateMatcher.Wait()
Expand Down Expand Up @@ -189,7 +188,7 @@ func (s *Suite) TestSimpleGame() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

firstIssueID, err = s.dealer.Deal(firstItemText)
firstIssueID, err = dealer.Deal(firstItemText)
s.Require().NoError(err)

state = stateMatcher.Wait()
Expand All @@ -199,12 +198,12 @@ func (s *Suite) TestSimpleGame() {
s.Logger.Info("match on deal first item")
}

currentIssue := s.dealer.CurrentState().Issues.Get(s.dealer.CurrentState().ActiveIssue)
currentIssue := dealer.CurrentState().Issues.Get(dealer.CurrentState().ActiveIssue)
s.Require().NotNil(currentIssue)
s.Require().Equal(firstItemText, currentIssue.TitleOrURL)

{ // Publish dealer vote
voteMatcher := matchers.NewVoteMatcher(s.dealer.Player().ID, currentIssue.ID, dealerVote)
voteMatcher := matchers.NewVoteMatcher(dealer.Player().ID, currentIssue.ID, dealerVote)
s.transport.EXPECT().
PublishPublicMessage(roomMatcher, voteMatcher).
Times(1)
Expand All @@ -214,7 +213,7 @@ func (s *Suite) TestSimpleGame() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

err = s.dealer.PublishVote(dealerVote)
err = dealer.PublishVote(dealerVote)
s.Require().NoError(err)

state = stateMatcher.Wait()
Expand All @@ -223,7 +222,7 @@ func (s *Suite) TestSimpleGame() {
s.Require().Nil(item.Result)
s.Require().Len(item.Votes, 1)

vote, ok := item.Votes[s.dealer.Player().ID]
vote, ok := item.Votes[dealer.Player().ID]
s.Require().True(ok)
s.Require().Empty(vote.Value)
s.Require().Greater(vote.Timestamp, int64(0))
Expand All @@ -235,15 +234,15 @@ func (s *Suite) TestSimpleGame() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

err = s.dealer.Reveal()
err = dealer.Reveal()
s.Require().NoError(err)

state = stateMatcher.Wait()
item := checkIssues(state.Issues)
s.Require().Nil(item.Result)
s.Require().Len(item.Votes, 1)

vote, ok := item.Votes[s.dealer.Player().ID]
vote, ok := item.Votes[dealer.Player().ID]
s.Require().True(ok)
s.Require().NotNil(vote)
s.Require().Equal(dealerVote, vote.Value)
Expand All @@ -258,7 +257,7 @@ func (s *Suite) TestSimpleGame() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

err = s.dealer.Finish(votingResult)
err = dealer.Finish(votingResult)
s.Require().NoError(err)

state = stateMatcher.Wait()
Expand All @@ -267,7 +266,7 @@ func (s *Suite) TestSimpleGame() {
s.Require().Equal(votingResult, *item.Result)
s.Require().Len(item.Votes, 1)

vote, ok := item.Votes[s.dealer.Player().ID]
vote, ok := item.Votes[dealer.Player().ID]
s.Require().True(ok)
s.Require().Equal(dealerVote, vote.Value)
s.Require().Greater(vote.Timestamp, int64(0))
Expand Down Expand Up @@ -296,7 +295,7 @@ func (s *Suite) TestSimpleGame() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

secondIssueID, err = s.dealer.Deal(secondItemText)
secondIssueID, err = dealer.Deal(secondItemText)
s.Require().NoError(err)

state = stateMatcher.Wait()
Expand Down Expand Up @@ -389,17 +388,17 @@ func (s *Suite) TestOnlineState() {
Name: gofakeit.Username(),
}

s.dealer = s.newGame([]Option{
dealer := s.newGame([]Option{
WithPlayerName("dealer"),
WithEnablePublishOnlineState(false), // FIXME: Add a separate test for self publishing
})

s.Logger.Debug("<<< test info",
s.Logger.Debug("xtest info",
zap.Any("player", player),
zap.Any("dealer", s.dealer.Player()),
zap.Any("dealer", dealer.Player()),
)

room, initialState, err := s.dealer.CreateNewRoom()
room, initialState, err := dealer.CreateNewRoom()
s.Require().NoError(err)
s.Require().NotNil(room)

Expand All @@ -410,15 +409,15 @@ func (s *Suite) TestOnlineState() {

//s.transport.EXPECT().
// PublishPublicMessage(roomMatcher,
// matchers.NewOnlineMatcher(s.T(), s.dealer.Player().ID)).
// matchers.NewOnlineMatcher(s.T(), dealer.Player().ID)).
// AnyTimes()

stateMatcher := s.newStateMatcher()
s.transport.EXPECT().
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

err = s.dealer.JoinRoom(roomID, initialState)
err = dealer.JoinRoom(roomID, initialState)
s.Require().NoError(err)

_ = stateMatcher.Wait()
Expand All @@ -438,7 +437,7 @@ func (s *Suite) TestOnlineState() {
PublishPublicMessage(roomMatcher, stateMatcher).
Times(1)

s.dealer.handlePlayerOnlineMessage(playerOnlineMessage)
dealer.handlePlayerOnlineMessage(playerOnlineMessage)

// Ensure new player joined
state := stateMatcher.Wait()
Expand All @@ -465,3 +464,30 @@ func (s *Suite) TestOnlineState() {
s.Require().False(p.Online)
s.Require().Equal(lastSeenAt, p.OnlineTimestampMilliseconds)
}

func (s *Suite) TestGameNotInitialized() {
options := []Option{
WithContext(s.ctx),
WithTransport(s.transport),
WithClock(s.clock),
WithLogger(s.Logger),
WithPlayerName(gofakeit.Username()),
WithPublishStateLoop(false),
}

g := NewGame(options)
s.Require().NotNil(g)
s.Require().False(g.Initialized())

room, state, err := g.CreateNewRoom()
s.Require().ErrorIs(err, ErrGameNotInitialized)
s.Require().Nil(room)
s.Require().Nil(state)

err = g.JoinRoom(protocol.NewRoomID(gofakeit.LetterN(5)), nil)
s.Require().ErrorIs(err, ErrGameNotInitialized)

err = g.Initialize()
s.Require().NoError(err)
s.Require().True(g.Initialized())
}

0 comments on commit 190b6b1

Please sign in to comment.