users_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. // Copyright 2020 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package db
  5. import (
  6. "testing"
  7. "time"
  8. "github.com/stretchr/testify/assert"
  9. "gogs.io/gogs/internal/errutil"
  10. )
  11. func Test_users(t *testing.T) {
  12. if testing.Short() {
  13. t.Skip()
  14. }
  15. t.Parallel()
  16. tables := []interface{}{new(User), new(EmailAddress)}
  17. db := &users{
  18. DB: initTestDB(t, "users", tables...),
  19. }
  20. for _, tc := range []struct {
  21. name string
  22. test func(*testing.T, *users)
  23. }{
  24. {"Authenticate", test_users_Authenticate},
  25. {"Create", test_users_Create},
  26. {"GetByEmail", test_users_GetByEmail},
  27. {"GetByID", test_users_GetByID},
  28. {"GetByUsername", test_users_GetByUsername},
  29. } {
  30. t.Run(tc.name, func(t *testing.T) {
  31. t.Cleanup(func() {
  32. err := clearTables(t, db.DB, tables...)
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. })
  37. tc.test(t, db)
  38. })
  39. }
  40. }
  41. // TODO: Only local account is tested, tests for external account will be added
  42. // along with addressing https://github.com/gogs/gogs/issues/6115.
  43. func test_users_Authenticate(t *testing.T, db *users) {
  44. password := "pa$$word"
  45. alice, err := db.Create(CreateUserOpts{
  46. Name: "alice",
  47. Email: "alice@example.com",
  48. Password: password,
  49. })
  50. if err != nil {
  51. t.Fatal(err)
  52. }
  53. t.Run("user not found", func(t *testing.T) {
  54. _, err := db.Authenticate("bob", password, -1)
  55. expErr := ErrUserNotExist{args: map[string]interface{}{"login": "bob"}}
  56. assert.Equal(t, expErr, err)
  57. })
  58. t.Run("invalid password", func(t *testing.T) {
  59. _, err := db.Authenticate(alice.Name, "bad_password", -1)
  60. expErr := ErrUserNotExist{args: map[string]interface{}{"userID": alice.ID, "name": alice.Name}}
  61. assert.Equal(t, expErr, err)
  62. })
  63. t.Run("via email and password", func(t *testing.T) {
  64. user, err := db.Authenticate(alice.Email, password, -1)
  65. if err != nil {
  66. t.Fatal(err)
  67. }
  68. assert.Equal(t, alice.Name, user.Name)
  69. })
  70. t.Run("via username and password", func(t *testing.T) {
  71. user, err := db.Authenticate(alice.Name, password, -1)
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. assert.Equal(t, alice.Name, user.Name)
  76. })
  77. }
  78. func test_users_Create(t *testing.T, db *users) {
  79. alice, err := db.Create(CreateUserOpts{
  80. Name: "alice",
  81. Email: "alice@example.com",
  82. Activated: true,
  83. })
  84. if err != nil {
  85. t.Fatal(err)
  86. }
  87. t.Run("name not allowed", func(t *testing.T) {
  88. _, err := db.Create(CreateUserOpts{
  89. Name: "-",
  90. })
  91. expErr := ErrNameNotAllowed{args: errutil.Args{"reason": "reserved", "name": "-"}}
  92. assert.Equal(t, expErr, err)
  93. })
  94. t.Run("name already exists", func(t *testing.T) {
  95. _, err := db.Create(CreateUserOpts{
  96. Name: alice.Name,
  97. })
  98. expErr := ErrUserAlreadyExist{args: errutil.Args{"name": alice.Name}}
  99. assert.Equal(t, expErr, err)
  100. })
  101. t.Run("email already exists", func(t *testing.T) {
  102. _, err := db.Create(CreateUserOpts{
  103. Name: "bob",
  104. Email: alice.Email,
  105. })
  106. expErr := ErrEmailAlreadyUsed{args: errutil.Args{"email": alice.Email}}
  107. assert.Equal(t, expErr, err)
  108. })
  109. user, err := db.GetByUsername(alice.Name)
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. assert.Equal(t, db.NowFunc().Format(time.RFC3339), user.Created.UTC().Format(time.RFC3339))
  114. assert.Equal(t, db.NowFunc().Format(time.RFC3339), user.Updated.UTC().Format(time.RFC3339))
  115. }
  116. func test_users_GetByEmail(t *testing.T, db *users) {
  117. t.Run("empty email", func(t *testing.T) {
  118. _, err := db.GetByEmail("")
  119. expErr := ErrUserNotExist{args: errutil.Args{"email": ""}}
  120. assert.Equal(t, expErr, err)
  121. })
  122. t.Run("ignore organization", func(t *testing.T) {
  123. // TODO: Use Orgs.Create to replace SQL hack when the method is available.
  124. org, err := db.Create(CreateUserOpts{
  125. Name: "gogs",
  126. Email: "gogs@exmaple.com",
  127. })
  128. if err != nil {
  129. t.Fatal(err)
  130. }
  131. err = db.Exec(`UPDATE user SET type = ? WHERE id = ?`, UserOrganization, org.ID).Error
  132. if err != nil {
  133. t.Fatal(err)
  134. }
  135. _, err = db.GetByEmail(org.Email)
  136. expErr := ErrUserNotExist{args: errutil.Args{"email": org.Email}}
  137. assert.Equal(t, expErr, err)
  138. })
  139. t.Run("by primary email", func(t *testing.T) {
  140. alice, err := db.Create(CreateUserOpts{
  141. Name: "alice",
  142. Email: "alice@exmaple.com",
  143. })
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. _, err = db.GetByEmail(alice.Email)
  148. expErr := ErrUserNotExist{args: errutil.Args{"email": alice.Email}}
  149. assert.Equal(t, expErr, err)
  150. // Mark user as activated
  151. // TODO: Use UserEmails.Verify to replace SQL hack when the method is available.
  152. err = db.Exec(`UPDATE user SET is_active = ? WHERE id = ?`, true, alice.ID).Error
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. user, err := db.GetByEmail(alice.Email)
  157. if err != nil {
  158. t.Fatal(err)
  159. }
  160. assert.Equal(t, alice.Name, user.Name)
  161. })
  162. t.Run("by secondary email", func(t *testing.T) {
  163. bob, err := db.Create(CreateUserOpts{
  164. Name: "bob",
  165. Email: "bob@example.com",
  166. })
  167. if err != nil {
  168. t.Fatal(err)
  169. }
  170. // TODO: Use UserEmails.Create to replace SQL hack when the method is available.
  171. email2 := "bob2@exmaple.com"
  172. err = db.Exec(`INSERT INTO email_address (uid, email) VALUES (?, ?)`, bob.ID, email2).Error
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. _, err = db.GetByEmail(email2)
  177. expErr := ErrUserNotExist{args: errutil.Args{"email": email2}}
  178. assert.Equal(t, expErr, err)
  179. // TODO: Use UserEmails.Verify to replace SQL hack when the method is available.
  180. err = db.Exec(`UPDATE email_address SET is_activated = ? WHERE email = ?`, true, email2).Error
  181. if err != nil {
  182. t.Fatal(err)
  183. }
  184. user, err := db.GetByEmail(email2)
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. assert.Equal(t, bob.Name, user.Name)
  189. })
  190. }
  191. func test_users_GetByID(t *testing.T, db *users) {
  192. alice, err := db.Create(CreateUserOpts{
  193. Name: "alice",
  194. Email: "alice@exmaple.com",
  195. })
  196. if err != nil {
  197. t.Fatal(err)
  198. }
  199. user, err := db.GetByID(alice.ID)
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. assert.Equal(t, alice.Name, user.Name)
  204. _, err = db.GetByID(404)
  205. expErr := ErrUserNotExist{args: errutil.Args{"userID": int64(404)}}
  206. assert.Equal(t, expErr, err)
  207. }
  208. func test_users_GetByUsername(t *testing.T, db *users) {
  209. alice, err := db.Create(CreateUserOpts{
  210. Name: "alice",
  211. Email: "alice@exmaple.com",
  212. })
  213. if err != nil {
  214. t.Fatal(err)
  215. }
  216. user, err := db.GetByUsername(alice.Name)
  217. if err != nil {
  218. t.Fatal(err)
  219. }
  220. assert.Equal(t, alice.Name, user.Name)
  221. _, err = db.GetByUsername("bad_username")
  222. expErr := ErrUserNotExist{args: errutil.Args{"name": "bad_username"}}
  223. assert.Equal(t, expErr, err)
  224. }