sending empty mail on mentioning

pull/9700/head
ulferts 3 years ago committed by Henriette Darge
parent c24508b07c
commit 8aca19d827
  1. 16
      app/mailers/application_mailer.rb
  2. 17
      app/mailers/user_mailer.rb
  3. 65
      app/mailers/work_package_mailer.rb
  4. 40
      app/services/notifications/mail_service/work_package_strategy.rb
  5. 0
      app/views/work_package_mailer/mentioned.html.erb
  6. 0
      app/views/work_package_mailer/mentioned.text.erb
  7. 2
      config/locales/en.yml
  8. 6
      spec/factories/user_factory.rb
  9. 52
      spec/features/notifications/immediate_reminder_spec.rb
  10. 108
      spec/mailers/work_package_mailer_spec.rb
  11. 86
      spec/services/notifications/mail_service_spec.rb

@ -110,10 +110,26 @@ class ApplicationMailer < ActionMailer::Base
super(headers, &block)
end
# like #mail, but contains special author based filters
# currently only:
# - remove_self_notifications
# might be refactored at a later time to be as generic as Interceptors
def mail_for_author(author, headers = {}, &block)
message = mail headers, &block
self.class.remove_self_notifications(message, author)
message
end
def message_id(object, user)
headers['Message-ID'] = "<#{self.class.generate_message_id(object, user)}>"
end
def references(object, user)
headers['References'] = "<#{self.class.generate_message_id(object, user)}>"
end
# Prepends given fields with 'X-OpenProject-' to save some duplication
def open_project_headers(hash)
hash.each { |key, value| headers["X-OpenProject-#{key}"] = value.to_s }

@ -279,22 +279,7 @@ class UserMailer < ApplicationMailer
"#{wp.project.name} - #{wp.status.name} #{wp.type.name} ##{wp.id}: #{wp.subject}"
end
# like #mail, but contains special author based filters
# currently only:
# - remove_self_notifications
# might be refactored at a later time to be as generic as Interceptors
def mail_for_author(author, headers = {}, &block)
message = mail headers, &block
self.class.remove_self_notifications(message, author)
message
end
def references(object, user)
headers['References'] = "<#{self.class.generate_message_id(object, user)}>"
end
# TODO: Delete since moved to WorkPackageMailer
def set_work_package_headers(work_package)
open_project_headers 'Project' => work_package.project.identifier,
'Issue-Id' => work_package.id,

@ -0,0 +1,65 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class WorkPackageMailer < ApplicationMailer
def mentioned(recipient, journal)
author = journal.user
work_package = journal.journable
User.execute_as author do
set_work_package_headers(work_package)
message_id journal, recipient
references work_package, recipient
with_locale_for(recipient) do
mail_for_author author,
to: recipient.mail,
subject: I18n.t(:'mail.mention.subject',
user_name: author.name,
id: work_package.id,
subject: work_package.subject)
end
end
end
private
def set_work_package_headers(work_package)
open_project_headers 'Project' => work_package.project.identifier,
'WorkPackage-Id' => work_package.id,
'WorkPackage-Author' => work_package.author.login,
'Type' => 'WorkPackage'
if work_package.assigned_to
open_project_headers 'WorkPackage-Assignee' => work_package.assigned_to.login
end
end
end

@ -0,0 +1,40 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
module Notifications::MailService::WorkPackageStrategy
class << self
def send_mail(notification)
return unless notification.ian_mentioned?
return unless notification.recipient.pref.immediate_reminders[:mentioned]
WorkPackageMailer
.mentioned(notification.recipient, notification.journal)
.deliver_later
end
end
end

@ -1998,6 +1998,8 @@ en:
updated_at: 'at %{timestamp} by %{user}'
you_have: 'You have'
logo_alt_text: 'Logo'
mention:
subject: "%{user_name} mentioned you in #%{id} - %{subject}"
notification:
center: 'To notification center'
settings: 'Change email settings'

@ -72,6 +72,12 @@ FactoryBot.define do
end
end
callback(:after_stub) do |user, evaluator|
if evaluator.preferences.present?
user.preference = FactoryBot.build_stubbed(:user_preference, user: user, settings: evaluator.preferences)
end
end
factory :admin do
firstname { 'OpenProject' }
sequence(:lastname) { |n| "Admin#{n}" }

@ -50,4 +50,56 @@ describe "Immediate reminder settings", type: :feature, js: true do
it_behaves_like 'immediate reminder settings'
end
describe 'email sending', js: false do
let(:project) { FactoryBot.create(:project) }
let(:work_package) { FactoryBot.create(:work_package, project: project) }
let(:receiver) do
FactoryBot.create(
:user,
preferences: {
immediate_reminders: {
mentioned: true
}
},
notification_settings: [
FactoryBot.build(:in_app_notification_setting,
mentioned: true),
FactoryBot.build(:mail_notification_setting,
mentioned: true)
],
member_in_project: project,
member_with_permissions: %i[view_work_packages]
)
end
current_user do
FactoryBot.create(:user)
end
it 'sends a mail to the mentioned user immediately' do
perform_enqueued_jobs do
note = <<~NOTE
Hey <mention class=\"mention\"
data-id=\"#{receiver.id}\"
data-type=\"user\"
data-text=\"@#{receiver.name}\">
@#{receiver.name}
</mention>
NOTE
work_package.add_journal(current_user, note)
work_package.save!
end
expect(ActionMailer::Base.deliveries.length)
.to be 1
expect(ActionMailer::Base.deliveries.first.subject)
.to eql I18n.t(:'mail.mention.subject',
user_name: current_user.name,
id: work_package.id,
subject: work_package.subject)
end
end
end

@ -0,0 +1,108 @@
#-- encoding: UTF-8
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
require 'spec_helper'
describe WorkPackageMailer, type: :mailer do
include OpenProject::ObjectLinking
include ActionView::Helpers::UrlHelper
include OpenProject::StaticRouting::UrlHelpers
let(:work_package) do
FactoryBot.build_stubbed(:work_package,
project: project,
assigned_to: assignee)
end
let(:project) { FactoryBot.build_stubbed(:project) }
let(:author) { FactoryBot.build_stubbed(:user) }
let(:recipient) { FactoryBot.build_stubbed(:user) }
let(:assignee) { FactoryBot.build_stubbed(:user) }
let(:journal) do
FactoryBot.build_stubbed(:work_package_journal,
journable: work_package,
user: author)
end
describe '#mentioned' do
subject(:mail) { described_class.mentioned(recipient, journal) }
it "has a subject" do
expect(mail.subject)
.to eql I18n.t(:'mail.mention.subject',
user_name: author.name,
id: work_package.id,
subject: work_package.subject)
end
it 'is sent to the recipient' do
expect(mail.to)
.to match_array([recipient.mail])
end
it 'has a project header' do
expect(mail['X-OpenProject-Project'].value)
.to eql project.identifier
end
it 'has a work package id header' do
expect(mail['X-OpenProject-WorkPackage-Id'].value)
.to eql work_package.id.to_s
end
it 'has a work package author header' do
expect(mail['X-OpenProject-WorkPackage-Author'].value)
.to eql work_package.author.login
end
it 'has a type header' do
expect(mail['X-OpenProject-Type'].value)
.to eql 'WorkPackage'
end
it 'has a message id header' do
created_at = work_package.created_at.strftime('%Y%m%d%H%M%S')
expect(mail['Message-ID'].value)
.to eql "<openproject.work_package-#{recipient.id}-#{work_package.id}.#{created_at}@example.net>"
end
it 'has a references header' do
created_at = work_package.created_at.strftime('%Y%m%d%H%M%S')
expect(mail['References'].value)
.to eql "<openproject.work_package-#{recipient.id}-#{work_package.id}.#{created_at}@example.net>"
end
it 'has a work package assignee header' do
expect(mail['X-OpenProject-WorkPackage-Assignee'].value)
.to eql work_package.assigned_to.login
end
end
end

@ -34,12 +34,96 @@ describe Notifications::MailService, type: :model do
subject(:call) { instance.call }
let(:recipient) do
FactoryBot.build_stubbed(:user)
FactoryBot.build_stubbed(:user,
preference: FactoryBot.build_stubbed(:user_preference,
settings: {
immediate_reminders: {
mentioned: immediate_reminders_mentioned
}
}))
end
let(:actor) do
FactoryBot.build_stubbed(:user)
end
let(:instance) { described_class.new(notification) }
let(:immediate_reminders_mentioned) { true }
context 'with a work package journal notification' do
let(:journal) do
FactoryBot.build_stubbed(:work_package_journal).tap do |j|
allow(j)
.to receive(:initial?)
.and_return(journal_initial)
end
end
let(:read_ian) { false }
let(:reason_ian) { :mentioned }
let(:notification) do
FactoryBot.build_stubbed(:notification,
journal: journal,
recipient: recipient,
actor: actor,
reason_ian: reason_ian,
read_ian: read_ian)
end
let(:journal_initial) { false }
let(:mail) do
mail = instance_double(ActionMailer::MessageDelivery)
allow(WorkPackageMailer)
.to receive(:mentioned)
.and_return(mail)
allow(mail)
.to receive(:deliver_later)
mail
end
before do
mail
end
shared_examples_for 'sends a mentioned mail' do
it 'sends a mail' do
call
expect(WorkPackageMailer)
.to have_received(:mentioned)
.with(recipient,
journal)
expect(mail)
.to have_received(:deliver_later)
end
end
shared_examples_for 'sends no mentioned mail' do
it 'sends no mail' do
call
expect(WorkPackageMailer)
.not_to have_received(:mentioned)
end
end
context 'with the notification mentioning the user' do
it_behaves_like 'sends a mentioned mail'
end
context 'with the notification not mentioning the user' do
let(:reason_ian) { false }
it_behaves_like 'sends no mentioned mail'
end
context 'with the notification mentioning the user but with the recipient having deactivated the mail' do
let(:immediate_reminders_mentioned) { false }
it_behaves_like 'sends no mentioned mail'
end
end
context 'with a wiki_content journal notification' do
let(:journal) do

Loading…
Cancel
Save