mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-08-01 00:18:07 -04:00
115 lines
4.4 KiB
Go
115 lines
4.4 KiB
Go
//go:build !nopayments
|
|
|
|
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/mock"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stripe/stripe-go/v74"
|
|
"heckel.io/ntfy/v2/user"
|
|
)
|
|
|
|
// stripeCheckoutMock wires up a testStripeAPI for a successful checkout of user u, with the given
|
|
// billing email on the session's CustomerDetails.
|
|
func stripeCheckoutMock(u *user.User, billingEmail string) *testStripeAPI {
|
|
m := &testStripeAPI{}
|
|
m.On("GetSession", "SOMETOKEN").Return(&stripe.CheckoutSession{
|
|
ClientReferenceID: u.ID,
|
|
Customer: &stripe.Customer{ID: "acct_5555"},
|
|
Subscription: &stripe.Subscription{ID: "sub_1234"},
|
|
CustomerDetails: &stripe.CheckoutSessionCustomerDetails{Email: billingEmail},
|
|
}, nil)
|
|
m.On("GetSubscription", "sub_1234").Return(&stripe.Subscription{
|
|
ID: "sub_1234",
|
|
Status: stripe.SubscriptionStatusActive,
|
|
CurrentPeriodEnd: 123456789,
|
|
Items: &stripe.SubscriptionItemList{
|
|
Data: []*stripe.SubscriptionItem{
|
|
{Price: &stripe.Price{ID: "price_1234", Recurring: &stripe.PriceRecurring{Interval: stripe.PriceRecurringIntervalMonth}}},
|
|
},
|
|
},
|
|
}, nil)
|
|
m.On("UpdateCustomer", "acct_5555", mock.Anything).Return(&stripe.Customer{}, nil)
|
|
return m
|
|
}
|
|
|
|
func newCheckoutEmailTestServer(t *testing.T, databaseURL string) (*Server, *captureMailer, *user.User) {
|
|
c := newTestConfigWithAuthFile(t, databaseURL)
|
|
c.StripeSecretKey = "secret key"
|
|
c.BaseURL = "https://ntfy.example.com"
|
|
c.SMTPSenderAddr = "localhost:25"
|
|
c.SMTPSenderFrom = "noreply@example.com"
|
|
s := newTestServer(t, c)
|
|
mailer := newCaptureMailer()
|
|
s.mailer = mailer
|
|
require.Nil(t, s.userManager.AddTier(&user.Tier{
|
|
ID: "ti_123", Code: "starter", StripeMonthlyPriceID: "price_1234", MessageLimit: 100, MessageExpiryDuration: time.Hour,
|
|
}))
|
|
require.Nil(t, s.userManager.AddUser("phil", "phil", user.RoleUser, false))
|
|
u, err := s.userManager.User("phil")
|
|
require.Nil(t, err)
|
|
return s, mailer, u
|
|
}
|
|
|
|
func TestPayments_Checkout_SendsBillingEmailVerification(t *testing.T) {
|
|
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
|
s, mailer, u := newCheckoutEmailTestServer(t, databaseURL)
|
|
defer s.closeDatabases()
|
|
s.stripe = stripeCheckoutMock(u, "billing@example.com")
|
|
|
|
rr := request(t, s, "GET", "/v1/account/billing/subscription/success/SOMETOKEN", "", nil)
|
|
require.Equal(t, 303, rr.Code)
|
|
|
|
// A verification link was auto-sent to the billing email; clicking it verifies + sets primary
|
|
link := mailer.verifyLinks["billing@example.com"]
|
|
require.NotEmpty(t, link)
|
|
token := tokenFromLink(t, link, "https://ntfy.example.com/account/email/verify/")
|
|
require.Equal(t, 200, request(t, s, "POST", "/v1/account/email/verify", fmt.Sprintf(`{"token":"%s"}`, token), nil).Code)
|
|
|
|
emails, err := s.userManager.Emails(u.ID)
|
|
require.Nil(t, err)
|
|
require.Equal(t, []string{"billing@example.com"}, emails.Strings())
|
|
primary, err := s.userManager.PrimaryEmail(u.ID)
|
|
require.Nil(t, err)
|
|
require.Equal(t, "billing@example.com", primary)
|
|
})
|
|
}
|
|
|
|
func TestPayments_Checkout_SkipsBillingEmailWhenAlreadyVerified(t *testing.T) {
|
|
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
|
s, mailer, u := newCheckoutEmailTestServer(t, databaseURL)
|
|
defer s.closeDatabases()
|
|
s.stripe = stripeCheckoutMock(u, "billing@example.com")
|
|
|
|
// User already has a verified email -> no auto-send on checkout
|
|
require.Nil(t, s.userManager.AddEmail(u.ID, "existing@example.com"))
|
|
|
|
rr := request(t, s, "GET", "/v1/account/billing/subscription/success/SOMETOKEN", "", nil)
|
|
require.Equal(t, 303, rr.Code)
|
|
require.Empty(t, mailer.verifyLinks)
|
|
})
|
|
}
|
|
|
|
func TestPayments_Checkout_SkipsBillingEmailWhenPrimaryElsewhere(t *testing.T) {
|
|
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
|
s, mailer, u := newCheckoutEmailTestServer(t, databaseURL)
|
|
defer s.closeDatabases()
|
|
s.stripe = stripeCheckoutMock(u, "billing@example.com")
|
|
|
|
// The billing email is already the recovery email on another account -> skip
|
|
require.Nil(t, s.userManager.AddUser("alice", "alice", user.RoleUser, false))
|
|
alice, err := s.userManager.User("alice")
|
|
require.Nil(t, err)
|
|
require.Nil(t, s.userManager.AddEmail(alice.ID, "billing@example.com"))
|
|
require.Nil(t, s.userManager.SetPrimaryEmail(alice.ID, "billing@example.com"))
|
|
|
|
rr := request(t, s, "GET", "/v1/account/billing/subscription/success/SOMETOKEN", "", nil)
|
|
require.Equal(t, 303, rr.Code)
|
|
require.Empty(t, mailer.verifyLinks)
|
|
})
|
|
}
|