package server import ( "net/http" "net/http/httptest" "strings" "testing" "github.com/google/uuid" "scrabble/backend/internal/account" "scrabble/backend/internal/game" "scrabble/backend/internal/session" ) // newRoutingServer builds a Server with non-nil (zero-value) services so the // routes register. The tests below exercise only the request-validation and // routing layers, which return before any service method is called; full // endpoint behaviour against real services is covered by the integration suite. func newRoutingServer() *Server { return New(":0", Deps{ Sessions: &session.Service{}, Accounts: &account.Store{}, Games: &game.Service{}, }) } func do(t *testing.T, s *Server, method, path, body string, headers map[string]string) *httptest.ResponseRecorder { t.Helper() var rdr *strings.Reader if body != "" { rdr = strings.NewReader(body) } else { rdr = strings.NewReader("") } req := httptest.NewRequest(method, path, rdr) req.Header.Set("Content-Type", "application/json") for k, v := range headers { req.Header.Set(k, v) } rec := httptest.NewRecorder() s.Handler().ServeHTTP(rec, req) return rec } func TestProfileRequiresUserID(t *testing.T) { rec := do(t, newRoutingServer(), http.MethodGet, "/api/v1/user/profile", "", nil) if rec.Code != http.StatusUnauthorized { t.Fatalf("profile without X-User-ID = %d, want 401", rec.Code) } } func TestResolveSessionRejectsEmptyToken(t *testing.T) { rec := do(t, newRoutingServer(), http.MethodPost, "/api/v1/internal/sessions/resolve", `{}`, nil) if rec.Code != http.StatusBadRequest { t.Fatalf("resolve with empty token = %d, want 400", rec.Code) } } func TestSubmitPlayRejectsBadDirection(t *testing.T) { headers := map[string]string{"X-User-ID": uuid.New().String()} path := "/api/v1/user/games/" + uuid.New().String() + "/play" rec := do(t, newRoutingServer(), http.MethodPost, path, `{"dir":"X","tiles":[]}`, headers) if rec.Code != http.StatusBadRequest { t.Fatalf("submit play bad dir = %d, want 400", rec.Code) } } func TestSubmitPlayRejectsBadGameID(t *testing.T) { headers := map[string]string{"X-User-ID": uuid.New().String()} rec := do(t, newRoutingServer(), http.MethodPost, "/api/v1/user/games/not-a-uuid/play", `{"dir":"H"}`, headers) if rec.Code != http.StatusBadRequest { t.Fatalf("submit play bad game id = %d, want 400", rec.Code) } }