Files
member-console/internal/stripetest/mock.go
T
cgalo5758 af8603b3cf Add billing sweep schedule and proration preview
Create Temporal billing sweep schedule, workflow and activities and
register them in the worker/start initialization. Add an HTMX preview
route and banner for plan switches (switch button now GETs a preview;
Confirm posts the switch). Extend the Stripe test mock to support
invoice previews and add integration tests for PreviewSwitch behavior.
2026-05-30 01:16:58 -05:00

84 lines
2.8 KiB
Go

// Package stripetest provides an in-process stripe.Backend that returns canned
// subscription data. It lets tests exercise the fulfillment reconciler's
// "refetch from the Stripe API" path deterministically and offline, without a
// live Stripe account.
package stripetest
import (
"bytes"
"encoding/json"
"errors"
"strings"
stripe "github.com/stripe/stripe-go/v81"
"github.com/stripe/stripe-go/v81/form"
)
// MockBackend implements stripe.Backend, returning canned data for subscription
// Get (GET /v1/subscriptions/{id}) and List (GET /v1/subscriptions). Set Err to
// make every call fail.
type MockBackend struct {
Sub *stripe.Subscription // returned for Get
List []*stripe.Subscription // returned for List
Invoice *stripe.Invoice // returned for invoice create-preview / upcoming
Err error // if set, every call returns it
}
func (m *MockBackend) Call(method, path, key string, params stripe.ParamsContainer, v stripe.LastResponseSetter) error {
if m.Err != nil {
return m.Err
}
var payload any
switch {
case path == "/v1/subscriptions":
payload = &stripe.SubscriptionList{Data: m.List}
case strings.HasPrefix(path, "/v1/subscriptions/"):
payload = m.Sub
case path == "/v1/invoices/create_preview" || path == "/v1/invoices/upcoming":
if m.Invoice == nil {
return errors.New("stripetest: no invoice preview configured")
}
payload = m.Invoice
default:
return errors.New("stripetest: unexpected path " + path)
}
b, err := json.Marshal(payload)
if err != nil {
return err
}
if err := json.Unmarshal(b, v); err != nil {
return err
}
v.SetLastResponse(&stripe.APIResponse{})
return nil
}
func (m *MockBackend) CallRaw(method, path, key string, body *form.Values, params *stripe.Params, v stripe.LastResponseSetter) error {
return m.Call(method, path, key, params, v)
}
func (m *MockBackend) CallStreaming(method, path, key string, params stripe.ParamsContainer, v stripe.StreamingLastResponseSetter) error {
return errors.New("stripetest: streaming not supported")
}
func (m *MockBackend) CallMultipart(method, path, key, boundary string, body *bytes.Buffer, params *stripe.Params, v stripe.LastResponseSetter) error {
return errors.New("stripetest: multipart not supported")
}
func (m *MockBackend) SetMaxNetworkRetries(_ int64) {}
// Install points stripe-go at m (with a dummy API key) and returns a function
// that restores the previous backend and key. Usage:
//
// defer stripetest.Install(m)() // or: t.Cleanup(stripetest.Install(m))
func Install(m *MockBackend) func() {
prevBackend := stripe.GetBackend(stripe.APIBackend)
prevKey := stripe.Key
stripe.SetBackend(stripe.APIBackend, m)
stripe.Key = "sk_test_mock"
return func() {
stripe.SetBackend(stripe.APIBackend, prevBackend)
stripe.Key = prevKey
}
}