package main // 🤖 donate_test.go — the /donate checkout (donate.go): mint path, amount // bounds, CORS scoping, and the off-until-keyed posture. import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "net/url" "strings" "testing" ) func donateTestCloud(t *testing.T) (*httptest.Server, *cloudServer, *url.Values) { t.Helper() stripe, captured := fakeStripe(t) srv, s := newTestCloud(t, okControl(t)) s.donate = newDonateCheckout("sk_test_donate", stripe.URL, "https://elevenmessenger.com") return srv, s, captured } func postDonate(t *testing.T, srv *httptest.Server, body map[string]any) *http.Response { t.Helper() raw, _ := json.Marshal(body) resp, err := http.Post(srv.URL+"/api/donate/checkout", "application/json", bytes.NewReader(raw)) if err != nil { t.Fatal(err) } t.Cleanup(func() { resp.Body.Close() }) return resp } func TestDonateCheckoutMintsSession(t *testing.T) { srv, _, captured := donateTestCloud(t) resp := postDonate(t, srv, map[string]any{"amount_minor": 1100, "currency": "eur"}) if resp.StatusCode != http.StatusOK { t.Fatalf("status = %d, want 200", resp.StatusCode) } if u, _ := decodeBody(t, resp)["url"].(string); !strings.Contains(u, "checkout.stripe.com") { t.Errorf("url = %q", u) } if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "https://elevenmessenger.com" { t.Errorf("CORS origin = %q", got) } f := *captured if f.Get("mode") != "payment" || f.Get("line_items[0][price_data][unit_amount]") != "1100" || f.Get("line_items[0][price_data][currency]") != "eur" { t.Errorf("form = %v", f) } if !strings.HasSuffix(f.Get("success_url"), "/donate/?thanks=1") || !strings.HasSuffix(f.Get("cancel_url"), "/donate/") { t.Errorf("redirects = %q / %q", f.Get("success_url"), f.Get("cancel_url")) } for k := range f { if strings.Contains(k, "customer") || strings.Contains(k, "email") { t.Errorf("donation form leaks a customer field: %s", k) } } } func TestDonateCheckoutValidation(t *testing.T) { srv, _, _ := donateTestCloud(t) for name, body := range map[string]map[string]any{ "below the €1.10 floor": {"amount_minor": 109, "currency": "eur"}, "zero": {"amount_minor": 0, "currency": "eur"}, "over the Stripe cap": {"amount_minor": 100_000_000, "currency": "eur"}, "bad currency": {"amount_minor": 1100, "currency": "chf"}, } { if resp := postDonate(t, srv, body); resp.StatusCode != http.StatusBadRequest { t.Errorf("%s: status = %d, want 400", name, resp.StatusCode) } } } func TestDonateCheckoutUnconfigured(t *testing.T) { srv, s, _ := donateTestCloud(t) s.donate = nil if resp := postDonate(t, srv, map[string]any{"amount_minor": 1100, "currency": "eur"}); resp.StatusCode != http.StatusNotImplemented { t.Fatalf("status = %d, want 501 when unkeyed", resp.StatusCode) } req, _ := http.NewRequest("OPTIONS", srv.URL+"/api/donate/checkout", nil) resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusNotImplemented { t.Errorf("preflight unkeyed: %d, want 501", resp.StatusCode) } }