Handle namespaced models

We encountered issues with setting module headers for namespaced models.
These changes address this. We retain the namespacing, but transform the
classnames to make them into safe email headers.
This commit is contained in:
Alex Kalderimis 2019-08-21 19:23:27 +00:00 committed by Mayra Cabrera
parent 2ef59c7e4b
commit ac94033b2d
2 changed files with 80 additions and 2 deletions

View file

@ -125,9 +125,8 @@ class Notify < BaseMailer
def mail_thread(model, headers = {})
add_project_headers
add_unsubscription_headers_and_links
add_model_headers(model)
headers["X-GitLab-#{model.class.name}-ID"] = model.id
headers["X-GitLab-#{model.class.name}-IID"] = model.iid if model.respond_to?(:iid)
headers['X-GitLab-Reply-Key'] = reply_key
@reason = headers['X-GitLab-NotificationReason']
@ -196,6 +195,18 @@ class Notify < BaseMailer
@reply_key ||= SentNotification.reply_key
end
# This method applies threading headers to the email to identify
# the instance we are discussing.
#
# All model instances must have `#id`, and may implement `#iid`.
def add_model_headers(object)
# Use replacement so we don't strip the module.
prefix = "X-GitLab-#{object.class.name.gsub(/::/, '-')}"
headers["#{prefix}-ID"] = object.id
headers["#{prefix}-IID"] = object.iid if object.respond_to?(:iid)
end
def add_project_headers
return unless @project

View file

@ -543,6 +543,73 @@ describe Notify do
end
end
describe '#mail_thread' do
set(:mail_thread_note) { create(:note) }
let(:headers) do
{
from: 'someone@test.com',
to: 'someone-else@test.com',
subject: 'something',
template_name: '_note_email' # re-use this for testing
}
end
let(:mailer) do
mailer = described_class.new
mailer.instance_variable_set(:@note, mail_thread_note)
mailer
end
context 'the model has no namespace' do
class TopLevelThing
include Referable
include Noteable
def to_reference(*_args)
'tlt-ref'
end
def id
'tlt-id'
end
end
subject do
mailer.send(:mail_thread, TopLevelThing.new, headers)
end
it 'has X-GitLab-Namespaced-Thing-ID header' do
expect(subject.header['X-GitLab-TopLevelThing-ID'].value).to eq('tlt-id')
end
end
context 'the model has a namespace' do
module Namespaced
class Thing
include Referable
include Noteable
def to_reference(*_args)
'some-reference'
end
def id
'some-id'
end
end
end
subject do
mailer.send(:mail_thread, Namespaced::Thing.new, headers)
end
it 'has X-GitLab-Namespaced-Thing-ID header' do
expect(subject.header['X-GitLab-Namespaced-Thing-ID'].value).to eq('some-id')
end
end
end
context 'for issue notes' do
let(:host) { Gitlab.config.gitlab.host }