You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mail_test.go 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package mailer
  5. import (
  6. "bytes"
  7. "html/template"
  8. "testing"
  9. texttmpl "text/template"
  10. "code.gitea.io/gitea/models"
  11. "code.gitea.io/gitea/modules/setting"
  12. "github.com/stretchr/testify/assert"
  13. )
  14. const subjectTpl = `
  15. {{.SubjectPrefix}}[{{.Repo}}] @{{.Doer.Name}} #{{.Issue.Index}} - {{.Issue.Title}}
  16. `
  17. const bodyTpl = `
  18. <!DOCTYPE html>
  19. <html>
  20. <head>
  21. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  22. <title>{{.Subject}}</title>
  23. </head>
  24. <body>
  25. <p>{{.Body}}</p>
  26. <p>
  27. ---
  28. <br>
  29. <a href="{{.Link}}">View it on Gitea</a>.
  30. </p>
  31. </body>
  32. </html>
  33. `
  34. func TestComposeIssueCommentMessage(t *testing.T) {
  35. assert.NoError(t, models.PrepareTestDatabase())
  36. var mailService = setting.Mailer{
  37. From: "test@gitea.com",
  38. }
  39. setting.MailService = &mailService
  40. setting.Domain = "localhost"
  41. doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  42. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository)
  43. issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue)
  44. comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment)
  45. stpl := texttmpl.Must(texttmpl.New("issue/comment").Parse(subjectTpl))
  46. btpl := template.Must(template.New("issue/comment").Parse(bodyTpl))
  47. InitMailRender(stpl, btpl)
  48. tos := []string{"test@gitea.com", "test2@gitea.com"}
  49. msgs := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue,
  50. Content: "test body", Comment: comment}, tos, false, "issue comment")
  51. assert.Len(t, msgs, 2)
  52. gomailMsg := msgs[0].ToMessage()
  53. mailto := gomailMsg.GetHeader("To")
  54. subject := gomailMsg.GetHeader("Subject")
  55. inreplyTo := gomailMsg.GetHeader("In-Reply-To")
  56. references := gomailMsg.GetHeader("References")
  57. assert.Len(t, mailto, 1, "exactly one recipient is expected in the To field")
  58. assert.Equal(t, "Re: ", subject[0][:4], "Comment reply subject should contain Re:")
  59. assert.Equal(t, "Re: [user2/repo1] @user2 #1 - issue1", subject[0])
  60. assert.Equal(t, inreplyTo[0], "<user2/repo1/issues/1@localhost>", "In-Reply-To header doesn't match")
  61. assert.Equal(t, references[0], "<user2/repo1/issues/1@localhost>", "References header doesn't match")
  62. }
  63. func TestComposeIssueMessage(t *testing.T) {
  64. assert.NoError(t, models.PrepareTestDatabase())
  65. var mailService = setting.Mailer{
  66. From: "test@gitea.com",
  67. }
  68. setting.MailService = &mailService
  69. setting.Domain = "localhost"
  70. doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  71. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository)
  72. issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue)
  73. stpl := texttmpl.Must(texttmpl.New("issue/new").Parse(subjectTpl))
  74. btpl := template.Must(template.New("issue/new").Parse(bodyTpl))
  75. InitMailRender(stpl, btpl)
  76. tos := []string{"test@gitea.com", "test2@gitea.com"}
  77. msgs := composeIssueCommentMessages(&mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue,
  78. Content: "test body"}, tos, false, "issue create")
  79. assert.Len(t, msgs, 2)
  80. gomailMsg := msgs[0].ToMessage()
  81. mailto := gomailMsg.GetHeader("To")
  82. subject := gomailMsg.GetHeader("Subject")
  83. messageID := gomailMsg.GetHeader("Message-ID")
  84. assert.Len(t, mailto, 1, "exactly one recipient is expected in the To field")
  85. assert.Equal(t, "[user2/repo1] @user2 #1 - issue1", subject[0])
  86. assert.Nil(t, gomailMsg.GetHeader("In-Reply-To"))
  87. assert.Nil(t, gomailMsg.GetHeader("References"))
  88. assert.Equal(t, messageID[0], "<user2/repo1/issues/1@localhost>", "Message-ID header doesn't match")
  89. }
  90. func TestTemplateSelection(t *testing.T) {
  91. assert.NoError(t, models.PrepareTestDatabase())
  92. var mailService = setting.Mailer{
  93. From: "test@gitea.com",
  94. }
  95. setting.MailService = &mailService
  96. setting.Domain = "localhost"
  97. doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  98. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository)
  99. issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue)
  100. tos := []string{"test@gitea.com"}
  101. stpl := texttmpl.Must(texttmpl.New("issue/default").Parse("issue/default/subject"))
  102. texttmpl.Must(stpl.New("issue/new").Parse("issue/new/subject"))
  103. texttmpl.Must(stpl.New("pull/comment").Parse("pull/comment/subject"))
  104. texttmpl.Must(stpl.New("issue/close").Parse("")) // Must default to fallback subject
  105. btpl := template.Must(template.New("issue/default").Parse("issue/default/body"))
  106. template.Must(btpl.New("issue/new").Parse("issue/new/body"))
  107. template.Must(btpl.New("pull/comment").Parse("pull/comment/body"))
  108. template.Must(btpl.New("issue/close").Parse("issue/close/body"))
  109. InitMailRender(stpl, btpl)
  110. expect := func(t *testing.T, msg *Message, expSubject, expBody string) {
  111. subject := msg.ToMessage().GetHeader("Subject")
  112. msgbuf := new(bytes.Buffer)
  113. _, _ = msg.ToMessage().WriteTo(msgbuf)
  114. wholemsg := msgbuf.String()
  115. assert.Equal(t, []string{expSubject}, subject)
  116. assert.Contains(t, wholemsg, expBody)
  117. }
  118. msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCreateIssue,
  119. Content: "test body"}, tos, false, "TestTemplateSelection")
  120. expect(t, msg, "issue/new/subject", "issue/new/body")
  121. comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment)
  122. msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCommentIssue,
  123. Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
  124. expect(t, msg, "issue/default/subject", "issue/default/body")
  125. pull := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 2, Repo: repo, Poster: doer}).(*models.Issue)
  126. comment = models.AssertExistsAndLoadBean(t, &models.Comment{ID: 4, Issue: pull}).(*models.Comment)
  127. msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: pull, Doer: doer, ActionType: models.ActionCommentPull,
  128. Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
  129. expect(t, msg, "pull/comment/subject", "pull/comment/body")
  130. msg = testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: models.ActionCloseIssue,
  131. Content: "test body", Comment: comment}, tos, false, "TestTemplateSelection")
  132. expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "issue/close/body")
  133. }
  134. func TestTemplateServices(t *testing.T) {
  135. assert.NoError(t, models.PrepareTestDatabase())
  136. var mailService = setting.Mailer{
  137. From: "test@gitea.com",
  138. }
  139. setting.MailService = &mailService
  140. setting.Domain = "localhost"
  141. doer := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
  142. repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1, Owner: doer}).(*models.Repository)
  143. issue := models.AssertExistsAndLoadBean(t, &models.Issue{ID: 1, Repo: repo, Poster: doer}).(*models.Issue)
  144. comment := models.AssertExistsAndLoadBean(t, &models.Comment{ID: 2, Issue: issue}).(*models.Comment)
  145. assert.NoError(t, issue.LoadRepo())
  146. expect := func(t *testing.T, issue *models.Issue, comment *models.Comment, doer *models.User,
  147. actionType models.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string) {
  148. stpl := texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject))
  149. btpl := template.Must(template.New("issue/default").Parse(tplBody))
  150. InitMailRender(stpl, btpl)
  151. tos := []string{"test@gitea.com"}
  152. msg := testComposeIssueCommentMessage(t, &mailCommentContext{Issue: issue, Doer: doer, ActionType: actionType,
  153. Content: "test body", Comment: comment}, tos, fromMention, "TestTemplateServices")
  154. subject := msg.ToMessage().GetHeader("Subject")
  155. msgbuf := new(bytes.Buffer)
  156. _, _ = msg.ToMessage().WriteTo(msgbuf)
  157. wholemsg := msgbuf.String()
  158. assert.Equal(t, []string{expSubject}, subject)
  159. assert.Contains(t, wholemsg, "\r\n"+expBody+"\r\n")
  160. }
  161. expect(t, issue, comment, doer, models.ActionCommentIssue, false,
  162. "{{.SubjectPrefix}}[{{.Repo}}]: @{{.Doer.Name}} commented on #{{.Issue.Index}} - {{.Issue.Title}}",
  163. "//{{.ActionType}},{{.ActionName}},{{if .IsMention}}norender{{end}}//",
  164. "Re: [user2/repo1]: @user2 commented on #1 - issue1",
  165. "//issue,comment,//")
  166. expect(t, issue, comment, doer, models.ActionCommentIssue, true,
  167. "{{if .IsMention}}must render{{end}}",
  168. "//subject is: {{.Subject}}//",
  169. "must render",
  170. "//subject is: must render//")
  171. expect(t, issue, comment, doer, models.ActionCommentIssue, true,
  172. "{{.FallbackSubject}}",
  173. "//{{.SubjectPrefix}}//",
  174. "Re: [user2/repo1] issue1 (#1)",
  175. "//Re: //")
  176. }
  177. func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, tos []string, fromMention bool, info string) *Message {
  178. msgs := composeIssueCommentMessages(ctx, tos, fromMention, info)
  179. assert.Len(t, msgs, 1)
  180. return msgs[0]
  181. }