game replace, game list
This commit is contained in:
@@ -16,10 +16,10 @@ type Game struct {
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
ID string
|
||||
Name string
|
||||
Card string
|
||||
Balance Currency
|
||||
ID string `json:",omitempty"`
|
||||
Name string `json:",omitempty"`
|
||||
Card string `json:",omitempty"`
|
||||
Balance Currency `json:",omitempty"`
|
||||
}
|
||||
|
||||
type Currency int
|
||||
@@ -34,12 +34,6 @@ func (game Game) GetPlayers() []Player {
|
||||
return players
|
||||
}
|
||||
|
||||
func (players Players) MarshalJSON() ([]byte, error) {
|
||||
game := Game{Players: players}
|
||||
subplayers := game.GetPlayers()
|
||||
return json.Marshal(subplayers)
|
||||
}
|
||||
|
||||
func (p Player) Empty() bool {
|
||||
return p == (Player{})
|
||||
}
|
||||
|
||||
@@ -5,36 +5,6 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPlayersMarshal(t *testing.T) {
|
||||
t.Run("0", func(t *testing.T) {
|
||||
var ps Players
|
||||
b, err := json.Marshal(ps)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if s := string(b); s != "[]" {
|
||||
t.Fatalf("didnt marshal empty Players as []: got %s", s)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("2", func(t *testing.T) {
|
||||
var ps Players
|
||||
ps[3].ID = "hi"
|
||||
ps[9].ID = "hi2"
|
||||
b, err := json.Marshal(ps)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var ps2 []Player
|
||||
if err := json.Unmarshal(b, &ps2); err != nil {
|
||||
t.Fatalf("%v: %s", err, b)
|
||||
}
|
||||
if len(ps2) != 2 {
|
||||
t.Fatal(len(ps2))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestCurrencyMarshal(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
input Currency
|
||||
|
||||
@@ -14,24 +14,35 @@ func NewGameMaster(config Config, storage *Storage) *GameMaster {
|
||||
}
|
||||
}
|
||||
|
||||
func (game *GameMaster) ListGames() ([]string, error) {
|
||||
return game.storage.ListGames()
|
||||
func (gm *GameMaster) ListGames() ([]string, error) {
|
||||
return gm.storage.ListGames()
|
||||
}
|
||||
|
||||
func (game *GameMaster) GetGame(id string) (Game, error) {
|
||||
game.locks.RLock(id)
|
||||
defer game.locks.RUnlock(id)
|
||||
func (gm *GameMaster) GetGame(id string) (Game, error) {
|
||||
gm.locks.RLock(id)
|
||||
defer gm.locks.RUnlock(id)
|
||||
|
||||
return game.storage.GetGame(id)
|
||||
return gm.storage.GetGame(id)
|
||||
}
|
||||
|
||||
func (game *GameMaster) CreateGame(id string) error {
|
||||
game.locks.Lock(id)
|
||||
defer game.locks.Unlock(id)
|
||||
func (gm *GameMaster) CreateGame(id string) error {
|
||||
gm.locks.Lock(id)
|
||||
defer gm.locks.Unlock(id)
|
||||
|
||||
if _, err := game.storage.GetGame(id); err == nil {
|
||||
if _, err := gm.storage.GetGame(id); err == nil {
|
||||
return errGameExists
|
||||
}
|
||||
|
||||
return game.storage.CreateGame(id)
|
||||
return gm.storage.CreateGame(id)
|
||||
}
|
||||
|
||||
func (gm *GameMaster) ReplaceGame(id string, game Game) error {
|
||||
gm.locks.Lock(id)
|
||||
defer gm.locks.Unlock(id)
|
||||
|
||||
if _, err := gm.storage.GetGame(id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return gm.storage.ReplaceGame(id, game)
|
||||
}
|
||||
|
||||
@@ -8,9 +8,8 @@ func mockGameMaster(t *testing.T) *GameMaster {
|
||||
return NewGameMaster(config, storage)
|
||||
}
|
||||
|
||||
func TestGameMasterGetCreateGet(t *testing.T) {
|
||||
func TestGameMasterGetCreateGetList(t *testing.T) {
|
||||
gm := mockGameMaster(t)
|
||||
|
||||
id := "game"
|
||||
|
||||
if games, err := gm.ListGames(); err != nil {
|
||||
@@ -33,3 +32,33 @@ func TestGameMasterGetCreateGet(t *testing.T) {
|
||||
t.Fatal(games)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGameMasterUpdate(t *testing.T) {
|
||||
gm := mockGameMaster(t)
|
||||
id := "game"
|
||||
|
||||
err := gm.CreateGame(id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
game, err := gm.GetGame(id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
game.Players[2].ID = "hi"
|
||||
game.Pot = 123
|
||||
err = gm.ReplaceGame(id, game)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
game2, err := gm.GetGame(id)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if game2 != game {
|
||||
t.Fatalf("replace+get don't match:\nwant\t%+v\ngot\t%+v", game, game2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,13 @@ func (server *Server) Routes() error {
|
||||
fmt.Sprintf("%s/%s%s", server.config.Server.File.Prefix, router.Wildcard, router.Wildcard): map[string]http.HandlerFunc{
|
||||
http.MethodGet: server.File,
|
||||
},
|
||||
fmt.Sprintf("%s/games", server.config.Server.API.Prefix): map[string]http.HandlerFunc{
|
||||
http.MethodGet: server.GameList,
|
||||
},
|
||||
fmt.Sprintf("%s/games/%s", server.config.Server.API.Prefix, router.Wildcard): map[string]http.HandlerFunc{
|
||||
http.MethodGet: server.GameGet,
|
||||
http.MethodPost: server.GameInsert,
|
||||
http.MethodPut: server.GameReplace,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -67,6 +71,15 @@ func (server *Server) File(w http.ResponseWriter, r *http.Request) {
|
||||
s.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (server *Server) GameList(w http.ResponseWriter, r *http.Request) {
|
||||
resp, err := server.gm.ListGames()
|
||||
if err != nil {
|
||||
internalError(w, err.Error())
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (server *Server) GameGet(w http.ResponseWriter, r *http.Request) {
|
||||
var gameID string
|
||||
err := router.Params(r, &gameID)
|
||||
@@ -82,6 +95,27 @@ func (server *Server) GameGet(w http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (server *Server) GameReplace(w http.ResponseWriter, r *http.Request) {
|
||||
var gameID string
|
||||
err := router.Params(r, &gameID)
|
||||
if err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
var game Game
|
||||
err = json.NewDecoder(r.Body).Decode(&game)
|
||||
if err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = server.gm.ReplaceGame(gameID, game)
|
||||
if err != nil {
|
||||
internalError(w, err.Error())
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(game)
|
||||
}
|
||||
|
||||
func (server *Server) GameInsert(w http.ResponseWriter, r *http.Request) {
|
||||
var gameID string
|
||||
err := router.Params(r, &gameID)
|
||||
|
||||
@@ -24,13 +24,21 @@ func TestServerRouter(t *testing.T) {
|
||||
path: path.Join(server.config.Server.File.Prefix),
|
||||
},
|
||||
"api: games: get": {
|
||||
method: http.MethodGet,
|
||||
path: path.Join(server.config.Server.API.Prefix, "games"),
|
||||
},
|
||||
"api: games: id: get": {
|
||||
method: http.MethodGet,
|
||||
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
||||
},
|
||||
"api: games: post": {
|
||||
"api: games: id: post": {
|
||||
method: http.MethodPost,
|
||||
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
||||
},
|
||||
"api: games: id: put": {
|
||||
method: http.MethodPut,
|
||||
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
||||
},
|
||||
}
|
||||
|
||||
for name, d := range cases {
|
||||
|
||||
@@ -21,6 +21,14 @@ func NewStorage(config Config) *Storage {
|
||||
}
|
||||
}
|
||||
|
||||
func (storage Storage) ReplaceGame(id string, game Game) error {
|
||||
b, err := json.Marshal(game)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return storage.db.Set(id, b, nsGames)
|
||||
}
|
||||
|
||||
func (storage Storage) GetGame(id string) (Game, error) {
|
||||
var game Game
|
||||
|
||||
|
||||
Reference in New Issue
Block a user