Skip to content

Commit 8d1b035

Browse files
committed
tests, including an attachment (gitea.png) in an issue
1 parent b2db1a7 commit 8d1b035

File tree

5 files changed

+163
-1
lines changed

5 files changed

+163
-1
lines changed

models/fixtures/attachment.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,16 @@
153153
download_count: 0
154154
size: 0
155155
created_unix: 946684800
156+
157+
-
158+
id: 13
159+
uuid: 1b267670-1793-4cd0-abc1-449269b7cff9
160+
repo_id: 1
161+
issue_id: 23
162+
release_id: 0
163+
uploader_id: 0
164+
comment_id: 2
165+
name: gitea.png
166+
download_count: 0
167+
size: 1458
168+
created_unix: 946684800

models/fixtures/issue.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,3 +372,20 @@
372372
created_unix: 1707270422
373373
updated_unix: 1707270422
374374
is_locked: false
375+
376+
-
377+
id: 23
378+
repo_id: 1
379+
index: 6
380+
poster_id: 1
381+
original_author_id: 0
382+
name: issue23
383+
content: 'content including this image: <image alt="gitea.png" src="attachments/1b267670-1793-4cd0-abc1-449269b7cff9" /> with some more content behind it'
384+
milestone_id: 0
385+
priority: 0
386+
is_closed: false
387+
is_pull: false
388+
num_comments: 2
389+
created_unix: 946684800
390+
updated_unix: 978307200
391+
is_locked: false

models/fixtures/repository.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
num_watches: 4
1010
num_stars: 0
1111
num_forks: 0
12-
num_issues: 2
12+
num_issues: 3
1313
num_closed_issues: 1
1414
num_pulls: 3
1515
num_closed_pulls: 0

services/mailer/mail_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"html/template"
1111
"io"
1212
"mime/quotedprintable"
13+
"path/filepath"
1314
"regexp"
1415
"strings"
1516
"testing"
@@ -23,6 +24,7 @@ import (
2324
user_model "code.gitea.io/gitea/models/user"
2425
"code.gitea.io/gitea/modules/markup"
2526
"code.gitea.io/gitea/modules/setting"
27+
"code.gitea.io/gitea/modules/storage"
2628
sender_service "code.gitea.io/gitea/services/mailer/sender"
2729

2830
"github.com/stretchr/testify/assert"
@@ -59,6 +61,7 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re
5961

6062
setting.MailService = &mailService
6163
setting.Domain = "localhost"
64+
setting.AppURL = "https://try.gitea.io/"
6265

6366
doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
6467
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer})
@@ -450,3 +453,132 @@ func TestFromDisplayName(t *testing.T) {
450453
assert.EqualValues(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"}))
451454
})
452455
}
456+
457+
func PrepareAttachmentsStorage(t testing.TB) { // same as in test_utils.go
458+
// prepare attachments directory and files
459+
assert.NoError(t, storage.Clean(storage.Attachments))
460+
461+
s, err := storage.NewStorage(setting.LocalStorageType, &setting.Storage{
462+
Path: filepath.Join(filepath.Dir(setting.AppPath), "tests", "testdata", "data", "attachments"),
463+
})
464+
assert.NoError(t, err)
465+
assert.NoError(t, s.IterateObjects("", func(p string, obj storage.Object) error {
466+
_, err = storage.Copy(storage.Attachments, p, s, p)
467+
return err
468+
}))
469+
}
470+
471+
func TestEmbedBase64ImagesInEmail(t *testing.T) {
472+
// Fake context setup
473+
doer, repo, _, _ := prepareMailerTest(t)
474+
PrepareAttachmentsStorage(t)
475+
setting.MailService.Base64EmbedImages = true
476+
setting.MailService.Base64EmbedImagesMaxSizePerEmail = 10 * 1024 * 1024
477+
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 23, Repo: repo, Poster: doer})
478+
assert.NoError(t, issue.LoadRepo(db.DefaultContext))
479+
480+
subjectTemplates = texttmpl.Must(texttmpl.New("issue/new").Parse(subjectTpl))
481+
bodyTemplates = template.Must(template.New("issue/new").Parse(bodyTpl))
482+
483+
recipients := []*user_model.User{{Name: "Test", Email: "[email protected]"}}
484+
msgs, err := composeIssueCommentMessages(&mailCommentContext{
485+
Context: context.TODO(), // TODO: use a correct context
486+
Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue,
487+
Content: strings.ReplaceAll(issue.Content, `src="`, `src="`+setting.AppURL),
488+
}, "en-US", recipients, false, "issue create")
489+
490+
mailBody := msgs[0].Body
491+
re := regexp.MustCompile(`(?s)<body>(.*?)</body>`)
492+
matches := re.FindStringSubmatch(mailBody)
493+
if len(matches) > 1 {
494+
mailBody = matches[1]
495+
}
496+
// check if the mail body was correctly generated
497+
assert.NoError(t, err)
498+
assert.Contains(t, mailBody, "content including this image")
499+
500+
// check if an image was embedded
501+
assert.Contains(t, mailBody, "data:image/png;base64,")
502+
503+
// check if the image was embedded only once
504+
assert.Equal(t, 1, strings.Count(mailBody, "data:image/png;base64,"))
505+
506+
img2InternalBase64 := "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAxAQMAAAB3d7wRAAAABlBMVEVgmyF6qkqITHmkAAAAAXRSTlMBN+Ho8AAAAJhJREFUKM+V0DsOwyAQBNCxXLjkCFwk0t7McDQfhS4tpQuEzWc/iaUU2eo1zC4DUMWYF3DxVKzGTXjBGb2RsjJEo6ZhN1Zj+cEgi/9hBQl3YflkkIsbo5IO5glKTuhPpavM3Hp4C7WdjEWYrL5GMkp/R+s4GPlh/CZn4MEwv9aHHiyD3ujm5X22eaMyDa5yAm+O0B1TPa1l3W2qZWMg+KgtAAAAAElFTkSuQmCC"
507+
508+
// check if the image was embedded correctly
509+
assert.Contains(t, mailBody, img2InternalBase64)
510+
}
511+
512+
func TestEmbedBase64Images(t *testing.T) {
513+
user, repo, _, _ := prepareMailerTest(t)
514+
PrepareAttachmentsStorage(t)
515+
setting.MailService.Base64EmbedImages = true
516+
setting.MailService.Base64EmbedImagesMaxSizePerEmail = 10 * 1024 * 1024
517+
518+
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 23, Repo: repo, Poster: user})
519+
520+
attachment := unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: 13, IssueID: issue.ID, RepoID: repo.ID})
521+
ctx0 := context.Background()
522+
523+
ctx := &mailCommentContext{Context: ctx0 /* TODO: use a correct context */, Issue: issue, Doer: user}
524+
525+
img1ExternalURL := "https://via.placeholder.com/10"
526+
img1ExternalImg := "<img src=\"" + img1ExternalURL + "\"/>"
527+
528+
img2InternalURL := setting.AppURL + repo.Owner.Name + "/" + repo.Name + "/attachments/" + attachment.UUID
529+
img2InternalImg := "<img src=\"" + img2InternalURL + "\"/>"
530+
img2InternalBase64 := "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAAAxAQMAAAB3d7wRAAAABlBMVEVgmyF6qkqITHmkAAAAAXRSTlMBN+Ho8AAAAJhJREFUKM+V0DsOwyAQBNCxXLjkCFwk0t7McDQfhS4tpQuEzWc/iaUU2eo1zC4DUMWYF3DxVKzGTXjBGb2RsjJEo6ZhN1Zj+cEgi/9hBQl3YflkkIsbo5IO5glKTuhPpavM3Hp4C7WdjEWYrL5GMkp/R+s4GPlh/CZn4MEwv9aHHiyD3ujm5X22eaMyDa5yAm+O0B1TPa1l3W2qZWMg+KgtAAAAAElFTkSuQmCC"
531+
img2InternalBase64Img := "<img src=\"" + img2InternalBase64 + "\"/>"
532+
533+
// 1st Test: convert internal image to base64
534+
t.Run("replaceSpecifiedBase64ImagesInternal", func(t *testing.T) {
535+
totalEmbeddedImagesSize := int64(0)
536+
537+
resultImg1Internal, err := AttachmentSrcToBase64DataURI(img2InternalURL, ctx, &totalEmbeddedImagesSize)
538+
assert.NoError(t, err)
539+
assert.Equal(t, img2InternalBase64, resultImg1Internal) // replace cause internal image
540+
})
541+
542+
// 2nd Test: convert external image to base64 -> abort cause external image
543+
t.Run("replaceSpecifiedBase64ImagesExternal", func(t *testing.T) {
544+
totalEmbeddedImagesSize := int64(0)
545+
546+
resultImg1External, err := AttachmentSrcToBase64DataURI(img1ExternalURL, ctx, &totalEmbeddedImagesSize)
547+
assert.Error(t, err)
548+
assert.Equal(t, "", resultImg1External) // don't replace cause external image
549+
})
550+
551+
// 3rd Test: generate email body with 1 internal and 1 external image, expect the result to have the internal image replaced with base64 data and the external not replaced
552+
t.Run("generateEmailBody", func(t *testing.T) {
553+
mailBody := "<html><head></head><body><p>Test1</p>" + img1ExternalImg + "<p>Test2</p>" + img2InternalImg + "<p>Test3</p></body></html>"
554+
expectedMailBody := "<html><head></head><body><p>Test1</p>" + img1ExternalImg + "<p>Test2</p>" + img2InternalBase64Img + "<p>Test3</p></body></html>"
555+
resultMailBody, err := Base64InlineImages(mailBody, ctx)
556+
557+
assert.NoError(t, err)
558+
assert.Equal(t, expectedMailBody, resultMailBody)
559+
})
560+
561+
// 4th Test, generate email body with 2 internal images, but set Mailer.Base64EmbedImagesMaxSizePerEmail to the size of the first image (+1), expect the first image to be replaced and the second not
562+
t.Run("generateEmailBodyWithMaxSize", func(t *testing.T) {
563+
setting.MailService.Base64EmbedImagesMaxSizePerEmail = int64(len(img2InternalBase64) + 1)
564+
565+
mailBody := "<html><head></head><body><p>Test1</p>" + img2InternalImg + "<p>Test2</p>" + img2InternalImg + "<p>Test3</p></body></html>"
566+
expectedMailBody := "<html><head></head><body><p>Test1</p>" + img2InternalBase64Img + "<p>Test2</p>" + img2InternalImg + "<p>Test3</p></body></html>"
567+
resultMailBody, err := Base64InlineImages(mailBody, ctx)
568+
569+
assert.NoError(t, err)
570+
assert.Equal(t, expectedMailBody, resultMailBody)
571+
})
572+
573+
// 5th Test, generate email body with 3 internal images, but set Mailer.Base64EmbedImagesMaxSizePerEmail to the size of all 3 images (+1), expect all images to be replaced
574+
t.Run("generateEmailBodyWith3Images", func(t *testing.T) {
575+
setting.MailService.Base64EmbedImagesMaxSizePerEmail = int64(len(img2InternalBase64)*3 + 1)
576+
577+
mailBody := "<html><head></head><body><p>Test1</p>" + img2InternalImg + "<p>Test2</p>" + img2InternalImg + "<p>Test3</p>" + img2InternalImg + "</body></html>"
578+
expectedMailBody := "<html><head></head><body><p>Test1</p>" + img2InternalBase64Img + "<p>Test2</p>" + img2InternalBase64Img + "<p>Test3</p>" + img2InternalBase64Img + "</body></html>"
579+
resultMailBody, err := Base64InlineImages(mailBody, ctx)
580+
581+
assert.NoError(t, err)
582+
assert.Equal(t, expectedMailBody, resultMailBody)
583+
})
584+
}
Binary file not shown.

0 commit comments

Comments
 (0)