2019-07-17 22:02:42 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2019-09-24 08:02:49 +03:00
package mailer
2019-07-17 22:02:42 +03:00
import (
2019-11-07 16:34:28 +03:00
"bytes"
2019-07-17 22:02:42 +03:00
"html/template"
"testing"
2019-11-07 16:34:28 +03:00
texttmpl "text/template"
2019-07-17 22:02:42 +03:00
2019-09-24 08:02:49 +03:00
"code.gitea.io/gitea/models"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-12 17:36:47 +03:00
"code.gitea.io/gitea/models/unittest"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2019-07-17 22:02:42 +03:00
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
2019-11-07 16:34:28 +03:00
const subjectTpl = `
{ { . SubjectPrefix } } [ { { . Repo } } ] @ { { . Doer . Name } } # { { . Issue . Index } } - { { . Issue . Title } }
`
const bodyTpl = `
2019-07-17 22:02:42 +03:00
< ! DOCTYPE html >
< html >
< head >
< meta http - equiv = "Content-Type" content = "text/html; charset=utf-8" / >
< title > { { . Subject } } < / title >
< / head >
< body >
< p > { { . Body } } < / p >
< p >
-- -
< br >
< a href = "{{.Link}}" > View it on Gitea < / a > .
< / p >
< / body >
< / html >
`
2021-12-10 04:27:50 +03:00
func prepareMailerTest ( t * testing . T ) ( doer * user_model . User , repo * repo_model . Repository , issue * models . Issue , comment * models . Comment ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2019-09-24 08:02:49 +03:00
var mailService = setting . Mailer {
From : "test@gitea.com" ,
}
2019-07-17 22:02:42 +03:00
2019-09-24 08:02:49 +03:00
setting . MailService = & mailService
setting . Domain = "localhost"
2019-07-17 22:02:42 +03:00
2021-11-24 12:49:20 +03:00
doer = unittest . AssertExistsAndLoadBean ( t , & user_model . User { ID : 2 } ) . ( * user_model . User )
2021-12-10 04:27:50 +03:00
repo = unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 , Owner : doer } ) . ( * repo_model . Repository )
2021-11-16 11:53:21 +03:00
issue = unittest . AssertExistsAndLoadBean ( t , & models . Issue { ID : 1 , Repo : repo , Poster : doer } ) . ( * models . Issue )
2021-05-22 09:47:16 +03:00
assert . NoError ( t , issue . LoadRepo ( ) )
2021-11-16 11:53:21 +03:00
comment = unittest . AssertExistsAndLoadBean ( t , & models . Comment { ID : 2 , Issue : issue } ) . ( * models . Comment )
2021-05-22 09:47:16 +03:00
return
}
func TestComposeIssueCommentMessage ( t * testing . T ) {
doer , _ , issue , comment := prepareMailerTest ( t )
2019-07-17 22:02:42 +03:00
2019-11-07 16:34:28 +03:00
stpl := texttmpl . Must ( texttmpl . New ( "issue/comment" ) . Parse ( subjectTpl ) )
btpl := template . Must ( template . New ( "issue/comment" ) . Parse ( bodyTpl ) )
InitMailRender ( stpl , btpl )
2019-07-17 22:02:42 +03:00
2021-11-24 12:49:20 +03:00
recipients := [ ] * user_model . User { { Name : "Test" , Email : "test@gitea.com" } , { Name : "Test2" , Email : "test2@gitea.com" } }
2021-04-20 01:25:08 +03:00
msgs , err := composeIssueCommentMessages ( & mailCommentContext { Issue : issue , Doer : doer , ActionType : models . ActionCommentIssue ,
2021-05-22 09:47:16 +03:00
Content : "test body" , Comment : comment } , "en-US" , recipients , false , "issue comment" )
2021-04-20 01:25:08 +03:00
assert . NoError ( t , err )
2019-11-18 11:08:20 +03:00
assert . Len ( t , msgs , 2 )
2020-01-16 20:55:36 +03:00
gomailMsg := msgs [ 0 ] . ToMessage ( )
mailto := gomailMsg . GetHeader ( "To" )
subject := gomailMsg . GetHeader ( "Subject" )
2021-10-01 18:24:43 +03:00
messageID := gomailMsg . GetHeader ( "Message-ID" )
inReplyTo := gomailMsg . GetHeader ( "In-Reply-To" )
2020-01-16 20:55:36 +03:00
references := gomailMsg . GetHeader ( "References" )
2019-07-17 22:02:42 +03:00
2019-11-18 11:08:20 +03:00
assert . Len ( t , mailto , 1 , "exactly one recipient is expected in the To field" )
2019-11-07 16:34:28 +03:00
assert . Equal ( t , "Re: " , subject [ 0 ] [ : 4 ] , "Comment reply subject should contain Re:" )
assert . Equal ( t , "Re: [user2/repo1] @user2 #1 - issue1" , subject [ 0 ] )
2021-10-01 18:24:43 +03:00
assert . Equal ( t , "<user2/repo1/issues/1@localhost>" , inReplyTo [ 0 ] , "In-Reply-To header doesn't match" )
assert . Equal ( t , "<user2/repo1/issues/1@localhost>" , references [ 0 ] , "References header doesn't match" )
assert . Equal ( t , "<user2/repo1/issues/1/comment/2@localhost>" , messageID [ 0 ] , "Message-ID header doesn't match" )
2019-07-17 22:02:42 +03:00
}
func TestComposeIssueMessage ( t * testing . T ) {
2021-05-22 09:47:16 +03:00
doer , _ , issue , _ := prepareMailerTest ( t )
2019-07-17 22:02:42 +03:00
2019-11-07 16:34:28 +03:00
stpl := texttmpl . Must ( texttmpl . New ( "issue/new" ) . Parse ( subjectTpl ) )
btpl := template . Must ( template . New ( "issue/new" ) . Parse ( bodyTpl ) )
InitMailRender ( stpl , btpl )
2019-07-17 22:02:42 +03:00
2021-11-24 12:49:20 +03:00
recipients := [ ] * user_model . User { { Name : "Test" , Email : "test@gitea.com" } , { Name : "Test2" , Email : "test2@gitea.com" } }
2021-04-20 01:25:08 +03:00
msgs , err := composeIssueCommentMessages ( & mailCommentContext { Issue : issue , Doer : doer , ActionType : models . ActionCreateIssue ,
2021-05-22 09:47:16 +03:00
Content : "test body" } , "en-US" , recipients , false , "issue create" )
2021-04-20 01:25:08 +03:00
assert . NoError ( t , err )
2019-11-18 11:08:20 +03:00
assert . Len ( t , msgs , 2 )
2019-07-17 22:02:42 +03:00
2020-01-16 20:55:36 +03:00
gomailMsg := msgs [ 0 ] . ToMessage ( )
mailto := gomailMsg . GetHeader ( "To" )
subject := gomailMsg . GetHeader ( "Subject" )
messageID := gomailMsg . GetHeader ( "Message-ID" )
2021-10-01 18:24:43 +03:00
inReplyTo := gomailMsg . GetHeader ( "In-Reply-To" )
references := gomailMsg . GetHeader ( "References" )
2019-07-17 22:02:42 +03:00
2019-11-18 11:08:20 +03:00
assert . Len ( t , mailto , 1 , "exactly one recipient is expected in the To field" )
2019-11-07 16:34:28 +03:00
assert . Equal ( t , "[user2/repo1] @user2 #1 - issue1" , subject [ 0 ] )
2021-10-01 18:24:43 +03:00
assert . Equal ( t , "<user2/repo1/issues/1@localhost>" , inReplyTo [ 0 ] , "In-Reply-To header doesn't match" )
assert . Equal ( t , "<user2/repo1/issues/1@localhost>" , references [ 0 ] , "References header doesn't match" )
assert . Equal ( t , "<user2/repo1/issues/1@localhost>" , messageID [ 0 ] , "Message-ID header doesn't match" )
2019-07-17 22:02:42 +03:00
}
2019-11-07 16:34:28 +03:00
func TestTemplateSelection ( t * testing . T ) {
2021-05-22 09:47:16 +03:00
doer , repo , issue , comment := prepareMailerTest ( t )
2021-11-24 12:49:20 +03:00
recipients := [ ] * user_model . User { { Name : "Test" , Email : "test@gitea.com" } }
2019-11-07 16:34:28 +03:00
stpl := texttmpl . Must ( texttmpl . New ( "issue/default" ) . Parse ( "issue/default/subject" ) )
texttmpl . Must ( stpl . New ( "issue/new" ) . Parse ( "issue/new/subject" ) )
texttmpl . Must ( stpl . New ( "pull/comment" ) . Parse ( "pull/comment/subject" ) )
texttmpl . Must ( stpl . New ( "issue/close" ) . Parse ( "" ) ) // Must default to fallback subject
btpl := template . Must ( template . New ( "issue/default" ) . Parse ( "issue/default/body" ) )
template . Must ( btpl . New ( "issue/new" ) . Parse ( "issue/new/body" ) )
template . Must ( btpl . New ( "pull/comment" ) . Parse ( "pull/comment/body" ) )
template . Must ( btpl . New ( "issue/close" ) . Parse ( "issue/close/body" ) )
InitMailRender ( stpl , btpl )
expect := func ( t * testing . T , msg * Message , expSubject , expBody string ) {
2020-01-16 20:55:36 +03:00
subject := msg . ToMessage ( ) . GetHeader ( "Subject" )
2019-11-07 16:34:28 +03:00
msgbuf := new ( bytes . Buffer )
2020-01-16 20:55:36 +03:00
_ , _ = msg . ToMessage ( ) . WriteTo ( msgbuf )
2019-11-07 16:34:28 +03:00
wholemsg := msgbuf . String ( )
assert . Equal ( t , [ ] string { expSubject } , subject )
assert . Contains ( t , wholemsg , expBody )
}
2019-11-18 11:08:20 +03:00
msg := testComposeIssueCommentMessage ( t , & mailCommentContext { Issue : issue , Doer : doer , ActionType : models . ActionCreateIssue ,
2021-05-22 09:47:16 +03:00
Content : "test body" } , recipients , false , "TestTemplateSelection" )
2019-11-07 16:34:28 +03:00
expect ( t , msg , "issue/new/subject" , "issue/new/body" )
2019-11-18 11:08:20 +03:00
msg = testComposeIssueCommentMessage ( t , & mailCommentContext { Issue : issue , Doer : doer , ActionType : models . ActionCommentIssue ,
2021-05-22 09:47:16 +03:00
Content : "test body" , Comment : comment } , recipients , false , "TestTemplateSelection" )
2019-11-07 16:34:28 +03:00
expect ( t , msg , "issue/default/subject" , "issue/default/body" )
2021-11-16 11:53:21 +03:00
pull := unittest . AssertExistsAndLoadBean ( t , & models . Issue { ID : 2 , Repo : repo , Poster : doer } ) . ( * models . Issue )
comment = unittest . AssertExistsAndLoadBean ( t , & models . Comment { ID : 4 , Issue : pull } ) . ( * models . Comment )
2019-12-22 11:29:26 +03:00
msg = testComposeIssueCommentMessage ( t , & mailCommentContext { Issue : pull , Doer : doer , ActionType : models . ActionCommentPull ,
2021-05-22 09:47:16 +03:00
Content : "test body" , Comment : comment } , recipients , false , "TestTemplateSelection" )
2019-11-07 16:34:28 +03:00
expect ( t , msg , "pull/comment/subject" , "pull/comment/body" )
2019-11-18 11:08:20 +03:00
msg = testComposeIssueCommentMessage ( t , & mailCommentContext { Issue : issue , Doer : doer , ActionType : models . ActionCloseIssue ,
2021-05-22 09:47:16 +03:00
Content : "test body" , Comment : comment } , recipients , false , "TestTemplateSelection" )
2019-11-18 11:08:20 +03:00
expect ( t , msg , "Re: [user2/repo1] issue1 (#1)" , "issue/close/body" )
2019-11-07 16:34:28 +03:00
}
func TestTemplateServices ( t * testing . T ) {
2021-05-22 09:47:16 +03:00
doer , _ , issue , comment := prepareMailerTest ( t )
2019-11-07 16:34:28 +03:00
assert . NoError ( t , issue . LoadRepo ( ) )
2021-11-24 12:49:20 +03:00
expect := func ( t * testing . T , issue * models . Issue , comment * models . Comment , doer * user_model . User ,
2019-11-07 16:34:28 +03:00
actionType models . ActionType , fromMention bool , tplSubject , tplBody , expSubject , expBody string ) {
stpl := texttmpl . Must ( texttmpl . New ( "issue/default" ) . Parse ( tplSubject ) )
btpl := template . Must ( template . New ( "issue/default" ) . Parse ( tplBody ) )
InitMailRender ( stpl , btpl )
2021-11-24 12:49:20 +03:00
recipients := [ ] * user_model . User { { Name : "Test" , Email : "test@gitea.com" } }
2019-11-18 11:08:20 +03:00
msg := testComposeIssueCommentMessage ( t , & mailCommentContext { Issue : issue , Doer : doer , ActionType : actionType ,
2021-05-22 09:47:16 +03:00
Content : "test body" , Comment : comment } , recipients , fromMention , "TestTemplateServices" )
2019-11-07 16:34:28 +03:00
2020-01-16 20:55:36 +03:00
subject := msg . ToMessage ( ) . GetHeader ( "Subject" )
2019-11-07 16:34:28 +03:00
msgbuf := new ( bytes . Buffer )
2020-01-16 20:55:36 +03:00
_ , _ = msg . ToMessage ( ) . WriteTo ( msgbuf )
2019-11-07 16:34:28 +03:00
wholemsg := msgbuf . String ( )
assert . Equal ( t , [ ] string { expSubject } , subject )
assert . Contains ( t , wholemsg , "\r\n" + expBody + "\r\n" )
}
expect ( t , issue , comment , doer , models . ActionCommentIssue , false ,
"{{.SubjectPrefix}}[{{.Repo}}]: @{{.Doer.Name}} commented on #{{.Issue.Index}} - {{.Issue.Title}}" ,
"//{{.ActionType}},{{.ActionName}},{{if .IsMention}}norender{{end}}//" ,
"Re: [user2/repo1]: @user2 commented on #1 - issue1" ,
"//issue,comment,//" )
expect ( t , issue , comment , doer , models . ActionCommentIssue , true ,
"{{if .IsMention}}must render{{end}}" ,
"//subject is: {{.Subject}}//" ,
"must render" ,
"//subject is: must render//" )
expect ( t , issue , comment , doer , models . ActionCommentIssue , true ,
"{{.FallbackSubject}}" ,
"//{{.SubjectPrefix}}//" ,
"Re: [user2/repo1] issue1 (#1)" ,
"//Re: //" )
}
2019-11-18 11:08:20 +03:00
2021-11-24 12:49:20 +03:00
func testComposeIssueCommentMessage ( t * testing . T , ctx * mailCommentContext , recipients [ ] * user_model . User , fromMention bool , info string ) * Message {
2021-05-22 09:47:16 +03:00
msgs , err := composeIssueCommentMessages ( ctx , "en-US" , recipients , fromMention , info )
2021-04-20 01:25:08 +03:00
assert . NoError ( t , err )
2019-11-18 11:08:20 +03:00
assert . Len ( t , msgs , 1 )
return msgs [ 0 ]
}
2021-05-22 09:47:16 +03:00
func TestGenerateAdditionalHeaders ( t * testing . T ) {
doer , _ , issue , _ := prepareMailerTest ( t )
ctx := & mailCommentContext { Issue : issue , Doer : doer }
2021-11-24 12:49:20 +03:00
recipient := & user_model . User { Name : "Test" , Email : "test@gitea.com" }
2021-05-22 09:47:16 +03:00
headers := generateAdditionalHeaders ( ctx , "dummy-reason" , recipient )
expected := map [ string ] string {
"List-ID" : "user2/repo1 <repo1.user2.localhost>" ,
"List-Archive" : "<https://try.gitea.io/user2/repo1>" ,
2021-12-22 01:53:03 +03:00
"List-Unsubscribe" : "https://try.gitea.io/user2/repo1/issues/1" ,
2021-05-22 09:47:16 +03:00
"X-Gitea-Reason" : "dummy-reason" ,
"X-Gitea-Sender" : "< U<se>r Tw<o > ><" ,
"X-Gitea-Recipient" : "Test" ,
"X-Gitea-Recipient-Address" : "test@gitea.com" ,
"X-Gitea-Repository" : "repo1" ,
"X-Gitea-Repository-Path" : "user2/repo1" ,
"X-Gitea-Repository-Link" : "https://try.gitea.io/user2/repo1" ,
"X-Gitea-Issue-ID" : "1" ,
"X-Gitea-Issue-Link" : "https://try.gitea.io/user2/repo1/issues/1" ,
}
for key , value := range expected {
if assert . Contains ( t , headers , key ) {
assert . Equal ( t , value , headers [ key ] )
}
}
}