code.gitea.io/gitea@v1.22.3/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/optional" 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 TestMakeEmailPrimary(t *testing.T) { 46 assert.NoError(t, unittest.PrepareTestDatabase()) 47 48 err := user_model.MakeActiveEmailPrimary(db.DefaultContext, 9999999) 49 assert.Error(t, err) 50 assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) 51 52 email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user11@example.com"}) 53 err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) 54 assert.Error(t, err) 55 assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) // inactive email is considered as not exist for "MakeActiveEmailPrimary" 56 57 email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user9999999@example.com"}) 58 err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) 59 assert.Error(t, err) 60 assert.True(t, user_model.IsErrUserNotExist(err)) 61 62 email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user101@example.com"}) 63 err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID) 64 assert.NoError(t, err) 65 66 user, _ := user_model.GetUserByID(db.DefaultContext, int64(10)) 67 assert.Equal(t, "user101@example.com", user.Email) 68 } 69 70 func TestActivate(t *testing.T) { 71 assert.NoError(t, unittest.PrepareTestDatabase()) 72 73 email := &user_model.EmailAddress{ 74 ID: int64(1), 75 UID: int64(1), 76 Email: "user11@example.com", 77 } 78 assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email)) 79 80 emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1)) 81 assert.Len(t, emails, 3) 82 assert.True(t, emails[0].IsActivated) 83 assert.True(t, emails[0].IsPrimary) 84 assert.False(t, emails[1].IsPrimary) 85 assert.True(t, emails[2].IsActivated) 86 assert.False(t, emails[2].IsPrimary) 87 } 88 89 func TestListEmails(t *testing.T) { 90 assert.NoError(t, unittest.PrepareTestDatabase()) 91 92 // Must find all users and their emails 93 opts := &user_model.SearchEmailOptions{ 94 ListOptions: db.ListOptions{ 95 PageSize: 10000, 96 }, 97 } 98 emails, count, err := user_model.SearchEmails(db.DefaultContext, opts) 99 assert.NoError(t, err) 100 assert.NotEqual(t, int64(0), count) 101 assert.True(t, count > 5) 102 103 contains := func(match func(s *user_model.SearchEmailResult) bool) bool { 104 for _, v := range emails { 105 if match(v) { 106 return true 107 } 108 } 109 return false 110 } 111 112 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 18 })) 113 // 'org3' is an organization 114 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 3 })) 115 116 // Must find no records 117 opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"} 118 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 119 assert.NoError(t, err) 120 assert.Equal(t, int64(0), count) 121 122 // Must find users 'user2', 'user28', etc. 123 opts = &user_model.SearchEmailOptions{Keyword: "user2"} 124 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 125 assert.NoError(t, err) 126 assert.NotEqual(t, int64(0), count) 127 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 })) 128 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 })) 129 130 // Must find only primary addresses (i.e. from the `user` table) 131 opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)} 132 emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) 133 assert.NoError(t, err) 134 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary })) 135 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary })) 136 137 // Must find only inactive addresses (i.e. not validated) 138 opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)} 139 emails, _, err = user_model.SearchEmails(db.DefaultContext, opts) 140 assert.NoError(t, err) 141 assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated })) 142 assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated })) 143 144 // Must find more than one page, but retrieve only one 145 opts = &user_model.SearchEmailOptions{ 146 ListOptions: db.ListOptions{ 147 PageSize: 5, 148 Page: 1, 149 }, 150 } 151 emails, count, err = user_model.SearchEmails(db.DefaultContext, opts) 152 assert.NoError(t, err) 153 assert.Len(t, emails, 5) 154 assert.Greater(t, count, int64(len(emails))) 155 } 156 157 func TestEmailAddressValidate(t *testing.T) { 158 kases := map[string]error{ 159 "abc@gmail.com": nil, 160 "132@hotmail.com": nil, 161 "1-3-2@test.org": nil, 162 "1.3.2@test.org": nil, 163 "a_123@test.org.cn": nil, 164 `first.last@iana.org`: nil, 165 `first!last@iana.org`: nil, 166 `first#last@iana.org`: nil, 167 `first$last@iana.org`: nil, 168 `first%last@iana.org`: nil, 169 `first&last@iana.org`: nil, 170 `first'last@iana.org`: nil, 171 `first*last@iana.org`: nil, 172 `first+last@iana.org`: nil, 173 `first/last@iana.org`: nil, 174 `first=last@iana.org`: nil, 175 `first?last@iana.org`: nil, 176 `first^last@iana.org`: nil, 177 "first`last@iana.org": nil, 178 `first{last@iana.org`: nil, 179 `first|last@iana.org`: nil, 180 `first}last@iana.org`: nil, 181 `first~last@iana.org`: nil, 182 `first;last@iana.org`: user_model.ErrEmailCharIsNotSupported{`first;last@iana.org`}, 183 ".233@qq.com": user_model.ErrEmailInvalid{".233@qq.com"}, 184 "!233@qq.com": nil, 185 "#233@qq.com": nil, 186 "$233@qq.com": nil, 187 "%233@qq.com": nil, 188 "&233@qq.com": nil, 189 "'233@qq.com": nil, 190 "*233@qq.com": nil, 191 "+233@qq.com": nil, 192 "-233@qq.com": user_model.ErrEmailInvalid{"-233@qq.com"}, 193 "/233@qq.com": nil, 194 "=233@qq.com": nil, 195 "?233@qq.com": nil, 196 "^233@qq.com": nil, 197 "_233@qq.com": nil, 198 "`233@qq.com": nil, 199 "{233@qq.com": nil, 200 "|233@qq.com": nil, 201 "}233@qq.com": nil, 202 "~233@qq.com": nil, 203 ";233@qq.com": user_model.ErrEmailCharIsNotSupported{";233@qq.com"}, 204 "Foo <foo@bar.com>": user_model.ErrEmailCharIsNotSupported{"Foo <foo@bar.com>"}, 205 string([]byte{0xE2, 0x84, 0xAA}): user_model.ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})}, 206 } 207 for kase, err := range kases { 208 t.Run(kase, func(t *testing.T) { 209 assert.EqualValues(t, err, user_model.ValidateEmail(kase)) 210 }) 211 } 212 }