gateway_service_subscription_billing_test.go 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //go:build unit
  2. package service
  3. import (
  4. "testing"
  5. )
  6. // TestBuildUsageBillingCommand_SubscriptionAppliesRateMultiplier locks in the fix
  7. // that subscription-mode billing honours the group (and any user-specific) rate
  8. // multiplier — i.e. cmd.SubscriptionCost tracks ActualCost (= TotalCost *
  9. // RateMultiplier), not raw TotalCost.
  10. func TestBuildUsageBillingCommand_SubscriptionAppliesRateMultiplier(t *testing.T) {
  11. t.Parallel()
  12. groupID := int64(7)
  13. subID := int64(42)
  14. tests := []struct {
  15. name string
  16. totalCost float64
  17. actualCost float64
  18. isSubscription bool
  19. wantSub float64
  20. wantBalance float64
  21. }{
  22. {
  23. name: "subscription with 2x multiplier consumes 2x quota",
  24. totalCost: 1.0,
  25. actualCost: 2.0,
  26. isSubscription: true,
  27. wantSub: 2.0,
  28. wantBalance: 0,
  29. },
  30. {
  31. name: "subscription with 0.5x multiplier consumes 0.5x quota",
  32. totalCost: 1.0,
  33. actualCost: 0.5,
  34. isSubscription: true,
  35. wantSub: 0.5,
  36. wantBalance: 0,
  37. },
  38. {
  39. name: "free subscription (multiplier 0) consumes no quota",
  40. totalCost: 1.0,
  41. actualCost: 0,
  42. isSubscription: true,
  43. wantSub: 0,
  44. wantBalance: 0,
  45. },
  46. {
  47. name: "balance billing keeps using ActualCost (regression)",
  48. totalCost: 1.0,
  49. actualCost: 2.0,
  50. isSubscription: false,
  51. wantSub: 0,
  52. wantBalance: 2.0,
  53. },
  54. }
  55. for _, tt := range tests {
  56. t.Run(tt.name, func(t *testing.T) {
  57. t.Parallel()
  58. p := &postUsageBillingParams{
  59. Cost: &CostBreakdown{TotalCost: tt.totalCost, ActualCost: tt.actualCost},
  60. User: &User{ID: 1},
  61. APIKey: &APIKey{ID: 2, GroupID: &groupID},
  62. Account: &Account{ID: 3},
  63. Subscription: &UserSubscription{ID: subID},
  64. IsSubscriptionBill: tt.isSubscription,
  65. }
  66. cmd := buildUsageBillingCommand("req-1", nil, p)
  67. if cmd == nil {
  68. t.Fatal("buildUsageBillingCommand returned nil")
  69. }
  70. if cmd.SubscriptionCost != tt.wantSub {
  71. t.Errorf("SubscriptionCost = %v, want %v", cmd.SubscriptionCost, tt.wantSub)
  72. }
  73. if cmd.BalanceCost != tt.wantBalance {
  74. t.Errorf("BalanceCost = %v, want %v", cmd.BalanceCost, tt.wantBalance)
  75. }
  76. })
  77. }
  78. }