mirror of
https://github.com/rjNemo/payit
synced 2026-06-06 02:16:40 +00:00
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)
|
|
}
|
|
}
|