waffo_pancake_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. package service
  2. import (
  3. "fmt"
  4. "strings"
  5. "testing"
  6. "time"
  7. "github.com/QuantumNous/new-api/common"
  8. "github.com/QuantumNous/new-api/model"
  9. "github.com/QuantumNous/new-api/setting"
  10. "github.com/glebarez/sqlite"
  11. "github.com/stretchr/testify/require"
  12. "gorm.io/gorm"
  13. )
  14. func setupWaffoPancakeTestDB(t *testing.T) *gorm.DB {
  15. t.Helper()
  16. common.UsingSQLite = true
  17. common.UsingMySQL = false
  18. common.UsingPostgreSQL = false
  19. common.RedisEnabled = false
  20. dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", strings.ReplaceAll(t.Name(), "/", "_"))
  21. db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
  22. require.NoError(t, err)
  23. model.DB = db
  24. model.LOG_DB = db
  25. require.NoError(t, db.AutoMigrate(&model.User{}, &model.TopUp{}))
  26. t.Cleanup(func() {
  27. sqlDB, err := db.DB()
  28. if err == nil {
  29. _ = sqlDB.Close()
  30. }
  31. })
  32. return db
  33. }
  34. func TestWaffoPancakeCreateSessionResponseParsesDocumentedPayload(t *testing.T) {
  35. var result waffoPancakeCreateSessionResponse
  36. err := common.Unmarshal([]byte(`{
  37. "data": {
  38. "sessionId": "cs_550e8400-e29b-41d4-a716-446655440000",
  39. "checkoutUrl": "https://checkout.waffo.ai/my-store-abc123/checkout/cs_550e8400-e29b-41d4-a716-446655440000",
  40. "expiresAt": "2026-01-22T10:30:00.000Z"
  41. }
  42. }`), &result)
  43. require.NoError(t, err)
  44. require.NotNil(t, result.Data)
  45. require.Equal(t, "cs_550e8400-e29b-41d4-a716-446655440000", result.Data.SessionID)
  46. require.Empty(t, result.Data.OrderID)
  47. }
  48. func TestResolveWaffoPancakeTradeNo_UsesWebhookOrderIDWhenLocalOrderExists(t *testing.T) {
  49. db := setupWaffoPancakeTestDB(t)
  50. topUp := &model.TopUp{
  51. UserId: 1,
  52. Amount: 10,
  53. Money: 29,
  54. TradeNo: "ORD_5dXBtmF2HLlHfbPNm0Wcnz",
  55. PaymentMethod: model.PaymentMethodWaffoPancake,
  56. CreateTime: time.Now().Unix(),
  57. Status: common.TopUpStatusPending,
  58. }
  59. require.NoError(t, db.Create(topUp).Error)
  60. tradeNo, err := ResolveWaffoPancakeTradeNo(&waffoPancakeWebhookEvent{
  61. Data: waffoPancakeWebhookData{
  62. OrderID: "ORD_5dXBtmF2HLlHfbPNm0Wcnz",
  63. },
  64. })
  65. require.NoError(t, err)
  66. require.Equal(t, "ORD_5dXBtmF2HLlHfbPNm0Wcnz", tradeNo)
  67. }
  68. func TestResolveWaffoPancakeTradeNo_FailsWhenWebhookOrderIDIsUnknown(t *testing.T) {
  69. db := setupWaffoPancakeTestDB(t)
  70. user := &model.User{
  71. Id: 42,
  72. Email: "buyer@example.com",
  73. Username: "buyer",
  74. Status: common.UserStatusEnabled,
  75. }
  76. require.NoError(t, db.Create(user).Error)
  77. topUp := &model.TopUp{
  78. UserId: user.Id,
  79. Amount: 10,
  80. Money: 29,
  81. TradeNo: "WAFFO_PANCAKE-42-123456-abc123",
  82. PaymentMethod: model.PaymentMethodWaffoPancake,
  83. CreateTime: time.Now().Unix(),
  84. Status: common.TopUpStatusPending,
  85. }
  86. require.NoError(t, db.Create(topUp).Error)
  87. tradeNo, err := ResolveWaffoPancakeTradeNo(&waffoPancakeWebhookEvent{
  88. Data: waffoPancakeWebhookData{
  89. OrderID: "ORD_unknown",
  90. BuyerEmail: user.Email,
  91. Amount: "29.00",
  92. },
  93. })
  94. require.Error(t, err)
  95. require.Empty(t, tradeNo)
  96. }
  97. func TestResolveWaffoPancakeWebhookEnvironment(t *testing.T) {
  98. originalSandbox := setting.WaffoPancakeSandbox
  99. t.Cleanup(func() {
  100. setting.WaffoPancakeSandbox = originalSandbox
  101. })
  102. testCases := []struct {
  103. name string
  104. payload string
  105. expected string
  106. sandbox bool
  107. }{
  108. {
  109. name: "test mode",
  110. payload: `{"mode":"test"}`,
  111. expected: "test",
  112. },
  113. {
  114. name: "prod mode",
  115. payload: `{"mode":"prod"}`,
  116. expected: "prod",
  117. },
  118. {
  119. name: "missing mode falls back to sandbox",
  120. payload: `{}`,
  121. expected: "test",
  122. sandbox: true,
  123. },
  124. {
  125. name: "invalid mode falls back to prod",
  126. payload: `{"mode":"staging"}`,
  127. expected: "prod",
  128. },
  129. }
  130. for _, tc := range testCases {
  131. t.Run(tc.name, func(t *testing.T) {
  132. setting.WaffoPancakeSandbox = tc.sandbox
  133. environment := resolveWaffoPancakeWebhookEnvironment(tc.payload)
  134. require.Equal(t, tc.expected, environment)
  135. })
  136. }
  137. }