made changes

This commit is contained in:
Niklas Kapelle 2025-01-06 01:14:32 +01:00
parent a69ef77e26
commit f4619ab7d2
Signed by: niklas
GPG Key ID: 4EB651B36D841D16
5 changed files with 184 additions and 38 deletions

View File

@ -31,7 +31,7 @@ func loadFromFile(repo repo.Repo, path string) error {
return err return err
} }
var payload []model.InputGame var payload []model.Game
err = json.Unmarshal(content, &payload) err = json.Unmarshal(content, &payload)
if err != nil { if err != nil {
return err return err

View File

@ -9,76 +9,92 @@ import (
type InMemoryRepo struct { type InMemoryRepo struct {
games []model.Game games []model.Game
players []model.Player players []model.Player
results []model.GameResult
} }
func NewInMemoryRepo() Repo { func NewInMemoryRepo() Repo {
return &InMemoryRepo{ return &InMemoryRepo{
games: []model.Game{}, games: []model.Game{},
players: []model.Player{}, players: []model.Player{},
results: []model.GameResult{},
} }
} }
func (r *InMemoryRepo) AddGame(game model.InputGame) model.GameID { func (r *InMemoryRepo) AddGame(game model.Game) (model.GameID, error) {
id := len(r.games) id := len(r.games)
authID := r.GetOrCreatePlayerID(game.Author)
t0p0ID := r.GetOrCreatePlayerID(game.Team0Player0)
t0p1ID := r.GetOrCreatePlayerID(game.Team0Player1)
t1p0ID := r.GetOrCreatePlayerID(game.Team1Player0)
t1p1ID := r.GetOrCreatePlayerID(game.Team1Player1)
parsedGame := model.Game{ parsedGame := model.Game{
ID: model.GameID(rune(id)), ID: model.GameID(strconv.Itoa(id)),
Added: game.Added, Added: game.Added,
Author: authID, Author: game.Author,
Team0Player0: t0p0ID, Team0Player0: game.Team0Player0,
Team0Player1: t0p1ID, Team0Player1: game.Team0Player1,
Team1Player0: t1p1ID, Team1Player0: game.Team1Player0,
Team1Player1: t1p0ID, Team1Player1: game.Team1Player1,
Score: game.Score, Score: game.Score,
Overtime: game.Overtime, Overtime: game.Overtime,
} }
r.games = append(r.games, parsedGame) r.games = append(r.games, parsedGame)
return model.GameID((rune(id))) return model.GameID(strconv.Itoa(id)), nil
} }
func (r *InMemoryRepo) GetGame(id model.GameID) model.Game { func (r *InMemoryRepo) GetGame(id model.GameID) (*model.Game, error) {
i, err := strconv.Atoi(string(id)) i, err := strconv.Atoi(string(id))
if err != nil { if err != nil {
panic(err) return nil, err
} }
return r.games[i] return &r.games[i], nil
} }
func (r *InMemoryRepo) GetAllGames() []model.Game { func (r *InMemoryRepo) GetAllGames() []model.Game {
return r.games return r.games
} }
func (r *InMemoryRepo) GetOrCreatePlayerID(name string) model.PlayerID { func (r *InMemoryRepo) GetOrCreatePlayerID(name string) (model.PlayerID, error) {
id := model.PlayerID(name) id := model.PlayerID(name)
for _, player := range r.players { for _, player := range r.players {
if player.ID == id { if player.ID == id {
return id return id, nil
} }
} }
// No player found. Create one. // No player found. Create one.
r.players = append(r.players, model.NewPlayer(id)) r.players = append(r.players, model.NewPlayer(id))
return id return id, nil
} }
func (r *InMemoryRepo) GetPlayer(id model.PlayerID) *model.Player { func (r *InMemoryRepo) GetPlayer(id model.PlayerID) (*model.Player, error) {
for _, player := range r.players { for _, player := range r.players {
if player.ID == id { if player.ID == id {
return &player return &player, nil
} }
} }
return nil return nil, nil
}
func (r *InMemoryRepo) AddGameResult(result model.GameResult) (model.GameResultID, error) {
id := model.GameResultID(strconv.Itoa(len(r.results)))
result.ID = id
r.results = append(r.results, result)
return id, nil
}
func (r *InMemoryRepo) GetGameResult(id model.GameResultID) (*model.GameResult,error) {
i, err := strconv.Atoi(string(id))
if err != nil {
return nil,nil
}
return &r.results[i],nil
} }

View File

@ -5,10 +5,21 @@ import (
) )
type Repo interface { type Repo interface {
AddGame(game model.InputGame) model.GameID // Add a new game to the repo. ID needs to be nil on argument. PlayerID are fetched beforehand.
GetGame(id model.GameID) model.Game AddGame(model.Game) (model.GameID, error)
GetAllGames() []model.Game
GetOrCreatePlayerID(name string) model.PlayerID //Get a game by ID. Returns nil if not found.
GetPlayer(id model.PlayerID) *model.Player GetGame(model.GameID) (*model.Game, error)
// Get ID of a player. Creates one if not found.
GetOrCreatePlayerID(string) (model.PlayerID, error)
// Get player by id. Returns nil if not found.
GetPlayer(model.PlayerID) (*model.Player, error)
// Adds a game result. ID needs to be nil on argument.
AddGameResult(model.GameResult) (model.GameResultID, error)
// Get a game result by ID. Returns nil if not found.
GetGameResult(model.GameResultID) (*model.GameResult, error)
} }

128
internal/repo/repo_test.go Normal file
View File

@ -0,0 +1,128 @@
package repo_test
import (
"testing"
"time"
"git.kapelle.org/niklas/beerpong-elo/internal/model"
"git.kapelle.org/niklas/beerpong-elo/internal/repo"
"github.com/stretchr/testify/assert"
)
func createRepo() repo.Repo {
return repo.NewInMemoryRepo()
}
func addGameToRepo(repo repo.Repo) model.GameID {
p1, _ := repo.GetOrCreatePlayerID("player1")
p2, _ := repo.GetOrCreatePlayerID("player2")
p3, _ := repo.GetOrCreatePlayerID("player3")
p4, _ := repo.GetOrCreatePlayerID("player4")
id, _ := repo.AddGame(model.Game{
Added: time.Date(2024, 6, 15, 12, 30, 31, 0, time.UTC),
Author: p1,
Team0Player0: p1,
Team0Player1: p2,
Team1Player0: p3,
Team1Player1: p4,
Score: 3,
Overtime: true,
})
return id
}
func TestAddGame(t *testing.T) {
repo := createRepo()
id := addGameToRepo(repo)
retGame, err := repo.GetGame(id)
assert.NoError(t, err)
assert.Equal(t, id, retGame.ID, "Returned ID and ID of retrieved game are not the same")
assert.Equal(t, 3, retGame.Score, "Score is not the same")
assert.Equal(t, true, retGame.Overtime, "Overtime is not the same")
assert.Equal(t, time.Date(2024, 6, 15, 12, 30, 31, 0, time.UTC).Unix(), retGame.Added.Unix(), "Added time is not the same")
}
func TestCreatePlayer(t *testing.T) {
repo := createRepo()
id, err := repo.GetOrCreatePlayerID("player1")
assert.NoError(t, err)
player, err := repo.GetPlayer(id)
assert.NoError(t, err)
assert.NotNil(t, player)
}
func TestPlayerNotFound(t *testing.T) {
repo := createRepo()
result, err := repo.GetPlayer("non existing")
assert.NoError(t, err)
assert.Nil(t, result)
}
func TestAddPlayer(t *testing.T) {
repo := createRepo()
gameID := addGameToRepo(repo)
retGame, err := repo.GetGame(gameID)
assert.NoError(t, err)
result, err := repo.GetPlayer(retGame.Team0Player0)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, retGame.Team0Player0, result.ID)
result, err = repo.GetPlayer(retGame.Team0Player1)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, retGame.Team0Player1, result.ID)
result, err = repo.GetPlayer(retGame.Team1Player0)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, retGame.Team1Player0, result.ID)
result, err = repo.GetPlayer(retGame.Team1Player1)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, retGame.Team1Player1, result.ID)
result, err = repo.GetPlayer(retGame.Author)
assert.NoError(t, err)
assert.NotNil(t, result)
assert.Equal(t, retGame.Team0Player0, result.ID)
}
func TestAddResult(t *testing.T) {
repo := createRepo()
gameID := addGameToRepo(repo)
retGame, err := repo.GetGame(gameID)
assert.NoError(t, err)
gameResult := model.GameResult{
Game: gameID,
Player: retGame.Team0Player0,
}
gameResultID, err := repo.AddGameResult(gameResult)
assert.NoError(t, err)
retResult, err := repo.GetGameResult(gameResultID)
assert.NoError(t, err)
assert.NotNil(t, retResult)
assert.Equal(t, retGame.Team0Player0, retResult.Player, "PlayerID is not the same as the one used in the game")
assert.Equal(t, gameID, retResult.Game, "GameID is not the same as the added Game")
}

View File

@ -1,7 +1,6 @@
package web package web
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
@ -15,13 +14,5 @@ func CreateWebserver(repo repo.Repo) *http.ServeMux {
fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path) fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
}) })
router.HandleFunc("GET /games", func(w http.ResponseWriter, r *http.Request) {
games := repo.GetAllGames()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(games)
})
return router return router
} }