summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/models/email_address.rb15
-rw-r--r--app/models/mailer.rb513
-rw-r--r--app/views/mailer/security_notification.html.erb3
-rw-r--r--app/views/mailer/security_notification.text.erb3
-rw-r--r--app/views/mailer/settings_updated.html.erb4
-rw-r--r--app/views/mailer/settings_updated.text.erb4
-rw-r--r--test/functional/documents_controller_test.rb2
-rw-r--r--test/functional/issues_controller_test.rb226
-rw-r--r--test/functional/issues_custom_fields_visibility_test.rb5
-rw-r--r--test/functional/messages_controller_test.rb15
-rw-r--r--test/functional/news_controller_test.rb2
-rw-r--r--test/unit/changeset_test.rb2
-rw-r--r--test/unit/comment_test.rb2
-rw-r--r--test/unit/document_test.rb2
-rw-r--r--test/unit/issue_test.rb9
-rw-r--r--test/unit/journal_observer_test.rb10
-rw-r--r--test/unit/journal_test.rb2
-rw-r--r--test/unit/mail_handler_test.rb11
-rw-r--r--test/unit/mailer_test.rb14
-rw-r--r--test/unit/news_test.rb2
-rw-r--r--test/unit/repository_test.rb17
-rw-r--r--test/unit/wiki_content_test.rb12
22 files changed, 593 insertions, 282 deletions
diff --git a/app/models/email_address.rb b/app/models/email_address.rb
index d144e2f88..ffd5d6b4f 100644
--- a/app/models/email_address.rb
+++ b/app/models/email_address.rb
@@ -52,7 +52,7 @@ class EmailAddress < ActiveRecord::Base
# in that case, the user is just being created and
# should not receive this email.
if user.mails != [address]
- deliver_security_notification(user,
+ deliver_security_notification(
message: :mail_body_security_notification_add,
field: :field_mail,
value: address
@@ -63,25 +63,26 @@ class EmailAddress < ActiveRecord::Base
# send a security notification to user that an email has been changed (notified/not notified)
def deliver_security_notification_update
if saved_change_to_address?
- recipients = [user, address_before_last_save]
options = {
+ recipients: [address_before_last_save],
message: :mail_body_security_notification_change_to,
field: :field_mail,
value: address
}
elsif saved_change_to_notify?
- recipients = [user, address]
options = {
+ recipients: [address],
message: notify_before_last_save ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled,
value: address
}
end
- deliver_security_notification(recipients, options)
+ deliver_security_notification(options)
end
# send a security notification to user that an email address was deleted
def deliver_security_notification_destroy
- deliver_security_notification([user, address],
+ deliver_security_notification(
+ recipients: [address],
message: :mail_body_security_notification_remove,
field: :field_mail,
value: address
@@ -89,8 +90,8 @@ class EmailAddress < ActiveRecord::Base
end
# generic method to send security notifications for email addresses
- def deliver_security_notification(recipients, options={})
- Mailer.security_notification(recipients,
+ def deliver_security_notification(options={})
+ Mailer.security_notification(user,
options.merge(
title: :label_my_account,
url: {controller: 'my', action: 'account'}
diff --git a/app/models/mailer.rb b/app/models/mailer.rb
index 466ebe467..4427d333d 100644
--- a/app/models/mailer.rb
+++ b/app/models/mailer.rb
@@ -26,6 +26,113 @@ class Mailer < ActionMailer::Base
include Redmine::I18n
include Roadie::Rails::Automatic
+ # This class wraps multiple generated `Mail::Message` objects and allows to
+ # deliver them all at once. It is usually used to handle multiple mails for
+ # different receivers created by a single mail event. The wrapped mails can
+ # then be delivered in one go.
+ #
+ # The public interface of the class resembles a single mail message. You can
+ # directly use any of the deliver_* methods to send the contained messages
+ # now or later.
+ class MultiMessage
+ attr_reader :mails
+
+ # @param mails [Array<Mail, Proc>] an Array of mails or Procs which create
+ # mail objects and allow to call a method on it.
+ def initialize(action, *args)
+ @action = action
+ @args = args
+
+ @mails = []
+ end
+
+ def for(users)
+ Array.wrap(users).each do |user|
+ @mails << ActionMailer::MessageDelivery.new(Mailer, @action, user, *@args)
+ end
+ self
+ end
+
+ def deliver_later(options = {})
+ enqueue_delivery :deliver_now, options
+ end
+
+ def deliver_later!(options = {})
+ enqueue_delivery :deliver_now!, options
+ end
+
+ def processed?
+ @mails.any?(&:processed?)
+ end
+
+ # @return [Object] the delivery method of the first mail.
+ # Usually, this is the very same value for all mails and matches the
+ # default value of the Mailer class
+ def delivery_method
+ (@mails.first || ActionMailer::Base::NullMail.new).delivery_method
+ end
+
+ # @return [ActionMailer::Base] the delivery handler of the first mail. This
+ # is always the `Mailer` class.
+ def delivery_handler
+ (@mails.first || ActionMailer::Base::NullMail.new).delivery_handler
+ end
+
+ private
+
+ def method_missing(method, *args, &block)
+ if method =~ /\Adeliver([_!?]|\z)/
+ @mails.each do |mail|
+ mail.public_send(method, *args, &block)
+ end
+ else
+ super
+ end
+ end
+
+ def respond_to_missing(method, *args)
+ method =~ /\Adeliver([_!?]|\z)/ || method == 'processed?' || super
+ end
+
+ # This method is slightly adapted from ActionMailer::MessageDelivery
+ def enqueue_delivery(delivery_method, options = {})
+ if processed?
+ ::Kernel.raise "You've accessed the message before asking to " \
+ "deliver it later, so you may have made local changes that would " \
+ "be silently lost if we enqueued a job to deliver it. Why? Only " \
+ "the mailer method *arguments* are passed with the delivery job! " \
+ "Do not access the message in any way if you mean to deliver it " \
+ "later. Workarounds: 1. don't touch the message before calling " \
+ "#deliver_later, 2. only touch the message *within your mailer " \
+ "method*, or 3. use a custom Active Job instead of #deliver_later."
+ else
+ args = 'Mailer', @action.to_s, delivery_method.to_s, *@args
+ ::ActionMailer::DeliveryJob.set(options).perform_later(*args)
+ end
+ end
+ end
+
+ def process(action, *args)
+ user = args.shift
+ raise ArgumentError, "First argument has to be a user, was #{user.inspect}" unless user.is_a?(User)
+
+ initial_user = User.current
+ initial_language = ::I18n.locale
+ begin
+ User.current = user
+
+ lang = find_language(user.language) if user.logged?
+ lang ||= Setting.default_language
+ set_language_if_valid(lang)
+
+ super(action, *args)
+ ensure
+ User.current = initial_user
+ ::I18n.locale = initial_language
+ end
+ end
+
+
def self.default_url_options
options = {:protocol => Setting.protocol}
if Setting.host_name.to_s =~ /\A(https?\:\/\/)?(.+?)(\:(\d+))?(\/.+)?\z/i
@@ -39,8 +146,11 @@ class Mailer < ActionMailer::Base
options
end
- # Builds a mail for notifying to_users and cc_users about a new issue
- def issue_add(issue, to_users, cc_users)
+ # Builds a mail for notifying the current user about a new issue
+ #
+ # Example:
+ # issue_add(issue) => Mail::Message object
+ def issue_add(issue)
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue.id,
'Issue-Author' => issue.author.login
@@ -49,24 +159,34 @@ class Mailer < ActionMailer::Base
references issue
@author = issue.author
@issue = issue
- @users = to_users + cc_users
+ @users = [User.current]
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue)
- mail :to => to_users,
- :cc => cc_users,
+ mail :to => User.current,
:subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
end
# Notifies users about a new issue
+ #
+ # Example:
+ # Mailer.issue_add(journal).deliver => sends emails to the project's recipients
+ def self.issue_add(issue)
+ users = issue.notified_users | issue.notified_watchers
+ MultiMessage.new(:issue_add, issue).for(users)
+ end
+
+ # Notifies users about a new issue
+ #
+ # Example:
+ # Mailer.deliver_issue_add(issue) => sends emails to the project's recipients
def self.deliver_issue_add(issue)
- to = issue.notified_users
- cc = issue.notified_watchers - to
- issue.each_notification(to + cc) do |users|
- issue_add(issue, to & users, cc & users).deliver
- end
+ issue_add(issue).deliver
end
- # Builds a mail for notifying to_users and cc_users about an issue update
- def issue_edit(journal, to_users, cc_users)
+ # Builds a mail for notifying the current user about an issue update
+ #
+ # Example:
+ # issue_edit(journal) => Mail::Message object
+ def issue_edit(journal)
issue = journal.journalized
redmine_headers 'Project' => issue.project.identifier,
'Issue-Id' => issue.id,
@@ -79,57 +199,88 @@ class Mailer < ActionMailer::Base
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
s << issue.subject
@issue = issue
- @users = to_users + cc_users
+ @users = [User.current]
@journal = journal
- @journal_details = journal.visible_details(@users.first)
+ @journal_details = journal.visible_details
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
- mail :to => to_users,
- :cc => cc_users,
+
+ mail :to => User.current,
:subject => s
end
+ # Build a MultiMessage to notify users about an issue update
+ #
+ # Example:
+ # Mailer.issue_edit(journal).deliver => sends emails to the project's recipients
+ def self.issue_edit(journal)
+ users = journal.notified_users
+ users |= journal.notified_watchers
+ users.select! do |user|
+ journal.notes? || journal.visible_details(user).any?
+ end
+ MultiMessage.new(:issue_edit, journal).for(users)
+ end
+
# Notifies users about an issue update
+ #
+ # Example:
+ # Mailer.deliver_issue_edit(journal) => sends emails to the project's recipients
def self.deliver_issue_edit(journal)
- issue = journal.journalized.reload
- to = journal.notified_users
- cc = journal.notified_watchers - to
- journal.each_notification(to + cc) do |users|
- issue.each_notification(users) do |users2|
- issue_edit(journal, to & users2, cc & users2).deliver
- end
- end
+ issue_edit(journal).deliver
end
- def reminder(user, issues, days)
- set_language_if_valid user.language
+ # Builds a Mail::Message object used to send en email reminder to the current
+ # user about their due issues.
+ #
+ # Example:
+ # reminder(issues, days) => Mail::Message object
+ def reminder(issues, days)
@issues = issues
@days = days
@issues_url = url_for(:controller => 'issues', :action => 'index',
- :set_filter => 1, :assigned_to_id => user.id,
+ :set_filter => 1, :assigned_to_id => User.current.id,
:sort => 'due_date:asc')
- mail :to => user,
+ mail :to => User.current,
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days)
end
- # Builds a Mail::Message object used to email users belonging to the added document's project.
+ # Builds a Mail::Message object used to email the given user about their due
+ # issues
+ #
+ # Example:
+ # Mailer.reminder(user, issues, days, author).deliver => sends an email to the user
+ def self.reminder(user, issues, days)
+ MultiMessage.new(:reminder, issues, days).for(user)
+ end
+
+ # Builds a Mail::Message object used to email the current user that a document
+ # was added.
#
# Example:
- # document_added(document) => Mail::Message object
- # Mailer.document_added(document).deliver => sends an email to the document's project recipients
- def document_added(document)
+ # document_added(document, author) => Mail::Message object
+ def document_added(document, author)
redmine_headers 'Project' => document.project.identifier
- @author = User.current
+ @author = author
@document = document
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
- mail :to => document.notified_users,
+ mail :to => User.current,
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
end
- # Builds a Mail::Message object used to email recipients of a project when an attachements are added.
+ # Build a MultiMessage to notify users about an added document.
+ #
+ # Example:
+ # Mailer.document_added(document).deliver => sends emails to the document's project recipients
+ def self.document_added(document)
+ users = document.notified_users
+ MultiMessage.new(:document_added, document, User.current).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user when
+ # attachements are added.
#
# Example:
# attachments_added(attachments) => Mail::Message object
- # Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients
def attachments_added(attachments)
container = attachments.first.container
added_to = ''
@@ -139,29 +290,42 @@ class Mailer < ActionMailer::Base
when 'Project'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container)
added_to = "#{l(:label_project)}: #{container}"
- recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
when 'Version'
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project)
added_to = "#{l(:label_version)}: #{container.name}"
- recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
when 'Document'
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id)
added_to = "#{l(:label_document)}: #{container.title}"
- recipients = container.notified_users
end
redmine_headers 'Project' => container.project.identifier
@attachments = attachments
@added_to = added_to
@added_to_url = added_to_url
- mail :to => recipients,
+ mail :to => User.current,
:subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
end
- # Builds a Mail::Message object used to email recipients of a news' project when a news item is added.
+ # Build a MultiMessage to notify users about an added attachment
+ #
+ # Example:
+ # Mailer.attachments_added(attachments).deliver => sends emails to the project's recipients
+ def self.attachments_added(attachments)
+ container = attachments.first.container
+ case container.class.name
+ when 'Project', 'Version'
+ users = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
+ when 'Document'
+ users = container.notified_users
+ end
+
+ MultiMessage.new(:attachments_added, attachments).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user when a news
+ # item is added.
#
# Example:
# news_added(news) => Mail::Message object
- # Mailer.news_added(news).deliver => sends an email to the news' project recipients
def news_added(news)
redmine_headers 'Project' => news.project.identifier
@author = news.author
@@ -169,16 +333,24 @@ class Mailer < ActionMailer::Base
references news
@news = news
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
- mail :to => news.notified_users,
- :cc => news.notified_watchers_for_added_news,
+ mail :to => User.current,
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
end
- # Builds a Mail::Message object used to email recipients of a news' project when a news comment is added.
+ # Build a MultiMessage to notify users about a new news item
+ #
+ # Example:
+ # Mailer.news_added(news).deliver => sends emails to the news' project recipients
+ def self.news_added(news)
+ users = news.notified_users | news.notified_watchers_for_added_news
+ MultiMessage.new(:news_added, news).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user when a news
+ # comment is added.
#
# Example:
# news_comment_added(comment) => Mail::Message object
- # Mailer.news_comment_added(comment) => sends an email to the news' project recipients
def news_comment_added(comment)
news = comment.commented
redmine_headers 'Project' => news.project.identifier
@@ -188,64 +360,87 @@ class Mailer < ActionMailer::Base
@news = news
@comment = comment
@news_url = url_for(:controller => 'news', :action => 'show', :id => news)
- mail :to => news.notified_users,
- :cc => news.notified_watchers,
+ mail :to => User.current,
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
end
- # Builds a Mail::Message object used to email the recipients of the specified message that was posted.
+ # Build a MultiMessage to notify users about a new news comment
+ #
+ # Example:
+ # Mailer.news_comment_added(comment).deliver => sends emails to the news' project recipients
+ def self.news_comment_added(comment)
+ news = comment.commented
+ users = news.notified_users | news.notified_watchers
+
+ MultiMessage.new(:news_comment_added, comment).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user that the
+ # specified message was posted.
#
# Example:
# message_posted(message) => Mail::Message object
- # Mailer.message_posted(message).deliver => sends an email to the recipients
def message_posted(message)
redmine_headers 'Project' => message.project.identifier,
'Topic-Id' => (message.parent_id || message.id)
@author = message.author
message_id message
references message.root
- recipients = message.notified_users
- cc = ((message.root.notified_watchers + message.board.notified_watchers).uniq - recipients)
@message = message
@message_url = url_for(message.event_url)
- mail :to => recipients,
- :cc => cc,
+ mail :to => User.current,
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
end
- # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added.
+ # Build a MultiMessage to notify users about a new forum message
+ #
+ # Example:
+ # Mailer.message_posted(message).deliver => sends emails to the recipients
+ def self.message_posted(message)
+ users = message.notified_users
+ users |= message.root.notified_watchers
+ users |= message.board.notified_watchers
+
+ MultiMessage.new(:message_posted, message).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user that the
+ # specified wiki content was added.
#
# Example:
# wiki_content_added(wiki_content) => Mail::Message object
- # Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients
def wiki_content_added(wiki_content)
redmine_headers 'Project' => wiki_content.project.identifier,
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
- recipients = wiki_content.notified_users
- cc = wiki_content.page.wiki.notified_watchers - recipients
@wiki_content = wiki_content
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
:id => wiki_content.page.title)
- mail :to => recipients,
- :cc => cc,
+ mail :to => User.current,
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
end
- # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated.
+ # Build a MultiMessage to notify users about added wiki content
+ #
+ # Example:
+ # Mailer.wiki_content_added(wiki_content).deliver => send emails to the project's recipients
+ def self.wiki_content_added(wiki_content)
+ users = wiki_content.notified_users | wiki_content.page.wiki.notified_watchers
+ MultiMessage.new(:wiki_content_added, wiki_content).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user about an update
+ # of the specified wiki content.
#
# Example:
# wiki_content_updated(wiki_content) => Mail::Message object
- # Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
def wiki_content_updated(wiki_content)
redmine_headers 'Project' => wiki_content.project.identifier,
'Wiki-Page-Id' => wiki_content.page.id
@author = wiki_content.author
message_id wiki_content
- recipients = wiki_content.notified_users
- cc = wiki_content.page.wiki.notified_watchers + wiki_content.page.notified_watchers - recipients
@wiki_content = wiki_content
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
:project_id => wiki_content.project,
@@ -253,56 +448,92 @@ class Mailer < ActionMailer::Base
@wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff',
:project_id => wiki_content.project, :id => wiki_content.page.title,
:version => wiki_content.version)
- mail :to => recipients,
- :cc => cc,
+ mail :to => User.current,
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
end
- # Builds a Mail::Message object used to email the specified user their account information.
+ # Build a MultiMessage to notify users about the update of the specified wiki content
#
# Example:
- # account_information(user, password) => Mail::Message object
- # Mailer.account_information(user, password).deliver => sends account information to the user
- def account_information(user, password)
- set_language_if_valid user.language
- @user = user
+ # Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients
+ def self.wiki_content_updated(wiki_content)
+ users = wiki_content.notified_users
+ users |= wiki_content.page.notified_watchers
+ users |= wiki_content.page.wiki.notified_watchers
+
+ MultiMessage.new(:wiki_content_updated, wiki_content).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the current user their account information.
+ #
+ # Example:
+ # account_information(password) => Mail::Message object
+ def account_information(password)
+ @user = User.current
@password = password
@login_url = url_for(:controller => 'account', :action => 'login')
- mail :to => user.mail,
+ mail :to => User.current.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
- # Builds a Mail::Message object used to email all active administrators of an account activation request.
+ # Build a MultiMessage to mail a user their account information
+ #
+ # Example:
+ # Mailer.account_information(user, password).deliver => sends account information to the user
+ def self.account_information(user, password)
+ MultiMessage.new(:account_information, password).for(user)
+ end
+
+ # Builds a Mail::Message object used to email the current user about an account activation request.
#
# Example:
# account_activation_request(user) => Mail::Message object
- # Mailer.account_activation_request(user).deliver => sends an email to all active administrators
def account_activation_request(user)
- # Send the email to all active administrators
- recipients = User.active.where(:admin => true)
@user = user
@url = url_for(:controller => 'users', :action => 'index',
:status => User::STATUS_REGISTERED,
:sort_key => 'created_on', :sort_order => 'desc')
- mail :to => recipients,
+ mail :to => User.current,
:subject => l(:mail_subject_account_activation_request, Setting.app_title)
end
- # Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
+ # Build a MultiMessage to email all active administrators of an account activation request.
#
# Example:
- # account_activated(user) => Mail::Message object
- # Mailer.account_activated(user).deliver => sends an email to the registered user
- def account_activated(user)
- set_language_if_valid user.language
- @user = user
+ # Mailer.account_activation_request(user).deliver => sends an email to all active administrators
+ def self.account_activation_request(user)
+ # Send the email to all active administrators
+ users = User.active.where(:admin => true)
+ MultiMessage.new(:account_activation_request, user).for(users)
+ end
+
+ # Builds a Mail::Message object used to email the account of the current user
+ # was activated by an administrator.
+ #
+ # Example:
+ # account_activated => Mail::Message object
+ def account_activated
+ @user = User.current
@login_url = url_for(:controller => 'account', :action => 'login')
- mail :to => user.mail,
+ mail :to => User.current.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
+ # Build a MultiMessage to email the specified user that their account was
+ # activated by an administrator.
+ #
+ # Example:
+ # Mailer.account_activated(user).deliver => sends an email to the registered user
+ def self.account_activated(user)
+ MultiMessage.new(:account_activated).for(user)
+ end
+
+ # Builds a Mail::Message object used to email the lost password token to the
+ # token's user (or a different recipient).
+ #
+ # Example:
+ # lost_password(token) => Mail::Message object
def lost_password(token, recipient=nil)
- set_language_if_valid(token.user.language)
recipient ||= token.user.mail
@token = token
@url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value)
@@ -310,6 +541,15 @@ class Mailer < ActionMailer::Base
:subject => l(:mail_subject_lost_password, Setting.app_title)
end
+ # Build a MultiMessage to email the token's user (or a different recipient)
+ # the lost password token for the token's user.
+ #
+ # Example:
+ # Mailer.lost_password(token).deliver => sends an email to the user
+ def self.lost_password(token, recipient=nil)
+ MultiMessage.new(:lost_password, token, recipient).for(token.user)
+ end
+
# Notifies user that his password was updated
def self.password_updated(user, options={})
# Don't send a notification to the dummy email address when changing the password
@@ -326,39 +566,92 @@ class Mailer < ActionMailer::Base
).deliver
end
+ # Builds a Mail::Message object used to email the user activation link to the
+ # token's user.
+ #
+ # Example:
+ # register(token) => Mail::Message object
def register(token)
- set_language_if_valid(token.user.language)
@token = token
@url = url_for(:controller => 'account', :action => 'activate', :token => token.value)
mail :to => token.user.mail,
:subject => l(:mail_subject_register, Setting.app_title)
end
- def security_notification(recipients, options={})
- @user = Array(recipients).detect{|r| r.is_a? User }
- set_language_if_valid(@user.try :language)
+ # Build a MultiMessage to email the user activation link to the token's user.
+ #
+ # Example:
+ # Mailer.register(token).deliver => sends an email to the token's user
+ def self.register(token)
+ MultiMessage.new(:register, token).for(token.user)
+ end
+
+ # Build a Mail::Message object to email the current user and the additional
+ # recipients given in options[:recipients] about a security related event.
+ #
+ # Example:
+ # security_notification(users,
+ # message: :mail_body_security_notification_add,
+ # field: :field_mail,
+ # value: address
+ # ) => Mail::Message object
+ def security_notification(sender, options={})
+ @sender = sender
+ redmine_headers 'Sender' => sender.login
@message = l(options[:message],
field: (options[:field] && l(options[:field])),
value: options[:value]
)
@title = options[:title] && l(options[:title])
- @originator = options[:originator] || User.current
+ @originator = options[:originator] || sender
@remote_ip = options[:remote_ip] || @originator.remote_ip
@url = options[:url] && (options[:url].is_a?(Hash) ? url_for(options[:url]) : options[:url])
redmine_headers 'Sender' => @originator.login
redmine_headers 'Url' => @url
- mail :to => recipients,
+ mail :to => [User.current, *options[:recipients]].uniq,
:subject => "[#{Setting.app_title}] #{l(:mail_subject_security_notification)}"
end
- def settings_updated(recipients, changes)
- redmine_headers 'Sender' => User.current.login
+ # Build a MultiMessage to email the given users about a security related event.
+ #
+ # You can specify additional recipients in options[:recipients]. These will be
+ # added to all generated mails for all given users. Usually, you'll want to
+ # give only a single user when setting the additional recipients.
+ #
+ # Example:
+ # Mailer.security_notification(users,
+ # message: :mail_body_security_notification_add,
+ # field: :field_mail,
+ # value: address
+ # ).deliver => sends a security notification to the given user(s)
+ def self.security_notification(users, options={})
+ sender = User.current
+ MultiMessage.new(:security_notification, sender, options).for(users)
+ end
+
+ # Build a Mail::Message object to email the current user about an updated
+ # setting.
+ #
+ # Example:
+ # settings_updated(sender, [:host_name]) => Mail::Message object
+ def settings_updated(sender, changes)
+ @sender = sender
+ redmine_headers 'Sender' => sender.login
@changes = changes
@url = url_for(controller: 'settings', action: 'index')
- mail :to => recipients,
+ mail :to => User.current,
:subject => "[#{Setting.app_title}] #{l(:mail_subject_security_notification)}"
end
+ # Build a MultiMessage to email the given users about an update of a setting.
+ #
+ # Example:
+ # Mailer.settings_updated(users, [:host_name]).deliver => sends emails to the given user(s) about the update
+ def self.settings_updated(users, changes)
+ sender = User.current
+ MultiMessage.new(:settings_updated, sender, changes).for(users)
+ end
+
# Notifies admins about settings changes
def self.security_settings_updated(changes)
return unless changes.present?
@@ -367,13 +660,24 @@ class Mailer < ActionMailer::Base
settings_updated(users, changes).deliver
end
- def test_email(user)
- set_language_if_valid(user.language)
+ # Build a Mail::Message object with a test email for the current user
+ #
+ # Example:
+ # test_email => Mail::Message object
+ def test_email
@url = url_for(:controller => 'welcome')
- mail :to => user.mail,
+ mail :to => User.current.mail,
:subject => 'Redmine test'
end
+ # Build a MultiMessage to send a test email the given user
+ #
+ # Example:
+ # Mailer.test_email(user).deliver => send an email to the given user
+ def self.test_email(user)
+ MultiMessage.new(:test_email).for(user)
+ end
+
# Sends reminders to issue assignees
# Available options:
# * :days => how many days in the future to remind about (defaults to 7)
@@ -483,7 +787,7 @@ class Mailer < ActionMailer::Base
headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ')
end
- m = if block_given?
+ if block_given?
super headers, &block
else
super headers do |format|
@@ -491,15 +795,6 @@ class Mailer < ActionMailer::Base
format.html unless Setting.plain_text_mail?
end
end
- set_language_if_valid @initial_language
-
- m
- end
-
- def initialize(*args)
- @initial_language = current_language
- set_language_if_valid Setting.default_language
- super
end
def self.deliver_mail(mail)
@@ -521,6 +816,8 @@ class Mailer < ActionMailer::Base
if m = method.to_s.match(%r{^deliver_(.+)$})
ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
send(m[1], *args).deliver
+ elsif action_methods.include?(method.to_s)
+ MultiMessage.new(method, *args).for(User.current)
else
super
end
diff --git a/app/views/mailer/security_notification.html.erb b/app/views/mailer/security_notification.html.erb
index 309e9437f..84394d1ab 100644
--- a/app/views/mailer/security_notification.html.erb
+++ b/app/views/mailer/security_notification.html.erb
@@ -9,5 +9,4 @@
<p><%= l(:field_user) %>: <strong><%= @originator.login %></strong><br/>
<%= l(:field_remote_ip) %>: <strong><%= @remote_ip %></strong><br/>
-<%= l(:label_date) %>: <strong><%= format_time Time.now, true, @user %></strong></p>
-
+<%= l(:label_date) %>: <strong><%= format_time Time.now, true %></strong></p>
diff --git a/app/views/mailer/security_notification.text.erb b/app/views/mailer/security_notification.text.erb
index 5be036b7a..7ff3f3d57 100644
--- a/app/views/mailer/security_notification.text.erb
+++ b/app/views/mailer/security_notification.text.erb
@@ -4,5 +4,4 @@
<%= l(:field_user) %>: <%= @originator.login %>
<%= l(:field_remote_ip) %>: <%= @remote_ip %>
-<%= l(:label_date) %>: <%= format_time Time.now, true, @user %>
-
+<%= l(:label_date) %>: <%= format_time Time.now, true %>
diff --git a/app/views/mailer/settings_updated.html.erb b/app/views/mailer/settings_updated.html.erb
index 8596089a2..c50eb9ea1 100644
--- a/app/views/mailer/settings_updated.html.erb
+++ b/app/views/mailer/settings_updated.html.erb
@@ -8,7 +8,7 @@
<%= link_to @url, @url %>
-<p><%= l(:field_user) %>: <strong><%= User.current.login %></strong><br/>
-<%= l(:field_remote_ip) %>: <strong><%= User.current.remote_ip %></strong><br/>
+<p><%= l(:field_user) %>: <strong><%= @sender.login %></strong><br/>
+<%= l(:field_remote_ip) %>: <strong><%= @sender.remote_ip %></strong><br/>
<%= l(:label_date) %>: <strong><%= format_time Time.now, true %></strong></p>
diff --git a/app/views/mailer/settings_updated.text.erb b/app/views/mailer/settings_updated.text.erb
index 51a2a8f6a..9b0be909d 100644
--- a/app/views/mailer/settings_updated.text.erb
+++ b/app/views/mailer/settings_updated.text.erb
@@ -6,7 +6,7 @@
<%= @url %>
-<%= l(:field_user) %>: <%= User.current.login %>
-<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
+<%= l(:field_user) %>: <%= @sender.login %>
+<%= l(:field_remote_ip) %>: <%= @sender.remote_ip %>
<%= l(:label_date) %>: <%= format_time Time.now, true %>
diff --git a/test/functional/documents_controller_test.rb b/test/functional/documents_controller_test.rb
index 0a7aed72b..c8c9fd57c 100644
--- a/test/functional/documents_controller_test.rb
+++ b/test/functional/documents_controller_test.rb
@@ -132,7 +132,7 @@ LOREM
assert_equal Enumeration.find(2), document.category
assert_equal 1, document.attachments.size
assert_equal 'testfile.txt', document.attachments.first.filename
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_with_failure
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index a5fb68b59..17af8981c 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -152,7 +152,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:f => ['tracker_id'],
:op => {
'tracker_id' => '='
- },
+ },
:v => {
'tracker_id' => ['1']
}
@@ -253,10 +253,10 @@ class IssuesControllerTest < Redmine::ControllerTest
:f => [filter_name],
:op => {
filter_name => '='
- },
+ },
:v => {
filter_name => ['Foo']
- },
+ },
:c => ['project']
}
assert_response :success
@@ -1459,7 +1459,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:f => ['start_date'],
:op => {
:start_date => '='
- },
+ },
:format => 'csv'
}
assert_equal 'text/csv', @response.content_type
@@ -2678,7 +2678,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => 3,
:description => 'Prefilled',
:custom_field_values => {
- '2' => 'Custom field value'}
+ '2' => 'Custom field value'}
}
}
@@ -2802,7 +2802,7 @@ class IssuesControllerTest < Redmine::ControllerTest
assert !t.disabled_core_fields.include?('parent_issue_id')
get :new, :params => {
- :project_id => 1, issue: { parent_issue_id: 1
+ :project_id => 1, issue: { parent_issue_id: 1
}
}
assert_response :success
@@ -2812,7 +2812,7 @@ class IssuesControllerTest < Redmine::ControllerTest
t.save!
assert t.disabled_core_fields.include?('parent_issue_id')
get :new, :params => {
- :project_id => 1, issue: { parent_issue_id: 1
+ :project_id => 1, issue: { parent_issue_id: 1
}
}
assert_response :success
@@ -2870,7 +2870,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:tracker_id => 2,
:status_id => 1
- },
+ },
:was_default_status => 1
}
assert_response :success
@@ -2889,7 +2889,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:project_id => 1,
:fixed_version_id => ''
- },
+ },
:form_update_triggered_by => 'issue_project_id'
}
assert_response :success
@@ -2917,7 +2917,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:start_date => '2010-11-07',
:estimated_hours => '',
:custom_field_values => {
- '2' => 'Value for field 2'}
+ '2' => 'Value for field 2'}
}
}
end
@@ -2976,7 +2976,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 5,
:estimated_hours => '',
:custom_field_values => {
- '2' => 'Value for field 2'}
+ '2' => 'Value for field 2'}
}
}
end
@@ -3002,7 +3002,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 5,
:estimated_hours => '',
:custom_field_values => {
- '2' => 'Value for field 2'}
+ '2' => 'Value for field 2'}
}
}
end
@@ -3023,7 +3023,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => 3,
:subject => 'This is first issue',
:priority_id => 5
- },
+ },
:continue => ''
}
end
@@ -3065,7 +3065,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:description => 'This is the description',
:priority_id => 5,
:custom_field_values => {
- '1' => ['', 'MySQL', 'Oracle']}
+ '1' => ['', 'MySQL', 'Oracle']}
}
}
end
@@ -3088,7 +3088,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:description => 'This is the description',
:priority_id => 5,
:custom_field_values => {
- '1' => ['']}
+ '1' => ['']}
}
}
end
@@ -3111,7 +3111,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:description => 'This is the description',
:priority_id => 5,
:custom_field_values => {
- field.id.to_s => ['', '2', '3']}
+ field.id.to_s => ['', '2', '3']}
}
}
end
@@ -3159,8 +3159,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:due_date => '',
:custom_field_values => {
cf1.id.to_s => '', cf2.id.to_s => ''
- }
-
+ }
+
}
}
assert_response :success
@@ -3189,8 +3189,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:due_date => '',
:custom_field_values => {
cf1.id.to_s => '', cf2.id.to_s => ['']
- }
-
+ }
+
}
}
assert_response :success
@@ -3219,8 +3219,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:due_date => '2012-07-16',
:custom_field_values => {
cf1.id.to_s => 'value1', cf2.id.to_s => 'value2'
- }
-
+ }
+
}
}
assert_response 302
@@ -3246,7 +3246,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => 1,
:status_id => 1,
:subject => 'Test'
-
+
}
}
assert_response 302
@@ -3424,7 +3424,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 3,
:tracker_id => 2,
:subject => 'Foo'
- },
+ },
:continue => '1'
}
assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2'
@@ -3477,13 +3477,13 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 5,
:estimated_hours => '',
:custom_field_values => {
- '2' => 'Value for field 2'}
+ '2' => 'Value for field 2'}
}
}
end
assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
end
@@ -3536,7 +3536,7 @@ class IssuesControllerTest < Redmine::ControllerTest
post :create, :params => {
:project_id => 1,
:issue => {
- :tracker => "A param can not be a Tracker"
+ :tracker => "A param can not be a Tracker"
}
}
end
@@ -3553,11 +3553,11 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 1,
:issue => {
:tracker_id => '1',
- :subject => 'With attachment'
- },
+ :subject => 'With attachment'
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
}
}
end
@@ -3588,11 +3588,11 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 1,
:issue => {
:tracker_id => '1',
- :subject => 'With attachment'
- },
+ :subject => 'With attachment'
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
}
}
end
@@ -3614,11 +3614,11 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 1,
:issue => {
:tracker_id => '1',
- :subject => ''
- },
+ :subject => ''
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
}
}
assert_response :success
@@ -3645,11 +3645,11 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 1,
:issue => {
:tracker_id => '1',
- :subject => ''
- },
+ :subject => ''
+ },
:attachments => {
'p0' => {
- 'token' => attachment.token}
+ 'token' => attachment.token}
}
}
assert_response :success
@@ -3671,11 +3671,11 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => 1,
:issue => {
:tracker_id => '1',
- :subject => 'Saved attachments'
- },
+ :subject => 'Saved attachments'
+ },
:attachments => {
'p0' => {
- 'token' => attachment.token}
+ 'token' => attachment.token}
}
}
assert_response 302
@@ -3997,7 +3997,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => '1',
:tracker_id => '1',
:status_id => '1'
- },
+ },
:was_default_status => '1'
}
end
@@ -4041,7 +4041,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => '3',
:status_id => '1',
:subject => 'Copy with attachments'
- },
+ },
:copy_attachments => '1'
}
end
@@ -4089,7 +4089,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => '3',
:status_id => '1',
:subject => 'Copy with attachments'
- },
+ },
:copy_attachments => '1',
:attachments => {
'1' => {
@@ -4188,7 +4188,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:tracker_id => '3',
:status_id => '1',
:subject => 'Copy with subtasks'
- },
+ },
:copy_subtasks => '1'
}
end
@@ -4212,8 +4212,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:status_id => '1',
:subject => 'Copy with subtasks',
:custom_field_values => {
- '2' => 'Foo'}
- },
+ '2' => 'Foo'}
+ },
:copy_subtasks => '1'
}
end
@@ -4394,12 +4394,12 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:status_id => 5,
- :priority_id => 7
- },
+ :priority_id => 7
+ },
:time_entry => {
:hours => '2.5',
:comments => 'test_get_edit_with_params',
- :activity_id => 10
+ :activity_id => 10
}
}
assert_response :success
@@ -4638,7 +4638,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:project_id => '1',
:tracker_id => '2',
:priority_id => '6'
-
+
}
}
end
@@ -4701,9 +4701,9 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:subject => 'Custom field change',
:custom_field_values => {
- '1' => ['', 'Oracle', 'PostgreSQL']
- }
-
+ '1' => ['', 'Oracle', 'PostgreSQL']
+ }
+
}
}
end
@@ -4724,12 +4724,12 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:status_id => 2,
:assigned_to_id => 3,
- :notes => 'Assigned to dlopper'
- },
+ :notes => 'Assigned to dlopper'
+ },
:time_entry => {
:hours => '',
:comments => '',
- :activity_id => TimeEntryActivity.first
+ :activity_id => TimeEntryActivity.first
}
}
end
@@ -4755,7 +4755,7 @@ class IssuesControllerTest < Redmine::ControllerTest
put :update, :params => {
:id => 1,
:issue => {
- :notes => notes
+ :notes => notes
}
}
end
@@ -4823,12 +4823,12 @@ class IssuesControllerTest < Redmine::ControllerTest
put :update, :params => {
:id => 1,
:issue => {
- :notes => '2.5 hours added'
- },
+ :notes => '2.5 hours added'
+ },
:time_entry => {
:hours => '2.5',
:comments => 'test_put_update_with_note_and_spent_time',
- :activity_id => TimeEntryActivity.first.id
+ :activity_id => TimeEntryActivity.first.id
}
}
end
@@ -4883,10 +4883,10 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:notes => ''
- },
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
}
}
end
@@ -4922,11 +4922,11 @@ class IssuesControllerTest < Redmine::ControllerTest
put :update, :params => {
:id => 1,
:issue => {
- :subject => ''
- },
+ :subject => ''
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
}
}
assert_response :success
@@ -4952,11 +4952,11 @@ class IssuesControllerTest < Redmine::ControllerTest
put :update, :params => {
:id => 1,
:issue => {
- :subject => ''
- },
+ :subject => ''
+ },
:attachments => {
'p0' => {
- 'token' => attachment.token}
+ 'token' => attachment.token}
}
}
assert_response :success
@@ -4979,10 +4979,10 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:notes => 'Attachment added'
- },
+ },
:attachments => {
'p0' => {
- 'token' => attachment.token}
+ 'token' => attachment.token}
}
}
assert_redirected_to '/issues/1'
@@ -5007,10 +5007,10 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:notes => ''
- },
+ },
:attachments => {
'1' => {
- 'file' => uploaded_test_file('testfile.txt', 'text/plain')}
+ 'file' => uploaded_test_file('testfile.txt', 'text/plain')}
}
}
assert_redirected_to :action => 'show', :id => '1'
@@ -5030,7 +5030,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:notes => 'Removing attachments',
:deleted_attachment_ids => ['1', '5']
-
+
}
}
end
@@ -5057,7 +5057,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:subject => '',
:notes => 'Removing attachments',
:deleted_attachment_ids => ['1', '5']
-
+
}
}
end
@@ -5100,10 +5100,10 @@ class IssuesControllerTest < Redmine::ControllerTest
:subject => new_subject,
:priority_id => '6',
:category_id => '1' # no change
-
+
}
}
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
end
@@ -5116,7 +5116,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:notes => notes
- },
+ },
:time_entry => {
"comments"=>"", "activity_id"=>"", "hours"=>"2z"
}
@@ -5138,7 +5138,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:notes => notes
- },
+ },
:time_entry => {
"comments"=>"this is my comment", "activity_id"=>"", "hours"=>""
}
@@ -5160,7 +5160,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => issue.id,
:issue => {
:fixed_version_id => 4
-
+
}
}
@@ -5178,8 +5178,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => issue.id,
:issue => {
:fixed_version_id => 4
-
- },
+
+ },
:back_url => '/issues'
}
@@ -5195,8 +5195,8 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => issue.id,
:issue => {
:fixed_version_id => 4
-
- },
+
+ },
:back_url => 'http://google.com'
}
@@ -5212,7 +5212,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:issue => {
:status_id => 6,
:notes => 'Notes'
- },
+ },
:prev_issue_id => 8,
:next_issue_id => 12,
:issue_position => 2,
@@ -5501,7 +5501,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 7,
:assigned_to_id => '',
:custom_field_values => {
- '2' => ''}
+ '2' => ''}
}
}
@@ -5531,7 +5531,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => '',
:assigned_to_id => group.id,
:custom_field_values => {
- '2' => ''}
+ '2' => ''}
}
}
@@ -5550,7 +5550,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 7,
:assigned_to_id => '',
:custom_field_values => {
- '2' => ''}
+ '2' => ''}
}
}
@@ -5578,14 +5578,14 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => 7,
:assigned_to_id => '',
:custom_field_values => {
- '2' => ''}
+ '2' => ''}
}
}
assert_response 403
assert_not_equal "Bulk should fail", Journal.last.notes
end
- def test_bullk_update_should_send_a_notification
+ def test_bulk_update_should_send_a_notification
@request.session[:user_id] = 2
ActionMailer::Base.deliveries.clear
with_settings :notified_events => %w(issue_updated) do
@@ -5599,7 +5599,7 @@ class IssuesControllerTest < Redmine::ControllerTest
}
}
assert_response 302
- assert_equal 2, ActionMailer::Base.deliveries.size
+ assert_equal 5, ActionMailer::Base.deliveries.size
end
end
@@ -5626,7 +5626,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => 1,
:issue => {
:project_id => '2'
- },
+ },
:follow => '1'
}
assert_redirected_to '/issues/1'
@@ -5638,7 +5638,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:id => [1, 2],
:issue => {
:project_id => '2'
- },
+ },
:follow => '1'
}
assert_redirected_to '/projects/onlinestore/issues'
@@ -5745,7 +5745,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => '',
:assigned_to_id => '',
:custom_field_values => {
- '2' => '777'}
+ '2' => '777'}
}
}
@@ -5768,7 +5768,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => '',
:assigned_to_id => '',
:custom_field_values => {
- '1' => '__none__'}
+ '1' => '__none__'}
}
}
assert_response 302
@@ -5788,7 +5788,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => '',
:assigned_to_id => '',
:custom_field_values => {
- '1' => ['MySQL', 'Oracle']}
+ '1' => ['MySQL', 'Oracle']}
}
}
@@ -5812,7 +5812,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:priority_id => '',
:assigned_to_id => '',
:custom_field_values => {
- '1' => ['__none__']}
+ '1' => ['__none__']}
}
}
assert_response 302
@@ -5969,7 +5969,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:ids => issue_ids,
:issue => {
:project_id => '2'
- },
+ },
:copy => '1'
}
end
@@ -5991,7 +5991,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:ids => [1, 2, 3],
:issue => {
:project_id => '2'
- },
+ },
:copy => '1'
}
assert_response 302
@@ -6006,7 +6006,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:ids => [1, 2, 3],
:issue => {
:project_id => ''
- },
+ },
:copy => '1'
}
assert_response 403
@@ -6020,7 +6020,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:ids => [1, 2, 3],
:issue => {
:project_id => '1'
- },
+ },
:copy => '1'
}
assert_response 403
@@ -6047,7 +6047,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:status_id => '',
:start_date => '',
:due_date => ''
-
+
}
}
end
@@ -6087,7 +6087,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:status_id => '1',
:start_date => '2009-12-01',
:due_date => '2009-12-31'
-
+
}
}
end
@@ -6117,7 +6117,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:status_id => '3',
:start_date => '2009-12-01',
:due_date => '2009-12-31'
-
+
}
}
end
@@ -6140,7 +6140,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_attachments => '0',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6160,7 +6160,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_attachments => '1',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6178,7 +6178,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:link_copy => '1',
:issue => {
:project_id => '1'
-
+
}
}
end
@@ -6196,7 +6196,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_subtasks => '0',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6214,7 +6214,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_subtasks => '1',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6233,7 +6233,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_watchers => '1',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6253,7 +6253,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy_subtasks => '1',
:issue => {
:project_id => ''
-
+
}
}
end
@@ -6268,7 +6268,7 @@ class IssuesControllerTest < Redmine::ControllerTest
:copy => '1',
:issue => {
:project_id => 2
- },
+ },
:follow => '1'
}
issue = Issue.order('id DESC').first
diff --git a/test/functional/issues_custom_fields_visibility_test.rb b/test/functional/issues_custom_fields_visibility_test.rb
index 1ce32bf79..485b55be8 100644
--- a/test/functional/issues_custom_fields_visibility_test.rb
+++ b/test/functional/issues_custom_fields_visibility_test.rb
@@ -285,7 +285,8 @@ class IssuesCustomFieldsVisibilityTest < Redmine::ControllerTest
assert_response 302
end
end
- assert_equal users_to_test.values.uniq.size, ActionMailer::Base.deliveries.size
+
+ assert_equal users_to_test.keys.size, ActionMailer::Base.deliveries.size
# tests that each user receives 1 email with the custom fields he is allowed to see only
users_to_test.each do |user, fields|
mails = ActionMailer::Base.deliveries.select {|m| m.bcc.include? user.mail}
@@ -322,7 +323,7 @@ class IssuesCustomFieldsVisibilityTest < Redmine::ControllerTest
}
assert_response 302
end
- assert_equal users_to_test.values.uniq.size, ActionMailer::Base.deliveries.size
+ assert_equal users_to_test.keys.size, ActionMailer::Base.deliveries.size
# tests that each user receives 1 email with the custom fields he is allowed to see only
users_to_test.each do |user, fields|
mails = ActionMailer::Base.deliveries.select {|m| m.bcc.include? user.mail}
diff --git a/test/functional/messages_controller_test.rb b/test/functional/messages_controller_test.rb
index 0f3d937db..b129cdd33 100644
--- a/test/functional/messages_controller_test.rb
+++ b/test/functional/messages_controller_test.rb
@@ -136,14 +136,17 @@ class MessagesControllerTest < Redmine::ControllerTest
assert_equal 2, message.author_id
assert_equal 1, message.board_id
- mail = ActionMailer::Base.deliveries.last
- assert_not_nil mail
- assert_equal "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] Test created message", mail.subject
- assert_mail_body_match 'Message body', mail
+ mails = ActionMailer::Base.deliveries
+ assert_not_empty mails
+ mails.each do |mail|
+ assert_equal "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] Test created message", mail.subject
+ assert_mail_body_match 'Message body', mail
+ end
+
# author
- assert mail.bcc.include?('jsmith@somenet.foo')
+ assert_equal ['jsmith@somenet.foo'], mails[0].bcc
# project member
- assert mail.bcc.include?('dlopper@somenet.foo')
+ assert_equal ['dlopper@somenet.foo'], mails[1].bcc
end
def test_get_edit
diff --git a/test/functional/news_controller_test.rb b/test/functional/news_controller_test.rb
index f62d21bf1..90a5a1112 100644
--- a/test/functional/news_controller_test.rb
+++ b/test/functional/news_controller_test.rb
@@ -127,7 +127,7 @@ class NewsControllerTest < Redmine::ControllerTest
assert_equal 'This is the description', news.description
assert_equal User.find(2), news.author
assert_equal Project.find(1), news.project
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_post_create_with_attachment
diff --git a/test/unit/changeset_test.rb b/test/unit/changeset_test.rb
index 8586d8fc7..a1c3cf8dc 100644
--- a/test/unit/changeset_test.rb
+++ b/test/unit/changeset_test.rb
@@ -46,7 +46,7 @@ class ChangesetTest < ActiveSupport::TestCase
fixed = Issue.find(1)
assert fixed.closed?
assert_equal 90, fixed.done_ratio
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_ref_keywords
diff --git a/test/unit/comment_test.rb b/test/unit/comment_test.rb
index 4597fd9e7..fe9776fc3 100644
--- a/test/unit/comment_test.rb
+++ b/test/unit/comment_test.rb
@@ -36,7 +36,7 @@ class CommentTest < ActiveSupport::TestCase
Watcher.create!(:watchable => @news, :user => @jsmith)
with_settings :notified_events => %w(news_comment_added) do
- assert_difference 'ActionMailer::Base.deliveries.size' do
+ assert_difference 'ActionMailer::Base.deliveries.size', 2 do
Comment.create!(:commented => @news, :author => @jsmith, :comments => "my comment")
end
end
diff --git a/test/unit/document_test.rb b/test/unit/document_test.rb
index 9adcd4724..e4243dd60 100644
--- a/test/unit/document_test.rb
+++ b/test/unit/document_test.rb
@@ -41,7 +41,7 @@ class DocumentTest < ActiveSupport::TestCase
doc = Document.new(:project => Project.find(1), :title => 'New document', :category => Enumeration.find_by_name('User documentation'))
assert doc.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_with_default_category
diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb
index a6ace2fa0..432dd8745 100644
--- a/test/unit/issue_test.rb
+++ b/test/unit/issue_test.rb
@@ -2529,7 +2529,7 @@ class IssueTest < ActiveSupport::TestCase
:subject => 'test_create', :estimated_hours => '1:30')
with_settings :notified_events => %w(issue_added) do
assert issue.save
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
end
@@ -2541,7 +2541,7 @@ class IssueTest < ActiveSupport::TestCase
:subject => 'test_create', :estimated_hours => '1:30')
with_settings :notified_events => %w(issue_added issue_updated) do
assert issue.save
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
end
@@ -2568,7 +2568,8 @@ class IssueTest < ActiveSupport::TestCase
issue.init_journal User.find(1)
issue.assigned_to = nil
issue.save!
- assert_include user.mail, ActionMailer::Base.deliveries.last.bcc
+
+ assert_include [user.mail], ActionMailer::Base.deliveries.map(&:bcc)
end
end
@@ -2581,7 +2582,7 @@ class IssueTest < ActiveSupport::TestCase
issue.subject = 'Subjet update'
with_settings :notified_events => %w(issue_updated) do
assert issue.save
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
ActionMailer::Base.deliveries.clear
stale.init_journal(User.find(1))
diff --git a/test/unit/journal_observer_test.rb b/test/unit/journal_observer_test.rb
index e9eac32e5..17695538a 100644
--- a/test/unit/journal_observer_test.rb
+++ b/test/unit/journal_observer_test.rb
@@ -36,7 +36,7 @@ class JournalObserverTest < ActiveSupport::TestCase
with_settings :notified_events => %w(issue_updated) do
assert journal.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_should_not_send_email_notification_with_notify_set_to_false
@@ -71,7 +71,7 @@ class JournalObserverTest < ActiveSupport::TestCase
with_settings :notified_events => %w(issue_note_added) do
assert journal.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_should_not_send_email_notification_without_issue_note_added
@@ -95,7 +95,7 @@ class JournalObserverTest < ActiveSupport::TestCase
with_settings :notified_events => %w(issue_status_updated) do
assert issue.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_should_not_send_email_notification_without_issue_status_updated
@@ -132,7 +132,7 @@ class JournalObserverTest < ActiveSupport::TestCase
with_settings :notified_events => %w(issue_assigned_to_updated) do
assert issue.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_should_not_send_email_notification_without_issue_assignee_updated
@@ -157,7 +157,7 @@ class JournalObserverTest < ActiveSupport::TestCase
with_settings :notified_events => %w(issue_priority_updated) do
assert issue.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_create_should_not_send_email_notification_without_issue_priority_updated
diff --git a/test/unit/journal_test.rb b/test/unit/journal_test.rb
index cca405a2e..9bbedd1d5 100644
--- a/test/unit/journal_test.rb
+++ b/test/unit/journal_test.rb
@@ -50,7 +50,7 @@ class JournalTest < ActiveSupport::TestCase
journal = issue.init_journal(user, issue)
assert journal.save
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_should_not_save_journal_with_blank_notes_and_no_details
diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb
index 401198fed..8aa2cdbe8 100644
--- a/test/unit/mail_handler_test.rb
+++ b/test/unit/mail_handler_test.rb
@@ -440,10 +440,11 @@ class MailHandlerTest < ActiveSupport::TestCase
)
end
- # only 1 email for the new issue notification
- assert_equal 1, ActionMailer::Base.deliveries.size
- email = ActionMailer::Base.deliveries.first
- assert_include 'Ticket by unknown user', email.subject
+ # only 2 emails for the new issue notification
+ assert_equal 2, ActionMailer::Base.deliveries.size
+ ActionMailer::Base.deliveries.each do |email|
+ assert_include 'Ticket by unknown user', email.subject
+ end
end
def test_created_user_should_have_mail_notification_to_none_with_no_notification_option
@@ -877,7 +878,7 @@ class MailHandlerTest < ActiveSupport::TestCase
def test_update_issue_should_send_email_notification
journal = submit_email('ticket_reply.eml')
assert journal.is_a?(Journal)
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 3, ActionMailer::Base.deliveries.size
end
def test_update_issue_should_not_set_defaults
diff --git a/test/unit/mailer_test.rb b/test/unit/mailer_test.rb
index 049db8198..0908e9e63 100644
--- a/test/unit/mailer_test.rb
+++ b/test/unit/mailer_test.rb
@@ -412,11 +412,15 @@ class MailerTest < ActiveSupport::TestCase
journal.save!
Role.find(2).add_permission! :view_private_notes
- Mailer.deliver_issue_edit(journal)
- assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort
+ assert_difference 'ActionMailer::Base.deliveries.size', 2 do
+ Mailer.deliver_issue_edit(journal)
+ end
+ assert_equal %w(dlopper@somenet.foo jsmith@somenet.foo), ActionMailer::Base.deliveries.last(2).flat_map(&:bcc).sort
Role.find(2).remove_permission! :view_private_notes
- Mailer.deliver_issue_edit(journal)
+ assert_difference 'ActionMailer::Base.deliveries.size', 1 do
+ Mailer.deliver_issue_edit(journal)
+ end
assert_equal %w(jsmith@somenet.foo), ActionMailer::Base.deliveries.last.bcc.sort
end
@@ -534,7 +538,7 @@ class MailerTest < ActiveSupport::TestCase
def test_wiki_content_added
content = WikiContent.find(1)
with_each_language_as_default do
- assert_difference 'ActionMailer::Base.deliveries.size' do
+ assert_difference 'ActionMailer::Base.deliveries.size', 2 do
assert Mailer.wiki_content_added(content).deliver
assert_select_email do
assert_select 'a[href=?]',
@@ -548,7 +552,7 @@ class MailerTest < ActiveSupport::TestCase
def test_wiki_content_updated
content = WikiContent.find(1)
with_each_language_as_default do
- assert_difference 'ActionMailer::Base.deliveries.size' do
+ assert_difference 'ActionMailer::Base.deliveries.size', 2 do
assert Mailer.wiki_content_updated(content).deliver
assert_select_email do
assert_select 'a[href=?]',
diff --git a/test/unit/news_test.rb b/test/unit/news_test.rb
index 7899ec2c2..03a868a91 100644
--- a/test/unit/news_test.rb
+++ b/test/unit/news_test.rb
@@ -34,7 +34,7 @@ class NewsTest < ActiveSupport::TestCase
with_settings :notified_events => %w(news_added) do
assert news.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
+ assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_should_include_news_for_projects_with_news_enabled
diff --git a/test/unit/repository_test.rb b/test/unit/repository_test.rb
index 59f011f9f..9552d0948 100644
--- a/test/unit/repository_test.rb
+++ b/test/unit/repository_test.rb
@@ -262,14 +262,15 @@ class RepositoryTest < ActiveSupport::TestCase
assert_equal User.find_by_login('dlopper'), journal.user
assert_equal 'Applied in changeset r2.', journal.notes
- # 2 email notifications
- assert_equal 2, ActionMailer::Base.deliveries.size
- mail = ActionMailer::Base.deliveries.first
- assert_not_nil mail
- assert mail.subject.starts_with?(
- "[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
- assert_mail_body_match(
- "Status changed from #{old_status} to #{fixed_issue.status}", mail)
+ # 5 email notifications, 2 for #1, 3 for #2
+ assert_equal 5, ActionMailer::Base.deliveries.size
+ ActionMailer::Base.deliveries.first(2).each do |mail|
+ assert_not_nil mail
+ assert mail.subject.starts_with?(
+ "[#{fixed_issue.project.name} - #{fixed_issue.tracker.name} ##{fixed_issue.id}]")
+ assert_mail_body_match(
+ "Status changed from #{old_status} to #{fixed_issue.status}", mail)
+ end
# ignoring commits referencing an issue of another project
assert_equal [], Issue.find(4).changesets
diff --git a/test/unit/wiki_content_test.rb b/test/unit/wiki_content_test.rb
index d3cb74427..1b6dcf095 100644
--- a/test/unit/wiki_content_test.rb
+++ b/test/unit/wiki_content_test.rb
@@ -53,8 +53,10 @@ class WikiContentTest < ActiveSupport::TestCase
assert page.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
- assert_include 'wiki page has been added', mail_body(ActionMailer::Base.deliveries.last)
+ assert_equal 2, ActionMailer::Base.deliveries.size
+ ActionMailer::Base.deliveries.each do |mail|
+ assert_include 'wiki page has been added', mail_body(mail)
+ end
end
def test_update_should_be_versioned
@@ -100,8 +102,10 @@ class WikiContentTest < ActiveSupport::TestCase
assert content.save
end
- assert_equal 1, ActionMailer::Base.deliveries.size
- assert_include 'wiki page has been updated', mail_body(ActionMailer::Base.deliveries.last)
+ assert_equal 2, ActionMailer::Base.deliveries.size
+ ActionMailer::Base.deliveries.each do |mail|
+ assert_include 'wiki page has been updated', mail_body(mail)
+ end
end
def test_fetch_history