mirror of
https://github.com/rjNemo/payit
synced 2026-06-06 02:16:40 +00:00
Introduced LoggerMiddleware for HTTP request logging. Refactored handler methods to return http.HandlerFunc for improved composability. Updated route registration and tests to use new handler signatures.
127 lines
3.5 KiB
Go
127 lines
3.5 KiB
Go
package web
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/rjNemo/payit/internal/payments"
|
|
)
|
|
|
|
type fakeCheckoutService struct {
|
|
result payments.CheckoutSessionResult
|
|
err error
|
|
req payments.CheckoutSessionRequest
|
|
}
|
|
|
|
func (f *fakeCheckoutService) CreateSession(ctx context.Context, req payments.CheckoutSessionRequest) (payments.CheckoutSessionResult, error) {
|
|
f.req = req
|
|
if f.err != nil {
|
|
return payments.CheckoutSessionResult{}, f.err
|
|
}
|
|
return f.result, nil
|
|
}
|
|
|
|
func TestCreateCheckoutSessionSuccess(t *testing.T) {
|
|
handler := &Handler{
|
|
checkout: &fakeCheckoutService{
|
|
result: payments.CheckoutSessionResult{ID: "cs_test_1", URL: "https://stripe.test/checkout"},
|
|
},
|
|
}
|
|
|
|
body, _ := json.Marshal(map[string]int{"quantity": 2})
|
|
req := httptest.NewRequest(http.MethodPost, "/api/checkout", bytes.NewReader(body))
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler.createCheckoutSession()(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", rec.Code)
|
|
}
|
|
|
|
if ct := rec.Header().Get("Content-Type"); ct != "application/json" {
|
|
t.Fatalf("expected json content type, got %s", ct)
|
|
}
|
|
|
|
var payload payments.CheckoutSessionResult
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
|
t.Fatalf("expected valid json response: %v", err)
|
|
}
|
|
if payload.ID != "cs_test_1" || payload.URL == "" {
|
|
t.Fatalf("unexpected payload: %#v", payload)
|
|
}
|
|
|
|
svc := handler.checkout.(*fakeCheckoutService)
|
|
if svc.req.Quantity != 2 {
|
|
t.Fatalf("expected quantity 2, got %d", svc.req.Quantity)
|
|
}
|
|
}
|
|
|
|
func TestCreateCheckoutSessionDefaultsQuantity(t *testing.T) {
|
|
fakeSvc := &fakeCheckoutService{
|
|
result: payments.CheckoutSessionResult{ID: "cs_test_1"},
|
|
}
|
|
handler := &Handler{checkout: fakeSvc}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/checkout", http.NoBody)
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler.createCheckoutSession()(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("expected status 200, got %d", rec.Code)
|
|
}
|
|
if fakeSvc.req.Quantity != 0 {
|
|
t.Fatalf("expected zero quantity in request, got %d", fakeSvc.req.Quantity)
|
|
}
|
|
}
|
|
|
|
func TestCreateCheckoutSessionRejectsInvalidJSON(t *testing.T) {
|
|
handler := &Handler{checkout: &fakeCheckoutService{}}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/checkout", bytes.NewBufferString("{"))
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler.createCheckoutSession()(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected status 400, got %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestCreateCheckoutSessionStripeFailure(t *testing.T) {
|
|
handler := &Handler{
|
|
checkout: &fakeCheckoutService{err: errors.New("stripe failure")},
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/checkout", http.NoBody)
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler.createCheckoutSession()(rec, req)
|
|
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Fatalf("expected status 500, got %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func TestCreateCheckoutSessionMethodNotAllowed(t *testing.T) {
|
|
handler := &Handler{checkout: &fakeCheckoutService{}}
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("POST /api/checkout", handler.createCheckoutSession())
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/api/checkout", http.NoBody)
|
|
rec := httptest.NewRecorder()
|
|
|
|
mux.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusMethodNotAllowed {
|
|
t.Fatalf("expected status 405, got %d", rec.Code)
|
|
}
|
|
if allow := rec.Header().Get("Allow"); allow != http.MethodPost {
|
|
t.Fatalf("expected Allow header to be POST, got %s", allow)
|
|
}
|
|
}
|