newdrive/internal/transport/httpapi/server_test.go
Elijah 077cf7601a
Some checks failed
CI / Backend (push) Failing after 4s
CI / Frontend (push) Successful in 11s
CI / Contracts and repository policy (push) Failing after 5s
CI / Container (push) Has been skipped
Initial phase 1 baseline implementation
2026-07-16 19:14:01 -07:00

98 lines
2.8 KiB
Go

package httpapi
import (
"context"
"errors"
"io"
"log/slog"
"net/http"
"net/http/httptest"
"strings"
"testing"
"drive.local/drivev2/internal/application"
"drive.local/drivev2/internal/config"
)
type systemServiceStub struct {
readinessErr error
setupStatus application.SetupStatus
setupErr error
}
func (s systemServiceStub) Readiness(context.Context) error {
return s.readinessErr
}
func (s systemServiceStub) SetupStatus(context.Context) (application.SetupStatus, error) {
return s.setupStatus, s.setupErr
}
func TestLiveHealth(t *testing.T) {
t.Parallel()
server := NewServer(
config.Config{HTTPAddress: ":0", WebRoot: t.TempDir()},
slog.New(slog.NewTextHandler(io.Discard, nil)),
systemServiceStub{},
http.NotFoundHandler(),
)
request := httptest.NewRequest(http.MethodGet, "/health/live", nil)
recorder := httptest.NewRecorder()
server.httpServer.Handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
}
if !strings.Contains(recorder.Body.String(), `"status":"live"`) {
t.Fatalf("unexpected body: %s", recorder.Body.String())
}
}
func TestReadinessReportsDependencyFailure(t *testing.T) {
t.Parallel()
server := NewServer(
config.Config{HTTPAddress: ":0", WebRoot: t.TempDir()},
slog.New(slog.NewTextHandler(io.Discard, nil)),
systemServiceStub{readinessErr: errors.New("database unavailable")},
http.NotFoundHandler(),
)
request := httptest.NewRequest(http.MethodGet, "/health/ready", nil)
recorder := httptest.NewRecorder()
server.httpServer.Handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusServiceUnavailable {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusServiceUnavailable)
}
if contentType := recorder.Header().Get("Content-Type"); contentType != "application/problem+json" {
t.Fatalf("Content-Type = %q, want application/problem+json", contentType)
}
if !strings.Contains(recorder.Body.String(), `"code":"dependency_unavailable"`) {
t.Fatalf("unexpected body: %s", recorder.Body.String())
}
}
func TestSetupStatusUsesApplicationService(t *testing.T) {
t.Parallel()
server := NewServer(
config.Config{HTTPAddress: ":0", WebRoot: t.TempDir()},
slog.New(slog.NewTextHandler(io.Discard, nil)),
systemServiceStub{setupStatus: application.SetupStatus{Initialized: true, Phase: "phase-1", Version: "test"}},
http.NotFoundHandler(),
)
request := httptest.NewRequest(http.MethodGet, "/api/v1/setup/status", nil)
recorder := httptest.NewRecorder()
server.httpServer.Handler.ServeHTTP(recorder, request)
if recorder.Code != http.StatusOK {
t.Fatalf("status = %d, want %d", recorder.Code, http.StatusOK)
}
if !strings.Contains(recorder.Body.String(), `"initialized":true`) {
t.Fatalf("unexpected body: %s", recorder.Body.String())
}
}