Files
gitea/models/user/email_address_test.go
T
silverwind 8abda62312 test: consolidate Go tests (#39962)
Consolidate all Go tests. Coverage is identical to before. Go tests are
around 5% faster while being 7% smaller. No non-test code is touched.
2026-10-24 13:48:19 +00:00

163 lines
5.8 KiB
Go

// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user_test
import (
"slices"
"testing"
"gitea.dev/models/db"
"gitea.dev/models/unittest"
user_model "gitea.dev/models/user"
"gitea.dev/modules/optional"
"github.com/stretchr/testify/assert"
)
func TestEmailAddresses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
t.Run("GetEmailAddresses", func(t *testing.T) {
emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1))
if assert.Len(t, emails, 3) {
assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[2].IsActivated)
assert.False(t, emails[2].IsPrimary)
}
emails, _ = user_model.GetEmailAddresses(t.Context(), int64(2))
if assert.Len(t, emails, 2) {
assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[0].IsActivated)
}
})
t.Run("IsEmailUsed", func(t *testing.T) {
isExist, _ := user_model.IsEmailUsed(t.Context(), "")
assert.True(t, isExist)
isExist, _ = user_model.IsEmailUsed(t.Context(), "user11@example.com")
assert.True(t, isExist)
isExist, _ = user_model.IsEmailUsed(t.Context(), "user1234567890@example.com")
assert.False(t, isExist)
})
t.Run("ListEmails", func(t *testing.T) {
search := func(opts *user_model.SearchEmailOptions) ([]*user_model.SearchEmailResult, int64) {
emails, count, err := user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
return emails, count
}
// Must find all users and their emails
emails, count := search(&user_model.SearchEmailOptions{ListOptions: db.ListOptions{PageSize: 10000}})
assert.Greater(t, count, int64(5))
contains := func(match func(s *user_model.SearchEmailResult) bool) bool {
return slices.ContainsFunc(emails, match)
}
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 18 }))
// 'org3' is an organization
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 3 }))
// Must find no records
emails, count = search(&user_model.SearchEmailOptions{Keyword: "NOTFOUND"})
assert.Equal(t, int64(0), count)
// Must find users 'user2', 'user28', etc.
emails, count = search(&user_model.SearchEmailOptions{Keyword: "user2"})
assert.NotEqual(t, int64(0), count)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 }))
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 }))
// Must find only primary addresses (i.e. from the `user` table)
emails, _ = search(&user_model.SearchEmailOptions{IsPrimary: optional.Some(true)})
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
// Must find only inactive addresses (i.e. not validated)
emails, _ = search(&user_model.SearchEmailOptions{IsActivated: optional.Some(false)})
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated }))
// Must find more than one page, but retrieve only one
emails, count = search(&user_model.SearchEmailOptions{ListOptions: db.ListOptions{PageSize: 5, Page: 1}})
assert.Len(t, emails, 5)
assert.Greater(t, count, int64(len(emails)))
})
t.Run("MakeEmailPrimary", func(t *testing.T) {
err := user_model.MakeActiveEmailPrimary(t.Context(), 1, 9999999)
assert.Error(t, err)
assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{})
email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user11@example.com"})
err = user_model.MakeActiveEmailPrimary(t.Context(), email.UID, email.ID)
assert.Error(t, err)
assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) // inactive email is considered as not exist for "MakeActiveEmailPrimary"
email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user9999999@example.com"})
err = user_model.MakeActiveEmailPrimary(t.Context(), email.UID, email.ID)
assert.Error(t, err)
assert.True(t, user_model.IsErrUserNotExist(err))
email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user101@example.com"})
err = user_model.MakeActiveEmailPrimary(t.Context(), email.UID, email.ID)
assert.NoError(t, err)
user, _ := user_model.GetUserByID(t.Context(), int64(10))
assert.Equal(t, "user101@example.com", user.Email)
})
t.Run("Activate", func(t *testing.T) {
email := &user_model.EmailAddress{
ID: int64(1),
UID: int64(1),
Email: "user11@example.com",
}
assert.NoError(t, user_model.ActivateEmail(t.Context(), email))
emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1))
assert.Len(t, emails, 3)
assert.True(t, emails[0].IsActivated)
assert.True(t, emails[0].IsPrimary)
assert.False(t, emails[1].IsPrimary)
assert.True(t, emails[2].IsActivated)
assert.False(t, emails[2].IsPrimary)
})
}
func TestEmailAddressValidate(t *testing.T) {
cases := map[string]bool{
"": false,
"@a": false,
// "_" shouldn't appear in domain but can appear in hostname, since we can't stop site admins from doing so, just accept it
"root@local_host": true,
"root@localhost": true,
"root@LOCALHOST": true,
"user@[192.168.1.2]": true,
"user@[IPv6:FFff::1]": true,
"abc@gmail.com": true,
"abc@gmail.com.": false,
"abc@gmail.com-": false,
"abc@gmail.com\n": false,
"abc@gmail..com": false,
"abc@gmail com": false,
"abc@gmail*com": false,
"Foo <foo@bar.com>": false,
"abc@gmail.com (x)": false,
"jürgen@example.com": false, // utf8 address is not supported yet
}
for tc, isValid := range cases {
t.Run(tc, func(t *testing.T) {
err := user_model.ValidateEmail(tc)
assert.Equal(t, err == nil, isValid)
})
}
}