service_test.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package service
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/glebarez/sqlite"
  7. "github.com/stretchr/testify/require"
  8. "gorm.io/gorm"
  9. "wails-app/internal/dao"
  10. "wails-app/internal/global"
  11. )
  12. func setupPaymentServiceTest(t *testing.T) *PaymentService {
  13. dsn := fmt.Sprintf("file:payment-service-%d?mode=memory&cache=shared", time.Now().UnixNano())
  14. db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
  15. require.NoError(t, err)
  16. sqlDB, err := db.DB()
  17. require.NoError(t, err)
  18. sqlDB.SetMaxOpenConns(16)
  19. t.Cleanup(func() {
  20. _ = sqlDB.Close()
  21. if global.GVA_DB == db {
  22. global.GVA_DB = nil
  23. }
  24. })
  25. global.GVA_DB = db
  26. require.NoError(t, db.AutoMigrate(&dao.PaymentMethodConfig{}, &dao.PaymentEntryConfig{}, &dao.PaymentEntryMethod{}, &dao.VehicleRecord{}, &dao.PaymentRecord{}))
  27. require.NoError(t, db.Create(&[]dao.PaymentMethodConfig{
  28. {Code: PaymentCash, Name: "人工支付", InputMode: InputModeManualAmount, Scenes: []string{SceneCounter}, Enabled: true, Sort: 10, IsSystem: true},
  29. {Code: PaymentPOS, Name: "POS机支付", InputMode: InputModeConfirm, Scenes: []string{SceneCounter}, Enabled: true, Sort: 20, IsSystem: true},
  30. {Code: PaymentTicketQR, Name: "小票扫码支付", InputMode: InputModeExternal, Scenes: []string{SceneTicket}, Enabled: true, Sort: 30, IsSystem: true},
  31. }).Error)
  32. require.NoError(t, db.Create(&[]dao.PaymentEntryConfig{
  33. {Code: EntryCounter, Name: "收费岗亭", Enabled: true, IsSystem: true},
  34. {Code: EntryTicket, Name: "停车小票", Enabled: true, IsSystem: true},
  35. }).Error)
  36. require.NoError(t, db.Create(&[]dao.PaymentEntryMethod{
  37. {EntryCode: EntryCounter, MethodCode: PaymentCash, Sort: 10},
  38. {EntryCode: EntryCounter, MethodCode: PaymentPOS, Sort: 20},
  39. {EntryCode: EntryTicket, MethodCode: PaymentCash, Sort: 10},
  40. {EntryCode: EntryTicket, MethodCode: PaymentPOS, Sort: 20},
  41. {EntryCode: EntryTicket, MethodCode: PaymentTicketQR, Sort: 30},
  42. }).Error)
  43. return NewPaymentService()
  44. }
  45. func TestCashCannotBeDisabledOrDeleted(t *testing.T) {
  46. svc := setupPaymentServiceTest(t)
  47. method, err := svc.repo.GetMethodByCode(nil, PaymentCash)
  48. require.NoError(t, err)
  49. require.EqualError(t, svc.SetMethodEnabled(method.ID, false), "人工支付是基础功能,不能停用")
  50. require.EqualError(t, svc.DeleteMethod(method.ID), "系统内置支付方式不能删除")
  51. }
  52. func TestPaymentMethodSceneAndAmountValidation(t *testing.T) {
  53. svc := setupPaymentServiceTest(t)
  54. _, _, err := svc.ValidatePayment(nil, PaymentTicketQR, SceneCounter, 10, 10)
  55. require.EqualError(t, err, "支付方式“小票扫码支付”未配置到当前支付入口")
  56. _, _, err = svc.ValidatePayment(nil, PaymentCash, SceneCounter, 10, 9.9)
  57. require.EqualError(t, err, "实收金额不足")
  58. _, paidAmount, err := svc.ValidatePayment(nil, PaymentPOS, SceneCounter, 10, 999)
  59. require.NoError(t, err)
  60. require.Equal(t, 10.0, paidAmount)
  61. _, paidAmount, err = svc.ValidatePayment(nil, PaymentFree, SceneCounter, 10, 0)
  62. require.NoError(t, err)
  63. require.Zero(t, paidAmount)
  64. _, _, err = svc.ValidatePayment(nil, PaymentFree, SceneTicket, 10, 0)
  65. require.EqualError(t, err, "免密放行不能用于当前支付场景")
  66. }
  67. func TestDisabledAndInvalidMethodsAreRejected(t *testing.T) {
  68. svc := setupPaymentServiceTest(t)
  69. method, err := svc.repo.GetMethodByCode(nil, PaymentPOS)
  70. require.NoError(t, err)
  71. require.NoError(t, svc.SetMethodEnabled(method.ID, false))
  72. _, _, err = svc.ValidatePayment(nil, PaymentPOS, SceneCounter, 10, 10)
  73. require.EqualError(t, err, "支付方式“POS机支付”已停用")
  74. err = svc.CreateMethod(&dao.PaymentMethodConfig{Code: "Bad Code", Name: "测试", InputMode: InputModeConfirm, Scenes: []string{SceneCounter}})
  75. require.ErrorContains(t, err, "支付编码必须")
  76. }
  77. func TestCustomMethodsAreOrderedAndDuplicateCodesRejected(t *testing.T) {
  78. svc := setupPaymentServiceTest(t)
  79. custom := &dao.PaymentMethodConfig{
  80. Code: "bank_card", Name: "银行卡", InputMode: InputModeConfirm,
  81. EntryCodes: []string{EntryCounter}, Enabled: true, Sort: 5,
  82. }
  83. require.NoError(t, svc.CreateMethod(custom))
  84. methods, err := svc.ListEnabledMethods(SceneCounter)
  85. require.NoError(t, err)
  86. require.Equal(t, "bank_card", methods[0].Code)
  87. duplicate := &dao.PaymentMethodConfig{
  88. Code: "bank_card", Name: "重复编码", InputMode: InputModeConfirm,
  89. EntryCodes: []string{EntryCounter}, Enabled: true,
  90. }
  91. require.EqualError(t, svc.CreateMethod(duplicate), "支付编码已存在")
  92. }