Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 

222 строки
6.2 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 TestGetUserAssetChannelsByTypesSortsLatestFirst(t *testing.T) {
  57. db := setupUserAssetChannelDB(t)
  58. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  59. require.NoError(t, BindUserAssetChannel(1, 3, "default", 200))
  60. require.NoError(t, BindUserAssetChannel(1, 4, "default", 300))
  61. require.NoError(t, db.Model(&UserAssetChannel{}).
  62. Where("user_id = ? AND channel_type = ?", 1, 2).
  63. Update("updated_at", int64(100)).Error)
  64. require.NoError(t, db.Model(&UserAssetChannel{}).
  65. Where("user_id = ? AND channel_type = ?", 1, 3).
  66. Update("updated_at", int64(200)).Error)
  67. bindings, err := GetUserAssetChannelsByTypes(1, []int{2, 3}, "default")
  68. require.NoError(t, err)
  69. require.Len(t, bindings, 2)
  70. assert.Equal(t, 3, bindings[0].ChannelType)
  71. assert.Equal(t, 200, bindings[0].ChannelId)
  72. assert.Equal(t, 2, bindings[1].ChannelType)
  73. }
  74. func TestBindUserAssetChannelWithTxUpserts(t *testing.T) {
  75. db := setupUserAssetChannelDB(t)
  76. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  77. require.NoError(t, BindUserAssetChannel(1, 2, "default", 200))
  78. binding, err := GetUserAssetChannel(1, 2, "default")
  79. require.NoError(t, err)
  80. require.NotNil(t, binding)
  81. assert.Equal(t, 200, binding.ChannelId)
  82. var count int64
  83. require.NoError(t, db.Model(&UserAssetChannel{}).Count(&count).Error)
  84. assert.Equal(t, int64(1), count)
  85. }
  86. func TestDeleteUserAssetChannelsByTypesWithTxDeletesOnlyRequestedRows(t *testing.T) {
  87. db := setupUserAssetChannelDB(t)
  88. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  89. require.NoError(t, BindUserAssetChannel(1, 3, "default", 200))
  90. require.NoError(t, BindUserAssetChannel(1, 4, "default", 300))
  91. require.NoError(t, BindUserAssetChannel(1, 2, "vip", 400))
  92. require.NoError(t, BindUserAssetChannel(2, 2, "default", 500))
  93. require.NoError(t, db.Transaction(func(tx *gorm.DB) error {
  94. return DeleteUserAssetChannelsByTypesWithTx(tx, 1, []int{2, 3}, "default")
  95. }))
  96. binding, err := GetUserAssetChannel(1, 2, "default")
  97. require.NoError(t, err)
  98. assert.Nil(t, binding)
  99. binding, err = GetUserAssetChannel(1, 3, "default")
  100. require.NoError(t, err)
  101. assert.Nil(t, binding)
  102. binding, err = GetUserAssetChannel(1, 4, "default")
  103. require.NoError(t, err)
  104. require.NotNil(t, binding)
  105. assert.Equal(t, 300, binding.ChannelId)
  106. binding, err = GetUserAssetChannel(1, 2, "vip")
  107. require.NoError(t, err)
  108. require.NotNil(t, binding)
  109. assert.Equal(t, 400, binding.ChannelId)
  110. binding, err = GetUserAssetChannel(2, 2, "default")
  111. require.NoError(t, err)
  112. require.NotNil(t, binding)
  113. assert.Equal(t, 500, binding.ChannelId)
  114. }
  115. func TestBindUserAssetChannel_IsolatesUserTypeGroup(t *testing.T) {
  116. setupUserAssetChannelDB(t)
  117. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  118. require.NoError(t, BindUserAssetChannel(2, 2, "default", 200))
  119. require.NoError(t, BindUserAssetChannel(1, 3, "default", 300))
  120. require.NoError(t, BindUserAssetChannel(1, 2, "vip", 400))
  121. cases := []struct {
  122. userId int
  123. channelType int
  124. group string
  125. channelId int
  126. }{
  127. {1, 2, "default", 100},
  128. {2, 2, "default", 200},
  129. {1, 3, "default", 300},
  130. {1, 2, "vip", 400},
  131. }
  132. for _, tc := range cases {
  133. binding, err := GetUserAssetChannel(tc.userId, tc.channelType, tc.group)
  134. require.NoError(t, err)
  135. require.NotNil(t, binding)
  136. assert.Equal(t, tc.channelId, binding.ChannelId)
  137. }
  138. }
  139. func TestBindUserAssetChannel_ConcurrentUpsert(t *testing.T) {
  140. db := setupUserAssetChannelDB(t)
  141. const workers = 20
  142. var wg sync.WaitGroup
  143. errCh := make(chan error, workers)
  144. expected := make(map[int]bool, workers)
  145. for i := 0; i < workers; i++ {
  146. channelId := 1000 + i
  147. expected[channelId] = true
  148. wg.Add(1)
  149. go func() {
  150. defer wg.Done()
  151. errCh <- BindUserAssetChannel(1, 2, "default", channelId)
  152. }()
  153. }
  154. wg.Wait()
  155. close(errCh)
  156. for err := range errCh {
  157. require.NoError(t, err)
  158. }
  159. var count int64
  160. require.NoError(t, db.Model(&UserAssetChannel{}).Count(&count).Error)
  161. assert.Equal(t, int64(1), count)
  162. binding, err := GetUserAssetChannel(1, 2, "default")
  163. require.NoError(t, err)
  164. require.NotNil(t, binding)
  165. assert.True(t, expected[binding.ChannelId])
  166. }
  167. func TestUnbindUserAssetChannel(t *testing.T) {
  168. setupUserAssetChannelDB(t)
  169. require.NoError(t, BindUserAssetChannel(1, 2, "default", 100))
  170. require.NoError(t, BindUserAssetChannel(1, 2, "vip", 200))
  171. require.NoError(t, UnbindUserAssetChannel(1, 2, "default"))
  172. binding, err := GetUserAssetChannel(1, 2, "default")
  173. require.NoError(t, err)
  174. assert.Nil(t, binding)
  175. binding, err = GetUserAssetChannel(1, 2, "vip")
  176. require.NoError(t, err)
  177. require.NotNil(t, binding)
  178. assert.Equal(t, 200, binding.ChannelId)
  179. }