mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stripe/stripe-go/v83"
|
|
)
|
|
|
|
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)
|
|
}
|
|
|
|
restore := stubConstructEvent(stripe.EventTypePaymentIntentSucceeded, payloadBytes)
|
|
defer restore()
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Stripe-Signature", "test")
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler(rec, req)
|
|
|
|
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)
|
|
restore := stubConstructEvent(stripe.EventTypeChargeRefunded, payloadBytes)
|
|
defer restore()
|
|
|
|
service := &stubStripeEventService{}
|
|
handler := handleStripeWebhook(service, secret)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader(string(payloadBytes)))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
req.Header.Set("Stripe-Signature", "test")
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler(rec, req)
|
|
|
|
if !service.chargeCalled {
|
|
t.Fatalf("expected charge handler to be called")
|
|
}
|
|
}
|
|
|
|
func TestHandleStripeWebhookInvalidSignature(t *testing.T) {
|
|
req := httptest.NewRequest(http.MethodPost, "/webhooks/stripe", strings.NewReader("{}"))
|
|
req.Header.Set("Stripe-Signature", "invalid")
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler := handleStripeWebhook(&stubStripeEventService{}, "secret")
|
|
handler(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Fatalf("expected 400 status, got %d", rec.Code)
|
|
}
|
|
}
|
|
|
|
func stubConstructEvent(eventType stripe.EventType, payload []byte) func() {
|
|
original := constructEvent
|
|
constructEvent = func(_ []byte, _ string, _ string) (stripe.Event, error) {
|
|
event := stripe.Event{Type: eventType}
|
|
event.Data = &stripe.EventData{Raw: payload}
|
|
return event, nil
|
|
}
|
|
return func() { constructEvent = original }
|
|
}
|