Project

General

Profile

Defect #17096 » 17096-fix-emails-threading.patch

Go MAEDA, 2019-02-17 14:56

View differences:

app/models/mailer.rb
134 134
    redmine_headers 'Project' => document.project.identifier
135 135
    @author = author
136 136
    @document = document
137
    @user = user
137 138
    @document_url = url_for(:controller => 'documents', :action => 'show', :id => document)
138 139
    mail :to => user,
139 140
      :subject => "[#{document.project.name}] #{l(:label_document_new)}: #{document.title}"
......
169 170
    end
170 171
    redmine_headers 'Project' => container.project.identifier
171 172
    @attachments = attachments
173
    @user = user
172 174
    @added_to = added_to
173 175
    @added_to_url = added_to_url
174 176
    mail :to => user,
......
200 202
    message_id news
201 203
    references news
202 204
    @news = news
205
    @user = user
203 206
    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
204 207
    mail :to => user,
205 208
      :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}"
......
225 228
    references news
226 229
    @news = news
227 230
    @comment = comment
231
    @user = user
228 232
    @news_url = url_for(:controller => 'news', :action => 'show', :id => news)
229 233
    mail :to => user,
230 234
     :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}"
......
250 254
    message_id message
251 255
    references message.root
252 256
    @message = message
257
    @user = user
253 258
    @message_url = url_for(message.event_url)
254 259
    mail :to => user,
255 260
      :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}"
......
276 281
    @author = wiki_content.author
277 282
    message_id wiki_content
278 283
    @wiki_content = wiki_content
284
    @user = user
279 285
    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
280 286
                                      :project_id => wiki_content.project,
281 287
                                      :id => wiki_content.page.title)
......
301 307
    @author = wiki_content.author
302 308
    message_id wiki_content
303 309
    @wiki_content = wiki_content
310
    @user = user
304 311
    @wiki_content_url = url_for(:controller => 'wiki', :action => 'show',
305 312
                                      :project_id => wiki_content.project,
306 313
                                      :id => wiki_content.page.title)
......
659 666
    end
660 667

  
661 668
    if @message_id_object
662
      headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>"
669
      headers[:message_id] = "<#{self.class.message_id_for(@message_id_object, @user)}>"
663 670
    end
664 671
    if @references_objects
665
      headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ')
672
      headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o, @user)}>"}.join(' ')
666 673
    end
667 674

  
668 675
    if block_given?
......
716 723
    h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s }
717 724
  end
718 725

  
719
  def self.token_for(object, rand=true)
726
  def self.token_for(object, user)
720 727
    timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on)
721 728
    hash = [
722 729
      "redmine",
723 730
      "#{object.class.name.demodulize.underscore}-#{object.id}",
724 731
      timestamp.strftime("%Y%m%d%H%M%S")
725 732
    ]
726
    if rand
727
      hash << Redmine::Utils.random_hex(8)
728
    end
733
    hash << user.id if user
729 734
    host = Setting.mail_from.to_s.strip.gsub(%r{^.*@|>}, '')
730 735
    host = "#{::Socket.gethostname}.redmine" if host.empty?
731 736
    "#{hash.join('.')}@#{host}"
732 737
  end
733 738

  
734 739
  # Returns a Message-Id for the given object
735
  def self.message_id_for(object)
736
    token_for(object, true)
740
  def self.message_id_for(object, user)
741
    token_for(object, user)
737 742
  end
738 743

  
739 744
  # Returns a uniq token for a given object referenced by all notifications
740 745
  # related to this object
741
  def self.references_for(object)
742
    token_for(object, false)
746
  def self.references_for(object, user)
747
    token_for(object, user)
743 748
  end
744 749

  
745 750
  def message_id(object)
......
751 756
    @references_objects << object
752 757
  end
753 758
end
759

  
test/unit/mailer_test.rb
293 293
    issue = Issue.find(2)
294 294
    Mailer.deliver_issue_add(issue)
295 295
    mail = last_email
296
    assert_match /^redmine\.issue-2\.20060719190421\.[a-f0-9]+@example\.net/, mail.message_id
297
    assert_include "redmine.issue-2.20060719190421@example.net", mail.references
296
    uid = destination_user(mail).id
297
    assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.message_id
298
    assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.references
298 299
  end
299 300

  
300 301
  def test_issue_edit_message_id
......
303 304

  
304 305
    Mailer.deliver_issue_edit(journal)
305 306
    mail = last_email
306
    assert_match /^redmine\.journal-3\.\d+\.[a-f0-9]+@example\.net/, mail.message_id
307
    assert_include "redmine.issue-2.20060719190421@example.net", mail.references
307
    uid = destination_user(mail).id
308
    assert_match /^redmine\.journal-3\.\d+\.#{uid}@example\.net/, mail.message_id
309
    assert_include "redmine.issue-2.20060719190421.#{uid}@example.net", mail.references
308 310
    assert_select_email do
309 311
      # link to the update
310 312
      assert_select "a[href=?]",
......
316 318
    message = Message.find(1)
317 319
    Mailer.deliver_message_posted(message)
318 320
    mail = last_email
319
    assert_match /^redmine\.message-1\.\d+\.[a-f0-9]+@example\.net/, mail.message_id
320
    assert_include "redmine.message-1.20070512151532@example.net", mail.references
321
    uid = destination_user(mail).id
322
    assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.message_id
323
    assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.references
321 324
    assert_select_email do
322 325
      # link to the message
323 326
      assert_select "a[href=?]",
......
330 333
    message = Message.find(3)
331 334
    Mailer.deliver_message_posted(message)
332 335
    mail = last_email
333
    assert_match /^redmine\.message-3\.\d+\.[a-f0-9]+@example\.net/, mail.message_id
334
    assert_include "redmine.message-1.20070512151532@example.net", mail.references
336
    uid = destination_user(mail).id
337
    assert_include "redmine.message-3.20070512151802.#{uid}@example.net", mail.message_id
338
    assert_include "redmine.message-1.20070512151532.#{uid}@example.net", mail.references
335 339
    assert_select_email do
336 340
      # link to the reply
337 341
      assert_select "a[href=?]",
......
745 749

  
746 750
  def test_token_for_should_strip_trailing_gt_from_address_with_full_name
747 751
    with_settings :mail_from => "Redmine Mailer<no-reply@redmine.org>" do
748
      assert_match /\Aredmine.issue-\d+\.\d+\.[0-9a-f]+@redmine.org\z/, Mailer.token_for(Issue.generate!)
752
      assert_match /\Aredmine.issue-\d+\.\d+\.3@redmine.org\z/,
753
        Mailer.token_for(Issue.generate!, User.find(3))
749 754
    end
750 755
  end
751 756

  
......
897 902
  def html_part
898 903
    last_email.parts.detect {|part| part.content_type.include?('text/html')}
899 904
  end
905

  
906
  def destination_user(mail)
907
    EmailAddress.where(:address => [mail.to, mail.cc, mail.bcc].flatten).map(&:user).first
908
  end
900 909
end
(3-3/4)