Skip to content

Commit

Permalink
fix: cache not updating correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
daithihearn committed Jan 25, 2024
1 parent 4c338cb commit 636fb43
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 75 deletions.
12 changes: 8 additions & 4 deletions pkg/game/deck.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ type Suit string

const (
Empty Suit = "EMPTY"
Clubs = "Clubs"
Diamonds = "Diamonds"
Hearts = "Hearts"
Spades = "Spades"
Clubs = "CLUBS"
Diamonds = "DIAMONDS"
Hearts = "HEARTS"
Spades = "SPADES"
Wild = "WILD"
)

func (s Suit) isValid() bool {
return s == Clubs || s == Diamonds || s == Hearts || s == Spades || s == Wild
}

type CardName string

const (
Expand Down
9 changes: 9 additions & 0 deletions pkg/game/game-methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ func (g *Game) completeHand() error {
return err
}

log.Printf("Winning card: %s", winningCard.Card)
log.Printf("Current hand: %v", g.CurrentRound.CurrentHand)
log.Printf("Current suit: %s", g.CurrentRound.Suit)

// 2. Add the hand to the completed hands
g.CurrentRound.CompletedHands = append(g.CurrentRound.CompletedHands, g.CurrentRound.CurrentHand)

Expand Down Expand Up @@ -397,6 +401,11 @@ func (g *Game) Call(playerID string, call Call) error {
}

func (g *Game) SelectSuit(playerID string, suit Suit, cards []CardName) error {
// Validate suit
if !suit.isValid() {
return fmt.Errorf("invalid suit")
}

// Validate the caller
err := g.validateCaller(playerID, Called)
if err != nil {
Expand Down
76 changes: 35 additions & 41 deletions pkg/game/game-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ func getCacheKey(gameId string, playerId string) string {
return gameId + "-" + playerId
}

func (s *Service) updateStateCache(game Game) error {
// Update the state cache for all players in the game.
for _, player := range game.Players {
state, err := game.GetState(player.ID)
if err != nil {
return err

Check warning on line 39 in pkg/game/game-service.go

View check run for this annotation

Codecov / codecov/patch

pkg/game/game-service.go#L39

Added line #L39 was not covered by tests
}
errC := s.Cache.Set(getCacheKey(game.ID, player.ID), state, time.Minute)
if errC != nil {
return errC
}
}
return nil
}

// Create a new game.
func (s *Service) Create(ctx context.Context, playerIDs []string, name string, adminID string) (Game, error) {
log.Printf("Creating new game (%s)", name)
Expand Down Expand Up @@ -77,16 +92,15 @@ func (s *Service) GetState(ctx context.Context, gameId string, playerID string)
return State{}, has, errG
}

// Get the state for the player.
state, err = game.GetState(playerID)
if err != nil {
return State{}, true, err
}

// Save the state to the cache.
err = s.Cache.Set(getCacheKey(gameId, playerID), state, 10*time.Minute)
if err != nil {
log.Printf("Failed to save state to cache: %s", err)
// Update the state cache for all players in the game.
errC := s.updateStateCache(game)
if errC != nil {
return State{}, true, errC
}

return state, true, nil
Expand Down Expand Up @@ -145,15 +159,10 @@ func (s *Service) Call(ctx context.Context, gameId string, playerID string, call
return Game{}, err
}

// Save the state to the cache.
state, err := game.GetState(playerID)
if err != nil {
return Game{}, err
}

err = s.Cache.Set(getCacheKey(gameId, playerID), state, 10*time.Minute)
if err != nil {
log.Printf("Failed to save state to cache: %s", err)
// Update the state cache for all players in the game.
errC := s.updateStateCache(game)
if errC != nil {
return Game{}, errC
}

return game, nil
Expand Down Expand Up @@ -182,15 +191,10 @@ func (s *Service) SelectSuit(ctx context.Context, gameId string, playerID string
return Game{}, err
}

// Save the state to the cache.
state, err := game.GetState(playerID)
if err != nil {
return Game{}, err
}

err = s.Cache.Set(getCacheKey(gameId, playerID), state, 10*time.Minute)
if err != nil {
log.Printf("Failed to save state to cache: %s", err)
// Update the state cache for all players in the game.
errC := s.updateStateCache(game)
if errC != nil {
return Game{}, errC
}

return game, nil
Expand Down Expand Up @@ -219,15 +223,10 @@ func (s *Service) Buy(ctx context.Context, gameId string, playerID string, cards
return Game{}, err
}

// Save the state to the cache.
state, err := game.GetState(playerID)
if err != nil {
return Game{}, err
}

err = s.Cache.Set(getCacheKey(gameId, playerID), state, 10*time.Minute)
if err != nil {
log.Printf("Failed to save state to cache: %s", err)
// Update the state cache for all players in the game.
errC := s.updateStateCache(game)
if errC != nil {
return Game{}, errC
}

return game, nil
Expand Down Expand Up @@ -256,15 +255,10 @@ func (s *Service) Play(ctx context.Context, gameId string, playerID string, card
return Game{}, err
}

// Save the state to the cache.
state, err := game.GetState(playerID)
if err != nil {
return Game{}, err
}

err = s.Cache.Set(getCacheKey(gameId, playerID), state, 10*time.Minute)
if err != nil {
log.Printf("Failed to save state to cache: %s", err)
// Update the state cache for all players in the game.
errC := s.updateStateCache(game)
if errC != nil {
return Game{}, errC
}

return game, nil
Expand Down
22 changes: 12 additions & 10 deletions pkg/game/game-service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ func TestGameService_GetState(t *testing.T) {
expectedExists: true,
},
{
name: "error writing to cache shouldn't stop the function from returning the result",
name: "error writing to cache should return an error",
gameID: TwoPlayerGame().ID,
playerID: "2",
mockGetResult: &[]Game{TwoPlayerGame()},
Expand All @@ -398,7 +398,7 @@ func TestGameService_GetState(t *testing.T) {
Players: TwoPlayerGame().Players,
},
expectedExists: true,
expectingError: false,
expectingError: true,
},
}

Expand Down Expand Up @@ -609,7 +609,7 @@ func TestGameService_Call(t *testing.T) {
mockGetError: &[]error{nil},
mockUpdateOneError: &[]error{nil},
mockSetCacheError: &[]error{nil},
expectedRevision: 1,
expectedRevision: 3,
},
{
name: "game not found",
Expand Down Expand Up @@ -663,7 +663,7 @@ func TestGameService_Call(t *testing.T) {
expectingError: true,
},
{
name: "error writing to cache shouldn't stop the function from returning the result",
name: "error writing to cache should return an error",
gameID: TwoPlayerGame().ID,
playerID: "2",
call: Jink,
Expand All @@ -672,7 +672,8 @@ func TestGameService_Call(t *testing.T) {
mockGetError: &[]error{nil},
mockUpdateOneError: &[]error{nil},
mockSetCacheError: &[]error{errors.New("failed to write to cache")},
expectedRevision: 1,
expectedRevision: 2,
expectingError: true,
},
}

Expand Down Expand Up @@ -807,7 +808,7 @@ func TestGameService_SelectSuit(t *testing.T) {
expectingError: true,
},
{
name: "error writing to cache shouldn't stop the function from returning the result",
name: "error writing to cache should return an error",
gameID: CalledGameFivePlayers().ID,
playerID: "PlayerCalled",
suit: Hearts,
Expand All @@ -818,6 +819,7 @@ func TestGameService_SelectSuit(t *testing.T) {
mockUpdateOneError: &[]error{nil},
mockSetCacheError: &[]error{errors.New("failed to write to cache")},
expectedRevision: 1,
expectingError: true,
},
}

Expand Down Expand Up @@ -936,7 +938,7 @@ func TestGameService_Buy(t *testing.T) {
expectingError: true,
},
{
name: "error writing to cache shouldn't stop the function from returning the result",
name: "error writing to cache should return an error",
gameID: "1",
playerID: "2",
cards: []CardName{SEVEN_HEARTS, EIGHT_HEARTS, NINE_HEARTS},
Expand All @@ -945,7 +947,7 @@ func TestGameService_Buy(t *testing.T) {
mockGetError: &[]error{nil},
mockUpdateOneError: &[]error{nil},
mockSetCacheError: &[]error{errors.New("failed to write to cache")},
expectedRevision: 1,
expectingError: true,
},
}

Expand Down Expand Up @@ -1068,7 +1070,7 @@ func TestGameService_Play(t *testing.T) {
expectingError: true,
},
{
name: "error writing to cache shouldn't stop the function from returning the result",
name: "error writing to cache should return an error",
gameID: "1",
playerID: "1",
card: TWO_HEARTS,
Expand All @@ -1077,7 +1079,7 @@ func TestGameService_Play(t *testing.T) {
mockGetError: &[]error{nil},
mockUpdateOneError: &[]error{nil},
mockSetCacheError: &[]error{errors.New("failed to write to cache")},
expectedRevision: 1,
expectingError: true,
},
}

Expand Down
3 changes: 3 additions & 0 deletions pkg/game/game-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ func findWinningCard(hand Hand, suit Suit) (PlayedCard, error) {
if len(hand.PlayedCards) == 0 {
return PlayedCard{}, errors.New("no cards played")
}
if !suit.isValid() {
return PlayedCard{}, errors.New("invalid suit")

Check warning on line 286 in pkg/game/game-utils.go

View check run for this annotation

Codecov / codecov/patch

pkg/game/game-utils.go#L286

Added line #L286 was not covered by tests
}

// Get active suit
activeSuit, err := getActiveSuit(hand, suit)
Expand Down
16 changes: 12 additions & 4 deletions pkg/game/game-utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,28 +460,36 @@ func TestGameUtils_findWinningCard(t *testing.T) {
hand: Hand{LeadOut: JACK_HEARTS, PlayedCards: []PlayedCard{{Card: JACK_HEARTS, PlayerID: "1"}, {Card: FIVE_HEARTS, PlayerID: "2"}, {Card: ACE_SPADES, PlayerID: "3"}}},
suit: Diamonds,
expectedResult: PlayedCard{Card: JACK_HEARTS, PlayerID: "1"},
expectingError: false,
},
{
name: "Trump cards played",
hand: Hand{LeadOut: JACK_HEARTS, PlayedCards: []PlayedCard{{Card: JACK_HEARTS, PlayerID: "1"}, {Card: FIVE_HEARTS, PlayerID: "2"}, {Card: ACE_HEARTS, PlayerID: "3"}}},
suit: Hearts,
expectedResult: PlayedCard{Card: FIVE_HEARTS, PlayerID: "2"},
expectingError: false,
},
{
name: "Trump cards played - Joker",
hand: Hand{LeadOut: JACK_CLUBS, PlayedCards: []PlayedCard{{Card: JACK_CLUBS, PlayerID: "1"}, {Card: SIX_CLUBS, PlayerID: "2"}, {Card: JOKER, PlayerID: "3"}}},
suit: Hearts,
expectedResult: PlayedCard{Card: JOKER, PlayerID: "3"},
expectingError: false,
},
{
name: "Trump cards played - Ace of hearts",
hand: Hand{LeadOut: JACK_CLUBS, PlayedCards: []PlayedCard{{Card: JACK_CLUBS, PlayerID: "1"}, {Card: SIX_CLUBS, PlayerID: "2"}, {Card: ACE_HEARTS, PlayerID: "3"}}},
suit: Hearts,
expectedResult: PlayedCard{Card: ACE_HEARTS, PlayerID: "3"},
expectingError: false,
},
{
name: "Ten of trumps beats jack of cold suit",
hand: Hand{LeadOut: JACK_SPADES, PlayedCards: []PlayedCard{{Card: JACK_SPADES, PlayerID: "1"}, {Card: TEN_DIAMONDS, PlayerID: "2"}}},
suit: Diamonds,
expectedResult: PlayedCard{Card: TEN_DIAMONDS, PlayerID: "2"},
},
{
name: "real world scenario",
hand: Hand{LeadOut: ACE_SPADES, PlayedCards: []PlayedCard{{Card: ACE_SPADES, PlayerID: "2"}, {Card: FIVE_SPADES, PlayerID: "1"}}},
suit: "SPADES",
expectedResult: PlayedCard{Card: FIVE_SPADES, PlayerID: "1"},
},
}

Expand Down
Loading

0 comments on commit 636fb43

Please sign in to comment.