0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-05-15 10:43:21 +02:00

feat: add tests for watch options

This commit is contained in:
Alexandre Bontems 2026-05-04 18:26:04 +02:00
parent f9f00cd598
commit 1552255e02
No known key found for this signature in database
GPG Key ID: 37B7C811C1723B5E
7 changed files with 261 additions and 20 deletions

View File

@ -7,9 +7,11 @@ import (
"context"
"testing"
"code.gitea.io/gitea/models/activities"
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -138,3 +140,69 @@ func TestSetIssueReadBy(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, activities_model.NotificationStatusRead, nt.Status)
}
func TestIssueNotificationWithWatchOptions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
watcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
iss := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
assert.NoError(t, issues_model.RemoveIssueWatchersByRepoID(t.Context(), watcher.ID, repo.ID))
assert.NoError(t, repo_model.WatchRepo(t.Context(), watcher, repo, true))
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: false,
Releases: true,
}))
assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(t.Context(), iss.ID, 0, doer.ID, 0))
notification, err := activities.GetIssueNotification(t.Context(), watcher.ID, iss.ID)
assert.NoError(t, err)
assert.Equal(t, int64(0), notification.IssueID) // No notification found
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: true,
Releases: true,
}))
assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(t.Context(), iss.ID, 0, doer.ID, 0))
notification, err = activities.GetIssueNotification(t.Context(), watcher.ID, iss.ID)
assert.NoError(t, err)
assert.Equal(t, activities.NotificationStatusUnread, notification.Status)
}
func TestPullRequestNotificationWithWatchOptions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
watcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8})
assert.NoError(t, repo_model.WatchRepo(t.Context(), watcher, repo2, true))
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo2, repo_model.WatchOptions{
PullRequests: false,
Issues: true,
Releases: true,
}))
assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(t.Context(), pr.ID, 0, doer.ID, 0))
notification, err := activities.GetIssueNotification(t.Context(), watcher.ID, pr.ID)
assert.NoError(t, err)
assert.Equal(t, int64(0), notification.IssueID) // No notification found
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo2, repo_model.WatchOptions{
PullRequests: true,
Issues: true,
Releases: true,
}))
assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(t.Context(), pr.ID, 0, doer.ID, 0))
notification, err = activities.GetIssueNotification(t.Context(), watcher.ID, pr.ID)
assert.NoError(t, err)
assert.Equal(t, activities.NotificationStatusUnread, notification.Status)
}

View File

@ -1,43 +1,56 @@
-
id: 1
- id: 1
user_id: 1
repo_id: 1
mode: 1 # normal
pull_requests: true
issues: true
releases: true
-
id: 2
- id: 2
user_id: 4
repo_id: 1
mode: 1 # normal
pull_requests: true
issues: true
releases: true
-
id: 3
- id: 3
user_id: 9
repo_id: 1
mode: 1 # normal
pull_requests: true
issues: true
releases: true
-
id: 4
- id: 4
user_id: 8
repo_id: 1
mode: 2 # don't watch
pull_requests: true
issues: true
releases: true
-
id: 5
- id: 5
user_id: 11
repo_id: 1
mode: 3 # auto
pull_requests: true
issues: true
releases: true
-
id: 6
- id: 6
user_id: 10
repo_id: 21
mode: 1 # normal
pull_requests: true
issues: true
releases: true
-
id: 7
- id: 7
user_id: 10
repo_id: 32
mode: 1 # normal
pull_requests: true
issues: true
releases: true
# DO NOT add more test data in the fixtures, test case should prepare their own test data separately and clearly

View File

@ -125,16 +125,41 @@ func TestClearRepoWatches(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
const repoID int64 = 1
watchers, err := repo_model.GetRepoWatchersIDs(t.Context(), repoID)
watchers, err := repo_model.GetRepoWatchers(t.Context(), repoID, db.ListOptions{Page: 1})
require.NoError(t, err)
require.NotEmpty(t, watchers)
assert.NoError(t, repo_model.ClearRepoWatches(t.Context(), repoID))
watchers, err = repo_model.GetRepoWatchersIDs(t.Context(), repoID)
watchers, err = repo_model.GetRepoWatchers(t.Context(), repoID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Empty(t, watchers)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
assert.Zero(t, repo.NumWatches)
}
func TestWatchOptions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 5})
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, repo_model.WatchRepo(t.Context(), user5, repo, true))
watch, err := repo_model.GetWatch(t.Context(), user5.ID, repo.ID)
assert.NoError(t, err)
assert.True(t, watch.PullRequests)
assert.True(t, watch.Issues)
assert.True(t, watch.Releases)
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), user5, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: false,
Releases: true,
}))
watch, err = repo_model.GetWatch(t.Context(), user5.ID, repo.ID)
assert.NoError(t, err)
assert.True(t, watch.PullRequests)
assert.False(t, watch.Issues)
assert.True(t, watch.Releases)
}

View File

@ -66,7 +66,7 @@ func mailIssueCommentToParticipants(ctx context.Context, comment *mailComment, m
// =========== Repo watchers ===========
// Make repo watchers last, since it's likely the list with the most users
if !(comment.Issue.IsPull && comment.Issue.PullRequest.IsWorkInProgress(ctx) && comment.ActionType != activities_model.ActionCreatePullRequest) {
var watchType repo_model.WatchType = repo_model.WatchIssues
watchType := repo_model.WatchIssues
if comment.Issue.IsPull {
watchType = repo_model.WatchPullRequests
}

View File

@ -0,0 +1,83 @@
package mailer
import (
"testing"
"code.gitea.io/gitea/models/activities"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/test"
sender_service "code.gitea.io/gitea/services/mailer/sender"
"github.com/stretchr/testify/assert"
)
func TestMailNewIssueAndPullRequest(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
defer test.MockVariableValue(&setting.MailService)()
defer test.MockVariableValue(&setting.Domain)()
defer test.MockVariableValue(&setting.AppName)()
defer test.MockVariableValue(&setting.AppURL)()
setting.MailService = &setting.Mailer{
From: "Gitea",
FromEmail: "noreply@example.com",
}
setting.Domain = "example.com"
setting.AppName = "Gitea"
setting.AppURL = "https://example.com/"
defer mockMailTemplates(string("repo/issue/new"), "{{.Subject}}", "<p>Issue</p>")()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
watcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
var didSend = false
origSend := SendAsync
SendAsync = func(msgs ...*sender_service.Message) {
for _, msg := range msgs {
if msg.To == watcher.Email {
didSend = true
}
}
}
defer func() {
SendAsync = origSend
}()
iss := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
assert.NoError(t, issues_model.RemoveIssueWatchersByRepoID(t.Context(), watcher.ID, repo.ID))
assert.NoError(t, repo_model.WatchRepo(t.Context(), watcher, repo, true))
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo, repo_model.WatchOptions{
PullRequests: false,
Issues: false,
Releases: true,
}))
var mentions []*user_model.User
assert.NoError(t, MailParticipants(t.Context(), iss, doer, activities.ActionCreateIssue, mentions))
assert.False(t, didSend)
didSend = false
assert.NoError(t, MailParticipants(t.Context(), pr, doer, activities.ActionCreatePullRequest, mentions))
assert.False(t, didSend)
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), watcher, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: true,
Releases: true,
}))
didSend = false
assert.NoError(t, MailParticipants(t.Context(), pr, doer, activities.ActionCreatePullRequest, mentions))
assert.True(t, didSend)
didSend = false
assert.NoError(t, MailParticipants(t.Context(), iss, doer, activities.ActionCreateIssue, mentions))
assert.True(t, didSend)
}

View File

@ -62,3 +62,55 @@ func TestMailNewReleaseFiltersUnauthorizedWatchers(t *testing.T) {
assert.Equal(t, admin.EmailTo(), sent[0].To)
assert.NotEqual(t, unauthorized.EmailTo(), sent[0].To)
}
func TestMailNewReleaseWithWatchOptions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
defer test.MockVariableValue(&setting.MailService)()
defer test.MockVariableValue(&setting.Domain)()
defer test.MockVariableValue(&setting.AppName)()
defer test.MockVariableValue(&setting.AppURL)()
setting.MailService = &setting.Mailer{
From: "Gitea",
FromEmail: "noreply@example.com",
}
setting.Domain = "example.com"
setting.AppName = "Gitea"
setting.AppURL = "https://example.com/"
defer mockMailTemplates(string(tplNewReleaseMail), "{{.Subject}}", "<p>{{.Release.TagName}}</p>")()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, repo_model.WatchRepo(t.Context(), user, repo, true))
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), user, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: true,
Releases: false,
}))
var didSend = false
origSend := SendAsync
SendAsync = func(msgs ...*sender_service.Message) {
didSend = true
}
defer func() {
SendAsync = origSend
}()
rel := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 11})
rel.Publisher = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: rel.PublisherID})
MailNewRelease(t.Context(), rel)
assert.False(t, didSend)
assert.NoError(t, repo_model.WatchRepoOptions(t.Context(), user, repo, repo_model.WatchOptions{
PullRequests: true,
Issues: true,
Releases: true,
}))
didSend = false
MailNewRelease(t.Context(), rel)
assert.True(t, didSend)
}

View File

@ -76,13 +76,13 @@ func TestMakeRepoPrivateClearsWatches(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo.IsPrivate)
watchers, err := repo_model.GetRepoWatchersIDs(t.Context(), repo.ID)
watchers, err := repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
require.NoError(t, err)
require.NotEmpty(t, watchers)
assert.NoError(t, MakeRepoPrivate(t.Context(), repo, true))
watchers, err = repo_model.GetRepoWatchersIDs(t.Context(), repo.ID)
watchers, err = repo_model.GetRepoWatchers(t.Context(), repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Empty(t, watchers)