Feature #26791 » 0001-Send-individual-emails-for-each-mail-recipient_v2.patch
| app/models/email_address.rb | ||
|---|---|---|
| 52 | 52 |
# in that case, the user is just being created and |
| 53 | 53 |
# should not receive this email. |
| 54 | 54 |
if user.mails != [address] |
| 55 |
deliver_security_notification(user,
|
|
| 55 |
deliver_security_notification( |
|
| 56 | 56 |
message: :mail_body_security_notification_add, |
| 57 | 57 |
field: :field_mail, |
| 58 | 58 |
value: address |
| ... | ... | |
| 63 | 63 |
# send a security notification to user that an email has been changed (notified/not notified) |
| 64 | 64 |
def deliver_security_notification_update |
| 65 | 65 |
if saved_change_to_address? |
| 66 |
recipients = [user, address_before_last_save] |
|
| 67 | 66 |
options = {
|
| 67 |
recipients: [address_before_last_save], |
|
| 68 | 68 |
message: :mail_body_security_notification_change_to, |
| 69 | 69 |
field: :field_mail, |
| 70 | 70 |
value: address |
| 71 | 71 |
} |
| 72 | 72 |
elsif saved_change_to_notify? |
| 73 |
recipients = [user, address] |
|
| 74 | 73 |
options = {
|
| 74 |
recipients: [address], |
|
| 75 | 75 |
message: notify_before_last_save ? :mail_body_security_notification_notify_disabled : :mail_body_security_notification_notify_enabled, |
| 76 | 76 |
value: address |
| 77 | 77 |
} |
| 78 | 78 |
end |
| 79 |
deliver_security_notification(recipients, options)
|
|
| 79 |
deliver_security_notification(options) |
|
| 80 | 80 |
end |
| 81 | 81 | |
| 82 | 82 |
# send a security notification to user that an email address was deleted |
| 83 | 83 |
def deliver_security_notification_destroy |
| 84 |
deliver_security_notification([user, address], |
|
| 84 |
deliver_security_notification( |
|
| 85 |
recipients: [address], |
|
| 85 | 86 |
message: :mail_body_security_notification_remove, |
| 86 | 87 |
field: :field_mail, |
| 87 | 88 |
value: address |
| ... | ... | |
| 89 | 90 |
end |
| 90 | 91 | |
| 91 | 92 |
# generic method to send security notifications for email addresses |
| 92 |
def deliver_security_notification(recipients, options={})
|
|
| 93 |
Mailer.security_notification(recipients,
|
|
| 93 |
def deliver_security_notification(options={})
|
|
| 94 |
Mailer.security_notification(user,
|
|
| 94 | 95 |
options.merge( |
| 95 | 96 |
title: :label_my_account, |
| 96 | 97 |
url: {controller: 'my', action: 'account'}
|
| app/models/mailer.rb | ||
|---|---|---|
| 26 | 26 |
include Redmine::I18n |
| 27 | 27 |
include Roadie::Rails::Automatic |
| 28 | 28 | |
| 29 |
# This class wraps multiple generated `Mail::Message` objects and allows to |
|
| 30 |
# deliver them all at once. It is usually used to handle multiple mails for |
|
| 31 |
# different receivers created by a single mail event. The wrapped mails can |
|
| 32 |
# then be delivered in one go. |
|
| 33 |
# |
|
| 34 |
# The public interface of the class resembles a single mail message. You can |
|
| 35 |
# directly use any of the deliver_* methods to send the contained messages |
|
| 36 |
# now or later. |
|
| 37 |
class MultiMessage |
|
| 38 |
attr_reader :mails |
|
| 39 | ||
| 40 |
# @param mails [Array<Mail, Proc>] an Array of mails or Procs which create |
|
| 41 |
# mail objects and allow to call a method on it. |
|
| 42 |
def initialize(action, *args) |
|
| 43 |
@action = action |
|
| 44 |
@args = args |
|
| 45 | ||
| 46 |
@mails = [] |
|
| 47 |
end |
|
| 48 | ||
| 49 |
def for(users) |
|
| 50 |
Array.wrap(users).each do |user| |
|
| 51 |
@mails << ActionMailer::MessageDelivery.new(Mailer, @action, user, *@args) |
|
| 52 |
end |
|
| 53 |
self |
|
| 54 |
end |
|
| 55 | ||
| 56 |
def deliver_later(options = {})
|
|
| 57 |
enqueue_delivery :deliver_now, options |
|
| 58 |
end |
|
| 59 | ||
| 60 |
def deliver_later!(options = {})
|
|
| 61 |
enqueue_delivery :deliver_now!, options |
|
| 62 |
end |
|
| 63 | ||
| 64 |
def processed? |
|
| 65 |
@mails.any?(&:processed?) |
|
| 66 |
end |
|
| 67 | ||
| 68 |
# @return [Object] the delivery method of the first mail. |
|
| 69 |
# Usually, this is the very same value for all mails and matches the |
|
| 70 |
# default value of the Mailer class |
|
| 71 |
def delivery_method |
|
| 72 |
(@mails.first || ActionMailer::Base::NullMail.new).delivery_method |
|
| 73 |
end |
|
| 74 | ||
| 75 |
# @return [ActionMailer::Base] the delivery handler of the first mail. This |
|
| 76 |
# is always the `Mailer` class. |
|
| 77 |
def delivery_handler |
|
| 78 |
(@mails.first || ActionMailer::Base::NullMail.new).delivery_handler |
|
| 79 |
end |
|
| 80 | ||
| 81 |
private |
|
| 82 | ||
| 83 |
def method_missing(method, *args, &block) |
|
| 84 |
if method =~ /\Adeliver([_!?]|\z)/ |
|
| 85 |
@mails.each do |mail| |
|
| 86 |
mail.public_send(method, *args, &block) |
|
| 87 |
end |
|
| 88 |
else |
|
| 89 |
super |
|
| 90 |
end |
|
| 91 |
end |
|
| 92 | ||
| 93 |
def respond_to_missing(method, *args) |
|
| 94 |
method =~ /\Adeliver([_!?]|\z)/ || method == 'processed?' || super |
|
| 95 |
end |
|
| 96 | ||
| 97 |
# This method is slightly adapted from ActionMailer::MessageDelivery |
|
| 98 |
def enqueue_delivery(delivery_method, options = {})
|
|
| 99 |
if processed? |
|
| 100 |
::Kernel.raise "You've accessed the message before asking to " \ |
|
| 101 |
"deliver it later, so you may have made local changes that would " \ |
|
| 102 |
"be silently lost if we enqueued a job to deliver it. Why? Only " \ |
|
| 103 |
"the mailer method *arguments* are passed with the delivery job! " \ |
|
| 104 |
"Do not access the message in any way if you mean to deliver it " \ |
|
| 105 |
"later. Workarounds: 1. don't touch the message before calling " \ |
|
| 106 |
"#deliver_later, 2. only touch the message *within your mailer " \ |
|
| 107 |
"method*, or 3. use a custom Active Job instead of #deliver_later." |
|
| 108 |
else |
|
| 109 |
args = 'Mailer', @action.to_s, delivery_method.to_s, *@args |
|
| 110 |
::ActionMailer::DeliveryJob.set(options).perform_later(*args) |
|
| 111 |
end |
|
| 112 |
end |
|
| 113 |
end |
|
| 114 | ||
| 115 |
def process(action, *args) |
|
| 116 |
user = args.shift |
|
| 117 |
raise ArgumentError, "First argument has to be a user, was #{user.inspect}" unless user.is_a?(User)
|
|
| 118 | ||
| 119 |
initial_user = User.current |
|
| 120 |
initial_language = ::I18n.locale |
|
| 121 |
begin |
|
| 122 |
User.current = user |
|
| 123 | ||
| 124 |
lang = find_language(user.language) if user.logged? |
|
| 125 |
lang ||= Setting.default_language |
|
| 126 |
set_language_if_valid(lang) |
|
| 127 | ||
| 128 |
super(action, *args) |
|
| 129 |
ensure |
|
| 130 |
User.current = initial_user |
|
| 131 |
::I18n.locale = initial_language |
|
| 132 |
end |
|
| 133 |
end |
|
| 134 | ||
| 135 | ||
| 29 | 136 |
def self.default_url_options |
| 30 | 137 |
options = {:protocol => Setting.protocol}
|
| 31 | 138 |
if Setting.host_name.to_s =~ /\A(https?\:\/\/)?(.+?)(\:(\d+))?(\/.+)?\z/i |
| ... | ... | |
| 39 | 146 |
options |
| 40 | 147 |
end |
| 41 | 148 | |
| 42 |
# Builds a mail for notifying to_users and cc_users about a new issue |
|
| 43 |
def issue_add(issue, to_users, cc_users) |
|
| 149 |
# Builds a mail for notifying the current user about a new issue |
|
| 150 |
# |
|
| 151 |
# Example: |
|
| 152 |
# issue_add(issue) => Mail::Message object |
|
| 153 |
def issue_add(issue) |
|
| 44 | 154 |
redmine_headers 'Project' => issue.project.identifier, |
| 45 | 155 |
'Issue-Id' => issue.id, |
| 46 | 156 |
'Issue-Author' => issue.author.login |
| ... | ... | |
| 49 | 159 |
references issue |
| 50 | 160 |
@author = issue.author |
| 51 | 161 |
@issue = issue |
| 52 |
@users = to_users + cc_users
|
|
| 162 |
@users = [User.current]
|
|
| 53 | 163 |
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue) |
| 54 |
mail :to => to_users, |
|
| 55 |
:cc => cc_users, |
|
| 164 |
mail :to => User.current, |
|
| 56 | 165 |
:subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}"
|
| 57 | 166 |
end |
| 58 | 167 | |
| 59 | 168 |
# Notifies users about a new issue |
| 169 |
# |
|
| 170 |
# Example: |
|
| 171 |
# Mailer.issue_add(journal).deliver => sends emails to the project's recipients |
|
| 172 |
def self.issue_add(issue) |
|
| 173 |
users = issue.notified_users | issue.notified_watchers |
|
| 174 |
MultiMessage.new(:issue_add, issue).for(users) |
|
| 175 |
end |
|
| 176 | ||
| 177 |
# Notifies users about a new issue |
|
| 178 |
# |
|
| 179 |
# Example: |
|
| 180 |
# Mailer.deliver_issue_add(issue) => sends emails to the project's recipients |
|
| 60 | 181 |
def self.deliver_issue_add(issue) |
| 61 |
to = issue.notified_users |
|
| 62 |
cc = issue.notified_watchers - to |
|
| 63 |
issue.each_notification(to + cc) do |users| |
|
| 64 |
issue_add(issue, to & users, cc & users).deliver |
|
| 65 |
end |
|
| 182 |
issue_add(issue).deliver |
|
| 66 | 183 |
end |
| 67 | 184 | |
| 68 |
# Builds a mail for notifying to_users and cc_users about an issue update |
|
| 69 |
def issue_edit(journal, to_users, cc_users) |
|
| 185 |
# Builds a mail for notifying the current user about an issue update |
|
| 186 |
# |
|
| 187 |
# Example: |
|
| 188 |
# issue_edit(journal) => Mail::Message object |
|
| 189 |
def issue_edit(journal) |
|
| 70 | 190 |
issue = journal.journalized |
| 71 | 191 |
redmine_headers 'Project' => issue.project.identifier, |
| 72 | 192 |
'Issue-Id' => issue.id, |
| ... | ... | |
| 79 | 199 |
s << "(#{issue.status.name}) " if journal.new_value_for('status_id')
|
| 80 | 200 |
s << issue.subject |
| 81 | 201 |
@issue = issue |
| 82 |
@users = to_users + cc_users
|
|
| 202 |
@users = [User.current]
|
|
| 83 | 203 |
@journal = journal |
| 84 |
@journal_details = journal.visible_details(@users.first)
|
|
| 204 |
@journal_details = journal.visible_details |
|
| 85 | 205 |
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}")
|
| 86 |
mail :to => to_users, |
|
| 87 |
:cc => cc_users,
|
|
| 206 | ||
| 207 |
mail :to => User.current,
|
|
| 88 | 208 |
:subject => s |
| 89 | 209 |
end |
| 90 | 210 | |
| 211 |
# Build a MultiMessage to notify users about an issue update |
|
| 212 |
# |
|
| 213 |
# Example: |
|
| 214 |
# Mailer.issue_edit(journal).deliver => sends emails to the project's recipients |
|
| 215 |
def self.issue_edit(journal) |
|
| 216 |
users = journal.notified_users |
|
| 217 |
users |= journal.notified_watchers |
|
| 218 |
users.select! do |user| |
|
| 219 |
journal.notes? || journal.visible_details(user).any? |
|
| 220 |
end |
|
| 221 |
MultiMessage.new(:issue_edit, journal).for(users) |
|
| 222 |
end |
|
| 223 | ||
| 91 | 224 |
# Notifies users about an issue update |
| 225 |
# |
|
| 226 |
# Example: |
|
| 227 |
# Mailer.deliver_issue_edit(journal) => sends emails to the project's recipients |
|
| 92 | 228 |
def self.deliver_issue_edit(journal) |
| 93 |
issue = journal.journalized.reload |
|
| 94 |
to = journal.notified_users |
|
| 95 |
cc = journal.notified_watchers - to |
|
| 96 |
journal.each_notification(to + cc) do |users| |
|
| 97 |
issue.each_notification(users) do |users2| |
|
| 98 |
issue_edit(journal, to & users2, cc & users2).deliver |
|
| 99 |
end |
|
| 100 |
end |
|
| 229 |
issue_edit(journal).deliver |
|
| 101 | 230 |
end |
| 102 | 231 | |
| 103 |
def reminder(user, issues, days) |
|
| 104 |
set_language_if_valid user.language |
|
| 232 |
# Builds a Mail::Message object used to send en email reminder to the current |
|
| 233 |
# user about their due issues. |
|
| 234 |
# |
|
| 235 |
# Example: |
|
| 236 |
# reminder(issues, days) => Mail::Message object |
|
| 237 |
def reminder(issues, days) |
|
| 105 | 238 |
@issues = issues |
| 106 | 239 |
@days = days |
| 107 | 240 |
@issues_url = url_for(:controller => 'issues', :action => 'index', |
| 108 |
:set_filter => 1, :assigned_to_id => user.id,
|
|
| 241 |
:set_filter => 1, :assigned_to_id => User.current.id,
|
|
| 109 | 242 |
:sort => 'due_date:asc') |
| 110 |
mail :to => user,
|
|
| 243 |
mail :to => User.current,
|
|
| 111 | 244 |
:subject => l(:mail_subject_reminder, :count => issues.size, :days => days) |
| 112 | 245 |
end |
| 113 | 246 | |
| 114 |
# Builds a Mail::Message object used to email users belonging to the added document's project. |
|
| 247 |
# Builds a Mail::Message object used to email the given user about their due |
|
| 248 |
# issues |
|
| 249 |
# |
|
| 250 |
# Example: |
|
| 251 |
# Mailer.reminder(user, issues, days, author).deliver => sends an email to the user |
|
| 252 |
def self.reminder(user, issues, days) |
|
| 253 |
MultiMessage.new(:reminder, issues, days).for(user) |
|
| 254 |
end |
|
| 255 | ||
| 256 |
# Builds a Mail::Message object used to email the current user that a document |
|
| 257 |
# was added. |
|
| 115 | 258 |
# |
| 116 | 259 |
# Example: |
| 117 |
# document_added(document) => Mail::Message object |
|
| 118 |
# Mailer.document_added(document).deliver => sends an email to the document's project recipients |
|
| 119 |
def document_added(document) |
|
| 260 |
# document_added(document, author) => Mail::Message object |
|
| 261 |
def document_added(document, author) |
|
| 120 | 262 |
redmine_headers 'Project' => document.project.identifier |
| 121 |
@author = User.current
|
|
| 263 |
@author = author
|
|
| 122 | 264 |
@document = document |
| 123 | 265 |
@document_url = url_for(:controller => 'documents', :action => 'show', :id => document) |
| 124 |
mail :to => document.notified_users,
|
|
| 266 |
mail :to => User.current,
|
|
| 125 | 267 |
:subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
|
| 126 | 268 |
end |
| 127 | 269 | |
| 128 |
# Builds a Mail::Message object used to email recipients of a project when an attachements are added. |
|
| 270 |
# Build a MultiMessage to notify users about an added document. |
|
| 271 |
# |
|
| 272 |
# Example: |
|
| 273 |
# Mailer.document_added(document).deliver => sends emails to the document's project recipients |
|
| 274 |
def self.document_added(document) |
|
| 275 |
users = document.notified_users |
|
| 276 |
MultiMessage.new(:document_added, document, User.current).for(users) |
|
| 277 |
end |
|
| 278 | ||
| 279 |
# Builds a Mail::Message object used to email the current user when |
|
| 280 |
# attachements are added. |
|
| 129 | 281 |
# |
| 130 | 282 |
# Example: |
| 131 | 283 |
# attachments_added(attachments) => Mail::Message object |
| 132 |
# Mailer.attachments_added(attachments).deliver => sends an email to the project's recipients |
|
| 133 | 284 |
def attachments_added(attachments) |
| 134 | 285 |
container = attachments.first.container |
| 135 | 286 |
added_to = '' |
| ... | ... | |
| 139 | 290 |
when 'Project' |
| 140 | 291 |
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container) |
| 141 | 292 |
added_to = "#{l(:label_project)}: #{container}"
|
| 142 |
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
|
|
| 143 | 293 |
when 'Version' |
| 144 | 294 |
added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project) |
| 145 | 295 |
added_to = "#{l(:label_version)}: #{container.name}"
|
| 146 |
recipients = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
|
|
| 147 | 296 |
when 'Document' |
| 148 | 297 |
added_to_url = url_for(:controller => 'documents', :action => 'show', :id => container.id) |
| 149 | 298 |
added_to = "#{l(:label_document)}: #{container.title}"
|
| 150 |
recipients = container.notified_users |
|
| 151 | 299 |
end |
| 152 | 300 |
redmine_headers 'Project' => container.project.identifier |
| 153 | 301 |
@attachments = attachments |
| 154 | 302 |
@added_to = added_to |
| 155 | 303 |
@added_to_url = added_to_url |
| 156 |
mail :to => recipients,
|
|
| 304 |
mail :to => User.current,
|
|
| 157 | 305 |
:subject => "[#{container.project.name}] #{l(:label_attachment_new)}"
|
| 158 | 306 |
end |
| 159 | 307 | |
| 160 |
# Builds a Mail::Message object used to email recipients of a news' project when a news item is added. |
|
| 308 |
# Build a MultiMessage to notify users about an added attachment |
|
| 309 |
# |
|
| 310 |
# Example: |
|
| 311 |
# Mailer.attachments_added(attachments).deliver => sends emails to the project's recipients |
|
| 312 |
def self.attachments_added(attachments) |
|
| 313 |
container = attachments.first.container |
|
| 314 |
case container.class.name |
|
| 315 |
when 'Project', 'Version' |
|
| 316 |
users = container.project.notified_users.select {|user| user.allowed_to?(:view_files, container.project)}
|
|
| 317 |
when 'Document' |
|
| 318 |
users = container.notified_users |
|
| 319 |
end |
|
| 320 | ||
| 321 |
MultiMessage.new(:attachments_added, attachments).for(users) |
|
| 322 |
end |
|
| 323 | ||
| 324 |
# Builds a Mail::Message object used to email the current user when a news |
|
| 325 |
# item is added. |
|
| 161 | 326 |
# |
| 162 | 327 |
# Example: |
| 163 | 328 |
# news_added(news) => Mail::Message object |
| 164 |
# Mailer.news_added(news).deliver => sends an email to the news' project recipients |
|
| 165 | 329 |
def news_added(news) |
| 166 | 330 |
redmine_headers 'Project' => news.project.identifier |
| 167 | 331 |
@author = news.author |
| ... | ... | |
| 169 | 333 |
references news |
| 170 | 334 |
@news = news |
| 171 | 335 |
@news_url = url_for(:controller => 'news', :action => 'show', :id => news) |
| 172 |
mail :to => news.notified_users, |
|
| 173 |
:cc => news.notified_watchers_for_added_news, |
|
| 336 |
mail :to => User.current, |
|
| 174 | 337 |
:subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
| 175 | 338 |
end |
| 176 | 339 | |
| 177 |
# Builds a Mail::Message object used to email recipients of a news' project when a news comment is added. |
|
| 340 |
# Build a MultiMessage to notify users about a new news item |
|
| 341 |
# |
|
| 342 |
# Example: |
|
| 343 |
# Mailer.news_added(news).deliver => sends emails to the news' project recipients |
|
| 344 |
def self.news_added(news) |
|
| 345 |
users = news.notified_users | news.notified_watchers_for_added_news |
|
| 346 |
MultiMessage.new(:news_added, news).for(users) |
|
| 347 |
end |
|
| 348 | ||
| 349 |
# Builds a Mail::Message object used to email the current user when a news |
|
| 350 |
# comment is added. |
|
| 178 | 351 |
# |
| 179 | 352 |
# Example: |
| 180 | 353 |
# news_comment_added(comment) => Mail::Message object |
| 181 |
# Mailer.news_comment_added(comment) => sends an email to the news' project recipients |
|
| 182 | 354 |
def news_comment_added(comment) |
| 183 | 355 |
news = comment.commented |
| 184 | 356 |
redmine_headers 'Project' => news.project.identifier |
| ... | ... | |
| 188 | 360 |
@news = news |
| 189 | 361 |
@comment = comment |
| 190 | 362 |
@news_url = url_for(:controller => 'news', :action => 'show', :id => news) |
| 191 |
mail :to => news.notified_users, |
|
| 192 |
:cc => news.notified_watchers, |
|
| 363 |
mail :to => User.current, |
|
| 193 | 364 |
:subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
|
| 194 | 365 |
end |
| 195 | 366 | |
| 196 |
# Builds a Mail::Message object used to email the recipients of the specified message that was posted. |
|
| 367 |
# Build a MultiMessage to notify users about a new news comment |
|
| 368 |
# |
|
| 369 |
# Example: |
|
| 370 |
# Mailer.news_comment_added(comment).deliver => sends emails to the news' project recipients |
|
| 371 |
def self.news_comment_added(comment) |
|
| 372 |
news = comment.commented |
|
| 373 |
users = news.notified_users | news.notified_watchers |
|
| 374 | ||
| 375 |
MultiMessage.new(:news_comment_added, comment).for(users) |
|
| 376 |
end |
|
| 377 | ||
| 378 |
# Builds a Mail::Message object used to email the current user that the |
|
| 379 |
# specified message was posted. |
|
| 197 | 380 |
# |
| 198 | 381 |
# Example: |
| 199 | 382 |
# message_posted(message) => Mail::Message object |
| 200 |
# Mailer.message_posted(message).deliver => sends an email to the recipients |
|
| 201 | 383 |
def message_posted(message) |
| 202 | 384 |
redmine_headers 'Project' => message.project.identifier, |
| 203 | 385 |
'Topic-Id' => (message.parent_id || message.id) |
| 204 | 386 |
@author = message.author |
| 205 | 387 |
message_id message |
| 206 | 388 |
references message.root |
| 207 |
recipients = message.notified_users |
|
| 208 |
cc = ((message.root.notified_watchers + message.board.notified_watchers).uniq - recipients) |
|
| 209 | 389 |
@message = message |
| 210 | 390 |
@message_url = url_for(message.event_url) |
| 211 |
mail :to => recipients, |
|
| 212 |
:cc => cc, |
|
| 391 |
mail :to => User.current, |
|
| 213 | 392 |
:subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
|
| 214 | 393 |
end |
| 215 | 394 | |
| 216 |
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added. |
|
| 395 |
# Build a MultiMessage to notify users about a new forum message |
|
| 396 |
# |
|
| 397 |
# Example: |
|
| 398 |
# Mailer.message_posted(message).deliver => sends emails to the recipients |
|
| 399 |
def self.message_posted(message) |
|
| 400 |
users = message.notified_users |
|
| 401 |
users |= message.root.notified_watchers |
|
| 402 |
users |= message.board.notified_watchers |
|
| 403 | ||
| 404 |
MultiMessage.new(:message_posted, message).for(users) |
|
| 405 |
end |
|
| 406 | ||
| 407 |
# Builds a Mail::Message object used to email the current user that the |
|
| 408 |
# specified wiki content was added. |
|
| 217 | 409 |
# |
| 218 | 410 |
# Example: |
| 219 | 411 |
# wiki_content_added(wiki_content) => Mail::Message object |
| 220 |
# Mailer.wiki_content_added(wiki_content).deliver => sends an email to the project's recipients |
|
| 221 | 412 |
def wiki_content_added(wiki_content) |
| 222 | 413 |
redmine_headers 'Project' => wiki_content.project.identifier, |
| 223 | 414 |
'Wiki-Page-Id' => wiki_content.page.id |
| 224 | 415 |
@author = wiki_content.author |
| 225 | 416 |
message_id wiki_content |
| 226 |
recipients = wiki_content.notified_users |
|
| 227 |
cc = wiki_content.page.wiki.notified_watchers - recipients |
|
| 228 | 417 |
@wiki_content = wiki_content |
| 229 | 418 |
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show', |
| 230 | 419 |
:project_id => wiki_content.project, |
| 231 | 420 |
:id => wiki_content.page.title) |
| 232 |
mail :to => recipients, |
|
| 233 |
:cc => cc, |
|
| 421 |
mail :to => User.current, |
|
| 234 | 422 |
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_added, :id => wiki_content.page.pretty_title)}"
|
| 235 | 423 |
end |
| 236 | 424 | |
| 237 |
# Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was updated. |
|
| 425 |
# Build a MultiMessage to notify users about added wiki content |
|
| 426 |
# |
|
| 427 |
# Example: |
|
| 428 |
# Mailer.wiki_content_added(wiki_content).deliver => send emails to the project's recipients |
|
| 429 |
def self.wiki_content_added(wiki_content) |
|
| 430 |
users = wiki_content.notified_users | wiki_content.page.wiki.notified_watchers |
|
| 431 |
MultiMessage.new(:wiki_content_added, wiki_content).for(users) |
|
| 432 |
end |
|
| 433 | ||
| 434 |
# Builds a Mail::Message object used to email the current user about an update |
|
| 435 |
# of the specified wiki content. |
|
| 238 | 436 |
# |
| 239 | 437 |
# Example: |
| 240 | 438 |
# wiki_content_updated(wiki_content) => Mail::Message object |
| 241 |
# Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients |
|
| 242 | 439 |
def wiki_content_updated(wiki_content) |
| 243 | 440 |
redmine_headers 'Project' => wiki_content.project.identifier, |
| 244 | 441 |
'Wiki-Page-Id' => wiki_content.page.id |
| 245 | 442 |
@author = wiki_content.author |
| 246 | 443 |
message_id wiki_content |
| 247 |
recipients = wiki_content.notified_users |
|
| 248 |
cc = wiki_content.page.wiki.notified_watchers + wiki_content.page.notified_watchers - recipients |
|
| 249 | 444 |
@wiki_content = wiki_content |
| 250 | 445 |
@wiki_content_url = url_for(:controller => 'wiki', :action => 'show', |
| 251 | 446 |
:project_id => wiki_content.project, |
| ... | ... | |
| 253 | 448 |
@wiki_diff_url = url_for(:controller => 'wiki', :action => 'diff', |
| 254 | 449 |
:project_id => wiki_content.project, :id => wiki_content.page.title, |
| 255 | 450 |
:version => wiki_content.version) |
| 256 |
mail :to => recipients, |
|
| 257 |
:cc => cc, |
|
| 451 |
mail :to => User.current, |
|
| 258 | 452 |
:subject => "[#{wiki_content.project.name}] #{l(:mail_subject_wiki_content_updated, :id => wiki_content.page.pretty_title)}"
|
| 259 | 453 |
end |
| 260 | 454 | |
| 261 |
# Builds a Mail::Message object used to email the specified user their account information.
|
|
| 455 |
# Build a MultiMessage to notify users about the update of the specified wiki content
|
|
| 262 | 456 |
# |
| 263 | 457 |
# Example: |
| 264 |
# account_information(user, password) => Mail::Message object |
|
| 265 |
# Mailer.account_information(user, password).deliver => sends account information to the user |
|
| 266 |
def account_information(user, password) |
|
| 267 |
set_language_if_valid user.language |
|
| 268 |
@user = user |
|
| 458 |
# Mailer.wiki_content_updated(wiki_content).deliver => sends an email to the project's recipients |
|
| 459 |
def self.wiki_content_updated(wiki_content) |
|
| 460 |
users = wiki_content.notified_users |
|
| 461 |
users |= wiki_content.page.notified_watchers |
|
| 462 |
users |= wiki_content.page.wiki.notified_watchers |
|
| 463 | ||
| 464 |
MultiMessage.new(:wiki_content_updated, wiki_content).for(users) |
|
| 465 |
end |
|
| 466 | ||
| 467 |
# Builds a Mail::Message object used to email the current user their account information. |
|
| 468 |
# |
|
| 469 |
# Example: |
|
| 470 |
# account_information(password) => Mail::Message object |
|
| 471 |
def account_information(password) |
|
| 472 |
@user = User.current |
|
| 269 | 473 |
@password = password |
| 270 | 474 |
@login_url = url_for(:controller => 'account', :action => 'login') |
| 271 |
mail :to => user.mail,
|
|
| 475 |
mail :to => User.current.mail,
|
|
| 272 | 476 |
:subject => l(:mail_subject_register, Setting.app_title) |
| 273 | 477 |
end |
| 274 | 478 | |
| 275 |
# Builds a Mail::Message object used to email all active administrators of an account activation request. |
|
| 479 |
# Build a MultiMessage to mail a user their account information |
|
| 480 |
# |
|
| 481 |
# Example: |
|
| 482 |
# Mailer.account_information(user, password).deliver => sends account information to the user |
|
| 483 |
def self.account_information(user, password) |
|
| 484 |
MultiMessage.new(:account_information, password).for(user) |
|
| 485 |
end |
|
| 486 | ||
| 487 |
# Builds a Mail::Message object used to email the current user about an account activation request. |
|
| 276 | 488 |
# |
| 277 | 489 |
# Example: |
| 278 | 490 |
# account_activation_request(user) => Mail::Message object |
| 279 |
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators |
|
| 280 | 491 |
def account_activation_request(user) |
| 281 |
# Send the email to all active administrators |
|
| 282 |
recipients = User.active.where(:admin => true) |
|
| 283 | 492 |
@user = user |
| 284 | 493 |
@url = url_for(:controller => 'users', :action => 'index', |
| 285 | 494 |
:status => User::STATUS_REGISTERED, |
| 286 | 495 |
:sort_key => 'created_on', :sort_order => 'desc') |
| 287 |
mail :to => recipients,
|
|
| 496 |
mail :to => User.current,
|
|
| 288 | 497 |
:subject => l(:mail_subject_account_activation_request, Setting.app_title) |
| 289 | 498 |
end |
| 290 | 499 | |
| 291 |
# Builds a Mail::Message object used to email the specified user that their account was activated by an administrator.
|
|
| 500 |
# Build a MultiMessage to email all active administrators of an account activation request.
|
|
| 292 | 501 |
# |
| 293 | 502 |
# Example: |
| 294 |
# account_activated(user) => Mail::Message object |
|
| 295 |
# Mailer.account_activated(user).deliver => sends an email to the registered user |
|
| 296 |
def account_activated(user) |
|
| 297 |
set_language_if_valid user.language |
|
| 298 |
@user = user |
|
| 503 |
# Mailer.account_activation_request(user).deliver => sends an email to all active administrators |
|
| 504 |
def self.account_activation_request(user) |
|
| 505 |
# Send the email to all active administrators |
|
| 506 |
users = User.active.where(:admin => true) |
|
| 507 |
MultiMessage.new(:account_activation_request, user).for(users) |
|
| 508 |
end |
|
| 509 | ||
| 510 |
# Builds a Mail::Message object used to email the account of the current user |
|
| 511 |
# was activated by an administrator. |
|
| 512 |
# |
|
| 513 |
# Example: |
|
| 514 |
# account_activated => Mail::Message object |
|
| 515 |
def account_activated |
|
| 516 |
@user = User.current |
|
| 299 | 517 |
@login_url = url_for(:controller => 'account', :action => 'login') |
| 300 |
mail :to => user.mail,
|
|
| 518 |
mail :to => User.current.mail,
|
|
| 301 | 519 |
:subject => l(:mail_subject_register, Setting.app_title) |
| 302 | 520 |
end |
| 303 | 521 | |
| 522 |
# Build a MultiMessage to email the specified user that their account was |
|
| 523 |
# activated by an administrator. |
|
| 524 |
# |
|
| 525 |
# Example: |
|
| 526 |
# Mailer.account_activated(user).deliver => sends an email to the registered user |
|
| 527 |
def self.account_activated(user) |
|
| 528 |
MultiMessage.new(:account_activated).for(user) |
|
| 529 |
end |
|
| 530 | ||
| 531 |
# Builds a Mail::Message object used to email the lost password token to the |
|
| 532 |
# token's user (or a different recipient). |
|
| 533 |
# |
|
| 534 |
# Example: |
|
| 535 |
# lost_password(token) => Mail::Message object |
|
| 304 | 536 |
def lost_password(token, recipient=nil) |
| 305 |
set_language_if_valid(token.user.language) |
|
| 306 | 537 |
recipient ||= token.user.mail |
| 307 | 538 |
@token = token |
| 308 | 539 |
@url = url_for(:controller => 'account', :action => 'lost_password', :token => token.value) |
| ... | ... | |
| 310 | 541 |
:subject => l(:mail_subject_lost_password, Setting.app_title) |
| 311 | 542 |
end |
| 312 | 543 | |
| 544 |
# Build a MultiMessage to email the token's user (or a different recipient) |
|
| 545 |
# the lost password token for the token's user. |
|
| 546 |
# |
|
| 547 |
# Example: |
|
| 548 |
# Mailer.lost_password(token).deliver => sends an email to the user |
|
| 549 |
def self.lost_password(token, recipient=nil) |
|
| 550 |
MultiMessage.new(:lost_password, token, recipient).for(token.user) |
|
| 551 |
end |
|
| 552 | ||
| 313 | 553 |
# Notifies user that his password was updated |
| 314 | 554 |
def self.password_updated(user, options={})
|
| 315 | 555 |
# Don't send a notification to the dummy email address when changing the password |
| ... | ... | |
| 326 | 566 |
).deliver |
| 327 | 567 |
end |
| 328 | 568 | |
| 569 |
# Builds a Mail::Message object used to email the user activation link to the |
|
| 570 |
# token's user. |
|
| 571 |
# |
|
| 572 |
# Example: |
|
| 573 |
# register(token) => Mail::Message object |
|
| 329 | 574 |
def register(token) |
| 330 |
set_language_if_valid(token.user.language) |
|
| 331 | 575 |
@token = token |
| 332 | 576 |
@url = url_for(:controller => 'account', :action => 'activate', :token => token.value) |
| 333 | 577 |
mail :to => token.user.mail, |
| 334 | 578 |
:subject => l(:mail_subject_register, Setting.app_title) |
| 335 | 579 |
end |
| 336 | 580 | |
| 337 |
def security_notification(recipients, options={})
|
|
| 338 |
@user = Array(recipients).detect{|r| r.is_a? User }
|
|
| 339 |
set_language_if_valid(@user.try :language) |
|
| 581 |
# Build a MultiMessage to email the user activation link to the token's user. |
|
| 582 |
# |
|
| 583 |
# Example: |
|
| 584 |
# Mailer.register(token).deliver => sends an email to the token's user |
|
| 585 |
def self.register(token) |
|
| 586 |
MultiMessage.new(:register, token).for(token.user) |
|
| 587 |
end |
|
| 588 | ||
| 589 |
# Build a Mail::Message object to email the current user and the additional |
|
| 590 |
# recipients given in options[:recipients] about a security related event. |
|
| 591 |
# |
|
| 592 |
# Example: |
|
| 593 |
# security_notification(users, |
|
| 594 |
# message: :mail_body_security_notification_add, |
|
| 595 |
# field: :field_mail, |
|
| 596 |
# value: address |
|
| 597 |
# ) => Mail::Message object |
|
| 598 |
def security_notification(sender, options={})
|
|
| 599 |
@sender = sender |
|
| 600 |
redmine_headers 'Sender' => sender.login |
|
| 601 |
@user = User.current |
|
| 340 | 602 |
@message = l(options[:message], |
| 341 | 603 |
field: (options[:field] && l(options[:field])), |
| 342 | 604 |
value: options[:value] |
| ... | ... | |
| 347 | 609 |
@url = options[:url] && (options[:url].is_a?(Hash) ? url_for(options[:url]) : options[:url]) |
| 348 | 610 |
redmine_headers 'Sender' => @originator.login |
| 349 | 611 |
redmine_headers 'Url' => @url |
| 350 |
mail :to => recipients,
|
|
| 612 |
mail :to => [User.current, *options[:recipients]].uniq,
|
|
| 351 | 613 |
:subject => "[#{Setting.app_title}] #{l(:mail_subject_security_notification)}"
|
| 352 | 614 |
end |
| 353 | 615 | |
| 354 |
def settings_updated(recipients, changes) |
|
| 355 |
redmine_headers 'Sender' => User.current.login |
|
| 616 |
# Build a MultiMessage to email the given users about a security related event. |
|
| 617 |
# |
|
| 618 |
# You can specify additional recipients in options[:recipients]. These will be |
|
| 619 |
# added to all generated mails for all given users. Usually, you'll want to |
|
| 620 |
# give only a single user when setting the additional recipients. |
|
| 621 |
# |
|
| 622 |
# Example: |
|
| 623 |
# Mailer.security_notification(users, |
|
| 624 |
# message: :mail_body_security_notification_add, |
|
| 625 |
# field: :field_mail, |
|
| 626 |
# value: address |
|
| 627 |
# ).deliver => sends a security notification to the given user(s) |
|
| 628 |
def self.security_notification(users, options={})
|
|
| 629 |
sender = User.current |
|
| 630 |
MultiMessage.new(:security_notification, sender, options).for(users) |
|
| 631 |
end |
|
| 632 | ||
| 633 |
# Build a Mail::Message object to email the current user about an updated |
|
| 634 |
# setting. |
|
| 635 |
# |
|
| 636 |
# Example: |
|
| 637 |
# settings_updated(sender, [:host_name]) => Mail::Message object |
|
| 638 |
def settings_updated(sender, changes) |
|
| 639 |
@sender = sender |
|
| 640 |
redmine_headers 'Sender' => sender.login |
|
| 356 | 641 |
@changes = changes |
| 357 | 642 |
@url = url_for(controller: 'settings', action: 'index') |
| 358 |
mail :to => recipients,
|
|
| 643 |
mail :to => User.current,
|
|
| 359 | 644 |
:subject => "[#{Setting.app_title}] #{l(:mail_subject_security_notification)}"
|
| 360 | 645 |
end |
| 361 | 646 | |
| 647 |
# Build a MultiMessage to email the given users about an update of a setting. |
|
| 648 |
# |
|
| 649 |
# Example: |
|
| 650 |
# Mailer.settings_updated(users, [:host_name]).deliver => sends emails to the given user(s) about the update |
|
| 651 |
def self.settings_updated(users, changes) |
|
| 652 |
sender = User.current |
|
| 653 |
MultiMessage.new(:settings_updated, sender, changes).for(users) |
|
| 654 |
end |
|
| 655 |
|
|
| 362 | 656 |
# Notifies admins about settings changes |
| 363 | 657 |
def self.security_settings_updated(changes) |
| 364 | 658 |
return unless changes.present? |
| ... | ... | |
| 367 | 661 |
settings_updated(users, changes).deliver |
| 368 | 662 |
end |
| 369 | 663 | |
| 370 |
def test_email(user) |
|
| 371 |
set_language_if_valid(user.language) |
|
| 664 |
# Build a Mail::Message object with a test email for the current user |
|
| 665 |
# |
|
| 666 |
# Example: |
|
| 667 |
# test_email => Mail::Message object |
|
| 668 |
def test_email |
|
| 372 | 669 |
@url = url_for(:controller => 'welcome') |
| 373 |
mail :to => user.mail,
|
|
| 670 |
mail :to => User.current.mail,
|
|
| 374 | 671 |
:subject => 'Redmine test' |
| 375 | 672 |
end |
| 376 | 673 | |
| 674 |
# Build a MultiMessage to send a test email the given user |
|
| 675 |
# |
|
| 676 |
# Example: |
|
| 677 |
# Mailer.test_email(user).deliver => send an email to the given user |
|
| 678 |
def self.test_email(user) |
|
| 679 |
MultiMessage.new(:test_email).for(user) |
|
| 680 |
end |
|
| 681 | ||
| 377 | 682 |
# Sends reminders to issue assignees |
| 378 | 683 |
# Available options: |
| 379 | 684 |
# * :days => how many days in the future to remind about (defaults to 7) |
| ... | ... | |
| 483 | 788 |
headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ')
|
| 484 | 789 |
end |
| 485 | 790 | |
| 486 |
m = if block_given?
|
|
| 791 |
if block_given? |
|
| 487 | 792 |
super headers, &block |
| 488 | 793 |
else |
| 489 | 794 |
super headers do |format| |
| ... | ... | |
| 491 | 796 |
format.html unless Setting.plain_text_mail? |
| 492 | 797 |
end |
| 493 | 798 |
end |
| 494 |
set_language_if_valid @initial_language |
|
| 495 | ||
| 496 |
m |
|
| 497 |
end |
|
| 498 | ||
| 499 |
def initialize(*args) |
|
| 500 |
@initial_language = current_language |
|
| 501 |
set_language_if_valid Setting.default_language |
|
| 502 |
super |
|
| 503 | 799 |
end |
| 504 | 800 | |
| 505 | 801 |
def self.deliver_mail(mail) |
| ... | ... | |
| 521 | 817 |
if m = method.to_s.match(%r{^deliver_(.+)$})
|
| 522 | 818 |
ActiveSupport::Deprecation.warn "Mailer.deliver_#{m[1]}(*args) is deprecated. Use Mailer.#{m[1]}(*args).deliver instead."
|
| 523 | 819 |
send(m[1], *args).deliver |
| 820 |
elsif action_methods.include?(method.to_s) |
|
| 821 |
MultiMessage.new(method, *args).for(User.current) |
|
| 524 | 822 |
else |
| 525 | 823 |
super |
| 526 | 824 |
end |
| app/views/mailer/security_notification.html.erb | ||
|---|---|---|
| 9 | 9 | |
| 10 | 10 |
<p><%= l(:field_user) %>: <strong><%= @originator.login %></strong><br/> |
| 11 | 11 |
<%= l(:field_remote_ip) %>: <strong><%= @remote_ip %></strong><br/> |
| 12 |
<%= l(:label_date) %>: <strong><%= format_time Time.now, true, @user %></strong></p> |
|
| 13 | ||
| 12 |
<%= l(:label_date) %>: <strong><%= format_time Time.now, true %></strong></p> |
|
| app/views/mailer/security_notification.text.erb | ||
|---|---|---|
| 4 | 4 | |
| 5 | 5 |
<%= l(:field_user) %>: <%= @originator.login %> |
| 6 | 6 |
<%= l(:field_remote_ip) %>: <%= @remote_ip %> |
| 7 |
<%= l(:label_date) %>: <%= format_time Time.now, true, @user %> |
|
| 8 | ||
| 7 |
<%= l(:label_date) %>: <%= format_time Time.now, true %> |
|
| app/views/mailer/settings_updated.html.erb | ||
|---|---|---|
| 8 | 8 | |
| 9 | 9 |
<%= link_to @url, @url %> |
| 10 | 10 | |
| 11 |
<p><%= l(:field_user) %>: <strong><%= User.current.login %></strong><br/>
|
|
| 12 |
<%= l(:field_remote_ip) %>: <strong><%= User.current.remote_ip %></strong><br/>
|
|
| 11 |
<p><%= l(:field_user) %>: <strong><%= @sender.login %></strong><br/>
|
|
| 12 |
<%= l(:field_remote_ip) %>: <strong><%= @sender.remote_ip %></strong><br/>
|
|
| 13 | 13 |
<%= l(:label_date) %>: <strong><%= format_time Time.now, true %></strong></p> |
| 14 | 14 | |
| app/views/mailer/settings_updated.text.erb | ||
|---|---|---|
| 6 | 6 | |
| 7 | 7 |
<%= @url %> |
| 8 | 8 | |
| 9 |
<%= l(:field_user) %>: <%= User.current.login %>
|
|
| 10 |
<%= l(:field_remote_ip) %>: <%= User.current.remote_ip %>
|
|
| 9 |
<%= l(:field_user) %>: <%= @sender.login %>
|
|
| 10 |
<%= l(:field_remote_ip) %>: <%= @sender.remote_ip %>
|
|
| 11 | 11 |
<%= l(:label_date) %>: <%= format_time Time.now, true %> |
| 12 | 12 | |
| test/functional/documents_controller_test.rb | ||
|---|---|---|
| 132 | 132 |
assert_equal Enumeration.find(2), document.category |
| 133 | 133 |
assert_equal 1, document.attachments.size |
| 134 | 134 |
assert_equal 'testfile.txt', document.attachments.first.filename |
| 135 |
assert_equal 1, ActionMailer::Base.deliveries.size
|
|
| 135 |
assert_equal 2, ActionMailer::Base.deliveries.size
|
|
| 136 | 136 |
end |
| 137 | 137 | |
| 138 | 138 |
def test_create_with_failure |
| test/functional/issues_controller_test.rb | ||
|---|---|---|
| 152 | 152 |
:f => ['tracker_id'], |
| 153 | 153 |
:op => {
|
| 154 | 154 |
'tracker_id' => '=' |
| 155 |
},
|
|
| 155 |
}, |
|
| 156 | 156 |
:v => {
|
| 157 | 157 |
'tracker_id' => ['1'] |
| 158 | 158 |
} |
| ... | ... | |
| 253 | 253 |
:f => [filter_name], |
| 254 | 254 |
:op => {
|
| 255 | 255 |
filter_name => '=' |
| 256 |
},
|
|
| 256 |
}, |
|
| 257 | 257 |
:v => {
|
| 258 | 258 |
filter_name => ['Foo'] |
| 259 |
},
|
|
| 259 |
}, |
|
| 260 | 260 |
:c => ['project'] |
| 261 | 261 |
} |
| 262 | 262 |
assert_response :success |
| ... | ... | |
| 1459 | 1459 |
:f => ['start_date'], |
| 1460 | 1460 |
:op => {
|
| 1461 | 1461 |
:start_date => '=' |
| 1462 |
},
|
|
| 1462 |
}, |
|
| 1463 | 1463 |
:format => 'csv' |
| 1464 | 1464 |
} |
| 1465 | 1465 |
assert_equal 'text/csv', @response.content_type |
| ... | ... | |
| 2678 | 2678 |
:tracker_id => 3, |
| 2679 | 2679 |
:description => 'Prefilled', |
| 2680 | 2680 |
:custom_field_values => {
|
| 2681 |
'2' => 'Custom field value'}
|
|
| 2681 |
'2' => 'Custom field value'} |
|
| 2682 | 2682 |
} |
| 2683 | 2683 |
} |
| 2684 | 2684 | |
| ... | ... | |
| 2802 | 2802 |
assert !t.disabled_core_fields.include?('parent_issue_id')
|
| 2803 | 2803 | |
| 2804 | 2804 |
get :new, :params => {
|
| 2805 |
:project_id => 1, issue: { parent_issue_id: 1
|
|
| 2805 |
:project_id => 1, issue: { parent_issue_id: 1
|
|
| 2806 | 2806 |
} |
| 2807 | 2807 |
} |
| 2808 | 2808 |
assert_response :success |
| ... | ... | |
| 2812 | 2812 |
t.save! |
| 2813 | 2813 |
assert t.disabled_core_fields.include?('parent_issue_id')
|
| 2814 | 2814 |
get :new, :params => {
|
| 2815 |
:project_id => 1, issue: { parent_issue_id: 1
|
|
| 2815 |
:project_id => 1, issue: { parent_issue_id: 1
|
|
| 2816 | 2816 |
} |
| 2817 | 2817 |
} |
| 2818 | 2818 |
assert_response :success |
| ... | ... | |
| 2870 | 2870 |
:issue => {
|
| 2871 | 2871 |
:tracker_id => 2, |
| 2872 | 2872 |
:status_id => 1 |
| 2873 |
},
|
|
| 2873 |
}, |
|
| 2874 | 2874 |
:was_default_status => 1 |
| 2875 | 2875 |
} |
| 2876 | 2876 |
assert_response :success |
| ... | ... | |
| 2889 | 2889 |
:issue => {
|
| 2890 | 2890 |
:project_id => 1, |
| 2891 | 2891 |
:fixed_version_id => '' |
| 2892 |
},
|
|
| 2892 |
}, |
|
| 2893 | 2893 |
:form_update_triggered_by => 'issue_project_id' |
| 2894 | 2894 |
} |
| 2895 | 2895 |
assert_response :success |
| ... | ... | |
| 2917 | 2917 |
:start_date => '2010-11-07', |
| 2918 | 2918 |
:estimated_hours => '', |
| 2919 | 2919 |
:custom_field_values => {
|
| 2920 |
'2' => 'Value for field 2'}
|
|
| 2920 |
'2' => 'Value for field 2'} |
|
| 2921 | 2921 |
} |
| 2922 | 2922 |
} |
| 2923 | 2923 |
end |
| ... | ... | |
| 2976 | 2976 |
:priority_id => 5, |
| 2977 | 2977 |
:estimated_hours => '', |
| 2978 | 2978 |
:custom_field_values => {
|
| 2979 |
'2' => 'Value for field 2'}
|
|
| 2979 |
'2' => 'Value for field 2'} |
|
| 2980 | 2980 |
} |
| 2981 | 2981 |
} |
| 2982 | 2982 |
end |
| ... | ... | |
| 3002 | 3002 |
:priority_id => 5, |
| 3003 | 3003 |
:estimated_hours => '', |
| 3004 | 3004 |
:custom_field_values => {
|
| 3005 |
'2' => 'Value for field 2'}
|
|
| 3005 |
'2' => 'Value for field 2'} |
|
| 3006 | 3006 |
} |
| 3007 | 3007 |
} |
| 3008 | 3008 |
end |
| ... | ... | |
| 3023 | 3023 |
:tracker_id => 3, |
| 3024 | 3024 |
:subject => 'This is first issue', |
| 3025 | 3025 |
:priority_id => 5 |
| 3026 |
},
|
|
| 3026 |
}, |
|
| 3027 | 3027 |
:continue => '' |
| 3028 | 3028 |
} |
| 3029 | 3029 |
end |
| ... | ... | |
| 3065 | 3065 |
:description => 'This is the description', |
| 3066 | 3066 |
:priority_id => 5, |
| 3067 | 3067 |
:custom_field_values => {
|
| 3068 |
'1' => ['', 'MySQL', 'Oracle']}
|
|
| 3068 |
'1' => ['', 'MySQL', 'Oracle']} |
|
| 3069 | 3069 |
} |
| 3070 | 3070 |
} |
| 3071 | 3071 |
end |
| ... | ... | |
| 3088 | 3088 |
:description => 'This is the description', |
| 3089 | 3089 |
:priority_id => 5, |
| 3090 | 3090 |
:custom_field_values => {
|
| 3091 |
'1' => ['']}
|
|
| 3091 |
'1' => ['']} |
|
| 3092 | 3092 |
} |
| 3093 | 3093 |
} |
| 3094 | 3094 |
end |
| ... | ... | |
| 3111 | 3111 |
:description => 'This is the description', |
| 3112 | 3112 |
:priority_id => 5, |
| 3113 | 3113 |
:custom_field_values => {
|
| 3114 |
field.id.to_s => ['', '2', '3']}
|
|
| 3114 |
field.id.to_s => ['', '2', '3']} |
|
| 3115 | 3115 |
} |
| 3116 | 3116 |
} |
| 3117 | 3117 |
end |
| ... | ... | |
| 3159 | 3159 |
:due_date => '', |
| 3160 | 3160 |
:custom_field_values => {
|
| 3161 | 3161 |
cf1.id.to_s => '', cf2.id.to_s => '' |
| 3162 |
}
|
|
| 3163 |
|
|
| 3162 |
} |
|
| 3163 | ||
| 3164 | 3164 |
} |
| 3165 | 3165 |
} |
| 3166 | 3166 |
assert_response :success |
| ... | ... | |
| 3189 | 3189 |
:due_date => '', |
| 3190 | 3190 |
:custom_field_values => {
|
| 3191 | 3191 |
cf1.id.to_s => '', cf2.id.to_s => [''] |
| 3192 |
}
|
|
| 3193 |
|
|
| 3192 |
} |
|
| 3193 | ||
| 3194 | 3194 |
} |
| 3195 | 3195 |
} |
| 3196 | 3196 |
assert_response :success |
| ... | ... | |
| 3219 | 3219 |
:due_date => '2012-07-16', |
| 3220 | 3220 |
:custom_field_values => {
|
| 3221 | 3221 |
cf1.id.to_s => 'value1', cf2.id.to_s => 'value2' |
| 3222 |
}
|
|
| 3223 |
|
|
| 3222 |
} |
|
| 3223 | ||
| 3224 | 3224 |
} |
| 3225 | 3225 |
} |
| 3226 | 3226 |
assert_response 302 |
| ... | ... | |
| 3246 | 3246 |
:tracker_id => 1, |
| 3247 | 3247 |
:status_id => 1, |
| 3248 | 3248 |
:subject => 'Test' |
| 3249 |
|
|
| 3249 | ||
| 3250 | 3250 |
} |
| 3251 | 3251 |
} |
| 3252 | 3252 |
assert_response 302 |
| ... | ... | |
| 3424 | 3424 |
:project_id => 3, |
| 3425 | 3425 |
:tracker_id => 2, |
| 3426 | 3426 |
:subject => 'Foo' |
| 3427 |
},
|
|
| 3427 |
}, |
|
| 3428 | 3428 |
:continue => '1' |
| 3429 | 3429 |
} |
| 3430 | 3430 |
assert_redirected_to '/issues/new?issue%5Bproject_id%5D=3&issue%5Btracker_id%5D=2' |
| ... | ... | |
| 3477 | 3477 |
:priority_id => 5, |
| 3478 | 3478 |
:estimated_hours => '', |
| 3479 | 3479 |
:custom_field_values => {
|
| 3480 |
'2' => 'Value for field 2'}
|
|
| 3480 |
'2' => 'Value for field 2'} |
|
| 3481 | 3481 |
} |
| 3482 | 3482 |
} |
| 3483 | 3483 |
end |
| 3484 | 3484 |
assert_redirected_to :controller => 'issues', :action => 'show', :id => Issue.last.id |
| 3485 | 3485 | |
| 3486 |
assert_equal 1, ActionMailer::Base.deliveries.size
|
|
| 3486 |
assert_equal 2, ActionMailer::Base.deliveries.size
|
|
| 3487 | 3487 |
end |
| 3488 | 3488 |
end |
| 3489 | 3489 | |
| ... | ... | |
| 3536 | 3536 |
post :create, :params => {
|
| 3537 | 3537 |
:project_id => 1, |
| 3538 | 3538 |
:issue => {
|
| 3539 |
:tracker => "A param can not be a Tracker"
|
|
| 3539 |
:tracker => "A param can not be a Tracker" |
|
| 3540 | 3540 |
} |
| 3541 | 3541 |
} |
| 3542 | 3542 |
end |
| ... | ... | |
| 3553 | 3553 |
:project_id => 1, |
| 3554 | 3554 |
:issue => {
|
| 3555 | 3555 |
:tracker_id => '1', |
| 3556 |
:subject => 'With attachment'
|
|
| 3557 |
},
|
|
| 3556 |
:subject => 'With attachment' |
|
| 3557 |
}, |
|
| 3558 | 3558 |
:attachments => {
|
| 3559 | 3559 |
'1' => {
|
| 3560 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3560 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3561 | 3561 |
} |
| 3562 | 3562 |
} |
| 3563 | 3563 |
end |
| ... | ... | |
| 3588 | 3588 |
:project_id => 1, |
| 3589 | 3589 |
:issue => {
|
| 3590 | 3590 |
:tracker_id => '1', |
| 3591 |
:subject => 'With attachment'
|
|
| 3592 |
},
|
|
| 3591 |
:subject => 'With attachment' |
|
| 3592 |
}, |
|
| 3593 | 3593 |
:attachments => {
|
| 3594 | 3594 |
'1' => {
|
| 3595 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3595 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3596 | 3596 |
} |
| 3597 | 3597 |
} |
| 3598 | 3598 |
end |
| ... | ... | |
| 3614 | 3614 |
:project_id => 1, |
| 3615 | 3615 |
:issue => {
|
| 3616 | 3616 |
:tracker_id => '1', |
| 3617 |
:subject => ''
|
|
| 3618 |
},
|
|
| 3617 |
:subject => '' |
|
| 3618 |
}, |
|
| 3619 | 3619 |
:attachments => {
|
| 3620 | 3620 |
'1' => {
|
| 3621 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3621 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 3622 | 3622 |
} |
| 3623 | 3623 |
} |
| 3624 | 3624 |
assert_response :success |
| ... | ... | |
| 3645 | 3645 |
:project_id => 1, |
| 3646 | 3646 |
:issue => {
|
| 3647 | 3647 |
:tracker_id => '1', |
| 3648 |
:subject => ''
|
|
| 3649 |
},
|
|
| 3648 |
:subject => '' |
|
| 3649 |
}, |
|
| 3650 | 3650 |
:attachments => {
|
| 3651 | 3651 |
'p0' => {
|
| 3652 |
'token' => attachment.token}
|
|
| 3652 |
'token' => attachment.token} |
|
| 3653 | 3653 |
} |
| 3654 | 3654 |
} |
| 3655 | 3655 |
assert_response :success |
| ... | ... | |
| 3671 | 3671 |
:project_id => 1, |
| 3672 | 3672 |
:issue => {
|
| 3673 | 3673 |
:tracker_id => '1', |
| 3674 |
:subject => 'Saved attachments'
|
|
| 3675 |
},
|
|
| 3674 |
:subject => 'Saved attachments' |
|
| 3675 |
}, |
|
| 3676 | 3676 |
:attachments => {
|
| 3677 | 3677 |
'p0' => {
|
| 3678 |
'token' => attachment.token}
|
|
| 3678 |
'token' => attachment.token} |
|
| 3679 | 3679 |
} |
| 3680 | 3680 |
} |
| 3681 | 3681 |
assert_response 302 |
| ... | ... | |
| 3997 | 3997 |
:project_id => '1', |
| 3998 | 3998 |
:tracker_id => '1', |
| 3999 | 3999 |
:status_id => '1' |
| 4000 |
},
|
|
| 4000 |
}, |
|
| 4001 | 4001 |
:was_default_status => '1' |
| 4002 | 4002 |
} |
| 4003 | 4003 |
end |
| ... | ... | |
| 4041 | 4041 |
:tracker_id => '3', |
| 4042 | 4042 |
:status_id => '1', |
| 4043 | 4043 |
:subject => 'Copy with attachments' |
| 4044 |
},
|
|
| 4044 |
}, |
|
| 4045 | 4045 |
:copy_attachments => '1' |
| 4046 | 4046 |
} |
| 4047 | 4047 |
end |
| ... | ... | |
| 4089 | 4089 |
:tracker_id => '3', |
| 4090 | 4090 |
:status_id => '1', |
| 4091 | 4091 |
:subject => 'Copy with attachments' |
| 4092 |
},
|
|
| 4092 |
}, |
|
| 4093 | 4093 |
:copy_attachments => '1', |
| 4094 | 4094 |
:attachments => {
|
| 4095 | 4095 |
'1' => {
|
| ... | ... | |
| 4188 | 4188 |
:tracker_id => '3', |
| 4189 | 4189 |
:status_id => '1', |
| 4190 | 4190 |
:subject => 'Copy with subtasks' |
| 4191 |
},
|
|
| 4191 |
}, |
|
| 4192 | 4192 |
:copy_subtasks => '1' |
| 4193 | 4193 |
} |
| 4194 | 4194 |
end |
| ... | ... | |
| 4212 | 4212 |
:status_id => '1', |
| 4213 | 4213 |
:subject => 'Copy with subtasks', |
| 4214 | 4214 |
:custom_field_values => {
|
| 4215 |
'2' => 'Foo'}
|
|
| 4216 |
},
|
|
| 4215 |
'2' => 'Foo'} |
|
| 4216 |
}, |
|
| 4217 | 4217 |
:copy_subtasks => '1' |
| 4218 | 4218 |
} |
| 4219 | 4219 |
end |
| ... | ... | |
| 4394 | 4394 |
:id => 1, |
| 4395 | 4395 |
:issue => {
|
| 4396 | 4396 |
:status_id => 5, |
| 4397 |
:priority_id => 7
|
|
| 4398 |
},
|
|
| 4397 |
:priority_id => 7 |
|
| 4398 |
}, |
|
| 4399 | 4399 |
:time_entry => {
|
| 4400 | 4400 |
:hours => '2.5', |
| 4401 | 4401 |
:comments => 'test_get_edit_with_params', |
| 4402 |
:activity_id => 10
|
|
| 4402 |
:activity_id => 10 |
|
| 4403 | 4403 |
} |
| 4404 | 4404 |
} |
| 4405 | 4405 |
assert_response :success |
| ... | ... | |
| 4638 | 4638 |
:project_id => '1', |
| 4639 | 4639 |
:tracker_id => '2', |
| 4640 | 4640 |
:priority_id => '6' |
| 4641 |
|
|
| 4641 | ||
| 4642 | 4642 |
} |
| 4643 | 4643 |
} |
| 4644 | 4644 |
end |
| ... | ... | |
| 4701 | 4701 |
:issue => {
|
| 4702 | 4702 |
:subject => 'Custom field change', |
| 4703 | 4703 |
:custom_field_values => {
|
| 4704 |
'1' => ['', 'Oracle', 'PostgreSQL']
|
|
| 4705 |
}
|
|
| 4706 |
|
|
| 4704 |
'1' => ['', 'Oracle', 'PostgreSQL'] |
|
| 4705 |
} |
|
| 4706 | ||
| 4707 | 4707 |
} |
| 4708 | 4708 |
} |
| 4709 | 4709 |
end |
| ... | ... | |
| 4724 | 4724 |
:issue => {
|
| 4725 | 4725 |
:status_id => 2, |
| 4726 | 4726 |
:assigned_to_id => 3, |
| 4727 |
:notes => 'Assigned to dlopper'
|
|
| 4728 |
},
|
|
| 4727 |
:notes => 'Assigned to dlopper' |
|
| 4728 |
}, |
|
| 4729 | 4729 |
:time_entry => {
|
| 4730 | 4730 |
:hours => '', |
| 4731 | 4731 |
:comments => '', |
| 4732 |
:activity_id => TimeEntryActivity.first
|
|
| 4732 |
:activity_id => TimeEntryActivity.first |
|
| 4733 | 4733 |
} |
| 4734 | 4734 |
} |
| 4735 | 4735 |
end |
| ... | ... | |
| 4755 | 4755 |
put :update, :params => {
|
| 4756 | 4756 |
:id => 1, |
| 4757 | 4757 |
:issue => {
|
| 4758 |
:notes => notes
|
|
| 4758 |
:notes => notes |
|
| 4759 | 4759 |
} |
| 4760 | 4760 |
} |
| 4761 | 4761 |
end |
| ... | ... | |
| 4823 | 4823 |
put :update, :params => {
|
| 4824 | 4824 |
:id => 1, |
| 4825 | 4825 |
:issue => {
|
| 4826 |
:notes => '2.5 hours added'
|
|
| 4827 |
},
|
|
| 4826 |
:notes => '2.5 hours added' |
|
| 4827 |
}, |
|
| 4828 | 4828 |
:time_entry => {
|
| 4829 | 4829 |
:hours => '2.5', |
| 4830 | 4830 |
:comments => 'test_put_update_with_note_and_spent_time', |
| 4831 |
:activity_id => TimeEntryActivity.first.id
|
|
| 4831 |
:activity_id => TimeEntryActivity.first.id |
|
| 4832 | 4832 |
} |
| 4833 | 4833 |
} |
| 4834 | 4834 |
end |
| ... | ... | |
| 4883 | 4883 |
:id => 1, |
| 4884 | 4884 |
:issue => {
|
| 4885 | 4885 |
:notes => '' |
| 4886 |
},
|
|
| 4886 |
}, |
|
| 4887 | 4887 |
:attachments => {
|
| 4888 | 4888 |
'1' => {
|
| 4889 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 4889 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 4890 | 4890 |
} |
| 4891 | 4891 |
} |
| 4892 | 4892 |
end |
| ... | ... | |
| 4922 | 4922 |
put :update, :params => {
|
| 4923 | 4923 |
:id => 1, |
| 4924 | 4924 |
:issue => {
|
| 4925 |
:subject => ''
|
|
| 4926 |
},
|
|
| 4925 |
:subject => '' |
|
| 4926 |
}, |
|
| 4927 | 4927 |
:attachments => {
|
| 4928 | 4928 |
'1' => {
|
| 4929 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 4929 |
'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'test file'}
|
|
| 4930 | 4930 |
} |
| 4931 | 4931 |
} |
| 4932 | 4932 |
assert_response :success |
| ... | ... | |
| 4952 | 4952 |
put :update, :params => {
|
| 4953 | 4953 |
:id => 1, |
| 4954 | 4954 |
:issue => {
|
| 4955 |
:subject => ''
|
|
| 4956 |
},
|
|
| 4955 |
:subject => '' |
|
| 4956 |
}, |
|
| 4957 | 4957 |
:attachments => {
|
| 4958 | 4958 |
'p0' => {
|
| 4959 |
'token' => attachment.token}
|
|
| 4959 |
'token' => attachment.token} |
|
| 4960 | 4960 |
} |
| 4961 | 4961 |
} |
| 4962 | 4962 |
assert_response :success |
| ... | ... | |
| 4979 | 4979 |
:id => 1, |
| 4980 | 4980 |
:issue => {
|
| 4981 | 4981 |
:notes => 'Attachment added' |
| 4982 |
},
|
|
| 4982 |
}, |
|
| 4983 | 4983 |
:attachments => {
|
| 4984 | 4984 |
'p0' => {
|
| 4985 |
'token' => attachment.token}
|
|
| 4985 |
'token' => attachment.token} |
|
| 4986 | 4986 |
} |
| 4987 | 4987 |
} |
| 4988 | 4988 |
assert_redirected_to '/issues/1' |
| ... | ... | |
| 5007 | 5007 |
:id => 1, |
| 5008 | 5008 |
:issue => {
|
| 5009 | 5009 |
:notes => '' |
| 5010 |
},
|
|
| 5010 |
}, |
|
| 5011 | 5011 |
:attachments => {
|
| 5012 | 5012 |
'1' => {
|
| 5013 |
'file' => uploaded_test_file('testfile.txt', 'text/plain')}
|
|
| 5013 |
'file' => uploaded_test_file('testfile.txt', 'text/plain')}
|
|
| 5014 | 5014 |
} |
| 5015 | 5015 |
} |
| 5016 | 5016 |
assert_redirected_to :action => 'show', :id => '1' |
| ... | ... | |
| 5030 | 5030 |
:issue => {
|
| 5031 | 5031 |
:notes => 'Removing attachments', |
| 5032 | 5032 |
:deleted_attachment_ids => ['1', '5'] |
| 5033 |
|
|
| 5033 | ||
| 5034 | 5034 |
} |
| 5035 | 5035 |
} |
| 5036 | 5036 |
end |
| ... | ... | |
| 5057 | 5057 |
:subject => '', |
| 5058 | 5058 |
:notes => 'Removing attachments', |
| 5059 | 5059 |
:deleted_attachment_ids => ['1', '5'] |
| 5060 |
|
|
| 5060 | ||
| 5061 | 5061 |
} |
| 5062 | 5062 |
} |
| 5063 | 5063 |
end |
| ... | ... | |
| 5100 | 5100 |
:subject => new_subject, |
| 5101 | 5101 |
:priority_id => '6', |
| 5102 | 5102 |
:category_id => '1' # no change |
| 5103 |
|
|
| 5103 | ||
| 5104 | 5104 |
} |
| 5105 | 5105 |
} |
| 5106 |
assert_equal 1, ActionMailer::Base.deliveries.size
|
|
| 5106 |
assert_equal 2, ActionMailer::Base.deliveries.size
|
|
| 5107 | 5107 |
end |
| 5108 | 5108 |
end |
| 5109 | 5109 | |
| ... | ... | |
| 5116 | 5116 |
:id => 1, |
| 5117 | 5117 |
:issue => {
|
| 5118 | 5118 |
:notes => notes |
| 5119 |
},
|
|
| 5119 |
}, |
|
| 5120 | 5120 |
:time_entry => {
|
| 5121 | 5121 |
"comments"=>"", "activity_id"=>"", "hours"=>"2z" |
| 5122 | 5122 |
} |
| ... | ... | |
| 5138 | 5138 |
:id => 1, |
| 5139 | 5139 |
:issue => {
|
| 5140 | 5140 |
:notes => notes |
| 5141 |
},
|
|
| 5141 |
}, |
|
| 5142 | 5142 |
:time_entry => {
|
| 5143 | 5143 |
"comments"=>"this is my comment", "activity_id"=>"", "hours"=>"" |
| 5144 | 5144 |
} |
| ... | ... | |
| 5160 | 5160 |
:id => issue.id, |
| 5161 | 5161 |
:issue => {
|
| 5162 | 5162 |
:fixed_version_id => 4 |
| 5163 |
|
|
| 5163 | ||
| 5164 | 5164 |
} |
| 5165 | 5165 |
} |
| 5166 | 5166 | |
| ... | ... | |
| 5178 | 5178 |
:id => issue.id, |
| 5179 | 5179 |
:issue => {
|
| 5180 | 5180 |
:fixed_version_id => 4 |
| 5181 |
|
|
| 5182 |
},
|
|
| 5181 | ||
| 5182 |
}, |
|
| 5183 | 5183 |
:back_url => '/issues' |
| 5184 | 5184 |
} |
| 5185 | 5185 | |
| ... | ... | |
| 5195 | 5195 |
:id => issue.id, |
| 5196 | 5196 |
:issue => {
|
| 5197 | 5197 |
:fixed_version_id => 4 |
| 5198 |
|
|
| 5199 |
},
|
|
| 5198 | ||
| 5199 |
}, |
|
| 5200 | 5200 |
:back_url => 'http://google.com' |
| 5201 | 5201 |
} |
| 5202 | 5202 | |
| ... | ... | |
| 5212 | 5212 |
:issue => {
|
- « Previous
- 1
- 2
- 3
- 4
- Next »