Add unit tests for middleware, models, services, handlers, and repository helpers
All checks were successful
CI / ci (push) Successful in 35s
All checks were successful
CI / ci (push) Successful in 35s
This commit is contained in:
114
internal/handler/handler_test.go
Normal file
114
internal/handler/handler_test.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHealthHandler(t *testing.T) {
|
||||
h := NewHealthHandler()
|
||||
req := httptest.NewRequest("GET", "/health", nil)
|
||||
rr := httptest.NewRecorder()
|
||||
h.Health(rr, req)
|
||||
|
||||
if rr.Code != http.StatusOK {
|
||||
t.Errorf("expected 200, got %d", rr.Code)
|
||||
}
|
||||
|
||||
var resp map[string]string
|
||||
json.NewDecoder(rr.Body).Decode(&resp)
|
||||
if resp["status"] != "ok" {
|
||||
t.Errorf("expected status ok, got %s", resp["status"])
|
||||
}
|
||||
if resp["service"] != "homelab-api" {
|
||||
t.Errorf("expected service homelab-api, got %s", resp["service"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteJSON(t *testing.T) {
|
||||
rr := httptest.NewRecorder()
|
||||
data := map[string]string{"hello": "world"}
|
||||
writeJSON(rr, data, http.StatusCreated)
|
||||
|
||||
if rr.Code != http.StatusCreated {
|
||||
t.Errorf("expected 201, got %d", rr.Code)
|
||||
}
|
||||
if ct := rr.Header().Get("Content-Type"); ct != "application/json" {
|
||||
t.Errorf("expected application/json, got %s", ct)
|
||||
}
|
||||
|
||||
var resp map[string]string
|
||||
json.NewDecoder(rr.Body).Decode(&resp)
|
||||
if resp["hello"] != "world" {
|
||||
t.Errorf("expected world, got %s", resp["hello"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteError(t *testing.T) {
|
||||
rr := httptest.NewRecorder()
|
||||
writeError(rr, "something went wrong", http.StatusBadRequest)
|
||||
|
||||
if rr.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", rr.Code)
|
||||
}
|
||||
|
||||
var resp map[string]string
|
||||
json.NewDecoder(rr.Body).Decode(&resp)
|
||||
if resp["error"] != "something went wrong" {
|
||||
t.Errorf("expected 'something went wrong', got %s", resp["error"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterestHandler_Unauthorized(t *testing.T) {
|
||||
h := &InterestHandler{secretKey: "my-secret"}
|
||||
|
||||
t.Run("missing key", func(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/internal/calculate-interest", nil)
|
||||
rr := httptest.NewRecorder()
|
||||
h.CalculateInterest(rr, req)
|
||||
if rr.Code != http.StatusUnauthorized {
|
||||
t.Errorf("expected 401, got %d", rr.Code)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("wrong key", func(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/internal/calculate-interest", nil)
|
||||
req.Header.Set("X-Internal-Key", "wrong-key")
|
||||
rr := httptest.NewRecorder()
|
||||
h.CalculateInterest(rr, req)
|
||||
if rr.Code != http.StatusUnauthorized {
|
||||
t.Errorf("expected 401, got %d", rr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Test request validation (without real service, just checking decoding)
|
||||
func TestDecodeInvalidJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
body string
|
||||
handler http.HandlerFunc
|
||||
}{
|
||||
{"invalid json", "{bad", func(w http.ResponseWriter, r *http.Request) {
|
||||
var req struct{ Email string }
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, "invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req := httptest.NewRequest("POST", "/test", bytes.NewBufferString(tt.body))
|
||||
rr := httptest.NewRecorder()
|
||||
tt.handler(rr, req)
|
||||
if rr.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", rr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user