discourse/spec/jobs/regular/group_smtp_email_spec.rb
Martin Brennan 64b0b50ac0
FIX: Pass user to Email::Sender to avoid broken reply key for group_smtp email (#10978)
Our Email::Sender class accepts an optional user argument, which is used to create a PostReplyKey record when present. This record is used to sub out the %{reply_key} placeholder in the Reply-To mail header, so if we do not pass in the user we get a broken Reply-To header.

This is especially problematic in the IMAP group SMTP situation, because these emails go to customers that we are replying to, and when they reply to us the email bounces! This fixes the issue by passing user to the Email::Sender when sending a group_smtp email but there is still more to do in another PR.

This Email::Sender optional user is a bit of a footgun IMO, especially because most of the time we use it there is a user we can source. I would like to do another PR for this after this one to make the parameter not optional, so we don't end up with these reply issues down the line again.
2020-10-22 10:49:08 +10:00

45 lines
1.6 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Jobs::GroupSmtpEmail do
let(:post) { Fabricate(:post) }
let(:group) { Fabricate(:imap_group) }
let(:args) do
{
group_id: group.id,
post_id: post.id,
email: "test@test.com"
}
end
before do
SiteSetting.reply_by_email_address = "test+%{reply_key}@incoming.com"
SiteSetting.manual_polling_enabled = true
SiteSetting.reply_by_email_enabled = true
SiteSetting.enable_smtp = true
end
it "sends an email using the GroupSmtpMailer and Email::Sender" do
message = Mail::Message.new(body: "hello", to: "myemail@example.invalid")
GroupSmtpMailer.expects(:send_mail).with(group, "test@test.com", post).returns(message)
Email::Sender.expects(:new).with(message, :group_smtp, post.user).returns(stub(send: nil))
subject.execute(args)
end
it "creates an IncomingEmail record to avoid double processing via IMAP" do
subject.execute(args)
incoming = IncomingEmail.find_by(post_id: post.id, user_id: post.user_id, topic_id: post.topic_id)
expect(incoming).not_to eq(nil)
expect(incoming.message_id).to eq("topic/#{post.topic_id}@test.localhost")
end
it "creates a PostReplyKey and correctly uses it for the email reply_key substitution" do
subject.execute(args)
incoming = IncomingEmail.find_by(post_id: post.id, user_id: post.user_id, topic_id: post.topic_id)
post_reply_key = PostReplyKey.where(user_id: post.user_id, post_id: post.id).first
expect(post_reply_key).not_to eq(nil)
expect(incoming.raw).to include("Reply-To: Discourse <test+#{post_reply_key.reply_key}@incoming.com>")
end
end