diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index e8af6bafd9..8ad016da36 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -53,30 +53,6 @@ class ApplicationMailer < ActionMailer::Base ActionMailer::Base.perform_deliveries = old_state end - def generate_message_id(object, user) - # id + timestamp should reduce the odds of a collision - # as long as we don't send multiple emails for the same object - journable = object.is_a?(Journal) ? object.journable : object - - timestamp = mail_timestamp(object) - hash = 'openproject'\ - '.'\ - "#{journable.class.name.demodulize.underscore}"\ - '-'\ - "#{user.id}"\ - '-'\ - "#{journable.id}"\ - '.'\ - "#{timestamp.strftime('%Y%m%d%H%M%S')}" - host = Setting.mail_from.to_s.gsub(%r{\A.*@}, '') - host = "#{::Socket.gethostname}.openproject" if host.empty? - "#{hash}@#{host}" - end - - def mail_timestamp(object) - object.send(object.respond_to?(:created_at) ? :created_at : :updated_at) - end - def host if OpenProject::Configuration.rails_relative_url_root.blank? Setting.host_name @@ -105,11 +81,19 @@ class ApplicationMailer < ActionMailer::Base end def message_id(object, user) - headers['Message-ID'] = "<#{self.class.generate_message_id(object, user)}>" + headers['Message-ID'] = "<#{message_id_value(object, user)}>" end - def references(object, user) - headers['References'] = "<#{self.class.generate_message_id(object, user)}>" + def references(*objects) + refs = objects.map do |object| + if object.is_a?(Journal) + "<#{references_value(object.journable)}> <#{references_value(object)}>" + else + "<#{references_value(object)}>" + end + end + + headers['References'] = refs.join(' ') end # Prepends given fields with 'X-OpenProject-' to save some duplication @@ -129,6 +113,57 @@ class ApplicationMailer < ActionMailer::Base mail to: user.mail, subject: subject end end + + # Generates a unique value for the Message-ID header. + # Contains: + # * an 'op' prefix + # * an object id part that consists of the object's class name and the id unless that part is provided as a string + # * the current time + # * the recipient's id + # + # Note that this values, as opposed to the one from #references_value is unique. + def message_id_value(object, recipient) + object_reference = case object + when String + object + else + "#{object.class.name.demodulize.underscore}-#{object.id}" + end + hash = 'op'\ + '.'\ + "#{object_reference}"\ + '.'\ + "#{Time.current.strftime('%Y%m%d%H%M%S')}"\ + '.'\ + "#{recipient.id}" + + "#{hash}@#{header_host_value}" + end + + # Generates a value for the References header. + # Contains: + # * an 'op' prefix + # * an object id part that consists of the object's class name and the id + # + # Note that this values, as opposed to the one from #message_id_value is not unique. + # It in fact is aimed not not so that similar messages (i.e. those belonging to the same + # work package and journal) end up being grouped together. + # + # The value is used within the MailHandler to find the appropriate objects for update + # when a mail has been received. + def references_value(object) + hash = 'op'\ + '.'\ + "#{object.class.name.demodulize.underscore}-#{object.id}" + + "#{hash}@#{header_host_value}" + end + + def header_host_value + host = Setting.mail_from.to_s.gsub(%r{\A.*@}, '') + host = "#{::Socket.gethostname}.openproject" if host.empty? + host + end end ## diff --git a/app/mailers/digest_mailer.rb b/app/mailers/digest_mailer.rb index 37ea8b54a7..9eb56880d5 100644 --- a/app/mailers/digest_mailer.rb +++ b/app/mailers/digest_mailer.rb @@ -56,7 +56,7 @@ class DigestMailer < ApplicationMailer recipient = User.find(recipient_id) open_project_headers User: recipient.name - message_id nil, recipient + message_id 'digest', recipient @user = recipient @notification_ids = notification_ids diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 5599edc70d..6f34d0ce7e 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -83,6 +83,7 @@ class UserMailer < ApplicationMailer open_project_headers 'Project' => @news.project.identifier if @news.project message_id @news, user + references @news subject = "#{News.model_name.human}: #{@news.title}" subject = "[#{@news.project.name}] #{subject}" if @news.project @@ -112,7 +113,7 @@ class UserMailer < ApplicationMailer open_project_headers 'Project' => @news.project.identifier if @news.project message_id @comment, user - references @news, user + references @news, @comment subject = "#{News.model_name.human}: #{@news.title}" subject = "Re: [#{@news.project.name}] #{subject}" if @news.project @@ -150,7 +151,7 @@ class UserMailer < ApplicationMailer open_project_message_headers(@message) message_id @message, user - references @message.parent, user if @message.parent + references *[@message.parent, @message].compact send_mail(user, "[#{@message.forum.project.name} - #{@message.forum.name} - msg#{@message.root.id}] #{@message.subject}") diff --git a/app/mailers/work_package_mailer.rb b/app/mailers/work_package_mailer.rb index dd4ea81c79..c5f3476ba1 100644 --- a/app/mailers/work_package_mailer.rb +++ b/app/mailers/work_package_mailer.rb @@ -42,6 +42,7 @@ class WorkPackageMailer < ApplicationMailer set_work_package_headers(@work_package) message_id journal, recipient + references journal with_locale_for(recipient) do mail to: recipient.mail, @@ -61,6 +62,7 @@ class WorkPackageMailer < ApplicationMailer set_work_package_headers(work_package) message_id work_package, user + references work_package with_locale_for(user) do mail to: user.mail, subject: subject_for_work_package(work_package) diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 6505a08efb..0694c28fbc 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -136,12 +136,12 @@ class MailHandler < ActionMailer::Base private - MESSAGE_ID_RE = %r{^ custom_field_values_from_keywords(work_package), 'subject' => email.subject.to_s.chomp[0, 255] || '(no subject)', @@ -567,7 +563,7 @@ class MailHandler < ActionMailer::Base end def collect_wp_attributes_from_email_on_update(work_package) - attributes = issue_attributes_from_keywords(work_package) + attributes = wp_attributes_from_keywords(work_package) attributes .merge('custom_field_values' => custom_field_values_from_keywords(work_package), 'journal_notes' => cleaned_up_text_body) diff --git a/spec/fixtures/mail_handler/message_reply.eml b/spec/fixtures/mail_handler/message_reply.eml index 6785d78197..c424840b27 100644 --- a/spec/fixtures/mail_handler/message_reply.eml +++ b/spec/fixtures/mail_handler/message_reply.eml @@ -1,9 +1,9 @@ Date: Tue, 16 Mar 2021 16:24:54 +0100 To: notifications@openproject.com -From: user@example.org -Message-ID: -Subject: [OpenProject - General discussion - msg12559] Test - fields in user stories +From: j.doe@openproject.org +Message-ID: +References: +Subject: [OpenProject - General discussion - msg70917] Response to the original message Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="--==_mimepart_6050cdc2e4db_2257939a87567a"; diff --git a/spec/fixtures/mail_handler/wp_mention_reply.eml b/spec/fixtures/mail_handler/wp_mention_reply.eml new file mode 100644 index 0000000000..d4166bca35 --- /dev/null +++ b/spec/fixtures/mail_handler/wp_mention_reply.eml @@ -0,0 +1,1564 @@ +Return-Path: +Delivered-To: j.doe@openproject.org +Received: from director-06.heinlein-hosting.de ([80.241.60.215]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) + by dobby34b.heinlein-hosting.de with LMTPS + id IICSCVE9iWE5eAEAlVRbNA + (envelope-from ) + for ; Mon, 08 Nov 2021 16:08:01 +0100 +Received: from mx2.mailbox.org ([80.241.60.215]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) + by director-06.heinlein-hosting.de with LMTPS + id SGvRB1E9iWEWWAEADc0bRg + (envelope-from ) + for ; Mon, 08 Nov 2021 16:08:01 +0100 +X-Virus-Scanned: amavisd-new at heinlein-support.de +Authentication-Results: spamfilter02.heinlein-hosting.de (amavisd-new); + dkim=pass (2048-bit key) header.d=example.com +X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .openproject. - helo: .mout-b-110.mailbox. - helo-domain: .mailbox.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -5.5 +Received: from mout-b-110.mailbox.org (mout-b-110.mailbox.org [IPv6:2001:67c:2050:101:465::110]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) + (No client certificate requested) + by mx2.mailbox.org (Postfix) with ESMTPS id 1BD41A101D + for ; Mon, 8 Nov 2021 16:07:48 +0100 (CET) +Received: from smtp202.mailbox.org (smtp202.mailbox.org [80.241.60.245]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) + (No client certificate requested) + by mout-b-110.mailbox.org (Postfix) with ESMTPS id 4HnvcM55hTzQjhq + for ; Mon, 8 Nov 2021 16:07:47 +0100 (CET) +Content-Type: multipart/alternative; + boundary="------------Oam4uVyurTHSwkdjLNRM4Y6W" +Message-ID: +Date: Mon, 8 Nov 2021 16:07:39 +0100 +MIME-Version: 1.0 +Subject: Bob Bobbit mentioned you in #399733 - Some subject of the bug +To: OpenProject +References: +From: Jane Doe +In-Reply-To: +X-Rspamd-Queue-Id: 1BD41A101D +X-Rspamd-Score: -5.45 / 15.00 / 15.00 +X-MBO-SPAM-Probability: + +This is a multi-part message in MIME format. +--------------Oam4uVyurTHSwkdjLNRM4Y6W +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: 8bit + +The text of the reply. + +Am 08.11.21 um 15:28 schrieb notifications@openproject.org: +> +> +> Hey Jane! +> Bob Bobbit mentioned you in a comment +> See comment in notification center +> +> +> +> example.community Logo +> +> +> prioritized +> +> #39733 - OpenProject - Mentioned +> +> +> +> +> BUG Some subject of the bug +> +> +> +> +> +> Hi Jane Doe , +> +> the text of the original mentioning. +> +> +> +> +> Change email settings +> +> +> Some footer text +> +-- Jane Doe, M.Sc. + The Important Job + The important company + At some address + +--------------Oam4uVyurTHSwkdjLNRM4Y6W +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + + + + + +

The text of the reply.
+

+
Am 08.11.21 um 15:28 schrieb + notifications@openproject.org:
+
+
+ + + + + + + + + + +

+
+ + + + + + +
+ + + + + + +
= +=C2=A0
+ + + + + + + + +
=C2=A0 + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + = + + + + + + + = + + + +
Hey + Jane!
=C2=A0
+ Marc Alcob=C3=A9 mentione= +d + you in a comment +
=C2=A0
= + + See comment in + notification center +
=C2=A0
+
=C2=A0<= +/td> + + + + + + + +
3D"OpenProject= + +
+
+
+ + + + + + + + + + + + + +
=C2=A0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
=C2=A0= + + + + + + + + + + +
+ + + + = + + + +
+ prioritized
+
=C2=A0= + + #39733 - OpenProject - + Mentioned + + + + + +
+
+
=C2=A0= +
=C2=A0= +=C2=A0=C2=A0= +
=C2=A0= + + + + + + + + + +
BUG =C2=A0= + + Some subject of the bug +
+
=C2=A0= +
=C2=A0= +=C2=A0=C2=A0= +
=C2=A0= + + + + + + + +
+

Hi <= +a + class=3D"user-mention= + + op-uc-link" + title=3D"User Jane + Doe" + href=3D"https://example.org/users/87" +moz-do-not-send=3D"true">Jane Doe,

+

+ the text of the original mentioning. +

+
+
=C2=A0= +
+
=C2=A0
+ + + + + + +
=C2=A0
+
+ + + + + + + + +
+ + + + + + +

+
+
=C2=A0 Change= + + email settings +
+ + + + + + +
=C2=A0
+
=C2=A0
+
+ + + + + + +
+

+ Some footer contents +

+
+
+
-- Jane Doe, M.Sc.
+      The Important Job
+      The important company
+      At some address
+    
+ + +--------------Oam4uVyurTHSwkdjLNRM4Y6W-- + diff --git a/spec/fixtures/mail_handler/wp_mention_reply_with_attributes.eml b/spec/fixtures/mail_handler/wp_mention_reply_with_attributes.eml new file mode 100644 index 0000000000..79881e3e51 --- /dev/null +++ b/spec/fixtures/mail_handler/wp_mention_reply_with_attributes.eml @@ -0,0 +1,1580 @@ +Return-Path: +Delivered-To: j.doe@openproject.org +Received: from director-06.heinlein-hosting.de ([80.241.60.215]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) + by dobby34b.heinlein-hosting.de with LMTPS + id IICSCVE9iWE5eAEAlVRbNA + (envelope-from ) + for ; Mon, 08 Nov 2021 16:08:01 +0100 +Received: from mx2.mailbox.org ([80.241.60.215]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) + by director-06.heinlein-hosting.de with LMTPS + id SGvRB1E9iWEWWAEADc0bRg + (envelope-from ) + for ; Mon, 08 Nov 2021 16:08:01 +0100 +X-Virus-Scanned: amavisd-new at heinlein-support.de +Authentication-Results: spamfilter02.heinlein-hosting.de (amavisd-new); + dkim=pass (2048-bit key) header.d=example.com +X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .openproject. - helo: .mout-b-110.mailbox. - helo-domain: .mailbox.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -5.5 +Received: from mout-b-110.mailbox.org (mout-b-110.mailbox.org [IPv6:2001:67c:2050:101:465::110]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) + (No client certificate requested) + by mx2.mailbox.org (Postfix) with ESMTPS id 1BD41A101D + for ; Mon, 8 Nov 2021 16:07:48 +0100 (CET) +Received: from smtp202.mailbox.org (smtp202.mailbox.org [80.241.60.245]) + (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) + key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) + (No client certificate requested) + by mout-b-110.mailbox.org (Postfix) with ESMTPS id 4HnvcM55hTzQjhq + for ; Mon, 8 Nov 2021 16:07:47 +0100 (CET) +Content-Type: multipart/alternative; + boundary="------------Oam4uVyurTHSwkdjLNRM4Y6W" +Message-ID: +Date: Mon, 8 Nov 2021 16:07:39 +0100 +MIME-Version: 1.0 +Subject: Bob Bobbit mentioned you in #399733 - Some subject of the bug +To: OpenProject +References: +From: Jane Doe +In-Reply-To: +X-Rspamd-Queue-Id: 1BD41A101D +X-Rspamd-Score: -5.45 / 15.00 / 15.00 +X-MBO-SPAM-Probability: + +This is a multi-part message in MIME format. +--------------Oam4uVyurTHSwkdjLNRM4Y6W +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: 8bit + +The text of the reply. + +Status: Resolved +due date: 2010-12-31 +Start Date:2010-01-01 +Assigned to: jsmith@somenet.foo +float field: 52.6 + +Am 08.11.21 um 15:28 schrieb notifications@openproject.org: +> +> +> Hey Jane! +> Bob Bobbit mentioned you in a comment +> See comment in notification center +> +> +> +> example.community Logo +> +> +> prioritized +> +> #39733 - OpenProject - Mentioned +> +> +> +> +> BUG Some subject of the bug +> +> +> +> +> +> Hi Jane Doe , +> +> the text of the original mentioning. +> +> +> +> +> Change email settings +> +> +> Some footer text +> +-- Jane Doe, M.Sc. + The Important Job + The important company + At some address + +--------------Oam4uVyurTHSwkdjLNRM4Y6W +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + + + + + +

The text of the reply.
+

+

Status: Resolved
+

+

due date: 2010-12-31
+

+

Start Date:2010-01-01
+

+

Assigned to: jsmith@somenet.foo
+

+

float field: 52.6
+

+
Am 08.11.21 um 15:28 schrieb + notifications@openproject.org:
+
+
+ + + + + + + + + + +

+
+ + + + + + +
+ + + + + + +
= +=C2=A0
+ + + + + + + + +
=C2=A0 + + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + = + + + + + + + = + + + +
Hey + Jane!
=C2=A0
+ Marc Alcob=C3=A9 mentione= +d + you in a comment +
=C2=A0
= + + See comment in + notification center +
=C2=A0
+
=C2=A0<= +/td> + + + + + + + +
3D"OpenProject= + +
+
+
+ + + + + + + + + + + + + +
=C2=A0
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
=C2=A0= + + + + + + + + + + +
+ + + + = + + + +
+ prioritized
+
=C2=A0= + + #39733 - OpenProject - + Mentioned + + + + + +
+
+
=C2=A0= +
=C2=A0= +=C2=A0=C2=A0= +
=C2=A0= + + + + + + + + + +
BUG =C2=A0= + + Some subject of the bug +
+
=C2=A0= +
=C2=A0= +=C2=A0=C2=A0= +
=C2=A0= + + + + + + + +
+

Hi <= +a + class=3D"user-mention= + + op-uc-link" + title=3D"User Jane + Doe" + href=3D"https://example.org/users/87" +moz-do-not-send=3D"true">Jane Doe,

+

+ the text of the original mentioning. +

+
+
=C2=A0= +
+
=C2=A0
+ + + + + + +
=C2=A0
+
+ + + + + + + + +
+ + + + + + +

+
+
=C2=A0 Change= + + email settings +
+ + + + + + +
=C2=A0
+
=C2=A0
+
+ + + + + + +
+

+ Some footer contents +

+
+
+
-- Jane Doe, M.Sc.
+      The Important Job
+      The important company
+      At some address
+    
+ + +--------------Oam4uVyurTHSwkdjLNRM4Y6W-- + diff --git a/spec/fixtures/mail_handler/wp_update_with_quoted_reply_above.eml b/spec/fixtures/mail_handler/wp_reply_with_quoted_reply_above.eml similarity index 96% rename from spec/fixtures/mail_handler/wp_update_with_quoted_reply_above.eml rename to spec/fixtures/mail_handler/wp_reply_with_quoted_reply_above.eml index 4b0cb9dd50..15a20bfe81 100644 --- a/spec/fixtures/mail_handler/wp_update_with_quoted_reply_above.eml +++ b/spec/fixtures/mail_handler/wp_reply_with_quoted_reply_above.eml @@ -3,7 +3,7 @@ Received: from osiris ([127.0.0.1]) by OSIRIS with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> -In-Reply-To: +References: From: "John Smith" To: Subject: Re: update to issue 2 diff --git a/spec/fixtures/mail_handler/wp_update_with_multiple_quoted_reply_above.eml b/spec/fixtures/mail_handler/wp_update_with_multiple_quoted_reply_above.eml deleted file mode 100644 index 4db4ab891b..0000000000 --- a/spec/fixtures/mail_handler/wp_update_with_multiple_quoted_reply_above.eml +++ /dev/null @@ -1,48 +0,0 @@ -Return-Path: -Received: from osiris ([127.0.0.1]) - by OSIRIS - with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200 -Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris> -In-Reply-To: -From: "John Smith" -To: -Subject: Re: update to issue 2 -Date: Sun, 22 Jun 2008 12:28:07 +0200 -MIME-Version: 1.0 -Content-Type: text/plain; - format=flowed; - charset="iso-8859-1"; - reply-type=original -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2900.2869 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 - -An update to the issue by the sender. - -Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet -turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus -blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti -sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In -in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras -sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum -id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus -eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique -sed, mauris --- Pellentesque habitant morbi tristique senectus et netus et -malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse -platea dictumst. - ->> > --- Reply above. Do not remove this line. --- ->> > ->> > Issue #6779 has been updated by Eric Davis. ->> > ->> > Subject changed from Projects with JSON to Project JSON API ->> > Status changed from New to Assigned ->> > Assignee set to Eric Davis ->> > Priority changed from Low to Normal ->> > Estimated time deleted (1.00) ->> > ->> > Looks like the JSON api for projects was missed. I'm going to be ->> > reviewing the existing APIs and trying to clean them up over the next ->> > few weeks. diff --git a/spec/mailers/digest_mailer_spec.rb b/spec/mailers/digest_mailer_spec.rb index 8baf8c0564..c675b000ec 100644 --- a/spec/mailers/digest_mailer_spec.rb +++ b/spec/mailers/digest_mailer_spec.rb @@ -94,8 +94,8 @@ describe DigestMailer, type: :mailer do .to receive(:current) .and_return(Time.current) - expect(mail['Message-ID']&.value) - .to eql "" + expect(mail.message_id) + .to eql "op.digest.#{Time.current.strftime('%Y%m%d%H%M%S')}.#{recipient.id}@example.net" end it 'sets the expected openproject headers' do diff --git a/spec/mailers/member_mailer_spec.rb b/spec/mailers/member_mailer_spec.rb index 74ef1bcfe6..196303e19c 100644 --- a/spec/mailers/member_mailer_spec.rb +++ b/spec/mailers/member_mailer_spec.rb @@ -47,6 +47,12 @@ describe MemberMailer, type: :mailer do let(:roles) { [FactoryBot.build_stubbed(:role), FactoryBot.build_stubbed(:role)] } let(:message) { nil } + around do |example| + Timecop.freeze(Time.current) do + example.run + end + end + shared_examples_for 'has a subject' do |key| it "has a subject" do if project @@ -82,7 +88,7 @@ describe MemberMailer, type: :mailer do shared_examples_for 'sets the expected message_id header' do it 'sets the expected message_id header' do expect(subject['Message-ID'].value) - .to eql "" + .to eql "" end end diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index ed09514bf8..62ea7459c1 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -49,6 +49,13 @@ describe UserMailer, type: :mailer do end let(:recipient) { FactoryBot.build_stubbed(:user) } + let(:current_time) { Time.current } + + around do |example| + Timecop.freeze(current_time) do + example.run + end + end before do allow(work_package).to receive(:reload).and_return(work_package) @@ -138,33 +145,62 @@ describe UserMailer, type: :mailer do end describe '#message_posted' do - let(:message) do - FactoryBot.build_stubbed(:message).tap do |msg| - allow(msg) - .to receive(:project) - .and_return(msg.forum.project) - end - end - before do described_class.message_posted(recipient, message).deliver_now end - it_behaves_like 'mail is sent' do - it 'carries a message_id' do - expect(deliveries.first.message_id) - .to eql(described_class.generate_message_id(message, recipient)) + context 'for a message without a parent' do + let(:message) do + FactoryBot.build_stubbed(:message).tap do |msg| + allow(msg) + .to receive(:project) + .and_return(msg.forum.project) + end end - it 'has no references' do - expect(deliveries.first.references) - .to be_nil + it_behaves_like 'mail is sent' do + it 'carries a message_id' do + expect(deliveries.first.message_id) + .to eql "op.message-#{message.id}.#{current_time.strftime('%Y%m%d%H%M%S')}.#{recipient.id}@doe.com" + end + + it 'references the message' do + expect(deliveries.first.references) + .to eql "op.message-#{message.id}@doe.com" + end + + it 'includes a link to the message' do + expect(html_body) + .to have_link(message.subject, + href: topic_url(message, host: Setting.host_name, r: message.id, anchor: "message-#{message.id}")) + end end + end - it 'includes a link to the message' do - expect(html_body) - .to have_link(message.subject, - href: topic_url(message, host: Setting.host_name, r: message.id, anchor: "message-#{message.id}")) + context 'for a message with a parent' do + let(:parent) do + FactoryBot.build_stubbed(:message) + end + + let(:message) do + FactoryBot.build_stubbed(:message, parent: parent).tap do |msg| + allow(msg) + .to receive(:project) + .and_return(msg.forum.project) + end + end + + it_behaves_like 'mail is sent' do + it 'carries a message_id' do + expect(deliveries.first.message_id) + .to eql "op.message-#{message.id}.#{current_time.strftime('%Y%m%d%H%M%S')}.#{recipient.id}@doe.com" + end + + it 'references the message' do + expect(deliveries.first.references) + .to eql %W[op.message-#{parent.id}@doe.com + op.message-#{message.id}@doe.com] + end end end end @@ -194,7 +230,12 @@ describe UserMailer, type: :mailer do it_behaves_like 'mail is sent' do it 'carries a message_id' do expect(mail.message_id) - .to eql(described_class.generate_message_id(news, recipient)) + .to eql "op.news-#{news.id}.#{current_time.strftime('%Y%m%d%H%M%S')}.#{recipient.id}@doe.com" + end + + it 'references the news' do + expect(deliveries.first.references) + .to eql "op.news-#{news.id}@doe.com" end end end @@ -207,7 +248,13 @@ describe UserMailer, type: :mailer do described_class.news_comment_added(recipient, comment).deliver_now end - it_behaves_like 'mail is sent' + it_behaves_like 'mail is sent' do + it 'references the news and the comment' do + expect(deliveries.first.references) + .to eql %W[op.news-#{news.id}@doe.com + op.comment-#{comment.id}@doe.com] + end + end end describe '#password_lost' do @@ -248,50 +295,6 @@ describe UserMailer, type: :mailer do end end - describe '#message_id' do - let(:project) { FactoryBot.build_stubbed(:project) } - let(:message) do - FactoryBot.build_stubbed(:message).tap do |m| - allow(m) - .to receive(:project) - .and_return project - end - end - let(:message2) do - FactoryBot.build_stubbed(:message).tap do |m| - allow(m) - .to receive(:project) - .and_return project - end - end - - describe 'same user' do - subject do - message_ids = [message, message2].map do |m| - described_class.message_posted(user, m).message_id - end - - message_ids.uniq.count - end - - it { expect(subject).to eq(2) } - end - - describe 'same timestamp' do - let(:user2) { FactoryBot.build_stubbed(:user) } - - subject do - message_ids = [user, user2].map do |user| - described_class.message_posted(user, message).message_id - end - - message_ids.uniq.count - end - - it { expect(subject).to eq(2) } - end - end - describe 'localization' do context 'with the user having a language configured', with_settings: { available_languages: %w[en de], diff --git a/spec/mailers/work_package_mailer_spec.rb b/spec/mailers/work_package_mailer_spec.rb index 965916e810..55d5438b11 100644 --- a/spec/mailers/work_package_mailer_spec.rb +++ b/spec/mailers/work_package_mailer_spec.rb @@ -89,10 +89,18 @@ describe WorkPackageMailer, type: :mailer do end it 'has a message id header' do - created_at = work_package.created_at.strftime('%Y%m%d%H%M%S') + Timecop.freeze(Time.current) do + expect(mail.message_id) + .to eql "op.journal-#{journal.id}.#{Time.current.strftime('%Y%m%d%H%M%S')}.#{recipient.id}@example.net" + end + end + + it 'has a references header' do + journal_part = "op.journal-#{journal.id}@example.net" + work_package_part = "op.work_package-#{work_package.id}@example.net" - expect(mail['Message-ID'].value) - .to eql "" + expect(mail.references) + .to eql [work_package_part, journal_part] end it 'has a work package assignee header' do @@ -106,16 +114,32 @@ describe WorkPackageMailer, type: :mailer do let(:watcher_changer) { author } - before do - described_class.watcher_changed(work_package, recipient, author, 'added').deliver_now - described_class.watcher_changed(work_package, recipient, author, 'removed').deliver_now + context 'for an added watcher' do + subject(:mail) { described_class.watcher_changed(work_package, recipient, author, 'added') } + + it 'contains the WP subject in the mail subject' do + expect(mail.subject) + .to include(work_package.subject) + end + + it 'has a references header' do + expect(mail.references) + .to eql "op.work_package-#{work_package.id}@example.net" + end end - include_examples 'multiple mails are sent', 2 + context 'for a removed watcher' do + subject(:mail) { described_class.watcher_changed(work_package, recipient, author, 'removed') } + + it 'contains the WP subject in the mail subject' do + expect(mail.subject) + .to include(work_package.subject) + end - it 'contains the WP subject in the mail subject' do - expect(deliveries.first.subject) - .to include(work_package.subject) + it 'has a references header' do + expect(mail.references) + .to eql "op.work_package-#{work_package.id}@example.net" + end end end end diff --git a/spec/models/mail_handler_spec.rb b/spec/models/mail_handler_spec.rb index 76b345b325..584c76cf56 100644 --- a/spec/models/mail_handler_spec.rb +++ b/spec/models/mail_handler_spec.rb @@ -80,7 +80,7 @@ describe MailHandler, type: :model do end end - shared_context 'wp_update_with_quoted_reply_above' do + shared_context 'with a reply to a wp mention with quotes above' do let(:permissions) { %i[edit_work_packages view_work_packages] } let!(:user) do FactoryBot.create(:user, @@ -90,54 +90,138 @@ describe MailHandler, type: :model do end let!(:work_package) do - FactoryBot.create(:work_package, id: 2, project: project) + FactoryBot.create(:work_package, + id: 2, + project: project).tap do |wp| + wp.journals.last.update_column(:id, 891223) + end end subject do - submit_email('wp_update_with_quoted_reply_above.eml') + submit_email('wp_reply_with_quoted_reply_above.eml') end end - shared_context 'wp_update_with_multiple_quoted_reply_above' do - let(:permissions) { %i[edit_work_packages view_work_packages] } + shared_context 'wp create with cc' do + let(:permissions) { %i[add_work_packages view_work_packages add_work_package_watchers] } let!(:user) do FactoryBot.create(:user, mail: 'JSmith@somenet.foo', + firstname: 'John', + lastname: 'Smith', + member_in_project: project, + member_with_permissions: permissions) + end + let!(:cc_user) do + FactoryBot.create(:user, + mail: 'dlopper@somenet.foo', + firstname: 'D', + lastname: 'Lopper', + member_in_project: project, + member_with_permissions: permissions) + end + let(:submit_options) { { issue: { project: project.identifier } } } + + subject do + submit_email('ticket_with_cc.eml', **submit_options) + end + end + + shared_context 'with a reply to a wp mention' do + let(:permissions) { %i[add_work_package_notes view_work_packages] } + let!(:user) do + FactoryBot.create(:user, + mail: 'j.doe@openproject.org', member_in_project: project, member_with_permissions: permissions) end let!(:work_package) do - FactoryBot.create(:work_package, id: 2, project: project) + FactoryBot.create(:work_package, + subject: 'Some subject of the bug', + id: 39733, + project: project).tap do |wp| + wp.journals.last.update_column(:id, 99999999) + end end subject do - submit_email('wp_update_with_multiple_quoted_reply_above.eml') + submit_email('wp_mention_reply.eml') end end - shared_context 'wp create with cc' do - let(:permissions) { %i[add_work_packages view_work_packages add_work_package_watchers] } + shared_context 'with a reply to a wp mention with attributes' do + let(:permissions) { %i[add_work_package_notes view_work_packages edit_work_packages] } + let(:role) do + FactoryBot.create(:role, permissions: permissions) + end let!(:user) do FactoryBot.create(:user, - mail: 'JSmith@somenet.foo', - firstname: 'John', - lastname: 'Smith', + mail: 'j.doe@openproject.org', member_in_project: project, - member_with_permissions: permissions) + member_through_role: role) end - let!(:cc_user) do + + let!(:work_package) do + FactoryBot.create(:work_package, + subject: 'Some subject of the bug', + id: 39733, + project: project, + status: original_status).tap do |wp| + wp.journals.last.update_column(:id, 99999999) + end + end + let!(:original_status) do + FactoryBot.create(:default_status) + end + let!(:resolved_status) do + FactoryBot.create(:status, + name: 'Resolved').tap do |status| + FactoryBot.create(:workflow, + old_status: original_status, + new_status: status, + role: role, + type: work_package.type) + end + end + let!(:other_user) do FactoryBot.create(:user, - mail: 'dlopper@somenet.foo', - firstname: 'D', - lastname: 'Lopper', + mail: 'jsmith@somenet.foo', + member_in_project: project, + member_through_role: role) + end + let!(:float_cf) do + FactoryBot.create(:float_wp_custom_field, + name: 'float field').tap do |cf| + project.work_package_custom_fields << cf + work_package.type.custom_fields << cf + end + end + + subject do + submit_email('wp_mention_reply_with_attributes.eml') + end + end + + shared_context 'with a reply to a message' do + let(:permissions) { %i[view_messages add_messages] } + let!(:user) do + FactoryBot.create(:user, + mail: 'j.doe@openproject.org', member_in_project: project, member_with_permissions: permissions) end - let(:submit_options) { { issue: { project: project.identifier } } } + + let!(:message) do + FactoryBot.create(:message, + id: 70917, + forum: FactoryBot.create(:forum, project: project)).tap do |wp| + wp.journals.last.update_column(:id, 99999999) + end + end subject do - submit_email('ticket_with_cc.eml', **submit_options) + submit_email('message_reply.eml') end end @@ -162,7 +246,7 @@ describe MailHandler, type: :model do end end - context 'create work package' do + context 'when sending a mail not as a reply' do context 'in a given project' do let!(:status) { FactoryBot.create(:status, name: 'Resolved') } let!(:version) { FactoryBot.create(:version, name: 'alpha', project: project) } @@ -402,7 +486,7 @@ describe MailHandler, type: :model do end end - describe 'update work package' do + context 'when sending a reply to work package mail' do let!(:mail_user) { FactoryBot.create :admin, mail: 'user@example.org' } let!(:work_package) { FactoryBot.create :work_package, project: project } @@ -445,7 +529,7 @@ describe MailHandler, type: :model do end context 'with reply text' do - include_context 'wp_update_with_quoted_reply_above' + include_context 'with a reply to a wp mention with quotes above' it_behaves_like 'journal created' @@ -466,6 +550,66 @@ describe MailHandler, type: :model do end end + context 'when replying to mention mail with only text' do + include_context 'with a reply to a wp mention' + + it_behaves_like 'journal created' + + it 'adds the content to the last journal' do + subject + + expect(work_package.journals.reload.last.notes) + .to include 'The text of the reply.' + end + + it 'does not alter any attributes' do + subject + + expect(work_package.journals.reload.last.details) + .to be_empty + end + + it 'performs the changes in the name of the sender' do + subject + + expect(work_package.journals.reload.last.user) + .to eql user + end + end + + context 'when replying to mention mail with text and attributes' do + include_context 'with a reply to a wp mention with attributes' + + it_behaves_like 'journal created' + + it 'adds the content to the last journal' do + subject + + expect(work_package.journals.reload.last.notes) + .to include 'The text of the reply.' + end + + it 'alters the attributes' do + subject + + expect(work_package.journals.reload.last.details) + .to eql( + "due_date" => [nil, Date.parse("Fri, 31 Dec 2010")], + "status_id" => [original_status.id, resolved_status.id], + "assigned_to_id" => [nil, other_user.id], + "start_date" => [nil, Date.parse("Fri, 01 Jan 2010")], + "custom_fields_#{float_cf.id}" => [nil, "52.6"] + ) + end + + it 'performs the changes in the name of the sender' do + subject + + expect(work_package.journals.reload.last.user) + .to eql user + end + end + context 'with a custom field' do let(:work_package) { FactoryBot.create :work_package, project: project } let(:type) { FactoryBot.create :type } @@ -515,6 +659,30 @@ describe MailHandler, type: :model do end end + context 'when sending a reply to a message mail' do + include_context 'with a reply to a message' + + it 'creates a new message in the name of the sender', aggregate_failures: true do + expect(subject) + .to be_a Message + + expect(subject.subject) + .to eql('Response to the original message') + + expect(subject.content) + .to include('Test message') + + expect(subject.author) + .to eql user + + expect(subject.forum) + .to eql message.forum + + expect(subject.parent) + .to eql message + end + end + context 'truncate emails based on the Setting' do context 'with no setting', with_settings: { mail_handler_body_delimiters: '' } do include_context 'wp_on_given_project' @@ -552,25 +720,7 @@ describe MailHandler, type: :model do context 'with a single quoted reply (e.g. reply to a OpenProject email notification)', with_settings: { mail_handler_body_delimiters: '--- Reply above. Do not remove this line. ---' } do - include_context 'wp_update_with_quoted_reply_above' - - it_behaves_like 'journal created' - - it 'truncates the email at the delimiter with the quoted reply symbols (>)' do - expect(subject.notes) - .to include('An update to the issue by the sender.') - - expect(subject.notes) - .not_to match(Regexp.escape('--- Reply above. Do not remove this line. ---')) - - expect(subject.notes) - .not_to include('Looks like the JSON api for projects was missed.') - end - end - - context 'with multiple quoted replies (e.g. reply to a reply of a Redmine email notification)', - with_settings: { mail_handler_body_delimiters: '--- Reply above. Do not remove this line. ---' } do - include_context 'wp_update_with_quoted_reply_above' + include_context 'with a reply to a wp mention with quotes above' it_behaves_like 'journal created' @@ -649,36 +799,6 @@ describe MailHandler, type: :model do end end - describe '#dispatch_target_from_message_id' do - let!(:mail_user) { FactoryBot.create :admin, mail: 'user@example.org' } - let(:instance) do - mh = MailHandler.new - mh.options = {} - mh - end - subject { instance.receive mail } - - context 'receiving reply from work package' do - let(:mail) { Mail.new(read_email('work_package_reply.eml')) } - - it 'calls the work package reply' do - expect(instance).to receive(:receive_work_package_reply).with(34540) - - subject - end - end - - context 'receiving reply from message' do - let(:mail) { Mail.new(read_email('message_reply.eml')) } - - it 'calls the work package reply' do - expect(instance).to receive(:receive_message_reply).with(12559) - - subject - end - end - end - private FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' diff --git a/spec/workers/copy_project_job_spec.rb b/spec/workers/copy_project_job_spec.rb index 847266b775..fed2872188 100644 --- a/spec/workers/copy_project_job_spec.rb +++ b/spec/workers/copy_project_job_spec.rb @@ -230,10 +230,11 @@ describe CopyProjectJob, type: :model do it "notifies the user of the success" do mail = ActionMailer::Base.deliveries - .find { |m| m.message_id.start_with? "openproject.project-#{user.id}-#{subject.id}" } + .find { |m| m.message_id.start_with? "op.project-#{subject.id}" } expect(mail).to be_present expect(mail.subject).to eq "Created project #{subject.name}" + expect(mail.to).to eq [user.mail] end end @@ -263,10 +264,11 @@ describe CopyProjectJob, type: :model do it "notifies the user of the success" do mail = ActionMailer::Base.deliveries - .find { |m| m.message_id.start_with? "openproject.project-#{user.id}-#{subject.id}" } + .find { |m| m.message_id.start_with? "op.project-#{subject.id}" } expect(mail).to be_present expect(mail.subject).to eq "Created project #{subject.name}" + expect(mail.to).to eq [user.mail] end end end diff --git a/spec_legacy/fixtures/mail_handler/message_reply.eml b/spec_legacy/fixtures/mail_handler/message_reply.eml deleted file mode 100644 index 182b9a6886..0000000000 --- a/spec_legacy/fixtures/mail_handler/message_reply.eml +++ /dev/null @@ -1,15 +0,0 @@ -Message-ID: <4974C93E.3070005@somenet.foo> -Date: Mon, 19 Jan 2009 19:41:02 +0100 -From: "John Smith" -User-Agent: Thunderbird 2.0.0.19 (Windows/20081209) -MIME-Version: 1.0 -To: openproject@somenet.foo -Subject: Reply via email -References: -In-Reply-To: -Content-Type: text/plain; charset=UTF-8; format=flowed -Content-Transfer-Encoding: 7bit - -This is a reply to a forum message. - - diff --git a/spec_legacy/fixtures/mail_handler/message_reply_by_subject.eml b/spec_legacy/fixtures/mail_handler/message_reply_by_subject.eml deleted file mode 100644 index 985aaa0e45..0000000000 --- a/spec_legacy/fixtures/mail_handler/message_reply_by_subject.eml +++ /dev/null @@ -1,13 +0,0 @@ -Message-ID: <4974C93E.3070005@somenet.foo> -Date: Mon, 19 Jan 2009 19:41:02 +0100 -From: "John Smith" -User-Agent: Thunderbird 2.0.0.19 (Windows/20081209) -MIME-Version: 1.0 -To: redmine@somenet.foo -Subject: Re: [eCookbook - Help board - msg2] Reply to the first post -Content-Type: text/plain; charset=UTF-8; format=flowed -Content-Transfer-Encoding: 7bit - -This is a reply to a forum message. - - diff --git a/spec_legacy/fixtures/mail_handler/ticket_reply.eml b/spec_legacy/fixtures/mail_handler/ticket_reply.eml deleted file mode 100644 index 4a8d4c4b3f..0000000000 --- a/spec_legacy/fixtures/mail_handler/ticket_reply.eml +++ /dev/null @@ -1,74 +0,0 @@ -Return-Path: -Received: from osiris ([127.0.0.1]) - by OSIRIS - with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200 -Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris> -In-Reply-To: -From: "John Smith" -To: -References: <485d0ad366c88_d7014663a025f@osiris.tmail> -Subject: Re: Add ingredients categories -Date: Sat, 21 Jun 2008 18:41:39 +0200 -MIME-Version: 1.0 -Content-Type: multipart/alternative; - boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0" -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2900.2869 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 - -This is a multi-part message in MIME format. - -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/plain; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -This is reply -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/html; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -=EF=BB=BF - - - - - - -
This is=20 -reply
- -------=_NextPart_000_0067_01C8D3CE.711F9CC0-- - diff --git a/spec_legacy/fixtures/mail_handler/ticket_reply_by_message_id.eml b/spec_legacy/fixtures/mail_handler/ticket_reply_by_message_id.eml deleted file mode 100644 index 70a3168ec4..0000000000 --- a/spec_legacy/fixtures/mail_handler/ticket_reply_by_message_id.eml +++ /dev/null @@ -1,74 +0,0 @@ -Return-Path: -Received: from osiris ([127.0.0.1]) - by OSIRIS - with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200 -Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris> -In-Reply-To: -From: "John Smith" -To: -References: <485d0ad366c88_d7014663a025f@osiris.tmail> -Subject: Re: Add ingredients categories -Date: Sat, 21 Jun 2008 18:41:39 +0200 -MIME-Version: 1.0 -Content-Type: multipart/alternative; - boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0" -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2900.2869 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 - -This is a multi-part message in MIME format. - -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/plain; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -This is reply -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/html; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -=EF=BB=BF - - - - - - -
This is=20 -reply
- -------=_NextPart_000_0067_01C8D3CE.711F9CC0-- - diff --git a/spec_legacy/fixtures/mail_handler/ticket_reply_with_status.eml b/spec_legacy/fixtures/mail_handler/ticket_reply_with_status.eml deleted file mode 100644 index 0a849dd588..0000000000 --- a/spec_legacy/fixtures/mail_handler/ticket_reply_with_status.eml +++ /dev/null @@ -1,80 +0,0 @@ -Return-Path: -Received: from osiris ([127.0.0.1]) - by OSIRIS - with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200 -Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris> -From: "John Smith" -To: -References: <485d0ad366c88_d7014663a025f@osiris.tmail> -Subject: Re: Cookbook - New Feature #2: Add ingredients categories -Date: Sat, 21 Jun 2008 18:41:39 +0200 -MIME-Version: 1.0 -Content-Type: multipart/alternative; - boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0" -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2900.2869 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869 - -This is a multi-part message in MIME format. - -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/plain; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -This is reply - -Status: Resolved -due date: 2010-12-31 -Start Date:2010-01-01 -Assigned to: jsmith@somenet.foo -float field: 52.6 - -------=_NextPart_000_0067_01C8D3CE.711F9CC0 -Content-Type: text/html; - charset="utf-8" -Content-Transfer-Encoding: quoted-printable - -=EF=BB=BF - - - - - - -
This is=20 -reply Status: Resolved
- -------=_NextPart_000_0067_01C8D3CE.711F9CC0-- - diff --git a/spec_legacy/unit/mail_handler_spec.rb b/spec_legacy/unit/mail_handler_spec.rb index 022f5757f4..ca9c6477a7 100644 --- a/spec_legacy/unit/mail_handler_spec.rb +++ b/spec_legacy/unit/mail_handler_spec.rb @@ -267,72 +267,6 @@ describe MailHandler, type: :model do end end - it 'should add work package note' do - journal = submit_email('ticket_reply.eml') - assert journal.is_a?(Journal) - assert_equal User.find_by_login('jsmith'), journal.user - assert_equal WorkPackage.find(2), journal.journable - assert_match /This is reply/, journal.notes - assert_equal 'Feature request', journal.journable.type.name - end - - specify 'reply to issue update (Journal) by message_id' do - Journal.delete_all - FactoryBot.create :work_package_journal, id: 3, version: 1, journable_id: 2 - journal = submit_email('ticket_reply_by_message_id.eml') - assert journal.data.is_a?(Journal::WorkPackageJournal), "Email was a #{journal.data.class}" - assert_equal User.find_by_login('jsmith'), journal.user - assert_equal WorkPackage.find(2), journal.journable - assert_match /This is reply/, journal.notes - assert_equal 'Feature request', journal.journable.type.name - end - - it 'should add work package note with attribute changes' do - # This email contains: 'Status: Resolved' - journal = submit_email('ticket_reply_with_status.eml') - assert journal.data.is_a?(Journal::WorkPackageJournal) - issue = WorkPackage.find(journal.journable.id) - assert_equal User.find_by_login('jsmith'), journal.user - assert_equal WorkPackage.find(2), journal.journable - assert_match /This is reply/, journal.notes - assert_equal 'Feature request', journal.journable.type.name - assert_equal Status.find_by(name: 'Resolved'), issue.status - assert_equal '2010-01-01', issue.start_date.to_s - assert_equal '2010-12-31', issue.due_date.to_s - assert_equal User.find_by_login('jsmith'), issue.assigned_to - assert_equal '52.6', issue.custom_value_for(CustomField.find_by(name: 'Float field')).value - # keywords should be removed from the email body - assert !journal.notes.match(/^Status:/i) - assert !journal.notes.match(/^Start Date:/i) - end - - it 'should add work package note should not set defaults' do - journal = submit_email('ticket_reply.eml', issue: { type: 'Support request', priority: 'High' }) - assert journal.is_a?(Journal) - assert_match /This is reply/, journal.notes - assert_equal 'Feature request', journal.journable.type.name - assert_equal 'Normal', journal.journable.priority.name - end - - it 'should reply to a message' do - m = submit_email('message_reply.eml') - assert m.is_a?(Message) - assert !m.new_record? - m.reload - assert_equal 'Reply via email', m.subject - # The email replies to message #2 which is part of the thread of message #1 - assert_equal Message.find(1), m.parent - end - - it 'should reply to a message by subject' do - m = submit_email('message_reply_by_subject.eml') - assert m.is_a?(Message) - assert !m.new_record? - m.reload - assert_equal 'Reply to the first post', m.subject - assert_equal Message.find(1), m.parent - end - it 'should strip tags of html only emails' do issue = submit_email('ticket_html_only.eml', issue: { project: 'ecookbook' }) assert issue.is_a?(WorkPackage)