slack-auth-1770277167/services/auth-api/internal/api/handlers/example_test.go
jordan 45269dc680
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Add service component: auth-api
2026-02-05 07:39:35 +00:00

184 lines
4.1 KiB
Go

package handlers
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/go-chi/chi/v5"
"git.threesix.ai/jordan/slack-auth-1770277167/pkg/logging"
)
func newTestLogger() *logging.Logger {
return logging.New(logging.Config{
Level: logging.LevelDebug,
Format: logging.FormatText,
})
}
func TestExample_List(t *testing.T) {
handler := NewExample(newTestLogger())
r := chi.NewRouter()
r.Get("/api/v1/examples", func(w http.ResponseWriter, r *http.Request) {
if err := handler.List(w, r); err != nil {
t.Fatalf("unexpected error: %v", err)
}
})
req := httptest.NewRequest(http.MethodGet, "/api/v1/examples", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status 200, got %d", w.Code)
}
var resp map[string]any
if err := json.NewDecoder(w.Body).Decode(&resp); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
data, ok := resp["data"]
if !ok {
t.Fatal("expected 'data' field in response")
}
items, ok := data.([]any)
if !ok {
t.Fatal("expected 'data' to be an array")
}
if len(items) == 0 {
t.Error("expected at least one item in response")
}
}
func TestExample_Get(t *testing.T) {
handler := NewExample(newTestLogger())
tests := []struct {
name string
id string
wantStatus int
}{
{
name: "valid uuid",
id: "550e8400-e29b-41d4-a716-446655440000",
wantStatus: http.StatusOK,
},
{
name: "invalid uuid",
id: "not-a-uuid",
wantStatus: http.StatusBadRequest,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := chi.NewRouter()
r.Get("/api/v1/examples/{id}", func(w http.ResponseWriter, r *http.Request) {
if err := handler.Get(w, r); err != nil {
// Error-returning handler: convert error to status
w.WriteHeader(http.StatusBadRequest)
return
}
})
req := httptest.NewRequest(http.MethodGet, "/api/v1/examples/"+tt.id, nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != tt.wantStatus {
t.Errorf("expected status %d, got %d", tt.wantStatus, w.Code)
}
})
}
}
func TestExample_Create(t *testing.T) {
handler := NewExample(newTestLogger())
tests := []struct {
name string
body any
wantStatus int
}{
{
name: "valid request",
body: CreateRequest{
Name: "Test Example",
Description: "A test description",
},
wantStatus: http.StatusCreated,
},
{
name: "empty body",
body: nil,
wantStatus: http.StatusBadRequest,
},
{
name: "missing required name",
body: map[string]string{
"description": "no name provided",
},
wantStatus: http.StatusUnprocessableEntity,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := chi.NewRouter()
r.Post("/api/v1/examples", func(w http.ResponseWriter, r *http.Request) {
if err := handler.Create(w, r); err != nil {
// Simulate Wrap behavior for tests
w.WriteHeader(http.StatusBadRequest)
return
}
})
var body []byte
if tt.body != nil {
var err error
body, err = json.Marshal(tt.body)
if err != nil {
t.Fatalf("failed to marshal body: %v", err)
}
}
req := httptest.NewRequest(http.MethodPost, "/api/v1/examples", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
// For the valid case, check 201
if tt.name == "valid request" && w.Code != http.StatusCreated {
t.Errorf("expected status %d, got %d", http.StatusCreated, w.Code)
}
})
}
}
func TestExample_Delete(t *testing.T) {
handler := NewExample(newTestLogger())
r := chi.NewRouter()
r.Delete("/api/v1/examples/{id}", func(w http.ResponseWriter, r *http.Request) {
if err := handler.Delete(w, r); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
})
req := httptest.NewRequest(http.MethodDelete, "/api/v1/examples/550e8400-e29b-41d4-a716-446655440000", nil)
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
if w.Code != http.StatusNoContent {
t.Errorf("expected status 204, got %d", w.Code)
}
}