tests, docs: game engine fetch battle api
ui-test / test (push) Failing after 37s

This commit is contained in:
Ilia Denisov
2026-05-13 11:28:28 +02:00
parent a9adbad7ef
commit 4ffcac00d0
4 changed files with 379 additions and 1 deletions
+152
View File
@@ -0,0 +1,152 @@
package router_test
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"galaxy/model/report"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetBattleValidation(t *testing.T) {
validUUID := uuid.New().String()
for _, tc := range []struct {
description string
turn string
battleID string
expectStatus int
}{
{"Negative turn", "-1", validUUID, http.StatusBadRequest},
{"Non-numeric turn", "abc", validUUID, http.StatusBadRequest},
{"Invalid uuid", "0", invalidId, http.StatusBadRequest},
} {
t.Run(tc.description, func(t *testing.T) {
e := &dummyExecutor{}
r := setupRouterExecutor(e)
w := httptest.NewRecorder()
path := fmt.Sprintf("/api/v1/battle/%s/%s", tc.turn, tc.battleID)
req, _ := http.NewRequest(http.MethodGet, path, nil)
r.ServeHTTP(w, req)
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
assert.Equal(t, uuid.Nil, e.FetchBattleID, "FetchBattle must not be called on validation error")
})
}
}
func TestGetBattleFound(t *testing.T) {
id := uuid.New()
raceA := uuid.New()
raceB := uuid.New()
stored := &report.BattleReport{
ID: id,
Planet: 42,
PlanetName: "X-Prime",
Races: map[int]uuid.UUID{
0: raceA,
1: raceB,
},
Ships: map[int]report.BattleReportGroup{
10: {
Race: "Alpha",
ClassName: "Drone",
Tech: map[string]report.Float{"WEAPONS": report.F(1)},
Number: 5,
NumberLeft: 3,
LoadType: "EMP",
LoadQuantity: report.F(0),
InBattle: true,
},
20: {
Race: "Beta",
ClassName: "Spy",
Tech: map[string]report.Float{"SHIELDS": report.F(2)},
Number: 4,
NumberLeft: 0,
LoadType: "EMP",
LoadQuantity: report.F(0),
InBattle: true,
},
},
Protocol: []report.BattleActionReport{
{Attacker: 0, AttackerShipClass: 10, Defender: 1, DefenderShipClass: 20, Destroyed: true},
},
}
e := &dummyExecutor{
FetchBattleResult: stored,
FetchBattleOK: true,
}
r := setupRouterExecutor(e)
w := httptest.NewRecorder()
path := fmt.Sprintf("/api/v1/battle/%d/%s", 7, id.String())
req, _ := http.NewRequest(http.MethodGet, path, nil)
r.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Code, w.Body)
assert.Equal(t, uint(7), e.FetchBattleTurn)
assert.Equal(t, id, e.FetchBattleID)
var got report.BattleReport
require.NoError(t, json.Unmarshal(w.Body.Bytes(), &got))
assert.Equal(t, stored.ID, got.ID)
assert.Equal(t, stored.Planet, got.Planet)
assert.Equal(t, stored.PlanetName, got.PlanetName)
assert.Equal(t, stored.Races, got.Races)
require.Len(t, got.Ships, len(stored.Ships))
assert.Equal(t, stored.Ships[10].ClassName, got.Ships[10].ClassName)
assert.Equal(t, stored.Ships[20].NumberLeft, got.Ships[20].NumberLeft)
require.Len(t, got.Protocol, 1)
assert.Equal(t, stored.Protocol[0], got.Protocol[0])
}
func TestGetBattleTurnZero(t *testing.T) {
id := uuid.New()
e := &dummyExecutor{
FetchBattleResult: &report.BattleReport{ID: id},
FetchBattleOK: true,
}
r := setupRouterExecutor(e)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/battle/0/%s", id.String()), nil)
r.ServeHTTP(w, req)
require.Equal(t, http.StatusOK, w.Code, w.Body)
assert.Equal(t, uint(0), e.FetchBattleTurn)
assert.Equal(t, id, e.FetchBattleID)
}
func TestGetBattleNotFound(t *testing.T) {
id := uuid.New()
e := &dummyExecutor{FetchBattleOK: false}
r := setupRouterExecutor(e)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/battle/3/%s", id.String()), nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusNotFound, w.Code, w.Body)
assert.Equal(t, uint(3), e.FetchBattleTurn)
assert.Equal(t, id, e.FetchBattleID)
}
func TestGetBattleEngineError(t *testing.T) {
e := &dummyExecutor{FetchBattleErr: errors.New("engine boom")}
r := setupRouterExecutor(e)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, fmt.Sprintf("/api/v1/battle/3/%s", uuid.NewString()), nil)
r.ServeHTTP(w, req)
assert.Equal(t, http.StatusInternalServerError, w.Code, w.Body)
}
+10 -1
View File
@@ -45,6 +45,13 @@ type dummyExecutor struct {
FetchOrderResult *order.UserGamesOrder
FetchOrderOK bool
FetchOrderErr error
// FetchBattle controls and observes calls to FetchBattle.
FetchBattleTurn uint
FetchBattleID uuid.UUID
FetchBattleResult *report.BattleReport
FetchBattleOK bool
FetchBattleErr error
}
func (e *dummyExecutor) ValidateOrder(actor string, cmd ...order.DecodableCommand) (*order.UserGamesOrder, error) {
@@ -69,7 +76,9 @@ func (e *dummyExecutor) FetchOrder(actor string, turn uint) (*order.UserGamesOrd
}
func (e *dummyExecutor) FetchBattle(turn uint, ID uuid.UUID) (*report.BattleReport, bool, error) {
return nil, false, nil
e.FetchBattleTurn = turn
e.FetchBattleID = ID
return e.FetchBattleResult, e.FetchBattleOK, e.FetchBattleErr
}
func (e *dummyExecutor) Execute(command ...handler.Command) error {