You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

153 lines
3.7 KiB

  1. package model
  2. import (
  3. "sync"
  4. "testing"
  5. "github.com/glebarez/sqlite"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. "gorm.io/gorm"
  9. "gorm.io/gorm/logger"
  10. )
  11. func setupUserAssetChannelDB(t *testing.T) *gorm.DB {
  12. t.Helper()
  13. db, err := gorm.Open(sqlite.Open("file:user_asset_channels?mode=memory&cache=shared"), &gorm.Config{
  14. Logger: logger.Default.LogMode(logger.Silent),
  15. })
  16. require.NoError(t, err)
  17. sqlDB, err := db.DB()
  18. require.NoError(t, err)
  19. sqlDB.SetMaxOpenConns(1)
  20. origDB := DB
  21. origGroupCol := commonGroupCol
  22. DB = db
  23. commonGroupCol = "`group`"
  24. require.NoError(t, db.AutoMigrate(&UserAssetChannel{}))
  25. t.Cleanup(func() {
  26. DB = origDB
  27. commonGroupCol = origGroupCol
  28. require.NoError(t, sqlDB.Close())
  29. })
  30. return db
  31. }
  32. func TestGetUserAssetChannel_NotFound(t *testing.T) {
  33. setupUserAssetChannelDB(t)
  34. binding, err := GetUserAssetChannel(1, 2, "default")
  35. require.NoError(t, err)
  36. assert.Nil(t, binding)
  37. }
  38. func TestBindUserAssetChannel_CreateAndUpdate(t *testing.T) {
  39. db := setupUserAssetChannelDB(t)
  40. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  41. binding, err := GetUserAssetChannel(1, 2, "default")
  42. require.NoError(t, err)
  43. require.NotNil(t, binding)
  44. assert.Equal(t, 100, binding.ChannelId)
  45. assert.NotZero(t, binding.CreatedAt)
  46. assert.NotZero(t, binding.UpdatedAt)
  47. require.NoError(t, BindUserAssetChannel(1, 2, "default", 200))
  48. binding, err = GetUserAssetChannel(1, 2, "default")
  49. require.NoError(t, err)
  50. require.NotNil(t, binding)
  51. assert.Equal(t, 200, binding.ChannelId)
  52. var count int64
  53. require.NoError(t, db.Model(&UserAssetChannel{}).Count(&count).Error)
  54. assert.Equal(t, int64(1), count)
  55. }
  56. func TestBindUserAssetChannel_IsolatesUserTypeGroup(t *testing.T) {
  57. setupUserAssetChannelDB(t)
  58. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  59. require.NoError(t, BindUserAssetChannel(2, 2, "default", 200))
  60. require.NoError(t, BindUserAssetChannel(1, 3, "default", 300))
  61. require.NoError(t, BindUserAssetChannel(1, 2, "vip", 400))
  62. cases := []struct {
  63. userId int
  64. channelType int
  65. group string
  66. channelId int
  67. }{
  68. {1, 2, "default", 100},
  69. {2, 2, "default", 200},
  70. {1, 3, "default", 300},
  71. {1, 2, "vip", 400},
  72. }
  73. for _, tc := range cases {
  74. binding, err := GetUserAssetChannel(tc.userId, tc.channelType, tc.group)
  75. require.NoError(t, err)
  76. require.NotNil(t, binding)
  77. assert.Equal(t, tc.channelId, binding.ChannelId)
  78. }
  79. }
  80. func TestBindUserAssetChannel_ConcurrentUpsert(t *testing.T) {
  81. db := setupUserAssetChannelDB(t)
  82. const workers = 20
  83. var wg sync.WaitGroup
  84. errCh := make(chan error, workers)
  85. expected := make(map[int]bool, workers)
  86. for i := 0; i < workers; i++ {
  87. channelId := 1000 + i
  88. expected[channelId] = true
  89. wg.Add(1)
  90. go func() {
  91. defer wg.Done()
  92. errCh <- BindUserAssetChannel(1, 2, "default", channelId)
  93. }()
  94. }
  95. wg.Wait()
  96. close(errCh)
  97. for err := range errCh {
  98. require.NoError(t, err)
  99. }
  100. var count int64
  101. require.NoError(t, db.Model(&UserAssetChannel{}).Count(&count).Error)
  102. assert.Equal(t, int64(1), count)
  103. binding, err := GetUserAssetChannel(1, 2, "default")
  104. require.NoError(t, err)
  105. require.NotNil(t, binding)
  106. assert.True(t, expected[binding.ChannelId])
  107. }
  108. func TestUnbindUserAssetChannel(t *testing.T) {
  109. setupUserAssetChannelDB(t)
  110. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  111. require.NoError(t, BindUserAssetChannel(1, 2, "vip", 200))
  112. require.NoError(t, UnbindUserAssetChannel(1, 2, "default"))
  113. binding, err := GetUserAssetChannel(1, 2, "default")
  114. require.NoError(t, err)
  115. assert.Nil(t, binding)
  116. binding, err = GetUserAssetChannel(1, 2, "vip")
  117. require.NoError(t, err)
  118. require.NotNil(t, binding)
  119. assert.Equal(t, 200, binding.ChannelId)
  120. }