mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
150 lines
4.1 KiB
Go
150 lines
4.1 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
"github.com/stripe/stripe-go/v83"
|
|
"github.com/stripe/stripe-go/v83/webhook"
|
|
)
|
|
|
|
type stubStripeEventService struct {
|
|
intentCalled bool
|
|
chargeCalled bool
|
|
err error
|
|
}
|
|
|
|
func (s *stubStripeEventService) HandlePaymentIntentSucceeded(ctx context.Context, pi *stripe.PaymentIntent) error {
|
|
s.intentCalled = true
|
|
return s.err
|
|
}
|
|
|
|
func (s *stubStripeEventService) HandleChargeRefunded(ctx context.Context, ch *stripe.Charge) error {
|
|
s.chargeCalled = true
|
|
return s.err
|
|
}
|
|
|
|
func TestHandleStripeWebhookPaymentIntent(t *testing.T) {
|
|
secret := "whsec_test"
|
|
payload := map[string]any{
|
|
"id": "evt_test",
|
|
"type": "payment_intent.succeeded",
|
|
"api_version": stripe.APIVersion,
|
|
"data": map[string]any{
|
|
"object": map[string]any{
|
|
"id": "pi_123",
|
|
"amount": 10000,
|
|
"amount_received": 10000,
|
|
"currency": "eur",
|
|
"status": "succeeded",
|
|
"metadata": map[string]string{"booking_id": "42"},
|
|
"payment_method_types": []string{"card"},
|
|
},
|
|
},
|
|
}
|
|
|
|
payloadBytes, err := json.Marshal(payload)
|
|
if err != nil {
|
|
t.Fatalf("failed to marshal payload: %v", err)
|
|
}
|
|
|
|
ts := time.Now()
|
|
sig := webhook.ComputeSignature(ts, payloadBytes, secret)
|
|
sigHeader := fmt.Sprintf("t=%d,v1=%s", ts.Unix(), hex.EncodeToString(sig))
|
|
if _, err := webhook.ConstructEvent(payloadBytes, sigHeader, secret); err != nil {
|
|
t.Fatalf("signature validation failed in setup: %v", err)
|
|
}
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
req.Header.Set("Stripe-Signature", sigHeader)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
if err := handler(c); err != nil {
|
|
t.Fatalf("handler returned error: %v", err)
|
|
}
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("expected 200, got %d", rec.Code)
|
|
}
|
|
|
|
if !service.intentCalled {
|
|
t.Fatalf("expected payment intent handler to be called")
|
|
}
|
|
}
|
|
|
|
func TestHandleStripeWebhookChargeRefunded(t *testing.T) {
|
|
secret := "whsec_test"
|
|
payload := map[string]any{
|
|
"id": "evt_charge",
|
|
"type": "charge.refunded",
|
|
"api_version": stripe.APIVersion,
|
|
"data": map[string]any{
|
|
"object": map[string]any{
|
|
"id": "ch_123",
|
|
"amount": 5000,
|
|
"amount_refunded": 5000,
|
|
"payment_intent": map[string]any{
|
|
"id": "pi_123",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
payloadBytes, _ := json.Marshal(payload)
|
|
ts := time.Now()
|
|
sig := webhook.ComputeSignature(ts, payloadBytes, secret)
|
|
sigHeader := fmt.Sprintf("t=%d,v1=%s", ts.Unix(), hex.EncodeToString(sig))
|
|
if _, err := webhook.ConstructEvent(payloadBytes, sigHeader, secret); err != nil {
|
|
t.Fatalf("signature validation failed in setup: %v", err)
|
|
}
|
|
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
|
|
req.Header.Set("Stripe-Signature", sigHeader)
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
if err := handler(c); err != nil {
|
|
t.Fatalf("handler returned error: %v", err)
|
|
}
|
|
|
|
if !service.chargeCalled {
|
|
t.Fatalf("expected charge handler to be called")
|
|
}
|
|
}
|
|
|
|
func TestHandleStripeWebhookInvalidSignature(t *testing.T) {
|
|
e := echo.New()
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader("{}"))
|
|
req.Header.Set("Stripe-Signature", "invalid")
|
|
rec := httptest.NewRecorder()
|
|
c := e.NewContext(req, rec)
|
|
|
|
handler := handleStripeWebhook(&stubStripeEventService{}, "secret")
|
|
err := handler(c)
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid signature")
|
|
}
|
|
|
|
if httpErr, ok := err.(*echo.HTTPError); !ok || httpErr.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected 400 HTTP error, got %v", err)
|
|
}
|
|
}
|