game replace, game list
This commit is contained in:
@@ -16,10 +16,10 @@ type Game struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Player struct {
|
type Player struct {
|
||||||
ID string
|
ID string `json:",omitempty"`
|
||||||
Name string
|
Name string `json:",omitempty"`
|
||||||
Card string
|
Card string `json:",omitempty"`
|
||||||
Balance Currency
|
Balance Currency `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Currency int
|
type Currency int
|
||||||
@@ -34,12 +34,6 @@ func (game Game) GetPlayers() []Player {
|
|||||||
return players
|
return players
|
||||||
}
|
}
|
||||||
|
|
||||||
func (players Players) MarshalJSON() ([]byte, error) {
|
|
||||||
game := Game{Players: players}
|
|
||||||
subplayers := game.GetPlayers()
|
|
||||||
return json.Marshal(subplayers)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Player) Empty() bool {
|
func (p Player) Empty() bool {
|
||||||
return p == (Player{})
|
return p == (Player{})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,36 +5,6 @@ import (
|
|||||||
"testing"
|
"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) {
|
func TestCurrencyMarshal(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
input Currency
|
input Currency
|
||||||
|
|||||||
@@ -14,24 +14,35 @@ func NewGameMaster(config Config, storage *Storage) *GameMaster {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *GameMaster) ListGames() ([]string, error) {
|
func (gm *GameMaster) ListGames() ([]string, error) {
|
||||||
return game.storage.ListGames()
|
return gm.storage.ListGames()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *GameMaster) GetGame(id string) (Game, error) {
|
func (gm *GameMaster) GetGame(id string) (Game, error) {
|
||||||
game.locks.RLock(id)
|
gm.locks.RLock(id)
|
||||||
defer game.locks.RUnlock(id)
|
defer gm.locks.RUnlock(id)
|
||||||
|
|
||||||
return game.storage.GetGame(id)
|
return gm.storage.GetGame(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (game *GameMaster) CreateGame(id string) error {
|
func (gm *GameMaster) CreateGame(id string) error {
|
||||||
game.locks.Lock(id)
|
gm.locks.Lock(id)
|
||||||
defer game.locks.Unlock(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 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)
|
return NewGameMaster(config, storage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGameMasterGetCreateGet(t *testing.T) {
|
func TestGameMasterGetCreateGetList(t *testing.T) {
|
||||||
gm := mockGameMaster(t)
|
gm := mockGameMaster(t)
|
||||||
|
|
||||||
id := "game"
|
id := "game"
|
||||||
|
|
||||||
if games, err := gm.ListGames(); err != nil {
|
if games, err := gm.ListGames(); err != nil {
|
||||||
@@ -33,3 +32,33 @@ func TestGameMasterGetCreateGet(t *testing.T) {
|
|||||||
t.Fatal(games)
|
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{
|
fmt.Sprintf("%s/%s%s", server.config.Server.File.Prefix, router.Wildcard, router.Wildcard): map[string]http.HandlerFunc{
|
||||||
http.MethodGet: server.File,
|
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{
|
fmt.Sprintf("%s/games/%s", server.config.Server.API.Prefix, router.Wildcard): map[string]http.HandlerFunc{
|
||||||
http.MethodGet: server.GameGet,
|
http.MethodGet: server.GameGet,
|
||||||
http.MethodPost: server.GameInsert,
|
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)
|
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) {
|
func (server *Server) GameGet(w http.ResponseWriter, r *http.Request) {
|
||||||
var gameID string
|
var gameID string
|
||||||
err := router.Params(r, &gameID)
|
err := router.Params(r, &gameID)
|
||||||
@@ -82,6 +95,27 @@ func (server *Server) GameGet(w http.ResponseWriter, r *http.Request) {
|
|||||||
json.NewEncoder(w).Encode(resp)
|
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) {
|
func (server *Server) GameInsert(w http.ResponseWriter, r *http.Request) {
|
||||||
var gameID string
|
var gameID string
|
||||||
err := router.Params(r, &gameID)
|
err := router.Params(r, &gameID)
|
||||||
|
|||||||
@@ -24,13 +24,21 @@ func TestServerRouter(t *testing.T) {
|
|||||||
path: path.Join(server.config.Server.File.Prefix),
|
path: path.Join(server.config.Server.File.Prefix),
|
||||||
},
|
},
|
||||||
"api: games: get": {
|
"api: games: get": {
|
||||||
|
method: http.MethodGet,
|
||||||
|
path: path.Join(server.config.Server.API.Prefix, "games"),
|
||||||
|
},
|
||||||
|
"api: games: id: get": {
|
||||||
method: http.MethodGet,
|
method: http.MethodGet,
|
||||||
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
||||||
},
|
},
|
||||||
"api: games: post": {
|
"api: games: id: post": {
|
||||||
method: http.MethodPost,
|
method: http.MethodPost,
|
||||||
path: path.Join(server.config.Server.API.Prefix, "games", "my-game-id"),
|
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 {
|
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) {
|
func (storage Storage) GetGame(id string) (Game, error) {
|
||||||
var game Game
|
var game Game
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user