2019-04-30 08:27:42 +08:00
# frozen_string_literal: true
2015-10-11 17:41:23 +08:00
require 'rails_helper'
2013-06-04 04:12:24 +08:00
describe Admin :: EmailController do
2019-05-07 11:12:20 +08:00
fab! ( :admin ) { Fabricate ( :admin ) }
fab! ( :email_log ) { Fabricate ( :email_log ) }
2018-06-11 12:50:08 +08:00
before do
sign_in ( admin )
end
2013-06-04 04:12:24 +08:00
it " is a subclass of AdminController " do
2015-01-10 01:04:02 +08:00
expect ( Admin :: EmailController < Admin :: AdminController ) . to eq ( true )
2013-06-04 04:12:24 +08:00
end
2018-06-11 12:50:08 +08:00
describe '#index' do
2013-06-04 04:12:24 +08:00
before do
2018-06-11 12:50:08 +08:00
Admin :: EmailController . any_instance
2017-08-31 12:06:56 +08:00
. expects ( :action_mailer_settings )
. returns (
username : 'username' ,
password : 'secret'
)
2013-06-04 04:12:24 +08:00
end
2013-06-12 07:00:13 +08:00
it 'does not include the password in the response' do
2018-06-11 12:50:08 +08:00
get " /admin/email.json "
2020-05-07 23:04:12 +08:00
mail_settings = response . parsed_body [ 'settings' ]
2013-06-12 07:00:13 +08:00
expect (
mail_settings . select { | setting | setting [ 'name' ] == 'password' }
) . to be_empty
end
2013-06-04 04:12:24 +08:00
end
2018-06-11 12:50:08 +08:00
describe '#sent' do
2019-05-07 11:12:20 +08:00
fab! ( :post ) { Fabricate ( :post ) }
fab! ( :email_log ) { Fabricate ( :email_log , post : post ) }
2018-07-18 16:28:44 +08:00
let ( :post_reply_key ) do
Fabricate ( :post_reply_key , post : post , user : email_log . user )
end
it " should return the right response " do
email_log
get " /admin/email/sent.json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
log = response . parsed_body . first
2018-07-18 16:28:44 +08:00
expect ( log [ " id " ] ) . to eq ( email_log . id )
expect ( log [ " reply_key " ] ) . to eq ( nil )
post_reply_key
2018-06-11 12:50:08 +08:00
get " /admin/email/sent.json "
2018-07-18 16:28:44 +08:00
2018-06-11 12:50:08 +08:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
log = response . parsed_body . first
2018-07-18 16:28:44 +08:00
expect ( log [ " id " ] ) . to eq ( email_log . id )
expect ( log [ " reply_key " ] ) . to eq ( post_reply_key . reply_key )
2014-02-15 07:50:08 +08:00
end
2019-01-10 09:21:28 +08:00
it 'should be able to filter by reply key' do
email_log_2 = Fabricate ( :email_log , post : post )
post_reply_key_2 = Fabricate ( :post_reply_key ,
post : post ,
user : email_log_2 . user ,
reply_key : " 2d447423-c625-4fb9-8717-ff04ac60eee8 "
)
[
2019-01-10 09:56:03 +08:00
" 17ff04 " ,
" 2d447423c6254fb98717ff04ac60eee8 "
2019-01-10 09:21:28 +08:00
] . each do | reply_key |
get " /admin/email/sent.json " , params : {
reply_key : reply_key
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
logs = response . parsed_body
2019-01-10 09:21:28 +08:00
expect ( logs . size ) . to eq ( 1 )
expect ( logs . first [ " reply_key " ] ) . to eq ( post_reply_key_2 . reply_key )
end
end
2014-02-15 07:50:08 +08:00
end
2018-06-11 12:50:08 +08:00
describe '#skipped' do
2019-05-07 11:12:20 +08:00
fab! ( :user ) { Fabricate ( :user ) }
2020-03-11 05:13:17 +08:00
fab! ( :log1 ) { Fabricate ( :skipped_email_log , user : user , created_at : 20 . minutes . ago ) }
fab! ( :log2 ) { Fabricate ( :skipped_email_log , created_at : 10 . minutes . ago ) }
2018-07-24 12:55:43 +08:00
2018-06-11 12:50:08 +08:00
it " succeeds " do
get " /admin/email/skipped.json "
2018-07-24 12:55:43 +08:00
2018-06-11 12:50:08 +08:00
expect ( response . status ) . to eq ( 200 )
2018-07-24 12:55:43 +08:00
2020-05-07 23:04:12 +08:00
logs = response . parsed_body
2018-07-24 12:55:43 +08:00
expect ( logs . first [ " id " ] ) . to eq ( log2 . id )
expect ( logs . last [ " id " ] ) . to eq ( log1 . id )
end
describe 'when filtered by username' do
it 'should return the right response' do
get " /admin/email/skipped.json " , params : {
user : user . username
}
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
logs = response . parsed_body
2018-07-24 12:55:43 +08:00
expect ( logs . count ) . to eq ( 1 )
expect ( logs . first [ " id " ] ) . to eq ( log1 . id )
end
2013-06-04 04:12:24 +08:00
end
end
2018-06-11 12:50:08 +08:00
describe '#test' do
2013-06-04 04:12:24 +08:00
it 'raises an error without the email parameter' do
2018-06-11 12:50:08 +08:00
post " /admin/email/test.json "
expect ( response . status ) . to eq ( 400 )
2013-06-04 04:12:24 +08:00
end
context 'with an email address' do
it 'enqueues a test email job' do
2018-06-11 12:50:08 +08:00
post " /admin/email/test.json " , params : { email_address : 'eviltrout@test.domain' }
2018-07-24 12:55:43 +08:00
2018-06-11 12:50:08 +08:00
expect ( response . status ) . to eq ( 200 )
expect ( ActionMailer :: Base . deliveries . map ( & :to ) . flatten ) . to include ( 'eviltrout@test.domain' )
2013-06-04 04:12:24 +08:00
end
end
2018-08-30 05:14:16 +08:00
context 'with SiteSetting.disable_emails' do
2019-05-07 11:12:20 +08:00
fab! ( :eviltrout ) { Fabricate ( :evil_trout ) }
fab! ( :admin ) { Fabricate ( :admin ) }
2018-08-30 05:14:16 +08:00
2019-03-22 05:57:09 +08:00
it 'bypasses disable when setting is "yes"' do
2018-08-30 05:14:16 +08:00
SiteSetting . disable_emails = 'yes'
post " /admin/email/test.json " , params : { email_address : admin . email }
2019-03-22 05:57:09 +08:00
expect ( ActionMailer :: Base . deliveries . first . to ) . to contain_exactly (
admin . email
)
2020-05-07 23:04:12 +08:00
incoming = response . parsed_body
2019-03-22 05:57:09 +08:00
expect ( incoming [ 'sent_test_email_message' ] ) . to eq ( I18n . t ( " admin.email.sent_test " ) )
2018-08-30 05:14:16 +08:00
end
2019-03-22 05:57:09 +08:00
it 'bypasses disable when setting is "non-staff"' do
2018-08-30 05:14:16 +08:00
SiteSetting . disable_emails = 'non-staff'
post " /admin/email/test.json " , params : { email_address : eviltrout . email }
2019-03-22 05:57:09 +08:00
expect ( ActionMailer :: Base . deliveries . first . to ) . to contain_exactly (
eviltrout . email
)
2020-05-07 23:04:12 +08:00
incoming = response . parsed_body
2019-03-22 05:57:09 +08:00
expect ( incoming [ 'sent_test_email_message' ] ) . to eq ( I18n . t ( " admin.email.sent_test " ) )
2018-08-30 05:14:16 +08:00
end
2019-03-22 05:57:09 +08:00
it 'works when setting is "no"' do
2018-08-30 05:14:16 +08:00
SiteSetting . disable_emails = 'no'
post " /admin/email/test.json " , params : { email_address : eviltrout . email }
2019-03-22 05:57:09 +08:00
expect ( ActionMailer :: Base . deliveries . first . to ) . to contain_exactly (
eviltrout . email
)
2020-05-07 23:04:12 +08:00
incoming = response . parsed_body
2018-08-30 05:14:16 +08:00
expect ( incoming [ 'sent_test_email_message' ] ) . to eq ( I18n . t ( " admin.email.sent_test " ) )
end
end
2013-06-04 04:12:24 +08:00
end
2018-06-11 12:50:08 +08:00
describe '#preview_digest' do
2013-06-04 04:12:24 +08:00
it 'raises an error without the last_seen_at parameter' do
2018-06-11 12:50:08 +08:00
get " /admin/email/preview-digest.json "
expect ( response . status ) . to eq ( 400 )
2013-06-04 04:12:24 +08:00
end
2019-01-30 16:04:47 +08:00
it " returns the right response when username is invalid " do
get " /admin/email/preview-digest.json " , params : {
last_seen_at : 1 . week . ago , username : " somerandomeusername "
}
expect ( response . status ) . to eq ( 400 )
end
2013-06-04 04:12:24 +08:00
it " previews the digest " do
2018-06-11 12:50:08 +08:00
get " /admin/email/preview-digest.json " , params : {
last_seen_at : 1 . week . ago , username : admin . username
}
2018-06-07 16:11:09 +08:00
expect ( response . status ) . to eq ( 200 )
2013-06-04 04:12:24 +08:00
end
end
2018-06-11 12:50:08 +08:00
describe '#handle_mail' do
2021-05-06 10:59:52 +08:00
it " returns a bad request if neither email parameter is present " do
post " /admin/email/handle_mail.json "
expect ( response . status ) . to eq ( 400 )
expect ( response . body ) . to include ( " param is missing " )
end
it 'should enqueue the right job, and show a deprecation warning (email_encoded param should be used)' do
expect_enqueued_with (
job : :process_email ,
args : { mail : email ( 'cc' ) , retry_on_rate_limit : true , source : :handle_mail }
) do
post " /admin/email/handle_mail.json " , params : { email : email ( 'cc' ) }
end
expect ( response . status ) . to eq ( 200 )
2022-01-14 07:33:15 +08:00
expect ( response . body ) . to eq ( " warning: the email parameter is deprecated. all POST requests to this route should be sent with a base64 strict encoded email_encoded parameter instead. email has been received and is queued for processing " )
2021-05-06 10:59:52 +08:00
end
it 'should enqueue the right job, decoding the raw email param' do
expect_enqueued_with (
job : :process_email ,
args : { mail : email ( 'cc' ) , retry_on_rate_limit : true , source : :handle_mail }
) do
post " /admin/email/handle_mail.json " , params : { email_encoded : Base64 . strict_encode64 ( email ( 'cc' ) ) }
end
2018-06-11 12:50:08 +08:00
expect ( response . status ) . to eq ( 200 )
2021-05-06 10:59:52 +08:00
expect ( response . body ) . to eq ( " email has been received and is queued for processing " )
2021-05-10 12:26:23 +08:00
end
it " retries enqueueing with forced UTF-8 encoding when encountering Encoding::UndefinedConversionError " do
post " /admin/email/handle_mail.json " , params : { email_encoded : Base64 . strict_encode64 ( email ( 'encoding_undefined_conversion' ) ) }
expect ( response . status ) . to eq ( 200 )
expect ( response . body ) . to eq ( " email has been received and is queued for processing " )
2017-04-24 12:06:28 +08:00
end
end
2018-06-11 12:50:08 +08:00
describe '#rejected' do
2017-08-05 02:04:26 +08:00
it 'should provide a string for a blank error' do
Fabricate ( :incoming_email , error : " " )
2018-06-11 12:50:08 +08:00
get " /admin/email/rejected.json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
rejected = response . parsed_body
2017-08-05 02:04:26 +08:00
expect ( rejected . first [ 'error' ] ) . to eq ( I18n . t ( " emails.incoming.unrecognized_error " ) )
end
end
2018-06-11 12:50:08 +08:00
describe '#incoming' do
2017-08-05 02:04:26 +08:00
it 'should provide a string for a blank error' do
incoming_email = Fabricate ( :incoming_email , error : " " )
2018-06-11 12:50:08 +08:00
get " /admin/email/incoming/ #{ incoming_email . id } .json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
incoming = response . parsed_body
2017-08-05 02:04:26 +08:00
expect ( incoming [ 'error' ] ) . to eq ( I18n . t ( " emails.incoming.unrecognized_error " ) )
end
end
2018-12-03 19:51:59 +08:00
2019-03-27 00:59:56 +08:00
describe '#incoming_from_bounced' do
it 'raises an error when the email log entry does not exist' do
get " /admin/email/incoming_from_bounced/12345.json "
expect ( response . status ) . to eq ( 404 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " errors " ] ) . to include ( " Discourse::InvalidParameters " )
end
it 'raises an error when the email log entry is not marked as bounced' do
get " /admin/email/incoming_from_bounced/ #{ email_log . id } .json "
expect ( response . status ) . to eq ( 404 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " errors " ] ) . to include ( " Discourse::InvalidParameters " )
end
context 'bounced email log entry exists' do
2019-05-07 11:12:20 +08:00
fab! ( :email_log ) { Fabricate ( :email_log , bounced : true , bounce_key : SecureRandom . hex ) }
2019-03-27 00:59:56 +08:00
let ( :error_message ) { " Email::Receiver::BouncedEmailError " }
it 'returns an incoming email sent to the reply_by_email_address' do
SiteSetting . reply_by_email_address = " replies+%{reply_key}@example.com "
Fabricate ( :incoming_email ,
is_bounce : true ,
error : error_message ,
to_addresses : Email :: Sender . bounce_address ( email_log . bounce_key )
)
get " /admin/email/incoming_from_bounced/ #{ email_log . id } .json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " error " ] ) . to eq ( error_message )
end
it 'returns an incoming email sent to the notification_email address' do
Fabricate ( :incoming_email ,
is_bounce : true ,
error : error_message ,
to_addresses : SiteSetting . notification_email . sub ( " @ " , " +verp- #{ email_log . bounce_key } @ " )
)
get " /admin/email/incoming_from_bounced/ #{ email_log . id } .json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " error " ] ) . to eq ( error_message )
end
it 'raises an error if the bounce_key is blank' do
email_log . update ( bounce_key : nil )
get " /admin/email/incoming_from_bounced/ #{ email_log . id } .json "
expect ( response . status ) . to eq ( 404 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " errors " ] ) . to include ( " Discourse::InvalidParameters " )
end
it 'raises an error if there is no incoming email' do
get " /admin/email/incoming_from_bounced/ #{ email_log . id } .json "
expect ( response . status ) . to eq ( 404 )
2020-05-07 23:04:12 +08:00
json = response . parsed_body
2019-03-27 00:59:56 +08:00
expect ( json [ " errors " ] ) . to include ( " Discourse::NotFound " )
end
end
end
2018-12-03 19:51:59 +08:00
describe '#advanced_test' do
it 'should ...' do
email = << ~ EMAIL
From : " somebody " < somebody @example . com >
To : someone @example . com
Date : Mon , 3 Dec 2018 00 : 00 : 00 - 0000
Subject : This is some subject
Content - Type : text / plain ; charset = " UTF-8 "
Hello , this is a test !
- - -
This part should be elided .
EMAIL
post " /admin/email/advanced-test.json " , params : { email : email }
expect ( response . status ) . to eq ( 200 )
2020-05-07 23:04:12 +08:00
incoming = response . parsed_body
2018-12-03 19:51:59 +08:00
expect ( incoming [ 'format' ] ) . to eq ( 1 )
expect ( incoming [ 'text' ] ) . to eq ( " Hello, this is a test! " )
expect ( incoming [ 'elided' ] ) . to eq ( " --- \n \n This part should be elided. " )
end
end
2013-06-04 04:12:24 +08:00
end