mirror of
https://github.com/Dvorinka/Bookra.git
synced 2026-10-28 07:41:16 +00:00
refactor(db): replace sqlc with handwritten pgx repos
- Finish Paddle-to-Stripe billing migration; drop paddle/stripe libs - Renumber migrations; add 00012 memberships+manage_token, 00013 location_type_capacity - Add tests: admin, auth, bookings customer service - Remove graphify-out artifacts and stale env files Authored By: TDvorak <[email protected]> Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2039669e2c
commit
f2f7439050
93 files changed
+6987
-69060
No files matched your search
@@ -12,12 +12,12 @@ import (
|
||||
func testConfig() config.Config {
|
||||
return config.Config{
|
||||
FrontendURL: "http://localhost:3000",
|
||||
PaddleAPIKey: "pdl_sdbx_apikey_123",
|
||||
PaddleWebhookKey: "pdl_ntf_123",
|
||||
PaddlePriceMatrix: map[string]map[string]string{
|
||||
"starter": {"czk": "pri_starter_czk", "usd": "pri_starter_usd"},
|
||||
"pro": {"czk": "pri_pro_czk", "usd": "pri_pro_usd"},
|
||||
"business": {"czk": "pri_business_czk", "usd": "pri_business_usd"},
|
||||
StripeAPIKey: "sk_test_123",
|
||||
StripeWebhookKey: "whsec_test_123",
|
||||
StripePriceMatrix: map[string]map[string]string{
|
||||
"starter": {"czk": "price_starter_czk", "usd": "price_starter_usd"},
|
||||
"pro": {"czk": "price_pro_czk", "usd": "price_pro_usd"},
|
||||
"business": {"czk": "price_business_czk", "usd": "price_business_usd"},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -36,66 +36,59 @@ func TestGetSubscriptionFallsBackToSnapshotAndEntitlements(t *testing.T) {
|
||||
if snapshot.PlanCode != "pro" {
|
||||
t.Fatalf("expected pro, got %s", snapshot.PlanCode)
|
||||
}
|
||||
if snapshot.Provider != "paddle" {
|
||||
t.Fatalf("expected paddle provider, got %s", snapshot.Provider)
|
||||
if snapshot.Provider != "stripe" {
|
||||
t.Fatalf("expected stripe provider, got %s", snapshot.Provider)
|
||||
}
|
||||
if snapshot.Entitlements.MaxLocations != 3 {
|
||||
t.Fatalf("expected 3 locations, got %d", snapshot.Entitlements.MaxLocations)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateCheckoutRequiresPaddleConfig(t *testing.T) {
|
||||
func TestCreateCheckoutRequiresStripeConfig(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.PaddleAPIKey = ""
|
||||
cfg.StripeAPIKey = ""
|
||||
service := NewService(cfg, db.NewMemoryRepository())
|
||||
|
||||
response, err := service.CreateCheckoutSession(context.Background(), domain.Principal{
|
||||
Subject: "demo-owner",
|
||||
Email: "[email protected]",
|
||||
}, "pro", "czk", "monthly")
|
||||
if err != ErrPaddleNotConfigured {
|
||||
t.Fatalf("expected ErrPaddleNotConfigured, got response=%v err=%v", response, err)
|
||||
if err != ErrStripeNotConfigured {
|
||||
t.Fatalf("expected ErrStripeNotConfigured, got response=%v err=%v", response, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateCheckoutReturnsLaunchPayload(t *testing.T) {
|
||||
service := NewService(testConfig(), db.NewMemoryRepository())
|
||||
func TestCreateCheckoutRejectsUnconfiguredPlan(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.StripePriceMatrix["pro"] = map[string]string{}
|
||||
service := NewService(cfg, db.NewMemoryRepository())
|
||||
|
||||
response, err := service.CreateCheckoutSession(context.Background(), domain.Principal{
|
||||
_, err := service.CreateCheckoutSession(context.Background(), domain.Principal{
|
||||
Subject: "demo-owner",
|
||||
Email: "[email protected]",
|
||||
}, "pro", "czk", "monthly")
|
||||
if err != nil {
|
||||
t.Fatalf("create checkout: %v", err)
|
||||
}
|
||||
if response.PriceID != "pri_pro_czk" {
|
||||
t.Fatalf("expected pri_pro_czk, got %s", response.PriceID)
|
||||
}
|
||||
if response.CustomData["tenantId"] == "" {
|
||||
t.Fatal("expected tenantId in customData")
|
||||
}
|
||||
if response.SuccessRedirectURL == "" || response.CancelRedirectURL == "" {
|
||||
t.Fatal("expected redirect URLs")
|
||||
if err != ErrBillingPlanUnsupported {
|
||||
t.Fatalf("expected ErrBillingPlanUnsupported, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRefreshRequiresPaddleKeyWhenCustomerExists(t *testing.T) {
|
||||
func TestRefreshRequiresStripeKeyWhenCustomerExists(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.PaddleAPIKey = ""
|
||||
cfg.StripeAPIKey = ""
|
||||
service := NewService(cfg, db.NewMemoryRepository())
|
||||
|
||||
snapshot, err := service.Refresh(context.Background(), domain.Principal{
|
||||
Subject: "demo-owner",
|
||||
Email: "[email protected]",
|
||||
})
|
||||
if err != ErrPaddleNotConfigured {
|
||||
t.Fatalf("expected ErrPaddleNotConfigured, got snapshot=%v err=%v", snapshot, err)
|
||||
if err != ErrStripeNotConfigured {
|
||||
t.Fatalf("expected ErrStripeNotConfigured, got snapshot=%v err=%v", snapshot, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSubscriptionDisablesCheckoutWhenWebhookMissing(t *testing.T) {
|
||||
cfg := testConfig()
|
||||
cfg.PaddleWebhookKey = ""
|
||||
cfg.StripeWebhookKey = ""
|
||||
service := NewService(cfg, db.NewMemoryRepository())
|
||||
|
||||
snapshot, err := service.GetSubscription(context.Background(), domain.Principal{
|
||||
@@ -110,7 +103,7 @@ func TestGetSubscriptionDisablesCheckoutWhenWebhookMissing(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSubscriptionEnablesCheckoutWhenPaddleConfigured(t *testing.T) {
|
||||
func TestGetSubscriptionEnablesCheckoutWhenStripeConfigured(t *testing.T) {
|
||||
service := NewService(testConfig(), db.NewMemoryRepository())
|
||||
|
||||
snapshot, err := service.GetSubscription(context.Background(), domain.Principal{
|
||||
@@ -121,7 +114,7 @@ func TestGetSubscriptionEnablesCheckoutWhenPaddleConfigured(t *testing.T) {
|
||||
t.Fatalf("get subscription: %v", err)
|
||||
}
|
||||
if !snapshot.CheckoutURLAvailable {
|
||||
t.Fatal("expected checkout available when paddle is configured")
|
||||
t.Fatal("expected checkout available when stripe is configured")
|
||||
}
|
||||
if !snapshot.PortalAvailable {
|
||||
t.Fatal("expected portal available when customer exists")
|
||||
@@ -130,11 +123,11 @@ func TestGetSubscriptionEnablesCheckoutWhenPaddleConfigured(t *testing.T) {
|
||||
|
||||
func TestCreatePortalSessionRequiresCustomer(t *testing.T) {
|
||||
repo := db.NewMemoryRepository()
|
||||
membership, err := repo.GetTenantMembershipByUserID(context.Background(), "demo-owner")
|
||||
membership, err := repo.GetTenantMembershipBySubject(context.Background(), "demo-owner")
|
||||
if err != nil {
|
||||
t.Fatalf("get membership: %v", err)
|
||||
}
|
||||
if err := repo.UpdateTenantBillingCustomerID(context.Background(), membership.Tenant.ID, ""); err != nil {
|
||||
if err := repo.UpdateTenantBillingCustomerID(context.Background(), membership.Tenant.ID, "stripe", ""); err != nil {
|
||||
t.Fatalf("clear billing customer: %v", err)
|
||||
}
|
||||
service := NewService(testConfig(), repo)
|
||||
|
||||
Reference in new issue
Block a user