feat: add a new endpoint - GET /api/v1/versions/:code/servers #47
|
@ -16,10 +16,10 @@ type Server struct {
|
|||
Config ServerConfig `json:"config"`
|
||||
BuildingInfo BuildingInfo `json:"buildingInfo"`
|
||||
UnitInfo UnitInfo `json:"unitInfo"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
PlayerDataUpdatedAt NullTime `json:"playerDataUpdatedAt"`
|
||||
TribeDataUpdatedAt NullTime `json:"tribeDataUpdatedAt"`
|
||||
VillageDataUpdatedAt NullTime `json:"villageDataUpdatedAt"`
|
||||
CreatedAt time.Time `json:"createdAt" format:"date-time"`
|
||||
PlayerDataUpdatedAt NullTime `json:"playerDataUpdatedAt" swaggertype:"string" format:"date-time" extensions:"x-nullable"`
|
||||
TribeDataUpdatedAt NullTime `json:"tribeDataUpdatedAt" swaggertype:"string" format:"date-time" extensions:"x-nullable"`
|
||||
VillageDataUpdatedAt NullTime `json:"villageDataUpdatedAt" swaggertype:"string" format:"date-time" extensions:"x-nullable"`
|
||||
} // @name Server
|
||||
|
||||
func NewServer(s domain.Server) Server {
|
||||
|
@ -48,3 +48,17 @@ func NewServer(s domain.Server) Server {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
type ListServersResp struct {
|
||||
Data []Server `json:"data"`
|
||||
} // @name ListServersResp
|
||||
|
||||
func NewListServersResp(servers []domain.Server) ListServersResp {
|
||||
resp := ListServersResp{
|
||||
Data: make([]Server, 0, len(servers)),
|
||||
}
|
||||
for _, srv := range servers {
|
||||
resp.Data = append(resp.Data, NewServer(srv))
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
|
|
@ -33,6 +33,52 @@ func TestNewServer(t *testing.T) {
|
|||
assertServer(t, srv, model.NewServer(srv))
|
||||
}
|
||||
|
||||
func TestNewListServersResp(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
servers := []domain.Server{
|
||||
{
|
||||
Key: "pl151",
|
||||
URL: "https://pl151.plemiona.pl",
|
||||
Open: true,
|
||||
Special: false,
|
||||
NumPlayers: 1234,
|
||||
NumTribes: 1235,
|
||||
NumVillages: 1236,
|
||||
Config: domain.ServerConfig{},
|
||||
BuildingInfo: domain.BuildingInfo{},
|
||||
UnitInfo: domain.UnitInfo{},
|
||||
CreatedAt: time.Now().Add(-20 * time.Hour),
|
||||
PlayerDataUpdatedAt: time.Time{},
|
||||
TribeDataUpdatedAt: time.Now(),
|
||||
VillageDataUpdatedAt: time.Now().Add(-5 * time.Hour),
|
||||
VersionCode: "pl",
|
||||
},
|
||||
{
|
||||
Key: "pl143",
|
||||
URL: "https://pl143.plemiona.pl",
|
||||
Open: false,
|
||||
Special: false,
|
||||
NumPlayers: 2234,
|
||||
NumTribes: 2235,
|
||||
NumVillages: 2236,
|
||||
Config: domain.ServerConfig{},
|
||||
BuildingInfo: domain.BuildingInfo{},
|
||||
UnitInfo: domain.UnitInfo{},
|
||||
CreatedAt: time.Now().Add(-40 * time.Hour),
|
||||
PlayerDataUpdatedAt: time.Now().Add(-1 * time.Second),
|
||||
TribeDataUpdatedAt: time.Now().Add(-5 * time.Second),
|
||||
VillageDataUpdatedAt: time.Now(),
|
||||
VersionCode: "pl",
|
||||
},
|
||||
}
|
||||
resp := model.NewListServersResp(servers)
|
||||
assert.Len(t, resp.Data, len(servers))
|
||||
for i, srv := range resp.Data {
|
||||
assertServer(t, servers[i], srv)
|
||||
}
|
||||
}
|
||||
|
||||
func assertServer(tb testing.TB, dsrv domain.Server, rsrv model.Server) {
|
||||
tb.Helper()
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ type Unit struct {
|
|||
DefenseCavalry int16 `json:"defenseCavalry"`
|
||||
DefenseArcher int16 `json:"defenseArcher"`
|
||||
Carry int16 `json:"carry"`
|
||||
}
|
||||
} // @name Unit
|
||||
|
||||
type UnitInfo struct {
|
||||
Spear Unit `json:"spear"`
|
||||
|
|
|
@ -47,7 +47,7 @@ func NewRouter(cfg RouterConfig) *chi.Mux {
|
|||
versionHandler := &version{
|
||||
svc: cfg.VersionService,
|
||||
}
|
||||
serverHandler := &Server{
|
||||
serverHandler := &server{
|
||||
svc: cfg.ServerService,
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,10 @@ func NewRouter(cfg RouterConfig) *chi.Mux {
|
|||
r.Get("/", versionHandler.list)
|
||||
r.Route("/{versionCode}", func(r chi.Router) {
|
||||
r.Get("/", versionHandler.getByCode)
|
||||
r.Route("/servers", func(r chi.Router) {
|
||||
r.Get("/", serverHandler.list)
|
||||
})
|
||||
r.With(verifyVersionCode(cfg.VersionService)).
|
||||
Route("/servers", func(r chi.Router) {
|
||||
r.Get("/", serverHandler.list)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -103,6 +104,18 @@ func methodNotAllowedHandler(w http.ResponseWriter, _ *http.Request) {
|
|||
})
|
||||
}
|
||||
|
||||
func verifyVersionCode(versionSvc VersionService) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if _, err := versionSvc.GetByCode(r.Context(), chi.URLParam(r, "versionCode")); err != nil {
|
||||
renderErr(w, err)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func renderErr(w http.ResponseWriter, err error) {
|
||||
var convError domain.Error
|
||||
if !errors.As(err, &convError) {
|
||||
|
|
|
@ -4,8 +4,11 @@ import (
|
|||
"context"
|
||||
"net/http"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/rest/internal/model"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"gitea.dwysokinski.me/twhelp/core/internal/domain"
|
||||
)
|
||||
|
||||
//counterfeiter:generate -o internal/mock/server_service.gen.go . ServerService
|
||||
|
@ -13,18 +16,37 @@ type ServerService interface {
|
|||
List(ctx context.Context, params domain.ListServersParams) ([]domain.Server, int64, error)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
type server struct {
|
||||
svc ServerService
|
||||
}
|
||||
|
||||
func NewServer(svc ServerService) *Server {
|
||||
return &Server{svc: svc}
|
||||
}
|
||||
|
||||
func (s *Server) Register(r chi.Router) {
|
||||
r.Get("/api/v1/versions/{versionCode}/servers", s.list)
|
||||
}
|
||||
|
||||
func (s *Server) list(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// @ID listServers
|
||||
// @Summary List servers
|
||||
// @Description List all servers
|
||||
// @Tags versions,servers
|
||||
// @Produce json
|
||||
// @Success 200 {object} model.ListServersResp
|
||||
// @Success 404 {object} model.ErrorResp
|
||||
// @Failure 500 {object} model.ErrorResp
|
||||
// @Header 200 {integer} X-Total-Count "Total number of records"
|
||||
// @Param versionCode path string true "Version code"
|
||||
// @Router /versions/{versionCode}/servers [get]
|
||||
func (s *server) list(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
// TODO: add pagination / filters
|
||||
servers, count, err := s.svc.List(ctx, domain.ListServersParams{
|
||||
Special: domain.NullBool{
|
||||
Valid: true,
|
||||
Bool: false,
|
||||
},
|
||||
Open: domain.NullBool{},
|
||||
VersionCodes: []string{chi.URLParamFromCtx(ctx, "versionCode")},
|
||||
Count: true,
|
||||
})
|
||||
if err != nil {
|
||||
renderErr(w, err)
|
||||
return
|
||||
}
|
||||
setTotalCountHeader(w.Header(), count)
|
||||
renderJSON(w, http.StatusOK, model.NewListServersResp(servers))
|
||||
}
|
||||
|
|
Reference in New Issue
Block a user