// Copyright 2026 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package mailer import ( "testing" repo_model "gitea.dev/models/repo" "gitea.dev/models/unittest" user_model "gitea.dev/models/user" "gitea.dev/modules/setting" "gitea.dev/modules/test" sender_service "gitea.dev/services/mailer/sender" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestMailNewReleaseFiltersUnauthorizedWatchers(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) defer test.MockVariableValue(&setting.MailService)() defer test.MockVariableValue(&setting.AppDomain)() defer test.MockVariableValue(&setting.AppName)() defer test.MockVariableValue(&setting.AppURL)() setting.MailService = &setting.Mailer{ From: "Gitea", FromEmail: "noreply@example.com", } setting.AppName = "Gitea" setting.AppURL = "https://example.com/" defer mockMailTemplates(string(tplNewReleaseMail), "{{.Subject}}", "

{{.Release.TagName}}

")() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) require.True(t, repo.IsPrivate) admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) unauthorized := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) assert.NoError(t, repo_model.WatchRepoAuto(t.Context(), admin, repo, true)) assert.NoError(t, repo_model.WatchRepoAuto(t.Context(), unauthorized, repo, true)) rel := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 11}) rel.Repo = nil rel.Publisher = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: rel.PublisherID}) var sent []*sender_service.Message origSend := SendAsync SendAsync = func(msgs ...*sender_service.Message) { sent = append(sent, msgs...) } defer func() { SendAsync = origSend }() MailNewRelease(t.Context(), rel) require.Len(t, sent, 1) assert.Equal(t, admin.EmailTo(), sent[0].To) assert.NotEqual(t, unauthorized.EmailTo(), sent[0].To) } func TestMailNewReleaseOnMentionCustomWatch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) defer test.MockVariableValue(&setting.MailService, &setting.Mailer{FromEmail: "noreply@example.com"})() defer mockMailTemplates(string(tplNewReleaseMail), "{{.Subject}}", "

{{.Release.TagName}}

")() // users 4 and 9 only get mail on mention and watch repo 1 with all activity repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) customWatcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) allWatcher := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 9}) require.NoError(t, repo_model.WatchRepoWithOptions(t.Context(), customWatcher, repo, repo_model.WatchOptions{Mode: repo_model.WatchModeCustom, WatchReleases: true})) rel := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 1, RepoID: repo.ID}) rel.Publisher = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: rel.PublisherID}) var recipients []string defer test.MockVariableValue(&SendAsync, func(msgs ...*sender_service.Message) { for _, msg := range msgs { recipients = append(recipients, msg.To) } })() MailNewRelease(t.Context(), rel) assert.Contains(t, recipients, customWatcher.EmailTo()) assert.NotContains(t, recipients, allWatcher.EmailTo()) }