You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
5.1 KiB

package httpapi
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"juegoland/games2/internal/domain/catalog"
"juegoland/games2/internal/server"
)
func TestPublishedCatalogIsTheOnlyPublicCatalog(t *testing.T) {
registry := catalog.NewRegistry([]catalog.Game{
{ID: "draft", Title: "Borrador", Published: false},
{ID: "conecta4", Version: "1.0.0", Title: "Conecta 4", Summary: "Cuatro fichas en línea", MinPlayers: 2, MaxPlayers: 2, Published: true},
})
handler := NewHandler(server.NewService(registry, time.Now))
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/api/v2/catalog", nil))
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", recorder.Code)
}
if recorder.Header().Get("Cache-Control") != "no-store" {
t.Fatal("catalog response must not be cached before audience policies exist")
}
var body struct {
RequestID string `json:"requestId"`
Data struct {
Items []struct {
ID string `json:"id"`
} `json:"items"`
} `json:"data"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body.RequestID == "" || len(body.Data.Items) != 1 || body.Data.Items[0].ID != "conecta4" {
t.Fatalf("unexpected catalog response: %+v", body)
}
}
func TestBootstrapDoesNotAdvertiseUnavailableFeatures(t *testing.T) {
handler := NewHandler(server.NewService(catalog.NewRegistry(nil), func() time.Time {
return time.Date(2026, time.October, 5, 12, 0, 0, 0, time.UTC)
}))
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, "/api/v2/bootstrap", nil))
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want 200", recorder.Code)
}
var body struct {
Data server.Bootstrap `json:"data"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body.Data.Features.Rooms || body.Data.Features.Chat || !body.Data.Features.Catalog {
t.Fatalf("incorrect advertised features: %+v", body.Data.Features)
}
if len(body.Data.PlatformProtocolVersions) != 0 || len(body.Data.GameProtocolVersions) != 0 {
t.Fatal("unimplemented realtime protocols must not be advertised")
}
if body.Data.DefaultLocale != "es" || len(body.Data.SupportedLocales) != 2 || body.Data.SupportedLocales[1] != "en" {
t.Fatalf("wrong locale capabilities: %+v", body.Data)
}
if body.Data.ServerTime.Format(time.RFC3339) != "2026-10-05T12:00:00Z" {
t.Fatalf("wrong server time: %s", body.Data.ServerTime)
}
}
func TestCatalogNegotiatesLanguageAndLabelsFallback(t *testing.T) {
registry := catalog.NewRegistry([]catalog.Game{
{
ID: "conecta4", Version: "1.0.0", Title: "Conecta 4", Summary: "Cuatro en línea",
DefaultLocale: "es", MinPlayers: 2, MaxPlayers: 2, Published: true,
Translations: map[string]catalog.Translation{
"en": {Title: "Connect Four", Summary: "Four in a row"},
},
},
})
handler := NewHandler(server.NewService(registry, time.Now))
request := httptest.NewRequest(http.MethodGet, "/api/v2/catalog", nil)
request.Header.Set("Accept-Language", "fr, en-GB;q=0.9, es;q=0.5")
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
var body struct {
Data struct {
Items []struct {
Title string `json:"title"`
Locale string `json:"locale"`
} `json:"items"`
} `json:"data"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if len(body.Data.Items) != 1 || body.Data.Items[0].Title != "Connect Four" || body.Data.Items[0].Locale != "en" {
t.Fatalf("unexpected translated catalog: %+v", body)
}
if recorder.Header().Get("Content-Language") != "en" || recorder.Header().Get("Vary") != "Accept-Language" {
t.Fatalf("missing language headers: %+v", recorder.Header())
}
request = httptest.NewRequest(http.MethodGet, "/api/v2/catalog", nil)
request.Header.Set("Accept-Language", "de, en;q=0, es;q=0.5")
recorder = httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
if recorder.Header().Get("Content-Language") != "es" {
t.Fatalf("expected Spanish fallback, got %q", recorder.Header().Get("Content-Language"))
}
}
func TestCatalogDeclaresGameFallbackLanguage(t *testing.T) {
registry := catalog.NewRegistry([]catalog.Game{
{ID: "hundido", Version: "1.0.0", Title: "Hundir la flota", Summary: "Encuentra los barcos", DefaultLocale: "es", MinPlayers: 2, MaxPlayers: 2, Published: true},
})
handler := NewHandler(server.NewService(registry, time.Now))
request := httptest.NewRequest(http.MethodGet, "/api/v2/catalog", nil)
request.Header.Set("Accept-Language", "en")
recorder := httptest.NewRecorder()
handler.ServeHTTP(recorder, request)
var body struct {
Data struct {
Items []struct {
Locale string `json:"locale"`
} `json:"items"`
} `json:"data"`
}
if err := json.Unmarshal(recorder.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if len(body.Data.Items) != 1 || body.Data.Items[0].Locale != "es" || recorder.Header().Get("Content-Language") != "es" {
t.Fatalf("fallback language not declared: %+v, header: %q", body, recorder.Header().Get("Content-Language"))
}
}

Powered by TurnKey Linux.