feat: order processing
feat: order commands result save/load
This commit is contained in:
@@ -6,29 +6,19 @@ import (
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
commandNoErrorsStatus = http.StatusNoContent
|
||||
commandDefaultActor = "Gorlum"
|
||||
apiCommandMethod = "PUT"
|
||||
apiCommandPath = "/api/v1/command"
|
||||
validId1 = uuid.New().String()
|
||||
validId2 = uuid.New().String()
|
||||
invalidId = "fd091c69-5976-4775-b2f9-7ba77735afb"
|
||||
)
|
||||
|
||||
func TestCommandRaceQuit(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandRaceQuit{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeRaceQuit},
|
||||
encodeCommand(&order.CommandRaceQuit{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceQuit},
|
||||
}),
|
||||
},
|
||||
}
|
||||
@@ -56,8 +46,8 @@ func TestCommandRaceQuit(t *testing.T) {
|
||||
|
||||
// unrecognized command type
|
||||
payload.Commands = []json.RawMessage{
|
||||
encodeCommand(&rest.CommandRaceQuit{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandType("-unknown-")},
|
||||
encodeCommand(&order.CommandRaceQuit{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandType("-unknown-")},
|
||||
}),
|
||||
}
|
||||
w = httptest.NewRecorder()
|
||||
@@ -95,8 +85,8 @@ func TestCommandRaceVote(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandRaceVote{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeRaceVote},
|
||||
encodeCommand(&order.CommandRaceVote{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceVote},
|
||||
Acceptor: tc.acceptor,
|
||||
}),
|
||||
},
|
||||
@@ -133,8 +123,8 @@ func TestCommandRaceRelation(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandRaceRelation{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeRaceRelation},
|
||||
encodeCommand(&order.CommandRaceRelation{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceRelation},
|
||||
Acceptor: tc.acceptor,
|
||||
Relation: tc.relation,
|
||||
}),
|
||||
@@ -184,8 +174,8 @@ func TestCommandShipClassCreate(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipClassCreate{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipClassCreate},
|
||||
encodeCommand(&order.CommandShipClassCreate{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassCreate},
|
||||
Name: tc.name,
|
||||
Drive: tc.D,
|
||||
Armament: tc.A,
|
||||
@@ -227,8 +217,8 @@ func TestCommandShipClassMerge(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipClassMerge{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipClassMerge},
|
||||
encodeCommand(&order.CommandShipClassMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassMerge},
|
||||
Name: tc.name,
|
||||
Target: tc.target,
|
||||
}),
|
||||
@@ -261,8 +251,8 @@ func TestCommandShipClassRemove(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipClassRemove{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipClassRemove},
|
||||
encodeCommand(&order.CommandShipClassRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassRemove},
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
@@ -300,8 +290,8 @@ func TestCommandShipGroupBreak(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupBreak{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupBreak},
|
||||
encodeCommand(&order.CommandShipGroupBreak{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupBreak},
|
||||
ID: tc.id,
|
||||
NewID: tc.newId,
|
||||
Quantity: tc.quantity,
|
||||
@@ -341,8 +331,8 @@ func TestCommandShipGroupLoad(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupLoad{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupLoad},
|
||||
encodeCommand(&order.CommandShipGroupLoad{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupLoad},
|
||||
ID: tc.id,
|
||||
Cargo: tc.cargo,
|
||||
Quantity: tc.quantity,
|
||||
@@ -378,8 +368,8 @@ func TestCommandShipGroupUnload(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupUnload{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupUnload},
|
||||
encodeCommand(&order.CommandShipGroupUnload{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupUnload},
|
||||
ID: tc.id,
|
||||
Quantity: tc.quantity,
|
||||
}),
|
||||
@@ -414,8 +404,8 @@ func TestCommandShipGroupSend(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupSend{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupSend},
|
||||
encodeCommand(&order.CommandShipGroupSend{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupSend},
|
||||
ID: tc.id,
|
||||
Destination: tc.destination,
|
||||
}),
|
||||
@@ -456,8 +446,8 @@ func TestCommandShipGroupUpgrade(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupUpgrade{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupUpgrade},
|
||||
encodeCommand(&order.CommandShipGroupUpgrade{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupUpgrade},
|
||||
ID: tc.id,
|
||||
Tech: tc.tech,
|
||||
Level: tc.level,
|
||||
@@ -487,8 +477,8 @@ func TestCommandShipGroupMerge(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupMerge{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupMerge},
|
||||
encodeCommand(&order.CommandShipGroupMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupMerge},
|
||||
}),
|
||||
},
|
||||
}
|
||||
@@ -518,8 +508,8 @@ func TestCommandShipGroupDismantle(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupDismantle{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupDismantle},
|
||||
encodeCommand(&order.CommandShipGroupDismantle{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupDismantle},
|
||||
ID: tc.id,
|
||||
}),
|
||||
},
|
||||
@@ -554,8 +544,8 @@ func TestCommandShipGroupTransfer(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupTransfer{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupTransfer},
|
||||
encodeCommand(&order.CommandShipGroupTransfer{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupTransfer},
|
||||
ID: tc.id,
|
||||
Acceptor: tc.acceptor,
|
||||
}),
|
||||
@@ -591,8 +581,8 @@ func TestCommandShipGroupJoinFleet(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandShipGroupJoinFleet{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeShipGroupJoinFleet},
|
||||
encodeCommand(&order.CommandShipGroupJoinFleet{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupJoinFleet},
|
||||
ID: tc.id,
|
||||
Name: tc.name,
|
||||
}),
|
||||
@@ -628,8 +618,8 @@ func TestCommandFleetMerge(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandFleetMerge{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeFleetMerge},
|
||||
encodeCommand(&order.CommandFleetMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeFleetMerge},
|
||||
Name: tc.name,
|
||||
Target: tc.target,
|
||||
}),
|
||||
@@ -664,8 +654,8 @@ func TestCommandFleetSend(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandFleetSend{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeFleetSend},
|
||||
encodeCommand(&order.CommandFleetSend{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeFleetSend},
|
||||
Name: tc.name,
|
||||
Destination: tc.destination,
|
||||
}),
|
||||
@@ -706,8 +696,8 @@ func TestCommandScienceCreate(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandScienceCreate{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeScienceCreate},
|
||||
encodeCommand(&order.CommandScienceCreate{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeScienceCreate},
|
||||
Name: tc.name,
|
||||
Drive: tc.D,
|
||||
Weapons: tc.W,
|
||||
@@ -743,8 +733,8 @@ func TestCommandScienceRemove(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandScienceRemove{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeScienceRemove},
|
||||
encodeCommand(&order.CommandScienceRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeScienceRemove},
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
@@ -779,8 +769,8 @@ func TestCommandPlanetRename(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandPlanetRename{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypePlanetRename},
|
||||
encodeCommand(&order.CommandPlanetRename{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRename},
|
||||
Number: tc.number,
|
||||
Name: tc.name,
|
||||
}),
|
||||
@@ -825,8 +815,8 @@ func TestCommandPlanetProduce(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandPlanetProduce{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypePlanetProduce},
|
||||
encodeCommand(&order.CommandPlanetProduce{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetProduce},
|
||||
Number: tc.number,
|
||||
Production: tc.production,
|
||||
Subject: tc.subject,
|
||||
@@ -866,8 +856,8 @@ func TestCommandPlanetRouteSet(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandPlanetRouteSet{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypePlanetRouteSet},
|
||||
encodeCommand(&order.CommandPlanetRouteSet{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRouteSet},
|
||||
Origin: tc.origin,
|
||||
Destination: tc.destination,
|
||||
LoadType: tc.loadType,
|
||||
@@ -905,8 +895,8 @@ func TestCommandPlanetRouteRemove(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandPlanetRouteRemove{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypePlanetRouteRemove},
|
||||
encodeCommand(&order.CommandPlanetRouteRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRouteRemove},
|
||||
Origin: tc.origin,
|
||||
LoadType: tc.loadType,
|
||||
}),
|
||||
@@ -929,13 +919,13 @@ func TestMultipleCommands(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&rest.CommandRaceRelation{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeRaceRelation},
|
||||
encodeCommand(&order.CommandRaceRelation{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceRelation},
|
||||
Acceptor: "Opponent",
|
||||
Relation: "PEACE",
|
||||
}),
|
||||
encodeCommand(&rest.CommandRaceVote{
|
||||
CommandMeta: rest.CommandMeta{Type: rest.CommandTypeRaceVote},
|
||||
encodeCommand(&order.CommandRaceVote{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceVote},
|
||||
Acceptor: "Opponent",
|
||||
}),
|
||||
},
|
||||
|
||||
@@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
@@ -11,29 +12,30 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
)
|
||||
|
||||
func CommandHandler(c *gin.Context, executor CommandExecutor) {
|
||||
var cmd rest.Command
|
||||
if errorResponded(c, c.ShouldBindJSON(&cmd)) {
|
||||
if errorResponse(c, c.ShouldBindJSON(&cmd)) {
|
||||
return
|
||||
}
|
||||
|
||||
commands := make([]Command, 0)
|
||||
commands := make([]Command, len(cmd.Commands))
|
||||
for i := range cmd.Commands {
|
||||
command, err := parseCommand(cmd.Actor, cmd.Commands[i])
|
||||
if errorResponded(c, err) {
|
||||
if errorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
commands = append(commands, command)
|
||||
commands[i] = command
|
||||
}
|
||||
if len(commands) == 0 {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "no commands given"})
|
||||
errorResponse(c, errors.New("no commands given"))
|
||||
return
|
||||
}
|
||||
|
||||
if errorResponded(c, executor.Execute(commands...)) {
|
||||
if errorResponse(c, executor.Execute(commands...)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -41,56 +43,56 @@ func CommandHandler(c *gin.Context, executor CommandExecutor) {
|
||||
}
|
||||
|
||||
func parseCommand(actor string, c json.RawMessage) (Command, error) {
|
||||
meta := new(rest.CommandMeta)
|
||||
meta := new(order.CommandMeta)
|
||||
if err := json.Unmarshal(c, meta); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch t := meta.Type; t {
|
||||
case rest.CommandTypeRaceQuit:
|
||||
switch t := meta.CmdType; t {
|
||||
case order.CommandTypeRaceQuit:
|
||||
return commandRaceQuit(actor)
|
||||
case rest.CommandTypeRaceVote:
|
||||
case order.CommandTypeRaceVote:
|
||||
return commandRaceVote(actor, c)
|
||||
case rest.CommandTypeRaceRelation:
|
||||
case order.CommandTypeRaceRelation:
|
||||
return commandRaceRelation(actor, c)
|
||||
case rest.CommandTypeShipClassCreate:
|
||||
case order.CommandTypeShipClassCreate:
|
||||
return commandShipClassCreate(actor, c)
|
||||
case rest.CommandTypeShipClassMerge:
|
||||
case order.CommandTypeShipClassMerge:
|
||||
return commandShipClassMerge(actor, c)
|
||||
case rest.CommandTypeShipClassRemove:
|
||||
case order.CommandTypeShipClassRemove:
|
||||
return commandShipClassRemove(actor, c)
|
||||
case rest.CommandTypeShipGroupBreak:
|
||||
case order.CommandTypeShipGroupBreak:
|
||||
return commandShipGroupBreak(actor, c)
|
||||
case rest.CommandTypeShipGroupLoad:
|
||||
case order.CommandTypeShipGroupLoad:
|
||||
return commandShipGroupLoad(actor, c)
|
||||
case rest.CommandTypeShipGroupUnload:
|
||||
case order.CommandTypeShipGroupUnload:
|
||||
return commandShipGroupUnload(actor, c)
|
||||
case rest.CommandTypeShipGroupSend:
|
||||
case order.CommandTypeShipGroupSend:
|
||||
return commandShipGroupSend(actor, c)
|
||||
case rest.CommandTypeShipGroupUpgrade:
|
||||
case order.CommandTypeShipGroupUpgrade:
|
||||
return commandShipGroupUpgrade(actor, c)
|
||||
case rest.CommandTypeShipGroupMerge:
|
||||
case order.CommandTypeShipGroupMerge:
|
||||
return commandShipGroupMerge(actor, c)
|
||||
case rest.CommandTypeShipGroupDismantle:
|
||||
case order.CommandTypeShipGroupDismantle:
|
||||
return commandShipGroupDismantle(actor, c)
|
||||
case rest.CommandTypeShipGroupTransfer:
|
||||
case order.CommandTypeShipGroupTransfer:
|
||||
return commandShipGroupTransfer(actor, c)
|
||||
case rest.CommandTypeShipGroupJoinFleet:
|
||||
case order.CommandTypeShipGroupJoinFleet:
|
||||
return commandShipGroupJoinFleet(actor, c)
|
||||
case rest.CommandTypeFleetMerge:
|
||||
case order.CommandTypeFleetMerge:
|
||||
return commandFleetMerge(actor, c)
|
||||
case rest.CommandTypeFleetSend:
|
||||
case order.CommandTypeFleetSend:
|
||||
return commandFleetSend(actor, c)
|
||||
case rest.CommandTypeScienceCreate:
|
||||
case order.CommandTypeScienceCreate:
|
||||
return commandScienceCreate(actor, c)
|
||||
case rest.CommandTypeScienceRemove:
|
||||
case order.CommandTypeScienceRemove:
|
||||
return commandScienceRemove(actor, c)
|
||||
case rest.CommandTypePlanetRename:
|
||||
case order.CommandTypePlanetRename:
|
||||
return commandPlanetRename(actor, c)
|
||||
case rest.CommandTypePlanetProduce:
|
||||
case order.CommandTypePlanetProduce:
|
||||
return commandPlanetProduce(actor, c)
|
||||
case rest.CommandTypePlanetRouteSet:
|
||||
case order.CommandTypePlanetRouteSet:
|
||||
return commandPlanetRouteSet(actor, c)
|
||||
case rest.CommandTypePlanetRouteRemove:
|
||||
case order.CommandTypePlanetRouteRemove:
|
||||
return commandPlanetRouteRemove(actor, c)
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown comman type: %s", t)
|
||||
@@ -102,7 +104,7 @@ func commandRaceQuit(actor string) (Command, error) {
|
||||
}
|
||||
|
||||
func commandRaceVote(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandRaceVote)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandRaceVote)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -112,7 +114,7 @@ func commandRaceVote(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandRaceRelation(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandRaceRelation)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandRaceRelation)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -122,7 +124,7 @@ func commandRaceRelation(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipClassCreate(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipClassCreate)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipClassCreate)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -132,7 +134,7 @@ func commandShipClassCreate(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipClassMerge(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipClassMerge)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipClassMerge)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -142,7 +144,7 @@ func commandShipClassMerge(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipClassRemove(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipClassRemove)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipClassRemove)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -152,7 +154,7 @@ func commandShipClassRemove(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupBreak(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupBreak)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupBreak)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -162,7 +164,7 @@ func commandShipGroupBreak(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupLoad(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupLoad)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupLoad)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -172,7 +174,7 @@ func commandShipGroupLoad(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupUnload(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupUnload)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupUnload)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -182,7 +184,7 @@ func commandShipGroupUnload(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupSend(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupSend)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupSend)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -192,7 +194,7 @@ func commandShipGroupSend(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupUpgrade(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupUpgrade)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupUpgrade)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -208,7 +210,7 @@ func commandShipGroupMerge(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandShipGroupDismantle(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupDismantle)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupDismantle)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -218,7 +220,7 @@ func commandShipGroupDismantle(actor string, c json.RawMessage) (Command, error)
|
||||
}
|
||||
|
||||
func commandShipGroupTransfer(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupTransfer)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupTransfer)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -228,7 +230,7 @@ func commandShipGroupTransfer(actor string, c json.RawMessage) (Command, error)
|
||||
}
|
||||
|
||||
func commandShipGroupJoinFleet(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandShipGroupJoinFleet)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandShipGroupJoinFleet)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -238,7 +240,7 @@ func commandShipGroupJoinFleet(actor string, c json.RawMessage) (Command, error)
|
||||
}
|
||||
|
||||
func commandFleetMerge(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandFleetMerge)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandFleetMerge)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -248,7 +250,7 @@ func commandFleetMerge(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandFleetSend(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandFleetSend)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandFleetSend)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -258,7 +260,7 @@ func commandFleetSend(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandScienceCreate(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandScienceCreate)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandScienceCreate)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -268,7 +270,7 @@ func commandScienceCreate(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandScienceRemove(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandScienceRemove)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandScienceRemove)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -278,7 +280,7 @@ func commandScienceRemove(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandPlanetRename(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandPlanetRename)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandPlanetRename)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -288,7 +290,7 @@ func commandPlanetRename(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandPlanetProduce(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandPlanetProduce)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandPlanetProduce)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -298,7 +300,7 @@ func commandPlanetProduce(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandPlanetRouteSet(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandPlanetRouteSet)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandPlanetRouteSet)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -308,7 +310,7 @@ func commandPlanetRouteSet(actor string, c json.RawMessage) (Command, error) {
|
||||
}
|
||||
|
||||
func commandPlanetRouteRemove(actor string, c json.RawMessage) (Command, error) {
|
||||
if v, err := unmarshallCommand(c, new(rest.CommandPlanetRouteRemove)); err != nil {
|
||||
if v, err := unmarshallCommand(c, new(order.CommandPlanetRouteRemove)); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return func(c controller.Ctrl) error {
|
||||
@@ -319,17 +321,17 @@ func commandPlanetRouteRemove(actor string, c json.RawMessage) (Command, error)
|
||||
|
||||
// Helpers
|
||||
|
||||
func unmarshallCommand[T rest.DecodableCommand](c json.RawMessage, v *T) (*T, error) {
|
||||
func unmarshallCommand[T order.DecodableCommand](c json.RawMessage, v T) (T, error) {
|
||||
if err := json.Unmarshal(c, v); err != nil {
|
||||
return nil, err
|
||||
return v, err
|
||||
}
|
||||
if err := validateCommand(v); err != nil {
|
||||
return nil, err
|
||||
return v, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func validateCommand(v any) error {
|
||||
func validateCommand(v order.DecodableCommand) error {
|
||||
if ve, ok := binding.Validator.Engine().(*validator.Validate); ok {
|
||||
if err := ve.Struct(v); err != nil {
|
||||
return err
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/iliadenisov/galaxy/internal/controller"
|
||||
e "github.com/iliadenisov/galaxy/internal/error"
|
||||
"github.com/iliadenisov/galaxy/internal/model/game"
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
)
|
||||
|
||||
@@ -18,6 +19,7 @@ type CommandExecutor interface {
|
||||
GenerateTurn() (rest.StateResponse, error)
|
||||
GameState() (rest.StateResponse, error)
|
||||
Execute(cmd ...Command) error
|
||||
ValidateOrder(actor string, cmd ...order.DecodableCommand) error
|
||||
}
|
||||
|
||||
type Command func(controller.Ctrl) error
|
||||
@@ -40,10 +42,10 @@ func NewDefaultConfigExecutor(configurer controller.Configurer) CommandExecutor
|
||||
return &executor{cfg: configurer}
|
||||
}
|
||||
|
||||
func (e *executor) Execute(command ...Command) error {
|
||||
func (e *executor) Execute(cmd ...Command) error {
|
||||
return controller.ExecuteCommand(e.cfg, func(c controller.Ctrl) error {
|
||||
for i := range command {
|
||||
if err := command[i](c); err != nil {
|
||||
for i := range cmd {
|
||||
if err := cmd[i](c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -51,6 +53,10 @@ func (e *executor) Execute(command ...Command) error {
|
||||
})
|
||||
}
|
||||
|
||||
func (e *executor) ValidateOrder(actor string, cmd ...order.DecodableCommand) error {
|
||||
return controller.ValidateOrder(e.cfg, actor, cmd...)
|
||||
}
|
||||
|
||||
func (e *executor) GenerateGame(races []string) (rest.StateResponse, error) {
|
||||
s, err := controller.GenerateGame(e.cfg, races)
|
||||
if err != nil {
|
||||
@@ -90,19 +96,17 @@ func stateResponse(s game.State) rest.StateResponse {
|
||||
return *result
|
||||
}
|
||||
|
||||
func errorResponded(c *gin.Context, err error) bool {
|
||||
func errorResponse(c *gin.Context, err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var ge = new(e.GenericError)
|
||||
|
||||
if v, ok := err.(validator.ValidationErrors); ok {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": v.Error()})
|
||||
return true
|
||||
}
|
||||
|
||||
if errors.As(err, ge) {
|
||||
if ge, ok := errors.AsType[*e.GenericError](err); ok {
|
||||
switch ge.Code {
|
||||
case e.ErrGameNotInitialized:
|
||||
c.Status(http.StatusNotImplemented)
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
func InitHandler(c *gin.Context, executor CommandExecutor) {
|
||||
var init rest.Init
|
||||
if errorResponded(c, c.ShouldBindJSON(&init)) {
|
||||
if errorResponse(c, c.ShouldBindJSON(&init)) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func InitHandler(c *gin.Context, executor CommandExecutor) {
|
||||
}
|
||||
|
||||
s, err := executor.GenerateGame(races)
|
||||
if errorResponded(c, err) {
|
||||
if errorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
"github.com/iliadenisov/galaxy/internal/repo"
|
||||
)
|
||||
|
||||
func OrderHandler(c *gin.Context, executor CommandExecutor) {
|
||||
var cmd rest.Command
|
||||
if errorResponse(c, c.ShouldBindJSON(&cmd)) {
|
||||
return
|
||||
}
|
||||
|
||||
commands := make([]order.DecodableCommand, len(cmd.Commands))
|
||||
for i := range cmd.Commands {
|
||||
command, err := repo.ParseOrder(cmd.Commands[i], validateCommand)
|
||||
if errorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
commands[i] = command
|
||||
}
|
||||
if len(commands) == 0 {
|
||||
errorResponse(c, errors.New("no commands given"))
|
||||
return
|
||||
}
|
||||
|
||||
if errorResponse(c, executor.ValidateOrder(cmd.Actor, commands...)) {
|
||||
return
|
||||
}
|
||||
|
||||
c.Status(http.StatusNoContent)
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func StatusHandler(c *gin.Context, executor CommandExecutor) {
|
||||
state, err := executor.GameState()
|
||||
|
||||
if errorResponded(c, err) {
|
||||
if errorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
func TurnHandler(c *gin.Context, executor CommandExecutor) {
|
||||
state, err := executor.GenerateTurn()
|
||||
|
||||
if errorResponded(c, err) {
|
||||
if errorResponse(c, err) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,941 @@
|
||||
package router_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestOrderRaceQuit(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandRaceQuit{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceQuit},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, commandNoErrorsStatus, w.Code, w.Body)
|
||||
|
||||
// error: actor not set
|
||||
payload.Actor = ""
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code, w.Body)
|
||||
|
||||
payload.Actor = " "
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code, w.Body)
|
||||
|
||||
// unrecognized command type
|
||||
payload.Commands = []json.RawMessage{
|
||||
encodeCommand(&order.CommandRaceQuit{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandType("-unknown-")},
|
||||
}),
|
||||
}
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code, w.Body)
|
||||
|
||||
// error: no commands
|
||||
payload = &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
}
|
||||
|
||||
w = httptest.NewRecorder()
|
||||
req, _ = http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, w.Code, w.Body)
|
||||
}
|
||||
|
||||
func TestOrderRaceVote(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
acceptor string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", "AnotherRace"},
|
||||
{http.StatusBadRequest, "Empty acceptor", ""},
|
||||
{http.StatusBadRequest, "Blank acceptor", " "},
|
||||
{http.StatusBadRequest, "Invalid acceptor", "Race_👽"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandRaceVote{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceVote},
|
||||
Acceptor: tc.acceptor,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderRaceRelation(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
relation string
|
||||
acceptor string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request 1", "WAR", "Opponent"},
|
||||
{commandNoErrorsStatus, "Valid request 2", "PEACE", "Opponent"},
|
||||
{http.StatusBadRequest, "Empty relation", "", "Opponent"},
|
||||
{http.StatusBadRequest, "Blank relation", " ", "Opponent"},
|
||||
{http.StatusBadRequest, "Invalid relation", "Woina", "Opponent"},
|
||||
{http.StatusBadRequest, "Empty acceptor", "WAR", ""},
|
||||
{http.StatusBadRequest, "Blank acceptor", "WAR", " "},
|
||||
{http.StatusBadRequest, "Invalid acceptor", "PEACE", "Race_👽"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandRaceRelation{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceRelation},
|
||||
Acceptor: tc.acceptor,
|
||||
Relation: tc.relation,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipClassCreate(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
D float64
|
||||
A int
|
||||
W, S, C float64
|
||||
name string
|
||||
expectStatus int
|
||||
description string
|
||||
}{
|
||||
{1, 0, 0, 0, 0, "Drone", commandNoErrorsStatus, "Simple Drone"},
|
||||
{1, 1, 1, 0, 0, "Drone", commandNoErrorsStatus, "Armed Drone"},
|
||||
{1, 0, 0, 1, 0, "Drone", commandNoErrorsStatus, "Shielded Drone"},
|
||||
{1, 0, 0, 0, 1, "Drone", commandNoErrorsStatus, "Carrying Drone"},
|
||||
{1, 0, 0, 0, 0, "", http.StatusBadRequest, "Empty name"},
|
||||
{1, 0, 0, 0, 0, " ", http.StatusBadRequest, "Blank name"},
|
||||
{1, 0, 0, 0, 0, "Drone🚀", http.StatusBadRequest, "Invalid name"},
|
||||
{-0.5, 0, 0, 0, 0, "Drone", http.StatusBadRequest, "Drive less than 0"},
|
||||
{0.9, 0, 0, 0, 0, "Drone", http.StatusBadRequest, "Drive less than 1"},
|
||||
{1, 1, 0, 0, 0, "Drone", http.StatusBadRequest, "Ammo without Weapons"},
|
||||
{1, 0, 1, 0, 0, "Drone", http.StatusBadRequest, "Weapons without Ammo"},
|
||||
{1, -1, 1, 0, 0, "Drone", http.StatusBadRequest, "Ammo less than 0"},
|
||||
{1, 1, 0.9, 0, 0, "Drone", http.StatusBadRequest, "Weapons less than 1"},
|
||||
{1, 1, -0.5, 0, 0, "Drone", http.StatusBadRequest, "Weapons less than 0"},
|
||||
{1, 0, 0, -0.5, 0, "Drone", http.StatusBadRequest, "Shields less than 0"},
|
||||
{1, 0, 0, 0.9, 0, "Drone", http.StatusBadRequest, "Shields less than 1"},
|
||||
{1, 0, 0, 0, -0.5, "Drone", http.StatusBadRequest, "Cargo less than 0"},
|
||||
{1, 0, 0, 0, 0.9, "Drone", http.StatusBadRequest, "Cargo less than 1"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipClassCreate{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassCreate},
|
||||
Name: tc.name,
|
||||
Drive: tc.D,
|
||||
Armament: tc.A,
|
||||
Weapons: tc.W,
|
||||
Shields: tc.S,
|
||||
Cargo: tc.C,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipClassMerge(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
name string
|
||||
target string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", "Drone", "Spy"},
|
||||
{http.StatusBadRequest, "Empty name", "", "Spy"},
|
||||
{http.StatusBadRequest, "Blank name", " ", "Spy"},
|
||||
{http.StatusBadRequest, "Invalid name", "Drone🚀", "Spy"},
|
||||
{http.StatusBadRequest, "Empty name", "Drone", " "},
|
||||
{http.StatusBadRequest, "Blank name", "Drone", " "},
|
||||
{http.StatusBadRequest, "Invalid name", "Drone", "Spy🚀"},
|
||||
{http.StatusBadRequest, "Equal names", "Drone", "Drone"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipClassMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassMerge},
|
||||
Name: tc.name,
|
||||
Target: tc.target,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipClassRemove(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
name string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", "Drone"},
|
||||
{http.StatusBadRequest, "Empty name", ""},
|
||||
{http.StatusBadRequest, "Blank name", " "},
|
||||
{http.StatusBadRequest, "Invalid name", "Drone🚀"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipClassRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipClassRemove},
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupBreak(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
newId string
|
||||
quantity int
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, validId2, 1},
|
||||
{commandNoErrorsStatus, "Valid request #2", validId1, validId2, 0},
|
||||
{http.StatusBadRequest, "Negative quantity", validId1, validId2, -1},
|
||||
{http.StatusBadRequest, "Empty id", "", validId2, 1},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, validId2, 1},
|
||||
{http.StatusBadRequest, "Empty newId", validId1, "", 1},
|
||||
{http.StatusBadRequest, "Invalid newId", validId1, invalidId, 1},
|
||||
{http.StatusBadRequest, "Equal id and newId", validId1, validId1, 1},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupBreak{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupBreak},
|
||||
ID: tc.id,
|
||||
NewID: tc.newId,
|
||||
Quantity: tc.quantity,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupLoad(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
cargo string
|
||||
quantity float64
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "COL", 0},
|
||||
{commandNoErrorsStatus, "Valid request #2", validId1, "MAT", 1},
|
||||
{commandNoErrorsStatus, "Valid request #2", validId1, "CAP", 2},
|
||||
{http.StatusBadRequest, "Invalid quantity", validId1, "COL", -0.5},
|
||||
{http.StatusBadRequest, "Empty cargo", validId1, "", 1},
|
||||
{http.StatusBadRequest, "Invalid cargo", validId1, "IND", 1},
|
||||
{http.StatusBadRequest, "Empty id", "", "COL", 1},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, "COL", 1},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupLoad{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupLoad},
|
||||
ID: tc.id,
|
||||
Cargo: tc.cargo,
|
||||
Quantity: tc.quantity,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupUnload(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
quantity float64
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, 0},
|
||||
{commandNoErrorsStatus, "Valid request #2", validId1, 1},
|
||||
{http.StatusBadRequest, "Invalid quantity", validId1, -0.5},
|
||||
{http.StatusBadRequest, "Empty id", "", 1},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, 1},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupUnload{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupUnload},
|
||||
ID: tc.id,
|
||||
Quantity: tc.quantity,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupSend(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
destination int
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, 0},
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, 1},
|
||||
{http.StatusBadRequest, "Invalid destination", validId1, -1},
|
||||
{http.StatusBadRequest, "Empty id", "", 1},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, 1},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupSend{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupSend},
|
||||
ID: tc.id,
|
||||
Destination: tc.destination,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupUpgrade(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
tech string
|
||||
level float64
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "ALL", 0},
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "DRIVE", 1.1},
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "WEAPONS", 2.1},
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "SHIELDS", 3.1},
|
||||
{commandNoErrorsStatus, "Valid request #1", validId1, "CARGO", 4.1},
|
||||
{http.StatusBadRequest, "Negative level", validId1, "DRIVE", -0.5},
|
||||
{http.StatusBadRequest, "Invalid level 0.5", validId1, "DRIVE", 0.5},
|
||||
{http.StatusBadRequest, "Invalid level 1.0", validId1, "DRIVE", 1.0},
|
||||
{http.StatusBadRequest, "Empty id", "", "ALL", 0},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, "ALL", 0},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupUpgrade{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupUpgrade},
|
||||
ID: tc.id,
|
||||
Tech: tc.tech,
|
||||
Level: tc.level,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupMerge(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupMerge},
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupDismantle(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", validId1},
|
||||
{http.StatusBadRequest, "Empty id", ""},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupDismantle{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupDismantle},
|
||||
ID: tc.id,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupTransfer(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
acceptor string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", validId1, "AnotherRace"},
|
||||
{http.StatusBadRequest, "Blank id", "", "AnotherRace"},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, "AnotherRace"},
|
||||
{http.StatusBadRequest, "Empty acceptor", validId1, ""},
|
||||
{http.StatusBadRequest, "Blank acceptor", validId1, " "},
|
||||
{http.StatusBadRequest, "Invalid acceptor", validId1, "Race_👽"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupTransfer{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupTransfer},
|
||||
ID: tc.id,
|
||||
Acceptor: tc.acceptor,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderShipGroupJoinFleet(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
id string
|
||||
name string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", validId1, "AnotherRace"},
|
||||
{http.StatusBadRequest, "Blank id", "", "AnotherRace"},
|
||||
{http.StatusBadRequest, "Invalid id", invalidId, "AnotherRace"},
|
||||
{http.StatusBadRequest, "Empty name", validId1, ""},
|
||||
{http.StatusBadRequest, "Blank name", validId1, " "},
|
||||
{http.StatusBadRequest, "Invalid name", validId1, "Fleet_🚢"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandShipGroupJoinFleet{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeShipGroupJoinFleet},
|
||||
ID: tc.id,
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderFleetMerge(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
name string
|
||||
target string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", "Fleet", "Bomber"},
|
||||
{http.StatusBadRequest, "Empty name", "", "Bomber"},
|
||||
{http.StatusBadRequest, "Invalid name", "Fleet_🚢", "Bomber"},
|
||||
{http.StatusBadRequest, "Empty target", "Fleet", ""},
|
||||
{http.StatusBadRequest, "Invalid target", "Fleet", "Bomber_🚢"},
|
||||
{http.StatusBadRequest, "Equal name and target", "Fleet", "Fleet"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandFleetMerge{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeFleetMerge},
|
||||
Name: tc.name,
|
||||
Target: tc.target,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderFleetSend(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
name string
|
||||
destination int
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", "Fleet", 0},
|
||||
{commandNoErrorsStatus, "Valid request #2", "Fleet", 1},
|
||||
{http.StatusBadRequest, "Invalid destination", "Fleet", -1},
|
||||
{http.StatusBadRequest, "Empty name", "", 1},
|
||||
{http.StatusBadRequest, "Invalid name", "Fleet_🚢", 1},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandFleetSend{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeFleetSend},
|
||||
Name: tc.name,
|
||||
Destination: tc.destination,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderScienceCreate(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
D, W, S, C float64
|
||||
name string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", 0.25, 0.25, 0.25, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Empty name", 0.25, 0.25, 0.25, 0.25, ""},
|
||||
{http.StatusBadRequest, "Invalid name", 0.25, 0.25, 0.25, 0.25, "Science🧪"},
|
||||
{http.StatusBadRequest, "Negative drive", -.5, 0.25, 0.25, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Negative weapons", 0.25, -.5, 0.25, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Negative shields", 0.25, 0.25, -.5, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Negative cargo", 0.25, 0.25, 0.25, -.5, "Science"},
|
||||
{http.StatusBadRequest, "Too big drive", 1.1, 0.25, 0.25, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Too big weapons", 0.25, 1.05, 0.25, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Too big shields", 0.25, 0.25, 1.5, 0.25, "Science"},
|
||||
{http.StatusBadRequest, "Too big cargo", 0.25, 0.25, 0.25, 1.01, "Science"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandScienceCreate{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeScienceCreate},
|
||||
Name: tc.name,
|
||||
Drive: tc.D,
|
||||
Weapons: tc.W,
|
||||
Shields: tc.S,
|
||||
Cargo: tc.C,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderScienceRemove(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
name string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request", "Drone"},
|
||||
{http.StatusBadRequest, "Empty name", ""},
|
||||
{http.StatusBadRequest, "Blank name", " "},
|
||||
{http.StatusBadRequest, "Invalid name", "Science🧪"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandScienceRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeScienceRemove},
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderPlanetRename(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
number int
|
||||
name string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request #1", 0, "HW"},
|
||||
{commandNoErrorsStatus, "Valid request #2", 1, "HW"},
|
||||
{http.StatusBadRequest, "Invalid number", -1, "HW"},
|
||||
{http.StatusBadRequest, "Empty name", 1, ""},
|
||||
{http.StatusBadRequest, "Blank name", 1, " "},
|
||||
{http.StatusBadRequest, "Invalid name", 1, "Planet🪐"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandPlanetRename{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRename},
|
||||
Number: tc.number,
|
||||
Name: tc.name,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderPlanetProduce(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
number int
|
||||
production, subject string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request MAT", 0, "MAT", ""},
|
||||
{commandNoErrorsStatus, "Valid request CAP", 1, "CAP", ""},
|
||||
{commandNoErrorsStatus, "Valid request DRIVE", 2, "DRIVE", ""},
|
||||
{commandNoErrorsStatus, "Valid request WEAPONS", 3, "WEAPONS", ""},
|
||||
{commandNoErrorsStatus, "Valid request SHIELDS", 4, "SHIELDS", ""},
|
||||
{commandNoErrorsStatus, "Valid request CARGO", 5, "CARGO", ""},
|
||||
{commandNoErrorsStatus, "Valid request SCIENCE", 6, "SCIENCE", "Science"},
|
||||
{commandNoErrorsStatus, "Valid request SHIP", 7, "SHIP", "Ship"},
|
||||
{http.StatusBadRequest, "Empty production", 0, "", ""},
|
||||
{http.StatusBadRequest, "Invalid production", 0, "IND", ""},
|
||||
{http.StatusBadRequest, "Invalid planet", -1, "DRIVE", ""},
|
||||
{http.StatusBadRequest, "Empty science subject", 6, "SCIENCE", ""},
|
||||
{http.StatusBadRequest, "Invalid science subject", 6, "SCIENCE", "Science🧪"},
|
||||
{http.StatusBadRequest, "Empty ship subject", 6, "SHIP", ""},
|
||||
{http.StatusBadRequest, "Invalid ship subject", 6, "SHIP", "Ship🚀"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandPlanetProduce{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetProduce},
|
||||
Number: tc.number,
|
||||
Production: tc.production,
|
||||
Subject: tc.subject,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderPlanetRouteSet(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
origin, destination int
|
||||
loadType string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request MAT", 1, 0, "MAT"},
|
||||
{commandNoErrorsStatus, "Valid request CAP", 0, 1, "CAP"},
|
||||
{commandNoErrorsStatus, "Valid request COL", 1, 2, "COL"},
|
||||
{commandNoErrorsStatus, "Valid request EMP", 3, 0, "EMP"},
|
||||
{http.StatusBadRequest, "Empty loadType", 0, 1, ""},
|
||||
{http.StatusBadRequest, "Invalid loadType", 0, 1, "IND"},
|
||||
{http.StatusBadRequest, "Invalid origin", -1, 1, "MAT"},
|
||||
{http.StatusBadRequest, "Invalid destination", 1, -1, "MAT"},
|
||||
{http.StatusBadRequest, "Origin equals destination", 1, 1, "COL"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandPlanetRouteSet{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRouteSet},
|
||||
Origin: tc.origin,
|
||||
Destination: tc.destination,
|
||||
LoadType: tc.loadType,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderPlanetRouteRemove(t *testing.T) {
|
||||
r := setupRouter()
|
||||
|
||||
for _, tc := range []struct {
|
||||
expectStatus int
|
||||
description string
|
||||
origin int
|
||||
loadType string
|
||||
}{
|
||||
{commandNoErrorsStatus, "Valid request MAT", 0, "MAT"},
|
||||
{commandNoErrorsStatus, "Valid request CAP", 1, "CAP"},
|
||||
{commandNoErrorsStatus, "Valid request COL", 2, "COL"},
|
||||
{commandNoErrorsStatus, "Valid request EMP", 0, "EMP"},
|
||||
{http.StatusBadRequest, "Empty loadType", 1, ""},
|
||||
{http.StatusBadRequest, "Invalid loadType", 1, "IND"},
|
||||
{http.StatusBadRequest, "Invalid origin", -1, "MAT"},
|
||||
} {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandPlanetRouteRemove{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypePlanetRouteRemove},
|
||||
Origin: tc.origin,
|
||||
LoadType: tc.loadType,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, tc.expectStatus, w.Code, w.Body)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleCommandOrder(t *testing.T) {
|
||||
e := newExecutor()
|
||||
r := setupRouterExecutor(e)
|
||||
|
||||
payload := &rest.Command{
|
||||
Actor: commandDefaultActor,
|
||||
Commands: []json.RawMessage{
|
||||
encodeCommand(&order.CommandRaceRelation{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceRelation},
|
||||
Acceptor: "Opponent",
|
||||
Relation: "PEACE",
|
||||
}),
|
||||
encodeCommand(&order.CommandRaceVote{
|
||||
CommandMeta: order.CommandMeta{CmdID: id(), CmdType: order.CommandTypeRaceVote},
|
||||
Acceptor: "Opponent",
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
req, _ := http.NewRequest(apiCommandMethod, apiOrderPath, asBody(payload))
|
||||
r.ServeHTTP(w, req)
|
||||
|
||||
assert.Equal(t, commandNoErrorsStatus, w.Code, w.Body)
|
||||
|
||||
assert.Equal(t, 2, e.(*dummyExecutor).CommandsExecuted)
|
||||
}
|
||||
@@ -67,6 +67,7 @@ func setupRouter(executor handler.CommandExecutor) *gin.Engine {
|
||||
groupV1.GET("/status", func(ctx *gin.Context) { handler.StatusHandler(ctx, executor) })
|
||||
groupV1.POST("/init", func(ctx *gin.Context) { handler.InitHandler(ctx, executor) })
|
||||
groupV1.PUT("/command", LimitMiddleware(1), func(ctx *gin.Context) { handler.CommandHandler(ctx, executor) })
|
||||
groupV1.PUT("/order", func(ctx *gin.Context) { handler.OrderHandler(ctx, executor) })
|
||||
groupV1.PUT("/turn", func(ctx *gin.Context) { handler.TurnHandler(ctx, executor) })
|
||||
|
||||
return r
|
||||
|
||||
@@ -2,17 +2,40 @@ package router_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/iliadenisov/galaxy/internal/model/order"
|
||||
"github.com/iliadenisov/galaxy/internal/model/rest"
|
||||
"github.com/iliadenisov/galaxy/internal/router"
|
||||
"github.com/iliadenisov/galaxy/internal/router/handler"
|
||||
)
|
||||
|
||||
var (
|
||||
commandNoErrorsStatus = http.StatusNoContent
|
||||
commandDefaultActor = "Gorlum"
|
||||
apiCommandMethod = "PUT"
|
||||
apiCommandPath = "/api/v1/command"
|
||||
apiOrderPath = "/api/v1/order"
|
||||
validId1 = id()
|
||||
validId2 = id()
|
||||
invalidId = "fd091c69-5976-4775-b2f9-7ba77735afb"
|
||||
)
|
||||
|
||||
func id() string {
|
||||
return uuid.New().String()
|
||||
}
|
||||
|
||||
type dummyExecutor struct {
|
||||
CommandsExecuted int
|
||||
}
|
||||
|
||||
func (e *dummyExecutor) ValidateOrder(actor string, cmd ...order.DecodableCommand) error {
|
||||
e.CommandsExecuted = len(cmd)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *dummyExecutor) Execute(command ...handler.Command) error {
|
||||
e.CommandsExecuted = len(command)
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user