payment_stats_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //go:build unit
  2. package service
  3. import (
  4. "testing"
  5. "time"
  6. dbent "github.com/Wei-Shaw/sub2api/ent"
  7. "github.com/stretchr/testify/require"
  8. )
  9. func TestComputeBasicStatsGroupsAmountsByCurrency(t *testing.T) {
  10. t.Parallel()
  11. todayStart := time.Date(2026, time.July, 25, 0, 0, 0, 0, time.UTC)
  12. yesterday := todayStart.Add(-time.Hour)
  13. today := todayStart.Add(time.Hour)
  14. orders := []*dbent.PaymentOrder{
  15. paymentStatsTestOrder(1, "alice@example.com", "CNY", 10, &today),
  16. paymentStatsTestOrder(2, "bob@example.com", "USD", 10, &today),
  17. paymentStatsTestOrder(1, "alice@example.com", "CNY", 5, &yesterday),
  18. }
  19. stats := &DashboardStats{}
  20. computeBasicStats(stats, orders, todayStart)
  21. require.Equal(t, CurrencyAmounts{"CNY": 15, "USD": 10}, stats.TotalAmount)
  22. require.Equal(t, CurrencyAmounts{"CNY": 10, "USD": 10}, stats.TodayAmount)
  23. require.Equal(t, CurrencyAmounts{"CNY": 7.5, "USD": 10}, stats.AvgAmount)
  24. require.Equal(t, 3, stats.TotalCount)
  25. require.Equal(t, 2, stats.TodayCount)
  26. }
  27. func TestPaymentDashboardBreakdownsGroupAmountsAndRankingsByCurrency(t *testing.T) {
  28. t.Parallel()
  29. firstDay := time.Date(2026, time.July, 24, 12, 0, 0, 0, time.UTC)
  30. secondDay := firstDay.AddDate(0, 0, 1)
  31. orders := []*dbent.PaymentOrder{
  32. paymentStatsTestOrder(1, "alice@example.com", "CNY", 5.555, &firstDay),
  33. paymentStatsTestOrder(2, "bob@example.com", "CNY", 10, &firstDay),
  34. paymentStatsTestOrder(1, "alice@example.com", "USD", 20, &secondDay),
  35. paymentStatsTestOrder(2, "bob@example.com", "USD", 10, &secondDay),
  36. }
  37. orders[0].PaymentType = "stripe"
  38. orders[1].PaymentType = "stripe"
  39. orders[2].PaymentType = "stripe"
  40. orders[3].PaymentType = "alipay"
  41. daily := buildDailySeries(orders, firstDay.AddDate(0, 0, -1), 2)
  42. require.Equal(t, []DailyStats{
  43. {Date: "2026-07-24", Amount: CurrencyAmounts{"CNY": 15.56}, Count: 2},
  44. {Date: "2026-07-25", Amount: CurrencyAmounts{"USD": 30}, Count: 2},
  45. }, daily)
  46. methods := buildMethodDistribution(orders)
  47. require.Equal(t, []PaymentMethodStat{
  48. {Type: "alipay", Amount: CurrencyAmounts{"USD": 10}, Count: 1},
  49. {Type: "stripe", Amount: CurrencyAmounts{"CNY": 15.56, "USD": 20}, Count: 3},
  50. }, methods)
  51. users := buildTopUsers(orders)
  52. require.Equal(t, TopUsersByCurrency{
  53. "CNY": {
  54. {UserID: 2, Email: "bob@example.com", Amount: 10},
  55. {UserID: 1, Email: "alice@example.com", Amount: 5.56},
  56. },
  57. "USD": {
  58. {UserID: 1, Email: "alice@example.com", Amount: 20},
  59. {UserID: 2, Email: "bob@example.com", Amount: 10},
  60. },
  61. }, users)
  62. }
  63. func paymentStatsTestOrder(userID int64, email, currency string, amount float64, paidAt *time.Time) *dbent.PaymentOrder {
  64. return &dbent.PaymentOrder{
  65. UserID: userID,
  66. UserEmail: email,
  67. PayAmount: amount,
  68. PaidAt: paidAt,
  69. ProviderSnapshot: map[string]any{"currency": currency},
  70. }
  71. }