code.gitea.io/gitea@v1.21.7/models/user/email_address_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package user_test 5 6 import ( 7 "testing" 8 9 "code.gitea.io/gitea/models/db" 10 "code.gitea.io/gitea/models/unittest" 11 user_model "code.gitea.io/gitea/models/user" 12 "code.gitea.io/gitea/modules/util" 13 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestGetEmailAddresses(t *testing.T) { 18 assert.NoError(t, unittest.PrepareTestDatabase()) 19 20 emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1)) 21 if assert.Len(t, emails, 3) { 22 assert.True(t, emails[0].IsPrimary) 23 assert.True(t, emails[2].IsActivated) 24 assert.False(t, emails[2].IsPrimary) 25 } 26 27 emails, _ = user_model.GetEmailAddresses(db.DefaultContext, int64(2)) 28 if assert.Len(t, emails, 2) { 29 assert.True(t, emails[0].IsPrimary) 30 assert.True(t, emails[0].IsActivated) 31 } 32 } 33 34 func TestIsEmailUsed(t *testing.T) { 35 assert.NoError(t, unittest.PrepareTestDatabase()) 36 37 isExist, _ := user_model.IsEmailUsed(db.DefaultContext, "") 38 assert.True(t, isExist) 39 isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user11@example.com") 40 assert.True(t, isExist) 41 isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user1234567890@example.com") 42 assert.False(t, isExist) 43 } 44 45 func TestAddEmailAddress(t *testing.T) { 46 assert.NoError(t, unittest.PrepareTestDatabase()) 47 48 assert.NoError(t, user_model.AddEmailAddress(db.DefaultContext, &user_model.EmailAddress{ 49 Email: "user1234567890@example.com", 50 LowerEmail: "user1234567890@example.com", 51 IsPrimary: true, 52 IsActivated: true, 53 })) 54 55 // ErrEmailAlreadyUsed 56 err := user_model.AddEmailAddress(db.DefaultContext, &user_model.EmailAddress{ 57 Email: "user1234567890@example.com", 58 LowerEmail: "user1234567890@example.com", 59 }) 60 assert.Error(t, err) 61 assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) 62 } 63 64 func TestAddEmailAddresses(t *testing.T) { 65 assert.NoError(t, unittest.PrepareTestDatabase()) 66 67 // insert multiple email address 68 emails := make([]*user_model.EmailAddress, 2) 69 emails[0] = &user_model.EmailAddress{ 70 Email: "user1234@example.com", 71 LowerEmail: "user1234@example.com", 72 IsActivated: true, 73 } 74 emails[1] = &user_model.EmailAddress{ 75 Email: "user5678@example.com", 76 LowerEmail: "user5678@example.com", 77 IsActivated: true, 78 } 79 assert.NoError(t, user_model.AddEmailAddresses(db.DefaultContext, emails)) 80 81 // ErrEmailAlreadyUsed 82 err := user_model.AddEmailAddresses(db.DefaultContext, emails) 83 assert.Error(t, err) 84 assert.True(t, user_model.IsErrEmailAlreadyUsed(err)) 85 } 86 87 func TestDeleteEmailAddress(t *testing.T) { 88 assert.NoError(t, unittest.PrepareTestDatabase()) 89 90 assert.NoError(t, user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{ 91 UID: int64(1), 92 ID: int64(33), 93 Email: "user1-2@example.com", 94 LowerEmail: "user1-2@example.com", 95 })) 96 97 assert.NoError(t, user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{ 98 UID: int64(1), 99 Email: "user1-3@example.com", 100 LowerEmail: "user1-3@example.com", 101 })) 102 103 // Email address does not exist 104 err := user_model.DeleteEmailAddress(db.DefaultContext, &user_model.EmailAddress{ 105 UID: int64(1), 106 Email: "user1234567890@example.com", 107 LowerEmail: "user1234567890@example.com", 108 }) 109 assert.Error(t, err) 110 } 111 112 func TestDeleteEmailAddresses(t *testing.T) { 113 assert.NoError(t, unittest.PrepareTestDatabase()) 114 115 // delete multiple email address 116 emails := make([]*user_model.EmailAddress, 2) 117 emails[0] = &user_model.EmailAddress{ 118 UID: int64(2), 119 ID: int64(3), 120 Email: "user2@example.com", 121 LowerEmail: "user2@example.com", 122 } 123 emails[1] = &user_model.EmailAddress{ 124 UID: int64(2), 125 Email: "user2-2@example.com", 126 LowerEmail: "user2-2@example.com", 127 } 128 assert.NoError(t, user_model.DeleteEmailAddresses(db.DefaultContext, emails)) 129 130 // ErrEmailAlreadyUsed 131 err := user_model.DeleteEmailAddresses(db.DefaultContext, emails) 132 assert.Error(t, err) 133 } 134 135 func TestMakeEmailPrimary(t *testing.T) { 136 assert.NoError(t, unittest.PrepareTestDatabase()) 137 138 email := &user_model.EmailAddress{ 139 Email: "user567890@example.com", 140 } 141 err := user_model.MakeEmailPrimary(db.DefaultContext, email) 142 assert.Error(t, err) 143 assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error()) 144 145 email = &user_model.EmailAddress{ 146 Email: "user11@example.com", 147 } 148 err = user_model.MakeEmailPrimary(db.DefaultContext, email) 149 assert.Error(t, err) 150 assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error()) 151 152 email = &user_model.EmailAddress{ 153 Email: "user9999999@example.com", 154 } 155 err = user_model.MakeEmailPrimary(db.DefaultContext, email) 156 assert.Error(t, err) 157 assert.True(t, user_model.IsErrUserNotExist(err)) 158 159 email = &user_model.EmailAddress{ 160 Email: "user101@example.com", 161 } 162 err = user_model.MakeEmailPrimary(db.DefaultContext, email) 163 assert.NoError(t, err) 164 165 user, _ := user_model.GetUserByID(db.DefaultContext, int64(10)) 166 assert.Equal(t, "user101@example.com", user.Email) 167 } 168 169 func TestActivate(t *testing.T) { 170 assert.NoError(t, unittest.PrepareTestDatabase()) 171 172 email := &user_model.EmailAddress{ 173 ID: int64(1), 174 UID: int64(1), 175 Email: "user11@example.com", 176 } 177 assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email)) 178 179 emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1)) 180 assert.Len(t, emails, 3) 181 assert.True(t, emails[0].IsActivated) 182 assert.True(t, emails[0].IsPrimary) 183 assert.False(t, emails[1].IsPrimary) 184 assert.True(t, emails[2].IsActivated) 185 assert.False(t, emails[2].IsPrimary) 186 } 187 188 func TestListEmails(t *testing.T) { 189 assert.NoError(t, unittest.PrepareTestDatabase()) 190 191 // Must find all users and their emails 192 opts := &user_model.SearchEmailOptions{ 193 ListOptions: db.ListOptions{ 194 PageSize: 10000, 195 }, 196 } 197 emails, count, err := user_model.SearchEmails(db.DefaultContext, opts) 198 assert.NoError(t, err) 199 assert.NotEqual(t, int64(0), count) 200 assert.True(t, count > 5) 201 202 contains := func(match func(s *user_model.SearchEmailResult) bool) bool { 203 for _, v := range emails { 204 if match(v) { 205 return true 206 } 207 } 208 return false 209 } 210 211 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 18 })) 212 // 'org3' is an organization 213 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 3 })) 214 215 // Must find no records 216 opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"} 217 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 218 assert.NoError(t, err) 219 assert.Equal(t, int64(0), count) 220 221 // Must find users 'user2', 'user28', etc. 222 opts = &user_model.SearchEmailOptions{Keyword: "user2"} 223 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 224 assert.NoError(t, err) 225 assert.NotEqual(t, int64(0), count) 226 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 })) 227 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 })) 228 229 // Must find only primary addresses (i.e. from the `user` table) 230 opts = &user_model.SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} 231 emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) 232 assert.NoError(t, err) 233 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary })) 234 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary })) 235 236 // Must find only inactive addresses (i.e. not validated) 237 opts = &user_model.SearchEmailOptions{IsActivated: util.OptionalBoolFalse} 238 emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) 239 assert.NoError(t, err) 240 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated })) 241 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated })) 242 243 // Must find more than one page, but retrieve only one 244 opts = &user_model.SearchEmailOptions{ 245 ListOptions: db.ListOptions{ 246 PageSize: 5, 247 Page: 1, 248 }, 249 } 250 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 251 assert.NoError(t, err) 252 assert.Len(t, emails, 5) 253 assert.Greater(t, count, int64(len(emails))) 254 } 255 256 func TestEmailAddressValidate(t *testing.T) { 257 kases := map[string]error{ 258 "abc@gmail.com": nil, 259 "132@hotmail.com": nil, 260 "1-3-2@test.org": nil, 261 "1.3.2@test.org": nil, 262 "a_123@test.org.cn": nil, 263 `first.last@iana.org`: nil, 264 `first!last@iana.org`: nil, 265 `first#last@iana.org`: nil, 266 `first$last@iana.org`: nil, 267 `first%last@iana.org`: nil, 268 `first&last@iana.org`: nil, 269 `first'last@iana.org`: nil, 270 `first*last@iana.org`: nil, 271 `first+last@iana.org`: nil, 272 `first/last@iana.org`: nil, 273 `first=last@iana.org`: nil, 274 `first?last@iana.org`: nil, 275 `first^last@iana.org`: nil, 276 "first`last@iana.org": nil, 277 `first{last@iana.org`: nil, 278 `first|last@iana.org`: nil, 279 `first}last@iana.org`: nil, 280 `first~last@iana.org`: nil, 281 `first;last@iana.org`: user_model.ErrEmailCharIsNotSupported{`first;last@iana.org`}, 282 ".233@qq.com": user_model.ErrEmailInvalid{".233@qq.com"}, 283 "!233@qq.com": nil, 284 "#233@qq.com": nil, 285 "$233@qq.com": nil, 286 "%233@qq.com": nil, 287 "&233@qq.com": nil, 288 "'233@qq.com": nil, 289 "*233@qq.com": nil, 290 "+233@qq.com": nil, 291 "-233@qq.com": user_model.ErrEmailInvalid{"-233@qq.com"}, 292 "/233@qq.com": nil, 293 "=233@qq.com": nil, 294 "?233@qq.com": nil, 295 "^233@qq.com": nil, 296 "_233@qq.com": nil, 297 "`233@qq.com": nil, 298 "{233@qq.com": nil, 299 "|233@qq.com": nil, 300 "}233@qq.com": nil, 301 "~233@qq.com": nil, 302 ";233@qq.com": user_model.ErrEmailCharIsNotSupported{";233@qq.com"}, 303 "Foo <foo@bar.com>": user_model.ErrEmailCharIsNotSupported{"Foo <foo@bar.com>"}, 304 string([]byte{0xE2, 0x84, 0xAA}): user_model.ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})}, 305 } 306 for kase, err := range kases { 307 t.Run(kase, func(t *testing.T) { 308 assert.EqualValues(t, err, user_model.ValidateEmail(kase)) 309 }) 310 } 311 }