go-api/group_test.go
Snider 6f5fb69944 feat: add RouteGroup and StreamGroup interfaces
RouteGroup declares Name, BasePath, and RegisterRoutes for subsystems
to mount their endpoints onto a Gin router group. StreamGroup optionally
declares WebSocket channel names. Gin v1.11.0 added as dependency.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-20 15:44:58 +00:00

90 lines
2.4 KiB
Go

// SPDX-License-Identifier: EUPL-1.2
package api_test
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
api "forge.lthn.ai/core/go-api"
)
// ── Stub implementations ────────────────────────────────────────────────
type stubGroup struct{}
func (s *stubGroup) Name() string { return "stub" }
func (s *stubGroup) BasePath() string { return "/stub" }
func (s *stubGroup) RegisterRoutes(rg *gin.RouterGroup) {
rg.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, api.OK("pong"))
})
}
type stubStreamGroup struct {
stubGroup
}
func (s *stubStreamGroup) Channels() []string {
return []string{"events", "updates"}
}
// ── RouteGroup interface ────────────────────────────────────────────────
func TestRouteGroup_Good_InterfaceSatisfaction(t *testing.T) {
var g api.RouteGroup = &stubGroup{}
if g.Name() != "stub" {
t.Fatalf("expected Name=%q, got %q", "stub", g.Name())
}
if g.BasePath() != "/stub" {
t.Fatalf("expected BasePath=%q, got %q", "/stub", g.BasePath())
}
}
func TestRouteGroup_Good_RegisterRoutes(t *testing.T) {
gin.SetMode(gin.TestMode)
engine := gin.New()
g := &stubGroup{}
rg := engine.Group(g.BasePath())
g.RegisterRoutes(rg)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/stub/ping", nil)
engine.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected status 200, got %d", w.Code)
}
}
// ── StreamGroup interface ───────────────────────────────────────────────
func TestStreamGroup_Good_InterfaceSatisfaction(t *testing.T) {
var g api.StreamGroup = &stubStreamGroup{}
channels := g.Channels()
if len(channels) != 2 {
t.Fatalf("expected 2 channels, got %d", len(channels))
}
if channels[0] != "events" {
t.Fatalf("expected channels[0]=%q, got %q", "events", channels[0])
}
if channels[1] != "updates" {
t.Fatalf("expected channels[1]=%q, got %q", "updates", channels[1])
}
}
func TestStreamGroup_Good_AlsoSatisfiesRouteGroup(t *testing.T) {
sg := &stubStreamGroup{}
// A StreamGroup's embedded stubGroup should also satisfy RouteGroup.
var rg api.RouteGroup = sg
if rg.Name() != "stub" {
t.Fatalf("expected Name=%q, got %q", "stub", rg.Name())
}
}