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.

mailer_test.rb 37KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. # frozen_string_literal: true
  2. # Redmine - project management software
  3. # Copyright (C) 2006-2017 Jean-Philippe Lang
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License
  7. # as published by the Free Software Foundation; either version 2
  8. # of the License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. require File.expand_path('../../test_helper', __FILE__)
  19. class MailerTest < ActiveSupport::TestCase
  20. include Redmine::I18n
  21. include Rails::Dom::Testing::Assertions
  22. fixtures :projects, :enabled_modules, :issues, :users, :email_addresses, :user_preferences, :members,
  23. :member_roles, :roles, :documents, :attachments, :news,
  24. :tokens, :journals, :journal_details, :changesets,
  25. :trackers, :projects_trackers,
  26. :issue_statuses, :enumerations, :messages, :boards, :repositories,
  27. :wikis, :wiki_pages, :wiki_contents, :wiki_content_versions,
  28. :versions,
  29. :comments
  30. def setup
  31. ActionMailer::Base.deliveries.clear
  32. Setting.plain_text_mail = '0'
  33. Setting.default_language = 'en'
  34. User.current = nil
  35. end
  36. def test_generated_links_in_emails
  37. with_settings :host_name => 'mydomain.foo', :protocol => 'https' do
  38. journal = Journal.find(3)
  39. assert Mailer.deliver_issue_edit(journal)
  40. end
  41. mail = last_email
  42. assert_select_email do
  43. # link to the main ticket on issue id
  44. assert_select 'a[href=?]',
  45. 'https://mydomain.foo/issues/2#change-3',
  46. :text => '#2'
  47. # link to the main ticket
  48. assert_select 'a[href=?]',
  49. 'https://mydomain.foo/issues/2#change-3',
  50. :text => 'Feature request #2: Add ingredients categories'
  51. # link to a referenced ticket
  52. assert_select 'a[href=?][title=?]',
  53. 'https://mydomain.foo/issues/1',
  54. "Bug: Cannot print recipes (New)",
  55. :text => '#1'
  56. # link to a changeset
  57. assert_select 'a[href=?][title=?]',
  58. 'https://mydomain.foo/projects/ecookbook/repository/10/revisions/2',
  59. 'This commit fixes #1, #2 and references #1 & #3',
  60. :text => 'r2'
  61. # link to a description diff
  62. assert_select 'a[href^=?][title=?]',
  63. # should be https://mydomain.foo/journals/diff/3?detail_id=4
  64. # but the Rails 4.2 DOM assertion doesn't handle the ? in the
  65. # attribute value
  66. 'https://mydomain.foo/journals/3/diff',
  67. 'View differences',
  68. :text => 'diff'
  69. # link to an attachment
  70. assert_select 'a[href=?]',
  71. 'https://mydomain.foo/attachments/download/4/source.rb',
  72. :text => 'source.rb'
  73. end
  74. end
  75. def test_generated_links_with_prefix
  76. relative_url_root = Redmine::Utils.relative_url_root
  77. with_settings :host_name => 'mydomain.foo/rdm', :protocol => 'http' do
  78. journal = Journal.find(3)
  79. assert Mailer.deliver_issue_edit(journal)
  80. end
  81. mail = last_email
  82. assert_select_email do
  83. # link to the main ticket
  84. assert_select 'a[href=?]',
  85. 'http://mydomain.foo/rdm/issues/2#change-3',
  86. :text => 'Feature request #2: Add ingredients categories'
  87. # link to a referenced ticket
  88. assert_select 'a[href=?][title=?]',
  89. 'http://mydomain.foo/rdm/issues/1',
  90. "Bug: Cannot print recipes (New)",
  91. :text => '#1'
  92. # link to a changeset
  93. assert_select 'a[href=?][title=?]',
  94. 'http://mydomain.foo/rdm/projects/ecookbook/repository/10/revisions/2',
  95. 'This commit fixes #1, #2 and references #1 & #3',
  96. :text => 'r2'
  97. # link to a description diff
  98. assert_select 'a[href^=?][title=?]',
  99. # should be http://mydomain.foo/rdm/journals/diff/3?detail_id=4
  100. # but the Rails 4.2 DOM assertion doesn't handle the ? in the
  101. # attribute value
  102. 'http://mydomain.foo/rdm/journals/3/diff',
  103. 'View differences',
  104. :text => 'diff'
  105. # link to an attachment
  106. assert_select 'a[href=?]',
  107. 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
  108. :text => 'source.rb'
  109. end
  110. end
  111. def test_generated_links_with_port_and_prefix
  112. with_settings :host_name => '10.0.0.1:81/redmine', :protocol => 'http' do
  113. Mailer.test_email(User.find(1)).deliver_now
  114. mail = last_email
  115. assert_include 'http://10.0.0.1:81/redmine', mail_body(mail)
  116. end
  117. end
  118. def test_generated_links_with_port
  119. with_settings :host_name => '10.0.0.1:81', :protocol => 'http' do
  120. Mailer.test_email(User.find(1)).deliver_now
  121. mail = last_email
  122. assert_include 'http://10.0.0.1:81', mail_body(mail)
  123. end
  124. end
  125. def test_issue_edit_should_generate_url_with_hostname_for_relations
  126. journal = Journal.new(:journalized => Issue.find(1), :user => User.find(1), :created_on => Time.now)
  127. journal.details << JournalDetail.new(:property => 'relation', :prop_key => 'label_relates_to', :value => 2)
  128. journal.save
  129. Mailer.deliver_issue_edit(journal)
  130. assert_not_nil last_email
  131. assert_select_email do
  132. assert_select 'a[href=?]', 'http://localhost:3000/issues/2', :text => 'Feature request #2'
  133. end
  134. end
  135. def test_generated_links_with_prefix_and_no_relative_url_root
  136. relative_url_root = Redmine::Utils.relative_url_root
  137. Redmine::Utils.relative_url_root = nil
  138. with_settings :host_name => 'mydomain.foo/rdm', :protocol => 'http' do
  139. journal = Journal.find(3)
  140. assert Mailer.deliver_issue_edit(journal)
  141. end
  142. mail = last_email
  143. assert_select_email do
  144. # link to the main ticket
  145. assert_select 'a[href=?]',
  146. 'http://mydomain.foo/rdm/issues/2#change-3',
  147. :text => 'Feature request #2: Add ingredients categories'
  148. # link to a referenced ticket
  149. assert_select 'a[href=?][title=?]',
  150. 'http://mydomain.foo/rdm/issues/1',
  151. "Bug: Cannot print recipes (New)",
  152. :text => '#1'
  153. # link to a changeset
  154. assert_select 'a[href=?][title=?]',
  155. 'http://mydomain.foo/rdm/projects/ecookbook/repository/10/revisions/2',
  156. 'This commit fixes #1, #2 and references #1 & #3',
  157. :text => 'r2'
  158. # link to a description diff
  159. assert_select 'a[href^=?][title=?]',
  160. # should be http://mydomain.foo/rdm/journals/diff/3?detail_id=4
  161. # but the Rails 4.2 DOM assertion doesn't handle the ? in the
  162. # attribute value
  163. 'http://mydomain.foo/rdm/journals/3/diff',
  164. 'View differences',
  165. :text => 'diff'
  166. # link to an attachment
  167. assert_select 'a[href=?]',
  168. 'http://mydomain.foo/rdm/attachments/download/4/source.rb',
  169. :text => 'source.rb'
  170. end
  171. ensure
  172. # restore it
  173. Redmine::Utils.relative_url_root = relative_url_root
  174. end
  175. def test_link_to_user_in_email
  176. issue = Issue.generate!(:description => '@jsmith')
  177. assert Mailer.deliver_issue_add(issue)
  178. assert_select_email do
  179. assert_select "a[href=?]", "http://localhost:3000/users/2", :text => 'John Smith'
  180. end
  181. end
  182. def test_email_headers
  183. with_settings :mail_from => 'Redmine <redmine@example.net>' do
  184. issue = Issue.find(1)
  185. Mailer.deliver_issue_add(issue)
  186. end
  187. mail = last_email
  188. assert_equal 'All', mail.header['X-Auto-Response-Suppress'].to_s
  189. assert_equal 'auto-generated', mail.header['Auto-Submitted'].to_s
  190. # List-Id should not include the display name "Redmine"
  191. assert_equal '<redmine.example.net>', mail.header['List-Id'].to_s
  192. end
  193. def test_email_headers_should_include_sender
  194. issue = Issue.find(1)
  195. Mailer.deliver_issue_add(issue)
  196. mail = last_email
  197. assert_equal issue.author.login, mail.header['X-Redmine-Sender'].to_s
  198. end
  199. def test_plain_text_mail
  200. Setting.plain_text_mail = 1
  201. journal = Journal.find(2)
  202. Mailer.deliver_issue_edit(journal)
  203. mail = last_email
  204. assert_equal "text/plain; charset=UTF-8", mail.content_type
  205. assert_equal 0, mail.parts.size
  206. assert !mail.encoded.include?('href')
  207. end
  208. def test_html_mail
  209. Setting.plain_text_mail = 0
  210. journal = Journal.find(2)
  211. Mailer.deliver_issue_edit(journal)
  212. mail = last_email
  213. assert_equal 2, mail.parts.size
  214. assert mail.encoded.include?('href')
  215. end
  216. def test_from_header
  217. with_settings :mail_from => 'redmine@example.net' do
  218. Mailer.deliver_test_email(User.find(1))
  219. end
  220. mail = last_email
  221. assert_equal 'redmine@example.net', mail.from_addrs.first
  222. end
  223. def test_from_header_with_phrase
  224. with_settings :mail_from => 'Redmine app <redmine@example.net>' do
  225. Mailer.deliver_test_email(User.find(1))
  226. end
  227. mail = last_email
  228. assert_equal 'redmine@example.net', mail.from_addrs.first
  229. assert_equal 'Redmine app <redmine@example.net>', mail.header['From'].to_s
  230. end
  231. def test_from_header_with_rfc_non_compliant_phrase
  232. # Send out the email instead of raising an exception
  233. # no matter if the emission email address is not RFC compliant
  234. assert_nothing_raised do
  235. with_settings :mail_from => '[Redmine app] <redmine@example.net>' do
  236. Mailer.deliver_test_email(User.find(1))
  237. end
  238. end
  239. mail = last_email
  240. assert_match /<redmine@example\.net>/, mail.from_addrs.first
  241. assert_equal '[Redmine app] <redmine@example.net>', mail.header['From'].to_s
  242. end
  243. def test_from_header_with_author_name
  244. # Use the author's name or Setting.app_title as a display name
  245. # when Setting.mail_from does not include a display name
  246. with_settings :mail_from => 'redmine@example.net', :app_title => 'Foo' do
  247. # Use @author.name as a display name
  248. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
  249. :subject => 'Issue created by Dave Lopper', :author_id => 3)
  250. mail = last_email
  251. assert_equal 'redmine@example.net', mail.from_addrs.first
  252. assert_equal 'Dave Lopper <redmine@example.net>', mail.header['From'].to_s
  253. # Use app_title if @author is nil or AnonymousUser
  254. Mailer.deliver_test_email(User.find(1))
  255. mail = last_email
  256. assert_equal 'redmine@example.net', mail.from_addrs.first
  257. assert_equal "Foo <redmine@example.net>", mail.header['From'].to_s
  258. end
  259. end
  260. def test_should_not_send_email_without_recipient
  261. news = News.first
  262. user = news.author
  263. # Remove members except news author
  264. news.project.memberships.each {|m| m.destroy unless m.user == user}
  265. user.pref.no_self_notified = false
  266. user.pref.save
  267. User.current = user
  268. Mailer.deliver_news_added(news.reload)
  269. assert_equal 1, last_email.bcc.size
  270. # nobody to notify
  271. user.pref.no_self_notified = true
  272. user.pref.save
  273. User.current = user
  274. ActionMailer::Base.deliveries.clear
  275. Mailer.deliver_news_added(news.reload)
  276. assert ActionMailer::Base.deliveries.empty?
  277. end
  278. def test_issue_add_message_id
  279. issue = Issue.find(2)
  280. Mailer.deliver_issue_add(issue)
  281. mail = last_email
  282. uid = destination_user(mail).id
  283. assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.message_id
  284. assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.references
  285. end
  286. def test_issue_edit_message_id
  287. journal = Journal.find(3)
  288. journal.issue = Issue.find(2)
  289. Mailer.deliver_issue_edit(journal)
  290. mail = last_email
  291. uid = destination_user(mail).id
  292. assert_match /^redmine\.journal-3\.\d+\.#{uid}@example\.net/, mail.message_id
  293. assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.references
  294. assert_select_email do
  295. # link to the update
  296. assert_select "a[href=?]",
  297. "http://localhost:3000/issues/#{journal.journalized_id}#change-#{journal.id}"
  298. end
  299. end
  300. def test_message_posted_message_id
  301. message = Message.find(1)
  302. Mailer.deliver_message_posted(message)
  303. mail = last_email
  304. uid = destination_user(mail).id
  305. assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.message_id
  306. assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.references
  307. assert_select_email do
  308. # link to the message
  309. assert_select "a[href=?]",
  310. "http://localhost:3000/boards/#{message.board.id}/topics/#{message.id}",
  311. :text => message.subject
  312. end
  313. end
  314. def test_reply_posted_message_id
  315. message = Message.find(3)
  316. Mailer.deliver_message_posted(message)
  317. mail = last_email
  318. uid = destination_user(mail).id
  319. assert_include "redmine.message-3.20070512151802.#{uid}@example.net", mail.message_id
  320. assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.references
  321. assert_select_email do
  322. # link to the reply
  323. assert_select "a[href=?]",
  324. "http://localhost:3000/boards/#{message.board.id}/topics/#{message.root.id}?r=#{message.id}#message-#{message.id}",
  325. :text => message.subject
  326. end
  327. end
  328. def test_timestamp_in_message_id_should_be_utc
  329. zone_was = Time.zone
  330. issue = Issue.find(3)
  331. user = User.find(1)
  332. %w(UTC Paris Tokyo).each do |zone|
  333. Time.zone = zone
  334. assert_match /^redmine\.issue-3\.20060719190727\.1@example\.net/, Mailer.token_for(issue, user)
  335. end
  336. ensure
  337. Time.zone = zone_was
  338. end
  339. test "#issue_add should notify project members" do
  340. issue = Issue.find(1)
  341. assert Mailer.deliver_issue_add(issue)
  342. assert_include 'dlopper@somenet.foo', recipients
  343. end
  344. def test_issue_add_should_send_mail_to_all_user_email_address
  345. EmailAddress.create!(:user_id => 3, :address => 'otheremail@somenet.foo')
  346. issue = Issue.find(1)
  347. assert Mailer.deliver_issue_add(issue)
  348. assert mail = ActionMailer::Base.deliveries.find {|m| m.bcc.include?('dlopper@somenet.foo')}
  349. assert mail.bcc.include?('otheremail@somenet.foo')
  350. end
  351. test "#issue_add should not notify project members that are not allow to view the issue" do
  352. issue = Issue.find(1)
  353. Role.find(2).remove_permission!(:view_issues)
  354. assert Mailer.deliver_issue_add(issue)
  355. assert_not_include 'dlopper@somenet.foo', recipients
  356. end
  357. test "#issue_add should notify issue watchers" do
  358. issue = Issue.find(1)
  359. user = User.find(9)
  360. # minimal email notification options
  361. user.pref.no_self_notified = '1'
  362. user.pref.save
  363. user.mail_notification = false
  364. user.save
  365. Watcher.create!(:watchable => issue, :user => user)
  366. assert Mailer.deliver_issue_add(issue)
  367. assert_include user.mail, recipients
  368. end
  369. test "#issue_add should not notify watchers not allowed to view the issue" do
  370. issue = Issue.find(1)
  371. user = User.find(9)
  372. Watcher.create!(:watchable => issue, :user => user)
  373. Role.non_member.remove_permission!(:view_issues)
  374. assert Mailer.deliver_issue_add(issue)
  375. assert_not_include user.mail, recipients
  376. end
  377. def test_issue_add_should_include_enabled_fields
  378. issue = Issue.find(2)
  379. assert Mailer.deliver_issue_add(issue)
  380. assert_mail_body_match '* Target version: 1.0', last_email
  381. assert_select_email do
  382. assert_select 'li', :text => 'Target version: 1.0'
  383. end
  384. end
  385. def test_issue_add_should_not_include_disabled_fields
  386. issue = Issue.find(2)
  387. tracker = issue.tracker
  388. tracker.core_fields -= ['fixed_version_id', 'start_date']
  389. tracker.save!
  390. assert Mailer.deliver_issue_add(issue)
  391. assert_mail_body_no_match 'Target version', last_email
  392. assert_mail_body_no_match 'Start date', last_email
  393. assert_select_email do
  394. assert_select 'li', :text => /Target version/, :count => 0
  395. assert_select 'li', :text => /Start date/, :count => 0
  396. end
  397. end
  398. def test_issue_add_subject_should_include_status_if_setting_is_enabled
  399. with_settings :show_status_changes_in_mail_subject => 1 do
  400. issue = Issue.find(2)
  401. Mailer.deliver_issue_add(issue)
  402. mail = last_email
  403. assert_equal "[eCookbook - Feature request #2] (Assigned) Add ingredients categories", mail.subject
  404. end
  405. end
  406. def test_issue_add_subject_should_not_include_status_if_setting_is_disabled
  407. with_settings :show_status_changes_in_mail_subject => 0 do
  408. issue = Issue.find(2)
  409. Mailer.deliver_issue_add(issue)
  410. mail = last_email
  411. assert_equal "[eCookbook - Feature request #2] Add ingredients categories", mail.subject
  412. end
  413. end
  414. def test_issue_edit_subject_should_include_status_changes_if_setting_is_enabled
  415. with_settings :show_status_changes_in_mail_subject => 1 do
  416. issue = Issue.find(2)
  417. issue.init_journal(User.current)
  418. issue.update(:status_id => 4)
  419. journal = issue.journals.last
  420. Mailer.deliver_issue_edit(journal)
  421. assert journal.new_value_for('status_id')
  422. mail = last_email
  423. assert_equal "[eCookbook - Feature request #2] (Feedback) Add ingredients categories", mail.subject
  424. end
  425. end
  426. def test_issue_edit_subject_should_not_include_status_changes_if_setting_is_disabled
  427. with_settings :show_status_changes_in_mail_subject => 0 do
  428. issue = Issue.find(2)
  429. issue.init_journal(User.current)
  430. issue.update(:status_id => 4)
  431. journal = issue.journals.last
  432. Mailer.deliver_issue_edit(journal)
  433. assert journal.new_value_for('status_id')
  434. mail = last_email
  435. assert_equal "[eCookbook - Feature request #2] Add ingredients categories", mail.subject
  436. end
  437. end
  438. def test_issue_edit_should_send_private_notes_to_users_with_permission_only
  439. journal = Journal.find(1)
  440. journal.private_notes = true
  441. journal.save!
  442. Role.find(2).add_permission! :view_private_notes
  443. assert_difference 'ActionMailer::Base.deliveries.size', 2 do
  444. Mailer.deliver_issue_edit(journal)
  445. end
  446. assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), recipients
  447. ActionMailer::Base.deliveries.clear
  448. Role.find(2).remove_permission! :view_private_notes
  449. assert_difference 'ActionMailer::Base.deliveries.size', 1 do
  450. Mailer.deliver_issue_edit(journal)
  451. end
  452. assert_equal %w(jsmith@somenet.foo), recipients
  453. end
  454. def test_issue_edit_should_send_private_notes_to_watchers_with_permission_only
  455. Issue.find(1).set_watcher(User.find_by_login('someone'))
  456. journal = Journal.find(1)
  457. journal.private_notes = true
  458. journal.save!
  459. Role.non_member.add_permission! :view_private_notes
  460. Mailer.deliver_issue_edit(journal)
  461. assert_include 'someone@foo.bar', recipients
  462. ActionMailer::Base.deliveries.clear
  463. Role.non_member.remove_permission! :view_private_notes
  464. Mailer.deliver_issue_edit(journal)
  465. assert_not_include 'someone@foo.bar', recipients
  466. end
  467. def test_issue_edit_should_mark_private_notes
  468. journal = Journal.find(2)
  469. journal.private_notes = true
  470. journal.save!
  471. with_settings :default_language => 'en' do
  472. Mailer.deliver_issue_edit(journal)
  473. end
  474. assert_mail_body_match '(Private notes)', last_email
  475. end
  476. def test_issue_edit_with_relation_should_notify_users_who_can_see_the_related_issue
  477. issue = Issue.generate!
  478. issue.init_journal(User.find(1))
  479. private_issue = Issue.generate!(:is_private => true)
  480. IssueRelation.create!(:issue_from => issue, :issue_to => private_issue, :relation_type => 'relates')
  481. issue.reload
  482. assert_equal 1, issue.journals.size
  483. journal = issue.journals.first
  484. ActionMailer::Base.deliveries.clear
  485. Mailer.deliver_issue_edit(journal)
  486. recipients.each do |email|
  487. user = User.find_by_mail(email)
  488. assert private_issue.visible?(user), "Issue was not visible to #{user}"
  489. end
  490. end
  491. def test_version_file_added
  492. attachements = [ Attachment.find_by_container_type('Version') ]
  493. assert Mailer.deliver_attachments_added(attachements)
  494. assert_not_nil last_email.bcc
  495. assert last_email.bcc.any?
  496. assert_select_email do
  497. assert_select "a[href=?]", "http://localhost:3000/projects/ecookbook/files"
  498. end
  499. end
  500. def test_project_file_added
  501. attachements = [ Attachment.find_by_container_type('Project') ]
  502. assert Mailer.deliver_attachments_added(attachements)
  503. assert_not_nil last_email.bcc
  504. assert last_email.bcc.any?
  505. assert_select_email do
  506. assert_select "a[href=?]", "http://localhost:3000/projects/ecookbook/files"
  507. end
  508. end
  509. def test_news_added_should_notify_project_news_watchers
  510. user1 = User.generate!
  511. user2 = User.generate!
  512. news = News.find(1)
  513. news.project.enabled_module('news').add_watcher(user1)
  514. Mailer.deliver_news_added(news)
  515. assert_include user1.mail, recipients
  516. assert_not_include user2.mail, recipients
  517. end
  518. def test_wiki_content_added
  519. content = WikiContent.find(1)
  520. assert_difference 'ActionMailer::Base.deliveries.size', 2 do
  521. assert Mailer.deliver_wiki_content_added(content)
  522. assert_select_email do
  523. assert_select 'a[href=?]',
  524. 'http://localhost:3000/projects/ecookbook/wiki/CookBook_documentation',
  525. :text => 'CookBook documentation'
  526. end
  527. end
  528. end
  529. def test_wiki_content_updated
  530. content = WikiContent.find(1)
  531. assert Mailer.deliver_wiki_content_updated(content)
  532. assert_select_email do
  533. assert_select 'a[href=?]',
  534. 'http://localhost:3000/projects/ecookbook/wiki/CookBook_documentation',
  535. :text => 'CookBook documentation'
  536. end
  537. end
  538. def test_register
  539. token = Token.find(1)
  540. assert Mailer.deliver_register(token.user, token)
  541. assert_select_email do
  542. assert_select "a[href=?]",
  543. "http://localhost:3000/account/activate?token=#{token.value}",
  544. :text => "http://localhost:3000/account/activate?token=#{token.value}"
  545. end
  546. end
  547. def test_test_email_later
  548. user = User.find(1)
  549. assert Mailer.test_email(user).deliver_later
  550. assert_equal 1, ActionMailer::Base.deliveries.size
  551. end
  552. def test_reminders
  553. users(:users_003).pref.update_attribute :time_zone, 'UTC' # dlopper
  554. Mailer.reminders(:days => 42)
  555. assert_equal 1, ActionMailer::Base.deliveries.size
  556. mail = last_email
  557. assert mail.bcc.include?('dlopper@somenet.foo')
  558. assert_mail_body_match 'Bug #3: Error 281 when updating a recipe (5 days late)', mail
  559. assert_mail_body_match 'View all issues (2 open)', mail
  560. assert_select_email do
  561. assert_select 'a[href=?]',
  562. 'http://localhost:3000/issues?assigned_to_id=me&set_filter=1&sort=due_date%3Aasc',
  563. :text => 'View all issues'
  564. assert_select '/p:nth-last-of-type(1)', :text => 'View all issues (2 open)'
  565. end
  566. assert_equal '1 issue(s) due in the next 42 days', mail.subject
  567. end
  568. def test_reminders_language_auto
  569. with_settings :default_language => 'fr' do
  570. user = User.find(3)
  571. user.update_attribute :language, ''
  572. user.pref.update_attribute :time_zone, 'UTC'
  573. Mailer.reminders(:days => 42)
  574. assert_equal 1, ActionMailer::Base.deliveries.size
  575. mail = last_email
  576. assert mail.bcc.include?('dlopper@somenet.foo')
  577. assert_mail_body_match 'Bug #3: Error 281 when updating a recipe (En retard de 5 jours)', mail
  578. assert_equal "1 demande(s) arrivent à échéance (42)", mail.subject
  579. end
  580. end
  581. def test_reminders_should_not_include_closed_issues
  582. with_settings :default_language => 'en' do
  583. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 5,
  584. :subject => 'Closed issue', :assigned_to_id => 3,
  585. :due_date => 5.days.from_now,
  586. :author_id => 2)
  587. ActionMailer::Base.deliveries.clear
  588. Mailer.reminders(:days => 42)
  589. assert_equal 1, ActionMailer::Base.deliveries.size
  590. mail = last_email
  591. assert mail.bcc.include?('dlopper@somenet.foo')
  592. assert_mail_body_no_match 'Closed issue', mail
  593. end
  594. end
  595. def test_reminders_for_users
  596. users(:users_003).pref.update_attribute :time_zone, 'UTC' # dlopper
  597. Mailer.reminders(:days => 42, :users => ['5'])
  598. assert_equal 0, ActionMailer::Base.deliveries.size # No mail for dlopper
  599. Mailer.reminders(:days => 42, :users => ['3'])
  600. assert_equal 1, ActionMailer::Base.deliveries.size # No mail for dlopper
  601. mail = last_email
  602. assert mail.bcc.include?('dlopper@somenet.foo')
  603. assert_mail_body_match 'Bug #3: Error 281 when updating a recipe (5 days late)', mail
  604. end
  605. def test_reminder_should_include_issues_assigned_to_groups
  606. with_settings :default_language => 'en', :issue_group_assignment => '1' do
  607. group = Group.generate!
  608. Member.create!(:project_id => 1, :principal => group, :role_ids => [1])
  609. [users(:users_002), users(:users_003)].each do |user| # jsmith, dlopper
  610. group.users << user
  611. user.pref.update_attribute :time_zone, 'UTC'
  612. end
  613. Issue.update_all(:assigned_to_id => nil)
  614. due_date = 10.days.from_now
  615. Issue.update(1, :due_date => due_date, :assigned_to_id => 3)
  616. Issue.update(2, :due_date => due_date, :assigned_to_id => group.id)
  617. Issue.create!(:project_id => 1, :tracker_id => 1, :status_id => 1,
  618. :subject => 'Assigned to group', :assigned_to => group,
  619. :due_date => 5.days.from_now,
  620. :author_id => 2)
  621. ActionMailer::Base.deliveries.clear
  622. Mailer.reminders(:days => 7)
  623. assert_equal 2, ActionMailer::Base.deliveries.size
  624. assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), recipients
  625. ActionMailer::Base.deliveries.each do |mail|
  626. assert_mail_body_match '1 issue(s) that are assigned to you are due in the next 7 days::', mail
  627. assert_mail_body_match 'Assigned to group (Due in 5 days)', mail
  628. assert_mail_body_match "View all issues (#{mail.bcc.include?('dlopper@somenet.foo') ? 3 : 2} open)", mail
  629. end
  630. end
  631. end
  632. def test_reminders_with_version_option
  633. with_settings :default_language => 'en' do
  634. version = Version.generate!(:name => 'Acme', :project_id => 1)
  635. Issue.generate!(:assigned_to => User.find(2), :due_date => 5.days.from_now)
  636. Issue.generate!(:assigned_to => User.find(3), :due_date => 5.days.from_now, :fixed_version => version)
  637. ActionMailer::Base.deliveries.clear
  638. Mailer.reminders(:days => 42, :version => 'acme')
  639. assert_equal 1, ActionMailer::Base.deliveries.size
  640. assert_include 'dlopper@somenet.foo', recipients
  641. end
  642. end
  643. def test_reminders_should_only_include_issues_the_user_can_see
  644. with_settings :default_language => 'en' do
  645. user = User.find(3)
  646. member = Member.create!(:project_id => 2, :principal => user, :role_ids => [1])
  647. Issue.create!(:project_id => 2, :tracker_id => 1, :status_id => 1,
  648. :subject => 'Issue dlopper should not see', :assigned_to_id => 3,
  649. :due_date => 5.days.from_now,
  650. :author_id => 2)
  651. member.destroy
  652. ActionMailer::Base.deliveries.clear
  653. Mailer.reminders(:days => 42)
  654. assert_equal 1, ActionMailer::Base.deliveries.size
  655. assert_include 'dlopper@somenet.foo', recipients
  656. mail = last_email
  657. assert_mail_body_no_match 'Issue dlopper should not see', mail
  658. end
  659. end
  660. def test_reminders_should_sort_issues_by_due_date
  661. user = User.find(2)
  662. user.pref.update_attribute :time_zone, 'UTC'
  663. Issue.generate!(:assigned_to => user, :due_date => 2.days.from_now, :subject => 'quux')
  664. Issue.generate!(:assigned_to => user, :due_date => 0.days.from_now, :subject => 'baz')
  665. Issue.generate!(:assigned_to => user, :due_date => 1.days.from_now, :subject => 'qux')
  666. Issue.generate!(:assigned_to => user, :due_date => -1.days.from_now, :subject => 'foo')
  667. Issue.generate!(:assigned_to => user, :due_date => -1.days.from_now, :subject => 'bar')
  668. ActionMailer::Base.deliveries.clear
  669. Mailer.reminders(:days => 7, :users => [user.id])
  670. assert_equal 1, ActionMailer::Base.deliveries.size
  671. assert_select_email do
  672. assert_select 'li', 5
  673. assert_select 'li:nth-child(1)', /foo \(1 day late\)/
  674. assert_select 'li:nth-child(2)', /bar \(1 day late\)/
  675. assert_select 'li:nth-child(3)', /baz \(Due in 0 days\)/
  676. assert_select 'li:nth-child(4)', /qux \(Due in 1 day\)/
  677. assert_select 'li:nth-child(5)', /quux \(Due in 2 days\)/
  678. end
  679. end
  680. def test_security_notification
  681. set_language_if_valid User.find(1).language
  682. with_settings :emails_footer => "footer without link" do
  683. sender = User.find(2)
  684. sender.remote_ip = '192.168.1.1'
  685. assert Mailer.deliver_security_notification(User.find(1), sender, message: :notice_account_password_updated)
  686. mail = last_email
  687. assert_mail_body_match sender.login, mail
  688. assert_mail_body_match '192.168.1.1', mail
  689. assert_mail_body_match I18n.t(:notice_account_password_updated), mail
  690. assert_select_email do
  691. assert_select "h1", false
  692. assert_select "a", false
  693. end
  694. end
  695. end
  696. def test_security_notification_with_overridden_remote_ip
  697. set_language_if_valid User.find(1).language
  698. with_settings :emails_footer => "footer without link" do
  699. sender = User.find(2)
  700. sender.remote_ip = '192.168.1.1'
  701. assert Mailer.deliver_security_notification(User.find(1), sender, message: :notice_account_password_updated, remote_ip: '10.0.0.42')
  702. mail = last_email
  703. assert_mail_body_match '10.0.0.42', mail
  704. end
  705. end
  706. def test_security_notification_should_include_title
  707. set_language_if_valid User.find(2).language
  708. with_settings :emails_footer => "footer without link" do
  709. assert Mailer.deliver_security_notification(User.find(2), User.find(2),
  710. message: :notice_account_password_updated,
  711. title: :label_my_account
  712. )
  713. assert_select_email do
  714. assert_select "a", false
  715. assert_select "h1", :text => I18n.t(:label_my_account)
  716. end
  717. end
  718. end
  719. def test_security_notification_should_include_link
  720. set_language_if_valid User.find(3).language
  721. with_settings :emails_footer => "footer without link" do
  722. assert Mailer.deliver_security_notification(User.find(3), User.find(3),
  723. message: :notice_account_password_updated,
  724. title: :label_my_account,
  725. url: {controller: 'my', action: 'account'}
  726. )
  727. assert_select_email do
  728. assert_select "h1", false
  729. assert_select 'a[href=?]', 'http://localhost:3000/my/account', :text => I18n.t(:label_my_account)
  730. end
  731. end
  732. end
  733. def test_mailer_should_not_change_locale
  734. # Set current language to italian
  735. set_language_if_valid 'it'
  736. # Send an email to a french user
  737. user = User.find(1)
  738. user.update_attribute :language, 'fr'
  739. Mailer.deliver_account_activated(user)
  740. mail = last_email
  741. assert_mail_body_match 'Votre compte', mail
  742. assert_equal :it, current_language
  743. end
  744. def test_with_deliveries_off
  745. Mailer.with_deliveries false do
  746. Mailer.test_email(User.find(1)).deliver_now
  747. end
  748. assert ActionMailer::Base.deliveries.empty?
  749. # should restore perform_deliveries
  750. assert ActionMailer::Base.perform_deliveries
  751. end
  752. def test_token_for_should_strip_trailing_gt_from_address_with_full_name
  753. with_settings :mail_from => "Redmine Mailer<no-reply@redmine.org>" do
  754. assert_match /\Aredmine.issue-\d+\.\d+\.3@redmine.org\z/,
  755. Mailer.token_for(Issue.generate!, User.find(3))
  756. end
  757. end
  758. def test_layout_should_include_the_emails_header
  759. with_settings :emails_header => "*Header content*" do
  760. with_settings :plain_text_mail => 0 do
  761. assert Mailer.test_email(User.find(1)).deliver_now
  762. assert_select_email do
  763. assert_select ".header" do
  764. assert_select "strong", :text => "Header content"
  765. end
  766. end
  767. end
  768. with_settings :plain_text_mail => 1 do
  769. assert Mailer.test_email(User.find(1)).deliver_now
  770. mail = last_email
  771. assert_include "*Header content*", mail.body.decoded
  772. end
  773. end
  774. end
  775. def test_layout_should_not_include_empty_emails_header
  776. with_settings :emails_header => "", :plain_text_mail => 0 do
  777. assert Mailer.test_email(User.find(1)).deliver_now
  778. assert_select_email do
  779. assert_select ".header", false
  780. end
  781. end
  782. end
  783. def test_layout_should_include_the_emails_footer
  784. with_settings :emails_footer => "*Footer content*" do
  785. with_settings :plain_text_mail => 0 do
  786. assert Mailer.test_email(User.find(1)).deliver_now
  787. assert_select_email do
  788. assert_select ".footer" do
  789. assert_select "strong", :text => "Footer content"
  790. end
  791. end
  792. end
  793. with_settings :plain_text_mail => 1 do
  794. assert Mailer.test_email(User.find(1)).deliver_now
  795. mail = last_email
  796. assert_include "\n-- \n", mail.body.decoded
  797. assert_include "*Footer content*", mail.body.decoded
  798. end
  799. end
  800. end
  801. def test_layout_should_not_include_empty_emails_footer
  802. with_settings :emails_footer => "" do
  803. with_settings :plain_text_mail => 0 do
  804. assert Mailer.test_email(User.find(1)).deliver_now
  805. assert_select_email do
  806. assert_select ".footer", false
  807. end
  808. end
  809. with_settings :plain_text_mail => 1 do
  810. assert Mailer.test_email(User.find(1)).deliver_now
  811. mail = last_email
  812. assert_not_include "\n-- \n", mail.body.decoded
  813. end
  814. end
  815. end
  816. def test_should_escape_html_templates_only
  817. Issue.generate!(:project_id => 1, :tracker_id => 1, :subject => 'Subject with a <tag>', :notify => true)
  818. mail = last_email
  819. assert_equal 2, mail.parts.size
  820. assert_include '<tag>', text_part.body.encoded
  821. assert_include '&lt;tag&gt;', html_part.body.encoded
  822. end
  823. def test_should_raise_delivery_errors_when_raise_delivery_errors_is_true
  824. mail = Mailer.test_email(User.find(1))
  825. mail.delivery_method.stubs(:deliver!).raises(StandardError.new("delivery error"))
  826. ActionMailer::Base.raise_delivery_errors = true
  827. assert_raise StandardError, "delivery error" do
  828. mail.deliver
  829. end
  830. ensure
  831. ActionMailer::Base.raise_delivery_errors = false
  832. end
  833. def test_should_log_delivery_errors_when_raise_delivery_errors_is_false
  834. mail = Mailer.test_email(User.find(1))
  835. mail.delivery_method.stubs(:deliver!).raises(StandardError.new("delivery error"))
  836. Rails.logger.expects(:error).with("Email delivery error: delivery error")
  837. ActionMailer::Base.raise_delivery_errors = false
  838. assert_nothing_raised do
  839. mail.deliver
  840. end
  841. end
  842. def test_with_synched_deliveries_should_yield_with_synced_deliveries
  843. ActionMailer::DeliveryJob.queue_adapter = ActiveJob::QueueAdapters::AsyncAdapter.new
  844. Mailer.with_synched_deliveries do
  845. assert_kind_of ActiveJob::QueueAdapters::InlineAdapter, ActionMailer::DeliveryJob.queue_adapter
  846. end
  847. assert_kind_of ActiveJob::QueueAdapters::AsyncAdapter, ActionMailer::DeliveryJob.queue_adapter
  848. ensure
  849. ActionMailer::DeliveryJob.queue_adapter = ActiveJob::QueueAdapters::InlineAdapter.new
  850. end
  851. def test_email_addresses_should_keep_addresses
  852. assert_equal ["foo@example.net"],
  853. Mailer.email_addresses("foo@example.net")
  854. assert_equal ["foo@example.net", "bar@example.net"],
  855. Mailer.email_addresses(["foo@example.net", "bar@example.net"])
  856. end
  857. def test_email_addresses_should_replace_users_with_their_email_addresses
  858. assert_equal ["admin@somenet.foo"],
  859. Mailer.email_addresses(User.find(1))
  860. assert_equal ["admin@somenet.foo", "jsmith@somenet.foo"],
  861. Mailer.email_addresses(User.where(:id => [1,2])).sort
  862. end
  863. def test_email_addresses_should_include_notified_emails_addresses_only
  864. EmailAddress.create!(:user_id => 2, :address => "another@somenet.foo", :notify => false)
  865. EmailAddress.create!(:user_id => 2, :address => "another2@somenet.foo")
  866. assert_equal ["another2@somenet.foo", "jsmith@somenet.foo"],
  867. Mailer.email_addresses(User.find(2)).sort
  868. end
  869. private
  870. # Returns an array of email addresses to which emails were sent
  871. def recipients
  872. ActionMailer::Base.deliveries.map(&:bcc).flatten.sort
  873. end
  874. def last_email
  875. mail = ActionMailer::Base.deliveries.last
  876. assert_not_nil mail
  877. mail
  878. end
  879. def text_part
  880. last_email.parts.detect {|part| part.content_type.include?('text/plain')}
  881. end
  882. def html_part
  883. last_email.parts.detect {|part| part.content_type.include?('text/html')}
  884. end
  885. def destination_user(mail)
  886. EmailAddress.where(:address => [mail.to, mail.cc, mail.bcc].flatten).map(&:user).first
  887. end
  888. end